• CC2530串口通信


    任何USART双向通信至少需要两个脚:接收数据输入(RX)和发送数据输出(TX)。

     RX:接收数据串行输入。通过采样技术来区别数据和噪音,从而恢复数据。

     TX :发送数据输出。当发送器被禁止时,输出引脚恢复到它的I/O端口配置。当发送器被激活,并且不发送数据时,TX引脚处于高电平。在单线和智能卡模式里,此I/O 口被同时用于数据的发送和接收。

    并行通信与串行通信

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

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

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

    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

    PERCFG寄存器:

     

    UART口与计算机的COM口连接

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

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

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

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

     

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

    需要用到的寄存器:

    端口相关的配置

    PERCFG:设置两个USART接口对应外部I/O引脚的映射关系:

    P0SEL: 设置成外设功能(1为外设)

    波特率相关的配置

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

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

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

      U0GCR = 8;            //16MHz---9; 32MHz---8

    串口属性相关的配置:

    U0UCR:USART 0 UART控制

    U0SCR:USART 0 控制与状态

     

    串口中断相关的配置

    UTX0IF = 0;           //清除TX发送中断标志

     URX0IF = 0;           //清除RX接收中断标志

     URX0IE = 1;           //使能URAT0的接收中断

    EA = 1;           //使能总中断

     

    题目:上位机通过串口控制LED灯的开关

    CC2530的串口0与上位机连接,在16HMz的内部系统时钟下产生9600BPS的波特率,禁止流控,无奇偶校验,采用8位数据,1位停止位,LSB先发送。上位机发送一一个字节控制目标板上的LED5和LED6的开关,具体要求如下:

    (1)0xA1--LED5点亮;返回字符串“The LED5 is Open!" (LED6用0xB1)

    (2)0xA2--LED5熄灭;返回字符串“The LED5 is Closed!" (LED6用0xB2)

    (3) 串口0数据的接收数据采用中断方式,发送数据采用查询方式。

     

     

    思路:

    1】计算波特率

    【2】串口0的初始化函数

              选择外设的引脚映射位置,并将对应的引脚设置为外设功能 ,然后对波特率、控制寄存器和中断的相关控制位进行设置。

    【3】数据接收中断服务函数

             USART0发送完成的中断向量是:0x3B ,也可以使用宏定义:URX0_VEXTOR 。在该中断服务函数中,要手工清除接收中断标志位URX0IF。

            当数据接收完毕后,通过将一个自定义的变量Flag设置为1,告诉主函数,已经成 功接收到所需要的数据,主函数可以对其进行解析和执行指令。

    【4】发送字节及发送字符串函数

             当USART 的发送/接收数据缓冲寄存器UxDBUF被写入数据时,该字节就会发送到TXD引脚,开始数据的传输。由于UxDBUF是双缓冲的,所以在发送开始后会立即触发TX完成中断标志UTX0IF,并且数据缓冲器被卸载,也就是说,当字节正在发送时,新 的字节能够装入数据缓冲器UxDBUF。

            在单字节的发送函数中,把要发送的数据写入UxDBUF后,查询TX完成标志UTX0IF,当该标志被置1时,表示数据发送完成,然后清除该标志。

    代码:

     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  0100 0000 0位默认1的位置
    10   P0SEL = 0x0C;     //将P0_2和P0_3端口设置成外设功能 0000 1100  1为外设功能
    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 != '')       //发送一个字符串
    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!
    ");
    52     break;
    53     case 0xa2:
    54       LED5 = 0;
    55       UR0SendString("The LED5 is Closed!
    ");
    56     break;
    57     case 0xb1:
    58       LED6 = 1;
    59       UR0SendString("The LED6 is Open!
    ");
    60     break;
    61     case 0xb2:
    62       LED6 = 0;
    63       UR0SendString("The LED6 is Closed!
    ");
    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("I am OK!
    ");
    82   while(1)
    83   {
    84     if(Flag == 1)      //查询是否收到上位机指令
    85     {
    86       ExecuteTheOrder();    //解析并执行指令
    87     }
    88   }
    89 }
    View Code
  • 相关阅读:
    Java WebSocket生命周期
    软件网络总结
    js模态弹窗
    spring boot
    spring aop
    lvs分布式
    如何在大牛面前装逼
    Java学习的思考
    javase知识点
    <nginx+PHP>nginx环境下配置支持php7
  • 原文地址:https://www.cnblogs.com/yuling520/p/12698891.html
Copyright © 2020-2023  润新知