您的位置:首页 > 其它

第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串口字符控制灯状态表



本章参考代码

点击进入
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: