IT技术互动交流平台

CC2541蓝牙学习串口_1

作者:欣庸  来源:IT165收集  发布日期:2015-05-27 21:29:50

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系统时钟。波特率误差,用百分数表示。

QTgpPC9zdHJvbmc+PC9wPgo8cD48aW1nIHNyYz0="http://www.it165.net/uploadfile/files/2015/0527/2015052719591851.png" alt="" />

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灭

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

为了验证程序,我做了一个上位机程序,界面如下,用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 temp;             //串口接收字符
 19 uchar datanum = 0;     //串口接收字符串长度
 20 uchar RXflag = 1;
 21 
 22 /****************************************************************
 23 *函 数 名:InitClock
 24 *功    能:系统时钟初始化
 25 *入口参数:无
 26 *出口参数:无
 27 *****************************************************************/
 28 void InitClock(void)
 29 {
 30 CLKCONCMD &= ~0x40; // 设置系统时钟源为 32MHZ晶振
 31 while(CLKCONSTA & 0x40); // 等待晶振稳定 
 32 CLKCONCMD &= ~0x47; // 设置系统主时钟频率为 32MHZ
 33 }
 34 
 35 
 36 /******************************************************************************
 37 *函 数 名:InitLED
 38 *功    能:LED口功能初始化
 39 *入口参数:无
 40 *出口参数:无
 41 ******************************************************************************/
 42 void InitLED(uchar On_Off)
 43 {
 44   P1SEL &= ~0x03;      //P1.0、P1.1设置为通用I/O口
 45   P1DIR |=  0x03;      ///P1.0、P1.1设置为输出
 46   LED1 = On_Off;       ///P1.0、P1.1亮灭初始化
 47   LED2 = On_Off;
 48 }
 49 
 50 /******************************************************************************
 51 *函 数 名:InitUART
 52 *功    能:UART0串口初始化,波特率:115200
 53 *入口参数:无
 54 *出口参数:无
 55 ******************************************************************************/
 56 void InitUART(void)
 57 {
 58   PERCFG &= ~0x01;     //USART0为位置1
 59   P2DIR &= ~0xc0;      //优先级USART0 >USART1 >定时器1
 60   P0SEL |= 0x0c;       //P0_2,P0_3 用作串口(外部设备功能)
 61   U0CSR |= 0x80;       //设置为UART 方式
 62   U0CSR |= 0x40;       //使能接收器
 63   
 64   U0UCR = 0x02;        //禁止流控制,8bits,无校验位,1位停止位
 65                        //起始位低电平,停止位高电平
 66   U0GCR |=11;          //32MHz 下的BAUD_E:11, 115200
 67   U0BAUD |= 216;       //32MHz 下的BAUD_M:216 11520
 68   UTX0IF = 0;          //UART0 TX 中断标志初始置位0
 69   IEN0 |= 0x04;        //使能USART0 RX中断
 70   EA = 1;              //开总中断
 71 }
 72 
 73 
 74 /******************************************************************************
 75 *函 数 名:UART0_ISR
 76 *功    能:串口0中断服务程序
 77 *入口参数:无
 78 *出口参数:无
 79 ******************************************************************************/
 80 #pragma vector = URX0_VECTOR 
 81 __interrupt void UART0_ISR(void) 
 82 { 
 83   URX0IF = 0;           //UART0 RX中断标志位清0
 84   temp = U0DBUF;        //读取U0DBUF的值
 85 }
 86 
 87 /******************************************************************************
 88 *程序入口函数
 89 ******************************************************************************/
 90 int main(void)
 91 {  
 92   InitClock();
 93   InitLED(0);          //LED初始化,熄灭LED1、LED2
 94   InitUART();          //UART0串口初始化
 95   
 96   while(1)
 97   {
 98     if(RXflag == 1)
 99     {
100       if(temp !=0)
101       {
102         if((temp != '#') && (datanum < 2))
103         {
104           Rxdata[datanum++] = temp;
105         }
106         else
107         {
108           RXflag = 2;
109         }
110 
111           temp = 0;
112       }
113     }
114     if(RXflag == 2)
115     {
116       switch(Rxdata[0])
117       {
118         case '1':LED1 = 0;break;
119         case '2':LED1 = 1;break;
120         case '3':LED2 = 0;break;
121         case '4':LED2 = 1;break;
122         case '5':
123         {
124           LED1 = 1;
125           LED2 = 1;
126           break;
127         }
128         case '6':
129         {
130           LED1 = 0;
131           LED2 = 0;
132           break;
133         }
134         default: 
135         {
136         };
137       }
138       RXflag = 1;
139       memset(Rxdata, 0, 2);
140       datanum = 0;
141     }
142   }
143 }
Tag标签: 蓝牙   串口  
  • 专题推荐

About IT165 - 广告服务 - 隐私声明 - 版权申明 - 免责条款 - 网站地图 - 网友投稿 - 联系方式
本站内容来自于互联网,仅供用于网络技术学习,学习中请遵循相关法律法规