CC2530 串口配置步骤

描述

一、并行通信与串行通信

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

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

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

二、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)
 {
     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;     //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系统时钟下对应的参数值。

微控制器

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分