CC2541有两个串行通信接口,分别是USART0和USART1,它们能够分别运行于异步UART模式或者同步SPI模式。两个USART具体同样的功能,可以设置在单独的I/O引脚。

来源-作者@欣庸:https://www.cnblogs.com/chenzhao207/p/4531941.html

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

重映射PERCFG |= BV(0)  位置2:P1_4----RX    P1_5----TX

UART1对应的外部设置IO引脚关系为:位置1:P0_5----RX    P0_4----TX

重映射PERCFG |= BV(1) 位置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系统时钟。波特率误差,用百分数表示。

CC2530配置串口的一般步骤

1、配置串口的备用位置,是备用位置1,还是备用位置2。配置寄存器PERCFG外设控制寄存器

2、配置端口的外设优先级。此处配置P0外设优先作为UART0。配置寄存器P2DIR

3、配置IO,使用外部设备功能。此处配置P0_2和P0_3用作串口UART0。配置寄存器P0SEL

4、配置相应串口的控制和状态寄存器。配置寄存器U0CSR、U0UCR

5、配置串口工作的波特率。配置寄存器U0GCR、U0BAUD

6、将对应的串口接收/发送中断标志位清0,清零:TCON.URX0IF、TCON.URX1IF、IRCON2.UTX0IF、IRCON2.UTX1IF

7、使能串口接收中断(一般发送不用中断),置1 IEN0.URX0IE

8、开总中断

中断相关的寄存器如下:

IEN0(0xA8)

TCON(0x88)

 IRCON2(0xE8)

串口0配置如下:

 /****************************************************************************
名    称: InitUart()
功    能: 串口初始化函数
入口参数: 无
出口参数: 无
****************************************************************************/
void InitUart(void)
{
#if  UART0_P0PERCFG &= ~0x01;     //USART0映射P2DIR &= ~0xc0;       P0SEL |= BV(2) | BV(3);//配置P0.2和P0.3为外设,非GPIO
#else PERCFG |= BV(0);     //USART0重映射P1SEL |= BV(4) | BV(5);//配置P1.4和P1.5为外设,非GPIO
#endifU0CSR |= BV(7); //配置当前为UART,非SPIU0GCR |= 11; //根据上述波特率设置表格设置115200波特率U0BAUD |= 216;// 根据上述波特率设置表格设置115200波特率UTX0IF = 0;//位寄存器,直接操作,清除中断标志U0CSR |= BV(6);//允许接收数据IEN0 |= BV(2);//打开接收中断EA=1;//打开总中断
}

总程序如下:

