zoukankan      html  css  js  c++  java
  • CC2541蓝牙学习——串口_1

    CC2541有两个串行通信接口,分别是USART0和USART1,它们能够分别运行于异步UART模式或者同步SPI模式。两个USART具体同样的功能,可以设置在单独的I/O引脚。

    1.UART模式

    UART模式提供异步串行接口,在UART模式中,有2种接口选择方式:2线接口和4线接口。

    • 2线接口,使用RXD、TXD。
    • 4线接口,使用RXD、TXD、RTS和CTS。

    I/O外设引脚映射如下图所示:

    根据上面的外设I/O引脚映射可知

    UART0对应的外部设置IO引脚关系为:位置1:P0_2----RX    P0_3----TX     位置2:P1_4----RX    P1_5----TX

    UART1对应的外部设置IO引脚关系为:位置1:P0_5----RX    P0_4----TX     位置2:P1_7----RX    P1_6----TX

    UART模式的操作有以下特点。

    • 8位或者9位负载数据
    • 奇校验、偶校验或者无奇偶校验
    • 配置起始位和停止位电平
    • 配置LSB(最低有效位)或MSB(最高有效位)首先传输
    • 独立接收中断
    • 独立收发DMA触发
    • 奇偶校验和帧检验出错状态

    UART模式提供全双工传送,也就是说可以同时收发数据,传送一个UART字节包括1个起始位,8个数据位,1个作为可选的第9位数据或者奇偶校验位,再加上1个或者2个停止位。

    UART操作由USART控制和状态寄存器UxCSR以及UART控制寄存器UxUCR来控制,x是USART的编号,数值为0或者1。

    当UxCSR.MODE设置为1时设定为UART模式。

    1)UART的发送过程

    当USART收发数据缓冲器UxDBUF写入数据时,该字节自动发送到输出引脚TXD,UxDBUF寄存器时双缓冲的。当字节传送开始时,UxCSR.ACTIVE位变为高电平,而当字节传送结束时变为低电平。当传送结束时,UxCSR.TX_BYTE位设置为1。当USART收发数据缓冲寄存器就绪,准备接收新的发送数据时,就产生了一个中断请求,该中断在传送开始后立刻发生。

    2)UART的接收过程

    当1写入UxCSR.RE位时,UART开始接收数据。UART在输入引脚RXD上寻找有效起始位,并且设置UxCSR.ACTIVE位为1,当检测出有效起始位时,收到的字节就传入到接收寄存器,UxCSR.RX_BYTE位设置为1,该操作完成时,产生接收中断,同时UxCSR.ACTIVE变为0,通过寄存器UxDBUF提取收到的数据字节。当UxDBUF读出时,UxCSR.RX_BYTE位由硬件清零。

    当运行UART模式时,内部的波特率发生器设置UART波特率。当运行在SPI模式时,内部的波特率发生器设置SPI主时钟频率。波特率由寄存器UxBAUD.BAUD_M[7:0] 和UxGCR.BAUD_E[4:0]定义。该波特率用于UART传送,也用于SPI传送的串行时钟速率。波特率定义公式:

    式中:f是系统的时钟频率,等于16MHz或者32MHz

    标准波特率所需的寄存器值如下表所示,该表适用于32MHz系统时钟。波特率误差,用百分数表示。

    CC2530配置串口的一般步骤

    1、配置串口的备用位置,是备用位置1,还是备用位置2。配置寄存器PERCFG外设控制寄存器

    2、配置端口的外设优先级。此处配置P0外设优先作为UART0。配置寄存器P2DIR

    3、配置IO,使用外部设备功能。此处配置P0_2和P0_3用作串口UART0。配置寄存器P0SEL

    4、配置相应串口的控制和状态寄存器。配置寄存器U0CSR、U0UCR

    5、配置串口工作的波特率。配置寄存器U0GCR、U0BAUD

    6、将对应的串口接收/发送中断标志位清0,清零:TCON.URX0IF、TCON.URX1IF、IRCON2.UTX0IF、IRCON2.UTX1IF

    7、使能串口接收中断(一般发送不用中断),置1 IEN0.URX0IE

    8、开总中断

    中断相关的寄存器如下:

    IEN0(0xA8)

    TCON(0x88)

     

     IRCON2(0xE8)

     1 /*****************************************************************************
     2 *函 数 名:InitUART
     3 *功    能:UART0串口初始化,波特率:115200
     4 *入口参数:无
     5 *出口参数:无
     6 ******************************************************************************/
     7 void InitUART(void)
     8 {
     9   PERCFG &= ~0x01;     //USART0为位置1
    10   P2DIR &= ~0xc0;      //优先级USART0 >USART1 >定时器1
    11   P0SEL |= 0x0c;       //P0_2,P0_3 用作串口(外部设备功能)
    12   U0CSR |= 0x80;       //设置为UART 方式
    13   U0CSR |= 0x40;       //使能接收器
    14   
    15   U0UCR = 0x02;        //禁止流控制,8bits,无校验位,1位停止位
    16                        //起始位低电平,停止位高电平
    17   U0GCR |=11;          //32MHz 下的BAUD_E:11, 115200
    18   U0BAUD |= 216;       //32MHz 下的BAUD_M:216 11520
    19   UTX0IF = 0;          //UART0 TX 中断标志初始置位0
    20   IEN0 |= 0x04;        //使能USART0 RX中断
    21   EA = 1;              //开总中断
    22 }

    实例程序:串口控制LED1和LED2等的亮灭以及上位机控制串口接收,这里的通信协议比较简单,上位机发送两字节的数据:一个控制灯亮灭的字节,一个结束字节'#'

    "1#":LED1灭

    "2#":LED1亮

    "3#":LED2灭

    "4#":LED2亮

    "5#":LED1、LED2亮

    "6#":LED1、LED2灭

    "7#":CC2541向上位机发送字符串”Hello Chen Zhao!“ 按一下界面上的”接收“按钮,接收下位机发送过来的字符串。

    这个程序写的比较简单,这里只是一个演示,很容易出现发送解码错误,应该组帧,以一定的通信协议传输数据,包括帧头、校验、数据字节、帧尾,在后续串口介绍中,将专门介绍下这方面的技巧。

    为了验证程序,我做了一个上位机程序,界面如下,用labview软件编写的。如果需要的话,可以拿走源程序。

      1 /******************************************************************************
      2 *文 件 名:main.c
      3 *作    者:陈照
      4 *时    间:2015-05-18
      5 *版    本:1.0
      6 *描    述:UART串口发送与接收
      7 ******************************************************************************/
      8 #include <iocc2541.h>
      9 #include <string.h>
     10 
     11 typedef unsigned char uchar;
     12 typedef unsigned int  uint;
     13 
     14 #define LED1 P1_0
     15 #define LED2 P1_1
     16 
     17 char Rxdata[2] = " " ;  //串口接收字符串
     18 char Txdata[] = "Hello Chen Zhao!" ;  //串口接收字符串
     19 int  txnum = sizeof(Txdata);
     20 
     21 char temp;             //串口接收字符
     22 uchar datanum = 0;     //串口接收字符串长度
     23 uchar RXflag = 1;
     24 uchar TXflag = 0;
     25 
     26 /****************************************************************
     27 *函 数 名:InitClock
     28 *功    能:系统时钟初始化
     29 *入口参数:无
     30 *出口参数:无
     31 *****************************************************************/
     32 void InitClock(void)
     33 {
     34 CLKCONCMD &= ~0x40; // 设置系统时钟源为 32MHZ晶振
     35 while(CLKCONSTA & 0x40); // 等待晶振稳定 
     36 CLKCONCMD &= ~0x47; // 设置系统主时钟频率为 32MHZ
     37 }
     38 
     39 /******************************************************************************
     40 *函 数 名:InitLED
     41 *功    能:LED口功能初始化
     42 *入口参数:无
     43 *出口参数:无
     44 ******************************************************************************/
     45 void InitLED(uchar On_Off)
     46 {
     47   P1SEL &= ~0x03;      //P1.0、P1.1设置为通用I/O口
     48   P1DIR |=  0x03;      ///P1.0、P1.1设置为输出
     49   LED1 = On_Off;       ///P1.0、P1.1亮灭初始化
     50   LED2 = On_Off;
     51 }
     52 
     53 /******************************************************************************
     54 *函 数 名:InitUART
     55 *功    能:UART0串口初始化,波特率:115200
     56 *入口参数:无
     57 *出口参数:无
     58 ******************************************************************************/
     59 void InitUART(void)
     60 {
     61   PERCFG &= ~0x01;     //USART0为位置1
     62   P2DIR &= ~0xc0;      //优先级USART0 >USART1 >定时器1
     63   P0SEL |= 0x0c;       //P0_2,P0_3 用作串口(外部设备功能)
     64   U0CSR |= 0x80;       //设置为UART 方式
     65   U0CSR |= 0x40;       //使能接收器
     66   
     67   U0UCR = 0x02;        //禁止流控制,8bits,无校验位,1位停止位
     68                        //起始位低电平,停止位高电平
     69   U0GCR |=11;          //32MHz 下的BAUD_E:11, 115200
     70   U0BAUD |= 216;       //32MHz 下的BAUD_M:216 11520
     71   UTX0IF = 0;          //UART0 TX 中断标志初始置位0
     72   IEN0 |= 0x04;        //使能USART0 RX中断
     73   //IEN2 |= 0x04;      //使能USART0 TX中断
     74   EA = 1;              //开总中断
     75 }
     76 
     77 /****************************************************************************
     78 * 名    称: UartSendString()
     79 * 功    能: 串口发送函数
     80 * 入口参数: Data:发送缓冲区   len:发送长度
     81 * 出口参数: 无
     82 ****************************************************************************/
     83 void UartSendString(char *Data, int len)
     84 {
     85   uint i;
     86   U0CSR &= ~0x40;  
     87   
     88   for(i=0; i<len; i++)
     89   {
     90     U0DBUF = *Data++;
     91     while(UTX0IF == 0);
     92     UTX0IF = 0;
     93   }
     94   TXflag = 0;  
     95   U0CSR |= 0x40;       //使能接收器
     96 }
     97 
     98 /******************************************************************************
     99 *函 数 名:UART0_ISR
    100 *功    能:串口0中断服务程序
    101 *入口参数:无
    102 *出口参数:无
    103 ******************************************************************************/
    104 #pragma vector = URX0_VECTOR 
    105 __interrupt void UART0_ISR(void) 
    106 { 
    107   URX0IF = 0;           //UART0 RX中断标志位清0
    108   temp = U0DBUF;        //读取U0DBUF的值
    109 }
    110 
    111 /******************************************************************************
    112 *程序入口函数
    113 ******************************************************************************/
    114 int main(void)
    115 {  
    116   InitClock();
    117   InitLED(0);          //LED初始化,熄灭LED1、LED2
    118   InitUART();          //UART0串口初始化
    119   
    120   UartSendString(Txdata,txnum); 
    121   while(1)
    122   {
    123     if(RXflag == 1)
    124     {
    125       if(temp !=0)
    126       {
    127         if((temp != '#') && (datanum < 2))
    128         {
    129           Rxdata[datanum++] = temp;
    130         }
    131         else
    132         {
    133           RXflag = 2;
    134         }
    135 
    136           temp = 0;
    137       }
    138     }
    139     if(RXflag == 2)
    140     {
    141       switch(Rxdata[0])
    142       {
    143         case '1':LED1 = 0;break;
    144         case '2':LED1 = 1;break;
    145         case '3':LED2 = 0;break;
    146         case '4':LED2 = 1;break;
    147         case '5':
    148         {
    149           LED1 = 1;
    150           LED2 = 1;
    151           break;
    152         }
    153         case '6':
    154         {
    155           LED1 = 0;
    156           LED2 = 0;
    157           break;
    158         }
    159         case '7':
    160         {
    161            TXflag = 1;
    162            break;
    163            
    164         }
    165         default: 
    166         {//LED1 = 0;
    167          //LED2 = 0;
    168         }
    169       }
    170       RXflag = 1;
    171       memset(Rxdata, 0, 2);
    172       datanum = 0;
    173     }
    174     if(TXflag == 1)
    175     {
    176        UartSendString(Txdata,txnum); 
    177        
    178     }
    179   }
    180 }
    View Code
  • 相关阅读:
    Java 8与Runtime.getRuntime().availableProcessors()
    nginx配置
    周末完成工作小结
    CentOS 8 安装MySQL 8.0
    centOS8网络获取不了
    IUAP平台新增菜单存储过程
    centOS8安装Docker
    Mybatis里用到的设计模式
    2020,回顾过往,展望未来
    使用 Apache SSI(Server Side Includes) 制作多语言版静态网页
  • 原文地址:https://www.cnblogs.com/chenzhao207/p/4531941.html
Copyright © 2011-2022 走看看