目录
前言
一、实验相关电路图
二、实验相关理论与寄存器
1.并行通信与串行通信
2.URAT
3.同步通信与异步通信
4.外设I/O
5.CC2530 的串口通信模块
6.相关寄存器
三、源码分析
1.发送字符串
2.接收字符串
前言
本实验用于学习CC2530芯片:
- 发送与接收字符串的串口配置与使用
- 观察串口发送指示灯的变化
一、实验相关电路图
P0_2、 P0_3 配置为外设功能时: P0_2 为 RX, P0_3 为 TX。USART0 和 USART1 是串行通信接口,它们能够分别运行于异步 UART 模式或者同步 SPI 模式。两个 USART 具有同样的功能,可以设置在单独的 I/O 引脚。更详细的说明请参考数据手册 7.6 和16.1 节。
二、实验相关理论与寄存器
1.并行通信与串行通信
微控制器与外设之间的数据通信,根据连线结构和传送方式的不同,可以分为两种:并行通信和串行通信。
并行通信:指数据的各位同时发送或接收,每个数据位使用单独的一条导线。传输速度快、效率高,但需要的数据线较多,成本高。
串行通信:指数据一位接一位地顺序发送或接收。需要的数据线少,成本低,但传输速度慢,效率低。
2.URAT
UART,即通用异步收发传输器(Universal Asynchronous Receiver/Transmitter),是一种异步收发传输器,是电脑硬件的一部分。它将要传输的资料在串行通信与并行通信之间加以转换。作为把并行输入信号转成串行输出信号的芯片,UART通常被集成于其他通讯接口的连结上。我们通常说的串口——UART包含TTL电平和RS-232电平两种,在嵌入式系统里面,单片机的串口一般都是TTL电平。
UART因为有两根线数据线TX和RX,可以以全双工的形式进行发送和接收数据,同一时刻,两条链路的发送器和接收器可以同时传输数据。
3.同步通信与异步通信
同步是指:发送方发出数据后,等接收方发回响应以后才发下一个数据包的通讯方式。
异步是指:发送方发出数据后,不等接收方发回响应,接着发送下个数据包的通讯方式。
其中SPI IIC为同步通信,UART为异步通信,USART为同步&异步通信(STM32有所应用)。
4.外设I/O
I/O接口是介于CPU和外设之间的一种缓冲电路,在CPU和外设之间起到速度匹配、信号转换(数据传输)等作用。对于USART 和定时器 I/O,在一个数字 I/O 引脚上选择外设 I/O 功能,需要设置对应的 PxSEL 位为 1。
注意,该外部单元具有两个可以选择的位置对应它们的 I/O 引脚,详情见下表。如果有关于 I/O 映射的冲突设置,可以在这些之间设置优先级(使用 P2SEL.PRIxP1 和 P2DIR.PRIP0 位)。所有不会导致冲突的组合都可以使用。注意即使没有使用,外设一般也会出现在选定的位置,使用引脚的其他外设必须给予较高的优先级。例外情况是流量控制禁用时 UART 模式下 USART 的 RTS 和 CTS 引脚, 以及 SPI 主模式下 USART 配置的 SSN 引脚。
还要注意 PxINP 的设置,有输入引脚的外设单元是从引脚接收输入,这可能会影响外设单元的状态。例如如果 RX 引脚在用作一个 UART 引脚之前,可能已经有活动, UART 在使用之前必须被清除。
按照表格寄存器的内容, 对 T3 进行配置,由于定时器 T3 为 8 位,所以配置稍有不同。
5.CC2530 的串口通信模块
CC2530 有两个串行通信接口 USART0 和 USART1,它们能够分别运行于异步 UART 模式或者同步 SPI 模式。两个 USART 接口具有相同的功能,通过 PERCFG 寄存器可以设置两个 USART 接口对应外部I/O 引脚的映射关系:
位置1 | RX0 --- P0_2 TX0 --- P0_3 | RX1 --- P0_5 TX1 --- P0_4 |
位置2 | RX0 --- P1_4 TX0 --- P1_5 | RX1 --- P1_7 TX1 --- P1_6 |
对每个 USART 串口通信编程,本质是设置相关的 5 个寄存器:
<1> UxCSR: USARTx 的控制和状态寄存器。
<2> UxUCR: USARTx 的 UART 控制寄存器。
<3> UxGCR: USARTx 的通用控制寄存器。
<4> UxDBUF: USARTx 的接收/发送数据缓冲寄存器。
<5> UxBAUD: USARTx 的波特率控制寄存器
6.相关寄存器
CC2530 单片机的 UART 接口则是 TTL 电平, 现在电脑一般去掉 232 串口了, 所以开发板自带了usb 转串口的芯片, 接上 usb 线装好驱动就可以和 2530 通讯。
相关寄存器 UxCSR、 UxCSR、 UxGCR、 UxBUF、 UxBAUD、 CLKCONCMD、 CLKCONSTA如下表所示:
寄存器 | 位 | 描述 |
U0CSR (0x86)– USART0控制和状态 |
Bit[7] MODE | USART模式选择 0:SPI模式 1:UART模式 |
Bit[6] RE | UART接收器使能 0:禁用接收器 1:接收器使能 |
|
Bit[5] SLAVE | SP主或者从模式选择 0:SPI主模式 1:SPI从模式 |
|
Bit[4] FE | UART帧错误状态 0:无帧错误检测 1:字节收到不正确停止位级别 |
|
Bit[3] ERR | UART奇偶错误状态 0:无奇偶错误检测 1:字节收到奇偶错误 |
|
Bit[2] RX_BYTE | 接收字节状态 |
|
Bit[1] TX_BYTE | 传送字节状态 0字节没有被传送 1写到数据缓存寄存器的最后字节被传送 |
|
Bit[0] ACTIVE | USART传送/接收主动状态、在SPI从模式下该位等于从模式选择 0:USART空闲 1:在传送或者接收模式USART忙碌 |
|
U0GCR (0xC5)–USART0通用控制 | Bit[7] CPOL | SPI的时钟极性 0:负时钟极性 1:正时钟极性 |
Bit[6] CPHA | SPI时钟相位 0:当SCK从CPOL倒置到CPOL时数据输出到MOSI,并且当SCK从CPOL倒置到CPOL时数据输入抽样到MISO。 1:当SCK从CPOL倒置到CPOL时数据输出到MOSI,并且当SCK从CPOL倒置到CPOL时数据输入抽样到MISO |
|
Bit[5] ORDER | 传送位顺序 0:LSB先传送 1:MSB先传送 |
|
Bit[4:0] BAUD_E | 波特率指数值。BAUD_E和BAUD_M决定了UART波特率和SPI的主SCK时钟频率 |
|
U0BAUD (0xC2– USART 0波特率控制 |
BAUD_M[7:0] | 波特率小数部分的值。BAUD_E和BAUD_M决定了UART的波特率和SPI的主SCK时钟频率 |
U0DBUF | USART 0接收/发送数据缓存 | |
UTX0IF(发送中断标志) | IRCON2 Bit1 | USART 0 TX中断标志 0:无中断未决 1:中断未决 |
CLKCONCMD时钟控制命令 | Bit[7] OSC32K | 32 kHz时钟振荡器选择 0:32 kHz XOSC 1:32 kHz RCOSC |
Bit[6] OSC | 系统时钟源选择 |
|
Bit[5:3] TICKSPD | 定时器标记输出设置 100:2 MHz 101:1 MHz 110:500 kHz 111:250 kHz |
|
Bit[2:0] CLKSP | 时钟速度 100:2 MHz 101:1 MHz 110:500 kHz 111:250 kHz |
|
CLKCONSTA | CLKCONSTA寄存器是一个只读寄存器,用来获得当前时钟状态 |
由寄存器UxBAUD.BAUD_M[7:0]和UxGCR.BAUD_E[4:0]定义波特率。该波特率用于UART传送,也用于SPI传送的串行时钟速率。波特率由下式给出:
其中F是系统时钟频率,等于16 MHz RCOSC或者32 MHz XOSC。
32 MHz系统时钟常用的波特率设置:文章来源:https://www.toymoban.com/news/detail-413288.html
CC2530 配置串口的一般步骤:
1、 配置 IO,使用外部设备功能。 此处配置 P0_2 和 P0_3 用作串口 UART0
2、 配置相应串口的控制和状态寄存器。
3、 配置串口工作的波特率。
寄存器具体配置如下:文章来源地址https://www.toymoban.com/news/detail-413288.html
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; //开总中断允许接收中断
三、源码分析
1.发送字符串
/****************************************************************************
* 文 件 名: main.c
* 描 述: 设置串口调试助手波特率:115200bps 8N1
* 会收到CC2530发过来的:Hello Zigbee
****************************************************************************/
#include <ioCC2530.h>
#include <string.h>
typedef unsigned char uchar;
typedef unsigned int uint;
#define TX_SIZE 20
#define TX_STRING "Hello Zigbee "
char TxData[TX_SIZE]; //存储发送字符串
//以毫秒为单位延时 16M时约为535,32M时要调整,系统时钟不修改默认为16M
//入口参数: msec 延时参数,值越大延时越久 出口参数: 无
void DelayMS(uint msec)
{
uint i,j;
for (i=0; i<msec; i++)
for (j=0; j<1070; j++);
}
//串口初始化函数
void InitUart(void)
{
PERCFG = 0x00; //外设控制寄存器 USART 0的IO位置:0为P0口位置1
P0SEL = 0x0c; //P0_2,P0_3用作串口(外设功能)
P2DIR &= ~0XC0; //P0优先作为UART0
U0CSR |= 0x80; //设置为UART方式
U0GCR |= 11;
U0BAUD |= 216; //波特率设为115200
UTX0IF = 0; //UART0 TX中断标志初始置位0
}
// 串口发送函数 入口参数: Data:发送缓冲区 len:发送长度
void UartSendString(char *Data, int len)
{
uint i;
for(i=0; i<len; i++)
{
U0DBUF = *Data++;
while(UTX0IF == 0);
UTX0IF = 0;
}
}
//程序入口函数
void main(void)
{
CLKCONCMD &= ~0x40; //设置系统时钟源为32MHZ晶振
while(CLKCONSTA & 0x40); //等待晶振稳定为32M
CLKCONCMD &= ~0x47; //设置系统主时钟频率为32MHZ
InitUart(); //调置串口相关寄存器
memset(TxData, 0, TX_SIZE); //数据清0
memcpy(TxData, TX_STRING, sizeof(TX_STRING)); //复制发送字符串到TxData
while(1)
{
UartSendString(TxData, sizeof(TX_STRING)); //串口发送数据
DelayMS(1000); //延时
}
}
2.接收字符串
/****************************************************************************
* 文 件 名: main.c
* 描 述: 串口调试助手给CC2530发字符串时,开发板会返回接收到的字符串
****************************************************************************/
#include <ioCC2530.h>
#include <string.h> //使用memset需要声明该头文件
typedef unsigned char uchar;
typedef unsigned int uint;
#define UART0_RX 1
#define UART0_TX 2
#define SIZE 51
char RxBuf;
char UartState;
uchar count;
char RxData[SIZE]; //存储发送字符串
void main(void) //主函数
{
CLKCONCMD &= ~0x40; //设置系统时钟源为32MHZ晶振
while(CLKCONSTA & 0x40); //等待晶振稳定为32M
CLKCONCMD &= ~0x47; //设置系统主时钟频率为32MHZ
InitUart(); //调用串口初始化函数
UartState = UART0_RX; //串口0默认处于接收模式
memset(RxData, 0, SIZE); //清空接收缓冲区
while(1)
{
if(UartState == UART0_RX) //接收状态
{
if(RxBuf != 0)
{
if((RxBuf != '#')&&(count < 50))//以'#'为结束符,一次最多接收50个字符
RxData[count++] = RxBuf;
else
{
if(count >= 50) //判断数据合法性,防止溢出
{
count = 0; //计数清0
memset(RxData, 0, SIZE);//清空接收缓冲区
}
else
UartState = UART0_TX; //进入发送状态
}
RxBuf = 0;
}
}
if(UartState == UART0_TX) //发送状态
{
U0CSR &= ~0x40; //禁止接收
UartSendString(RxData, count); //发送已记录的字符串。
U0CSR |= 0x40; //允许接收
UartState = UART0_RX; //恢复到接收状态
count = 0; //计数清0
memset(RxData, 0, SIZE); //清空接收缓冲区
}
}
}
void DelayMS(uint msec) //以毫秒为单位延时,msec 延时参数,值越大,延时越久
{
uint i,j;
for (i=0; i<msec; i++)
for (j=0; j<1070; j++);
}
void InitUart(void) //串口初始化
{
PERCFG = 0x00; //外设控制寄存器 USART 0的IO位置:0为P0口位置1
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; //开总中断允许接收中断
}
//串口发送函数 Data:发送缓冲区 len:发送长度
void UartSendString(char *Data, int len)
{
uint i;
for(i=0; i<len; i++)
{
U0DBUF = *Data++;
while(UTX0IF == 0);
UTX0IF = 0;
}
}
//UART0_ISR(void) 串口中断处理函数
//当串口0产生接收中断,将收到的数据保存在RxBuf中
#pragma vector = URX0_VECTOR
__interrupt void UART0_ISR(void)
{
URX0IF = 0; // 清中断标志
RxBuf = U0DBUF;
}
到了这里,关于CC2530基础实验:(6)串口通讯-发送与接收字符串的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!