#include <ioCC2540.h>
//CC2541也可以使用该头文件
//串口收发验,波特率115200,8N1.typedef unsigned char uint8;
typedef char int8;
typedef unsigned short int  uint16;#define LED1 P1_0       //定义P1.0口为LED1控制端
#define LED2 P1_1
/****************************************************************************
常用宏定义
****************************************************************************/
#define BV(x) (1<<(x))#define UART0_P0  1
#define UART1_P0  1//定义P0口为UART0、1输出端/****************************************************************************
名    称: DelayMS()
功    能: 毫秒延时,系统时钟不配置时默认使用内部16M,本demo中,时钟为外部32M
入口参数: msec 延时参数,注意,最大数值为65536ms
出口参数: 无
****************************************************************************/
void DelayMS(uint16 msec)
{ uint16 i,j;for (i=0; i<msec; i++)for (j=0; j<536*2; j++);
}/****************************************************************************
名    称: InitLed()
功    能: 设置LED相应的IO口
入口参数: 无
出口参数: 无
****************************************************************************/
void InitLed(void)
{P1DIR |= BV(0);      // P1.0定义为输出LED1 = 0;           // LED1灯熄灭    P1DIR |= BV(1);      // P1.0定义为输出LED2 = 0;           // LED1灯熄灭
}/****************************************************************************
名    称: InitUart()
功    能: 串口初始化函数
入口参数: 无
出口参数: 无
****************************************************************************/
void InitUart(void)
{
#if UART0_P0PERCFG &= ~0x01;     //USART0映射P2DIR &= ~0xc0;       P0SEL |= BV(2) | BV(3);//配置P0.2和P0.3为外设,非GPIO
#else PERCFG |= BV(0);     //USART0重映射P1SEL |= BV(4) | BV(5);//配置P1.4和P1.5为外设,非GPIO
#endifU0CSR |= BV(7); //配置当前为UART,非SPIU0GCR |= 11; //根据上述波特率设置表格设置115200波特率U0BAUD |= 216;// 根据上述波特率设置表格设置115200波特率UTX0IF = 0;//位寄存器,直接操作,清除中断标志U0CSR |= BV(6);//允许接收数据IEN0 |= BV(2);//打开接收中断EA=1;//打开总中断}
/****************************************************************************
名    称: InitUart1()
功    能: 串口初始化函数
入口参数: 无
出口参数: 无
****************************************************************************/
void InitUart1(void)
{
#if UART1_P0PERCFG &= ~0x02;     //USART1映射  P1SEL |= BV(4) | BV(5);//配置P0.4和P0.5为外设,非GPIO
#elsePERCFG |= BV(1);     //USART1重映射//P2SEL|=BV(6);//P2SEL&=~BV(5);//P2DIR &=~BV(7);//P2DIR |=BV(6);P1SEL |= BV(6) | BV(7);//配置P1.6和P1.7为外设,非GPIO
#endifU1CSR |= BV(7); //配置当前为UART,非SPIU1GCR |= 11; //根据上述波特率设置表格设置115200波特率U1BAUD |= 216;// 根据上述波特率设置表格设置115200波特率UTX1IF = 0;//位寄存器,直接操作,清除中断标志U1CSR |= BV(6);//允许接收数据IEN0 |= BV(3);//打开接收中断EA=1;//打开总中断}
/****************************************************************************
名    称: UartSendString()
功    能: 串口发送函数
入口参数: Data:发送缓冲区   len:发送长度
出口参数: 无
****************************************************************************/
void UartSendString(int8 *Data, uint16 len)
{uint16 i;for(i=0; i<len; i++){U0DBUF = *Data++;while(UTX0IF == 0);UTX0IF = 0;}
}
/****************************************************************************
名    称: Uart1SendString()
功    能: 串口发送函数
入口参数: Data:发送缓冲区   len:发送长度
出口参数: 无
****************************************************************************/
void Uart1SendString(int8 *Data, uint16 len)
{uint16 i;for(i=0; i<len; i++){U1DBUF = *Data++;while(UTX1IF == 0);UTX1IF = 0;}
}
/****************************************************************************
名    称: UartSendByte()
功    能: 串口发送函数
入口参数: byte,带发送的数据
出口参数: 无
****************************************************************************/
void UartSendByte(int8 byte)
{U0DBUF = byte;while(UTX0IF == 0);UTX0IF = 0;
}
/****************************************************************************
名    称: Uart1SendByte()
功    能: 串口发送函数
入口参数: byte,带发送的数据
出口参数: 无
****************************************************************************/
void Uart1SendByte(int8 byte)
{U1DBUF = byte;while(UTX1IF == 0);UTX1IF = 0;
}
/****************************************************************************
名    称: UART1_ISR(void) 串口中断处理函数
描    述: 当串口 0 产生接收中断,将收到的数据保存在 RxBuf 中,每次接收一个字节
****************************************************************************/
#pragma vector = URX0_VECTOR
__interrupt void UART0_ISR(void)
{  URX0IF = 0;       // 清中断标志Uart1SendByte(U0DBUF); //收到后uart1立即发送出去}
/****************************************************************************
Ãû    ³Æ: UART1_ISR(void) ´®¿ÚÖжϴ¦Àíº¯Êý
Ãè    Êö: µ±´®¿Ú 0 ²úÉú½ÓÊÕÖжϣ¬½«ÊÕµ½µÄÊý¾Ý±£´æÔÚ RxBuf ÖУ¬Ã¿´Î½ÓÊÕÒ»¸ö×Ö½Ú
****************************************************************************/
#pragma vector = URX1_VECTOR
__interrupt void UART1_ISR(void)
{  URX1IF = 0;       // 清中断标志UartSendByte(U1DBUF); //收到后uart0立即发送出去}/*****************************************************************函 数 名:SysStartXOSC*功    能:系统时钟初始化*入口参数:无*出口参数:无*****************************************************************/void SysStartXOSC(void){SLEEPCMD &= ~0x04;                      // 启动所有晶振while (!(SLEEPSTA & 0x40));             // 等待晶振稳定 CLKCONCMD = (CLKCONCMD & 0x80) | 0x49;  // 使用16M晶振作为主时钟while ((CLKCONSTA & ~0x80) != 0x49 );   // 等待主时钟切换到16M晶振CLKCONCMD = (CLKCONCMD & ~0x80) ;       // 使用外部32K晶振作为休眠时钟while ( (CLKCONSTA & 0x80) != 0 );      // 等待睡眠时钟切换到外部32K晶振CLKCONCMD = (CLKCONCMD & 0x80) ;        // 使用32M晶振作为主时钟while ( (CLKCONSTA & ~0x80) != 0 );     // 等待主时钟切换到32M晶振SLEEPCMD |= 0x04;                       // 关闭未使用的晶振}
void main(void)
{   //CLKCONCMD &= ~0x40;               //设置系统时钟源为32MHZ晶振//while(CLKCONSTA & 0x40);          //等待晶振稳定//CLKCONCMD &= ~0x47;               //设置系统主时钟频率为32MHZ   SysStartXOSC();  InitLed();InitUart();                       //调置串口相关寄存器InitUart1();
#if UART0_P0 UartSendString("UART0\r\nP0.2--RX P0.3--TX\r\n",26); Uart1SendString("UART1\r\nP0.5--RX P0.4--TX\r\n",26);
#elseUartSendString("UART0\r\nP1.4--RX P1.5--TX\r\n",26); Uart1SendString("UART1\r\nP1.7--RX P1.6--TX\r\n",26);
#endifwhile(1){DelayMS(500);//UartSendByte(0x30);//Uart1SendByte(0x31);LED1=~LED1;LED2=~LED2;}
}

CC2541蓝牙学习——串口_0和1(寄存器版本)相关推荐

  1. 汇承4.0蓝牙BLE串口助手HC-COM的使用方法及出错的原因和改正方法

       本文主要介绍在使用汇承4.0蓝牙BLE串口助手HC-COM,通过手机向蓝牙模块发送数据.或者通过手机向与蓝牙模块连接的单片机发送指令时,串口中断函数的编写方法及出错的原因和改正方法    我们怎 ...

  2. 【转载】传统蓝牙协议栈 串口协议SPP

    零. 概述 主要介绍下蓝牙协议栈(bluetooth stack) 串口协议(bluetooth SPP)Serial Port Profile 协议概念介绍. 一. 声明 本专栏文章我们会以连载的方 ...

  3. 嵌入式学习——串口通信小试

    嵌入式学习--串口通信小试 目录 嵌入式学习--串口通信小试 1.了解串口协议和RS-232.485标准,以及RS-232.485电平与TTL电平的区别 1.1 什么是串口协议 1.2 RS-232标 ...

  4. Android BLE(2)---蓝牙学习

    Android 普通蓝牙学习 需要的权限 <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" ...

  5. PC下串口IO空间及其寄存器详解

    2019独角兽企业重金招聘Python工程师标准>>> 串口(Serial UART), 全称是通用异步收发口universal asynchronous receiver/tran ...

  6. QT学习串口编程之串口软件的UI设计

    学会了如何使用QT进行界面设计之后,接下来让我们来进入第二阶段的学习--串口编程吧. 首先我们需要对串口软件的UI界面进行仿写. 首先存在一个接收方和发送方,接收框主要是串口软件接收设备发来的数据,发 ...

  7. cc2541中文数据手册及cc2541蓝牙源程序

    cc2541中文数据手册及cc2541蓝牙源程序 发表于 2018-05-02 17:09:35 无线通信15人已加入 +加入圈子 cc2541概述 CC2541 是一款针对低能耗以及私有 2.4GH ...

  8. crh寄存器_牛人的STM32学习笔记(寄存器版本).doc

    牛人的STM32学习笔记(寄存器版本) 一.GPIO口的配置 STM32的DGPIO口最多可以有7组(GPIOa~GPIOg),而每一组GPIO口均有16个双向IO组成.并且没个IO口均可配置成8种模 ...

  9. 蓝牙学习五(广播包分析wireshark)

    1.简介 软件工具:wireshark 硬件抓包工具:nrf52840 dongle 2.数据包分析 使用wireshark抓到的数据包分为两个部分,一部分是软件自己添加的内容,另一部分才是广播出来的 ...

  10. 无人机蓝牙图传串口助手APP(地面端、飞机端)

    这个APP是在2016年11月底-12月初开发的,现在想把这项目开源共享给有需要的开发者参考!源码有需要请留言联系本人,由于本项目属于公司项目,不能完全开源出来,只提供部分技术支持!请谅解! 由于地面 ...

最新文章

  1. python官网下载安装教程-Python和Anoconda和Pycharm安装教程
  2. 前端基础:web语义化
  3. C语言宏定义中使用 do{}while(0) 的情形
  4. 常用的相似性度量(距离总结)
  5. 如何理解java反射_怎么理解java反射
  6. 【转载】同步和互斥的POSIX支持(互斥锁,条件变量,自旋锁)
  7. CodeForces - 336D Vasily the Bear and Beautiful Strings(dp+组合数学)
  8. SpringMVC框架第一天
  9. 刚刚看到 PNaCl, 这才是我一直期待的跨平台的好东西!
  10. NOIP2015题解
  11. 陀螺信号一阶差分matlab,卡尔曼滤波在陀螺漂移时间序列模型中的应用
  12. sublime text3找到定义_决策易aPaaS,一款非技术人员也能使用的自定义开发神器
  13. frontpage 2010.2003绿色版
  14. openwrt 开启KV漫游
  15. 基于似然比检验统计量的异常轨迹检测
  16. 没有对象,你凭什么成为百万富翁
  17. JS逆向 2021-8-16 网易云音乐 params、encSecKey参数
  18. 图片上传实时预览效果
  19. 「 C++ 函数 」“WSAStartup()使用”讲解
  20. 微信公众号发送模版消息详细过程

热门文章

  1. 什么是像素格式(色彩采样、色度抽样)RGB 4:4:4、(Limit)RGB 4:4:4、Ycbcr 4:4:4、Ycbcr 4:2:2、Ycbcr 4:2:0又是什么?
  2. 鸿蒙大陆9.1正式版礼包,鸿蒙大陆2.0正式版
  3. 16比9尺寸是多少厘米_16比9尺寸的长宽是多少像素
  4. Mangos某人经验
  5. linux根据uid反查用户名
  6. 使用 关键字来创建python自定义函数_python 自定义函数
  7. vue倒计时翻页插件
  8. 个性化不和谐帐户的8种方法
  9. C++中begin()函数的含参数的使用
  10. Android开发:引入重复包报错Error:Execution failed for task ':app:transformDexArchiveWithExternalLibsDe...’解决方法