【CC2530入门教程-05】CC2530的串行接口原理与应用

[复制链接]
 楼主| ohy3686 发表于 2017-7-1 17:31 | 显示全部楼层 |阅读模式
本帖最后由 ohy3686 于 2017-7-1 17:34 编辑

【CC2530入门教程-05】CC2530的串行接口原理与应用

一、并行通信与串行通信
    微控制器与外设之间的数据通信,根据连线结构传送方式的不同,可以分为两种:并行通信和串行通信。
    并行通信:指数据的各位同时发送或接收,每个数据位使用单独的一条导线。传输速度快、效率高,但需要的数据线较多,成本高。
    串行通信:指数据一位接一位地顺 序发送或接收。需要的数据线少,成本低,但传输速度慢,效率低。

二、CC2530的串口通信模块
    CC2530有两个串行通信接口USART0USART1,它们能够分别运行于异步UART模式或者同步SPI模式
    两个USART接口具有相同的功能,通过PERCFG寄存器可以设置两个USART接口对应外部I/O引脚的映射关系:
    位置1RX0 --- P0_2   TX0 --- P0_3               RX1 --- P0_5   TX1 --- P0_4
    位置2RX0 --- 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的接收/发送数据缓冲寄存器。
    <5> 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接口中,公头和母头的排列顺序是不同的


四、实训项目:上位机通过串口控制LED灯的开关

【1】计算波特率
    CC2530的波特率BAUD_EBAUD_M共同决定:


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



【2】串口0的初始化函数
    选择外设的引脚映射位置,并将对应的引脚设置为外设功能 ,然后对波特率、控制寄存器和中断的相关控制位进行设置。
【3】数据接收中断服务函数
    USART0发送完成的中断向量是:0x3B,也可以使用宏定义:URX0_VEXTOR。在该中断服务函数中,要手工清除接收中断标志位URX0IF
    当数据接收完毕后,通过将一个自定义的变量Flag设置为1,告诉主函数,已经成功接收到所需要的数据,主函数可以对其进行解析和执行指令。
【4】发送字节及发送字符串函数
    当USART的发送/接收数据缓冲寄存器UxDBUF被写入数据时,该字节就会发送到TXD引脚,开始数据的传输。由于UxDBUF是双缓冲的,所以在发送开始后会立即触发TX完成中断标志UTX0IF,并且数据缓冲器被卸载,也就是说,当字节正在发送时,新的字节能够装入数据缓冲器UxDBUF
    在单字节的发送函数中,把要发送的数据写入UxDBUF后,查询TX完成标志UTX0IF,当该标志被置1时,表示数据发送完成,然后清除该标志。
【5】项目源代码
  1. #include "ioCC2530.h"
  2. #define  LED5   P1_3
  3. #define  LED6   P1_4
  4. unsigned char dataRecv;
  5. unsigned char Flag = 0;
  6. /*===================UR0初始化函数====================*/
  7. void Init_Uart0()
  8. {
  9.   PERCFG = 0x00;    //串口0的引脚映射到位置1,即P0_2和P0_3
  10.   P0SEL = 0x0C;     //将P0_2和P0_3端口设置成外设功能
  11.   U0BAUD = 59;      //16MHz的系统时钟产生9600BPS的波特率
  12.   U0GCR = 9;
  13.   U0UCR |= 0x80;    //禁止流控,8位数据,清除缓冲器
  14.   U0CSR |= 0xC0;    //选择UART模式,使能接收器
  15.   UTX0IF = 0;       //清除TX发送中断标志
  16.   URX0IF = 0;       //清除RX接收中断标志
  17.   URX0IE = 1;       //使能URAT0的接收中断
  18.   EA = 1;           //使能总中断
  19. }
  20. /*================UR0接收中断服务函数================*/
  21. #pragma vector = URX0_VECTOR
  22. __interrupt void UR0_RecvInt()
  23. {
  24.   URX0IF = 0;           //清除RX接收中断标志
  25.   dataRecv =  U0DBUF;   //将数据从接收缓冲区读出
  26.   Flag = 1;             //设置接收指令标志
  27. }
  28. /*=================UR0发送单字节函数=================*/
  29. void UR0SendByte(unsigned char dat)
  30. {
  31.   U0DBUF = dat;         //将要发送的1字节数据写入U0DBUF
  32.   while(!UTX0IF);       //等待TX中断标志,即数据发送完成
  33.   UTX0IF = 0;           //清除TX中断标志,准备下一次发送
  34. }
  35. /*=================UR0发送字符串函数===============*/
  36. void UR0SendString(unsigned char *str)
  37. {
  38.   while(*str != '\0')       //发送一个字符串
  39.   {
  40.     UR0SendByte(*str++);    //逐个发送字符串中的字节
  41.   }
  42. }
  43. /*================执行上位机的指令=================*/
  44. void ExecuteTheOrder()
  45. {
  46.   Flag = 0 ;            //清除接收指令标志
  47.   switch(dataRecv)
  48.   {
  49.     case 0xa1:
  50.       LED5 = 1;
  51.       UR0SendString("The LED5 is Open!\r\n");
  52.     break;
  53.     case 0xa2:
  54.       LED5 = 0;
  55.       UR0SendString("The LED5 is Closed!\r\n");
  56.     break;
  57.     case 0xb1:
  58.       LED6 = 1;
  59.       UR0SendString("The LED6 is Open!\r\n");
  60.     break;
  61.     case 0xb2:
  62.       LED6 = 0;
  63.       UR0SendString("The LED6 is Closed!\r\n");
  64.     break;
  65.   }
  66. }
  67. /*=================端口初始化函数====================*/
  68. void Init_Port()
  69. {
  70.   P1SEL &= ~0x18;       //将P1_3和P1_4设置为通用I/O端口功能
  71.   P1DIR |= 0x18;        //将P1_3和P1_4的端口设置为输出
  72.   LED5 = 0;             //关闭LED5灯
  73.   LED6 = 0;             //关闭LED6灯
  74. }
  75. /*===================主函数=========================*/
  76. void main()
  77. {
  78.   Init_Port();         //初始化端口
  79.   Init_Uart0();        //初始化串口0
  80.   //先发送一个字符串,测试串口0数据传输是否正确
  81.   UR0SendString("*广东职业技术学院--欧浩源*\r\n");
  82.   while(1)
  83.   {
  84.     if(Flag == 1)      //查询是否收到上位机指令
  85.     {
  86.      
  87.       ExecuteTheOrder();    //解析并执行指令
  88.     }
  89.   }
  90. }

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
 楼主| ohy3686 发表于 2017-7-2 15:33 | 显示全部楼层
系列教材完成。
好风四季 发表于 2018-12-7 08:39 | 显示全部楼层
厉害了,我看到中断里面只是处理FLAG,中断函数越短越好,不明觉厉!学习了!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:广东职业技术学院 欧浩源(ohy3686@foxmail.com)    [Zigbee技术&物联网应用] 群:168225322    [技术交流微信]:gzyohy (暗号:宝塔镇河妖)

322

主题

899

帖子

3548

粉丝
快速回复 在线客服 返回列表 返回顶部