第二部分 基础篇-第6章 CC2530串口通讯-串口控制LED
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相关电路图
2.4实验分析
相关寄存器CLKCONCMD、CLKCONSTA、PERCFG 、P0SEL、P2DIR、 UxCSR、UxUCR、UxGCR、UxBUF、UxBAUD、IRCON2如下表所示.
由寄存器UxBAUD.BAUD_M[7:0]和UxGCR.BAUD_E[4:0]定义波特率。该波特率用于UART 传送,也用于SPI 传送的串行时钟速率。波特率由下式给出:
其中:F 是系统时钟频率,等于16 MHz RCOSC 或者32 MHz XOSC。
32 MHz 系统时钟常用的波特率设置。
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实验现象
串口设置如下图.
串口字符控制灯状态表
本章参考代码
上一篇: spark提交任务事例
下一篇: 面试总结二:对CAS的理解