一、并行通信与串行通信

微控制器与外设之间的数据通信,根据连线结构和传送方式的不同,可以分为两种:并行通信和串行通信。

并行通信:指数据的各位同时发送或接收,每个数据位使用单独的一条导线。传输速度快、效率高,但需要的数据线较多,成本高。

串行通信:指数据一位接一位地顺序发送或接收。需要的数据线少,成本低,但传输速度慢,效率低。

二、CC2530的串口通信模块

CC2530有两个串行通信接口USART0USART1,它们能够分别运行于异步UART模式或者同步SPI模式。

两个USART接口具有相同的功能,通过PERCFG寄存器可以设置两个USART接口对应外部I/O引脚的映射关系:

位置1:RX0 --- P0_2 TX0 --- P0_3 RX1 --- P0_5 TX1 --- P0_4

位置2:RX0 --- P1_4 TX0 --- P1_5 RX1 --- P1_7 TX1 --- P1_6

对每个USART串口通信编程,本质是设置相关的5个寄存器:

<1> UxCSR: USARTx的控制和状态寄存器。

<2> UxUCR: USARTx的UART控制寄存器。

<3> UxGCR: USARTx的通用控制寄存器。

<4> UxDBUF:USARTx的接收/发送数据缓冲寄存器。

<4> UxBAUD:USARTx的波特率控制寄存器。

三、UART口与计算机的COM口连接

先认识两种电平:TTL电平和RS232电平。

TTL电平: 逻辑0----小于0.8V 逻辑1----大于2.4V。

RS232电平: 逻辑0----5~15V 逻辑1---- -5~-15V。

计算机的串行通信接口是RS-232的标准接口,而CC2530单片机的UART接口则是TTL电平,两者的电气规范不一致,所以要完成两者之间的数据通信,就需要借助接口芯片在两者之间进行电平转换,常用的有MAX232芯片。

#导入Word文档图片# CC2530 串口配置步骤_串口

注意:DB9接口中,公头和母头的排列顺序是不同的。

四、原理图数据手册分析

#导入Word文档图片# CC2530 串口配置步骤_串口_02

#导入Word文档图片# CC2530 串口配置步骤_串口_03


#导入Word文档图片# CC2530 串口配置步骤_串口_04

#导入Word文档图片# CC2530 串口配置步骤_串口_05

  • 配置串口的步骤

