CC2530 串口配置步骤
编辑:
2023-07-06 15:34:06
一、并行通信与串行通信

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


【资料图】

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

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

二、CC2530的串口通信模块

CC2530有两个串行通信接口USART0和USART1,它们能够分别运行于异步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芯片。

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

四、原理图数据手册分析

配置串口的步骤

五、代码示例

(1) 示例1: 编写串口初始化函数,实现串口字符串发送 (CPU频率在32MHZ下,波特率的为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) {     staticunsigned 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;     //32MHz的系统时钟产生115200BPS的波特率   U0GCR&=~(0x1F< <0);//清空波特率指数   U0GCR|=11< <0;      //32MHz的系统时钟产生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;       //清除发送完成标志,准备下一次发送   } } ​ /******************************************   * 函数描述:32M系统时钟下的毫秒延时函数   ******************************************/   void Delay_ms(unsigned int ms)   {     unsigned int i,j;     for(i = 0; i < ms; i++)     {       for(j = 0;j < 1774; j++);     }   }   ​ ​ /*主函数*/ void main(void) {     char buff[]="-----万邦易嵌嵌入式开发-----\\r\\n";     unsigned char key;     CLKCONCMD &= ~0x40;            //设置系统时钟源为32MHz晶振       for(; CLKCONSTA & 0x40;);      //等待晶振稳定       CLKCONCMD &= ~0X47;            //设置系统主时钟频率为32MHz          LED_Init();//初始化LED灯控制IO口     KEY_Init();//按键初始化     Init_Uart0();        //初始化串口0     while(1)               {          key=Key_Scan();        if(key)        {           //先发送一个字符串,测试串口0数据传输是否正确           UR0SendString(buff,strlen(buff));                LED2 = !LED2;        }            } } ​ ​

(2)示例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;       //清除发送完成标志,准备下一次发送   } } ​ /******************************************   * 函数描述:32M系统时钟下的毫秒延时函数   ******************************************/   void Delay_ms(unsigned int ms)   {     unsigned int i,j;     for(i = 0; i < ms; i++)     {       for(j = 0;j < 1774; j++);     }   }   ​ ​ /*主函数*/ 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));                LED2 = !LED2;        }            } } ​ ​

(3)示例3:中断接收

#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口控制 ​ unsigned char dataRecv; unsigned char Flag = 0; ​ /* 函数功能: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模式,使能接收器   UTX0IF = 0;       //清除TX发送中断标志   URX0IF = 0;       //清除RX接收中断标志   URX0IE = 1;       //使能URAT0的接收中断   EA = 1;           //使能总中断 } ​ ​ ​ /* 函数功能: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;       //清除发送完成标志,准备下一次发送   } } ​ /*================UR0接收中断服务函数================*/ #pragma vector = URX0_VECTOR __interrupt void UART0_RecvInterrupt() {   URX0IF = 0;           //清除RX接收中断标志   dataRecv =  U0DBUF;   //将数据从接收缓冲区读出   Flag = 1;             //设置接收指令标志 } ​ ​ /*================执行上位机的指令=================*/ void ExecuteTheOrder() {   Flag = 0 ;            //清除接收指令标志   switch(dataRecv)   {     case "A":       UR0SendString("选择1!\\r\\n",9);       break;     case "B":       UR0SendString("选择2!\\r\\n",9);       break;     case "C":       UR0SendString("选择3!\\r\\n",9);       break;     case "D":       UR0SendString("选择4!\\r\\n",9);       break;   } } ​ ​ /*主函数*/ 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));                LED2 = !LED2;        }              if(Flag == 1)      //查询是否收到上位机指令       {         ExecuteTheOrder();       }     } } ​ ​ ​
六、波特率计算

计算波特率

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

F为微控制器的系统时钟频率:16MHz或32MHz。

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

关键词:

分享到:
相关阅读>>
最新排行
热门资讯