第11章 CC2530串口通讯-串口控制LED
2018-01-01 12:49
288 查看
1 理论分析
1.1 Usart 发送
当 USART 收/发数据缓冲器、寄存器 UxBUF 写入数据时,该字节发送到输出引脚TXDx。 UxBUF 寄存器是双缓冲的。当字节传送开始时, UxCSR.ACTIVE 位变为高电平,而当字节传送结束时为低。当传送结束时,UxCSR.TX_BYTE 位设置为 1。当 USART 收/发数据缓冲寄存器就绪,准备接收新的发送数据时,就产生了一个中断请求。该中断在传送开始之后立刻发生,因此,当字节正在发送时,新的字节能够装入数据缓冲器。
1.2 Usart 接收
当 1 写入 UxCSR.RE 位时,在 UART 上数据接收就开始了。然后 UART 会在输入引脚 RXDx 中寻找有效起始位,并且设置 UxCSR.ACTIVE 位为 1。当检测出有效起始位时,收到的字节就传入到接收寄存器,UxCSR.RX_BYTE 位设置为 1。该操作完成时,产生接收中断。同时 UxCSR.ACTIVE 变为低电平。通过寄存器 UxBUF 提供收到的数据字节。当 UxBUF 读出时,UxCSR.RX_BYTE位由硬件清 0。
注意:当应用程序读 UxDBUF,很重要的一点是不清除 UxCSR.RX_BYTE。清除UxCSR.RX_BYTE 暗示 UART,使得它以为 UART RX 移位寄存器为空,即使它可能保存有未决数据 (一般是由于背对背传输) 。 所以 UART 声明 (TTL 为低电平) RT/RTS线,这会允许数据流进入 UART,导致潜在的溢出。因此 UxCSR.RX_BYTE 标志紧密结合了自动 RT/RTS 功能,因此只能被 SoC UART 本身控制。否则应用程序一般可以经历以下事件:RT/RTS 线保持声明(TTL 为低电平)的状态,即使一个背对背传输清楚地表明应该间歇性地停止数据流。
2实验详解
2.1实验目的
1)、通过实验掌握CC2530 芯片串口配置与使用2)、接收串口发送过来的数据,通过数据内容分析控制LED
注:嵌入式开发中,当程序能跑起来后,串口是第一个要跑起来的设备,所有的工作状态,交互信息都会从串口输出。我们用的是世界上最好的串口芯片FT232,贵的USB串口线都用该芯片。
2.2实验设备
硬件:PC 机一台 ZB2530(底板、核心板、仿真器、USB 线) 一套软件:2000/XP/win7 系统,IAR 8.20 集成开发环境、串口助手
2.3相关电路图
图1 FT232
图2 USB
2.4实验分析
相关寄存器CLKCONCMD、CLKCONSTA、PERCFG 、P0SEL、P2DIR、 UxCSR、UxUCR、UxGCR、UxBUF、UxBAUD、IRCON2如下表所示.表1 时钟控制命令
表2 时钟控制状态
表3 外设控制
表4端口0功能选择
表5端口2方向和端口0外设优先级模式
表6 USART 0控制和状态
表7 USART 0 UART控制
表8 USART 0通用控制
表9 USART 0接收/传送数据缓存
表10 USART 0 波特率控制
表11中断标志
表12 中断使能
表13 串口寄存器
由寄存器UxBAUD.BAUD_M[7:0]和UxGCR.BAUD_E[4:0]定义波特率。该波特率用于UART 传送,也用于SPI 传送的串行时钟速率。波特率由下式给出:
波特率=(256+BAUD_M)∗2BAUD_E228∗F
其中:F 是系统时钟频率,等于16 MHz RCOSC 或者32 MHz XOSC。
32 MHz 系统时钟常用的波特率设置。
表14 波特率设置
CC2530 配置串口的一般步骤:
1、配置IO,使用外部设备功能。此处配置P0_2 和P0_3 用作串口UART0
2、配置相应串口的控制和状态寄存器。此处配置 UART0 的工作寄存器。
3、配置串口工作的波特率, 此处配置为波特率为 115200。由于此实验增加了串口接收功能,寄存器有所改变(红色部分),具体配置如下:
PERCFG = 0x00; //位置1 P0 口 P0SEL = 0x0c; //P0_2,P0_3用作串口(外部设备功能) P2DIR &= ~0XC0; //P0优先作为UART0 U0CSR |= 0x80; //设置为UART方式 U0GCR |= 11; U0BAUD |= 216; //波特率设为115200 根据上面表中获得的数据 UTX0IF = 0; //UART0 TX 中断标志初始置位0 U0CSR |= 0x40; //允许接收 IEN0 |= 0x84; //开总中断允许接收中断
2.5源码分析
/**Includes*********************************************************************/ #include <ioCC2530.h> #include <string.h> /**宏定义***********************************************************************/ //定义数据类型 #define uint unsigned int #define uchar unsigned char //定义控制灯的端口 #define LED1 P1_0 #define LED2 P1_1 #define LED3 P0_4 /**函数声明*********************************************************************/ void initUART0(void); void Init_LED_IO(void); //LED初始化 /**全局变量*********************************************************************/ uchar Recdata[3]="000"; uchar RXTXflag = 1; uchar temp; uint datanumber = 0; uint stringlen; /** * @brief 主函数 * @param None * @retval None */ void main(void) { uchar i; Init_LED_IO(); initUART0(); while(1) { if(RXTXflag == 1) //接收状态 { if( temp != 0) { if((temp!='#')&&(datanumber<3)) { //’#‘被定义为结束字符 //最多能接收3个字符 Recdata[datanumber++] = temp; } else { RXTXflag = 3; //进入改变小灯的程序 } if(datanumber == 3)RXTXflag = 3; temp = 0; } } if(RXTXflag == 3) { if(Recdata[0]=='R') { if(Recdata[1]=='0') LED1 = 1; // R0# 关D1 else LED1 = 0; // R1# 开D1 } if(Recdata[0]=='Y') { if(Recdata[1]=='0') LED3 = 1; // Y0# 关D3 else LED3 = 0; // Y1# 开D3 } if(Recdata[0]=='G') { if(Recdata[1]=='0') LED2 = 1; // G0# 关D2 else LED2 = 0; // G1# 开D2 } if(Recdata[0]=='A') { if(Recdata[1]=='0') { LED1 = 1; LED3 = 1; LED2 = 1; // A0# 关所有LED } else { LED1 = 0; LED3 = 0; LED2 = 0; // A1# 开所有LED } } RXTXflag = 1; for(i=0;i<3;i++) Recdata[i]=' '; //清除刚才的命令 datanumber = 0; //指针归0 } }//while } /** * @brief 串口(UART0)初始化函数 * @param None * @retval None */ void initUART0(void) { CLKCONCMD &= ~0x40; //设置系统时钟源为32MHZ晶振 while(CLKCONSTA & 0x40); //等待晶振稳定 CLKCONCMD &= ~0x47; //设置系统主时钟频率为32MHZ PERCFG = 0x00; //位置1 P0口 P0SEL = 0x0c; //P0用作串口 P2DIR &= ~0XC0; //P0优先作为UART0 U0CSR |= 0x80; //串口设置为UART方式 U0GCR |= 11; U0BAUD |= 216; //波特率设为115200 UTX0IF = 1; //UART0 TX中断标志初始置位1 U0CSR |= 0X40; //允许接收 IEN0 |= 0x84; //开总中断,接收中断 } /** * @brief 初始化LED IO口 * @param None * @retval None */ void Init_LED_IO(void) { P1DIR = 0x03; //P10 P11 为输出 P0DIR = 0x10; //P04为输出 LED1 = 1; LED3 = 1; LED2 = 1; //灭LED } /** * @brief 串口接收一个字符:一旦有数据从串口传至CC2530,则进入中断,将接收到的数据赋值给变量temp. * @param None * @retval None */ #pragma vector = URX0_VECTOR __interrupt void UART0_ISR(void) { URX0IF = 0; //清中断标志 temp = U0DBUF; }
注意:本实验如果觉得较复杂可以先来看看参考代码,先把参考带代码看懂,再来看本实验的相关代码。
2.6实验现象
串口设置如下图.图3
串口字符控制灯状态表
表15串口字符控制灯状态表
本章参考代码
点击进入相关文章推荐
- cc2530 串口实验--控制led灯
- CC2530基础实验之串口控制LED灯
- cc2530 串口实验--控制led灯
- MSP430串口接收控制LED
- CC2530学习笔记の外部中断——按键控制LED
- 嵌入式成长轨迹51 【Zigbee项目】【CC2430基础实验】【在PC用串口控制LED】
- 远程控制通讯——基于树莓派 Python gpiozero 远程控制LED灯并返回控制结果
- 嵌入式QTSerialPort串口程序,rs458通讯方式下gpio控制引脚设置(接收)
- 2.串口通讯点亮LED灯
- RTOS_TINY中实现串口发送字符串控制LED
- 四、串口控制LED灯
- 上位机串口控制FPGA开发板LED
- 2440汇编控制LED(IO端口)和串口输出,用于调试wince的startup.s函数
- STM32 串口发数据来控制开发板上的LED亮度
- zigbee协议栈应用(三)无线收发控制LED与串口使用
- CC2530学习路线-基础实验-GPIO 控制LED灯亮灭(1)
- 要编写一个程序,控制串口通讯,java里面有...
- CC2530学习路线-基础实验-GPIO 按键控制LED灯亮灭(2)
- 利用.NET进行排队叫号LED屏控制与物理呼叫终端的串口通讯开发总结
- CC2530基础实验之采集光照模拟量控制LED状态