五、代码示例

  • 示例1: 编写串口初始化函数,实现串口字符串发送(CPU频率在16MHZ下,波特率的为9600


#include <ioCC2530.h>

#include <string.h>


//定义LED灯的端口

#define LED1 P1_2

#define LED2 P1_3


//定义KEY按键的端口

#define KEY1 P1_0 //定义按键为P1_0口控制

#define KEY2 P1_1 //定义按键为P1_1口控制


/*

函数功能:LED灯IO口初始化

硬件连接:LED1-->P1_2 , LED2-->P1_3

*/

void LED_Init(void)

{

P1DIR |=0x3<<2; //配置P1_2、P1_3为输出模式

LED1 = 1;

LED2 = 1;

}


/*

函数功能:按键IO口初始化

硬件连接:KEY1-->P1_0 KEY2-->P1_1

*/

void KEY_Init(void)

{

P1SEL&=~(0x3<<0); //配置P1_0,P1_1处于通用GPIO口模式

P1DIR&=~(0x3<<0); //配置P1_0,P1_1为输入模式

P1INP|= 0x3<<0; //上拉

}



void delay10ms(void) //误差 0us

{

unsigned char a,b,c;

for(c=193;c>0;c--)

for(b=118;b>0;b--)

for(a=2;a>0;a--);

}



/*

函数功能:按键扫描

返 回 值:按下的按键值

*/

unsigned char Key_Scan(void)

{

static unsigned char stat=1;

if((KEY1==0||KEY2==0)&&stat)

{

stat=0;

delay10ms();

if(KEY1==0)return 1;

if(KEY2==0)return 2;

}

else

{

if(KEY1&&KEY2)stat=1;

}

return 0;

}


/*

函数功能:串口0初始化

*/

void Init_Uart0(void)

{

PERCFG&=~(1<<0); //串口0的引脚映射到位置1,即P0_2和P0_3

P0SEL|=0x3<<2; //将P0_2和P0_3端口设置成外设功能

U0BAUD = 59; //16MHz的系统时钟产生9600BPS的波特率

U0GCR&=~(0x1F<<0);//清空波特率指数

U0GCR|=9<<0; //配置波特率的指数值

U0UCR |= 0x80; //禁止流控,8位数据,清除缓冲器

U0CSR |= 0x3<<6; //选择UART模式,使能接收器

}


/*

函数功能:UART0发送字符串函数

*/

void UR0SendString(char *str,unsigned int len)

{

int j;

for(j=0;j<len;j++)

{

U0DBUF = *str++; //将要发送的1字节数据写入U0DBUF

while(UTX0IF == 0);//等待数据发送完成

UTX0IF = 0; //清除发送完成标志,准备下一次发送

}

}


/*主函数*/

void main(void)

{

char buff[]="-----万邦易嵌嵌入式开发-----\r\n";

unsigned char key;

LED_Init();//初始化LED灯控制IO口

KEY_Init();//按键初始化

Init_Uart0(); //初始化串口0

while(1)

{

key=Key_Scan();

if(key)

{

//先发送一个字符串,测试串口0数据传输是否正确

UR0SendString(buff,strlen(buff));

LED1 = !LED1;

LED2 = !LED2;

}

}

}


  • 示例2:编写串口初始化函数,实现串口字符串发送(CPU频率在16MHZ下,波特率为115200


#include <ioCC2530.h>

#include <string.h>


//定义LED灯的端口

#define LED1 P1_2

#define LED2 P1_3


//定义KEY按键的端口

#define KEY1 P1_0 //定义按键为P1_0口控制

#define KEY2 P1_1 //定义按键为P1_1口控制


/*

函数功能:LED灯IO口初始化

硬件连接:LED1-->P1_2 , LED2-->P1_3

*/

void LED_Init(void)

{

P1DIR |=0x3<<2; //配置P1_2、P1_3为输出模式

LED1 = 1;

LED2 = 1;

}


/*

函数功能:按键IO口初始化

硬件连接:KEY1-->P1_0 KEY2-->P1_1

*/

void KEY_Init(void)

{

P1SEL&=~(0x3<<0); //配置P1_0,P1_1处于通用GPIO口模式

P1DIR&=~(0x3<<0); //配置P1_0,P1_1为输入模式

P1INP|= 0x3<<0; //上拉

}



void delay10ms(void) //误差 0us

{

unsigned char a,b,c;

for(c=193;c>0;c--)

for(b=118;b>0;b--)

for(a=2;a>0;a--);

}



/*

函数功能:按键扫描

返 回 值:按下的按键值

*/

unsigned char Key_Scan(void)

{

static unsigned char stat=1;

if((KEY1==0||KEY2==0)&&stat)

{

stat=0;

delay10ms();

if(KEY1==0)return 1;

if(KEY2==0)return 2;

}

else

{

if(KEY1&&KEY2)stat=1;

}

return 0;

}


/*

函数功能:串口0初始化

*/

void Init_Uart0(void)

{

PERCFG&=~(1<<0); //串口0的引脚映射到位置1,即P0_2和P0_3

P0SEL|=0x3<<2; //将P0_2和P0_3端口设置成外设功能

U0BAUD = 216; //16MHz的系统时钟产生115200BPS的波特率

U0GCR&=~(0x1F<<0);//清空波特率指数

U0GCR|=12<<0; //16MHz的系统时钟产生115200BPS的波特率

U0UCR |= 0x80; //禁止流控,8位数据,清除缓冲器

U0CSR |= 0x3<<6; //选择UART模式,使能接收器

}


/*

函数功能:UART0发送字符串函数

*/

void UR0SendString(char *str,unsigned int len)

{

int j;

for(j=0;j<len;j++)

{

U0DBUF = *str++; //将要发送的1字节数据写入U0DBUF

while(UTX0IF == 0);//等待数据发送完成

UTX0IF = 0; //清除发送完成标志,准备下一次发送

}

}


/*主函数*/

void main(void)

{

char buff[]="-----万邦易嵌嵌入式开发-----\r\n";

unsigned char key;

LED_Init();//初始化LED灯控制IO口

KEY_Init();//按键初始化

Init_Uart0(); //初始化串口0

while(1)

{

key=Key_Scan();

if(key)

{

//先发送一个字符串,测试串口0数据传输是否正确

UR0SendString(buff,strlen(buff));

LED1 = !LED1;

LED2 = !LED2;

}

}

}


六、波特率计算

  • 计算波特率

CC2530的波特率由BAUD_E和BAUD_M共同决定:

#导入Word文档图片# CC2530 串口配置步骤_串口_06

F为微控制器的系统时钟频率:16MHz32MHz

在TI公司提供的数据手册中,给出了32MHz系统时钟下各常用波特率的参数值,由计算公式亦不难得出16MHz系统时钟下对应的参数值。

#导入Word文档图片# CC2530 串口配置步骤_串口_07

#导入Word文档图片# CC2530 串口配置步骤_串口_08