物联网|串口的编程技巧|发送函数分析|初始化函数|IAR显示行号|串口的数据格式|数据帧的设计思路|物联网之蓝牙4.0 BLE基础-学习笔记(9)

串口的编程技巧

串口编程是一种通过串行端口与外部设备进行通信的方法。在串口编程中,需要注意以下几点技巧:

了解串口通信的基本原理和特点。
选择合适的串口控制器和通讯方式。
熟悉常用的串口调试工具,如串口调试助手、PuTTY等。
熟悉常用的编程语言,如C、C++、Java等。
熟悉常用的串口编程库,如WinAPI、RXTX等。
这里主要针对物联网模块的串口编程进行讨论。

发送函数分析

void UartSendString(char *Data,int len)
{
  uint i;

  for(i = 0;i<len;i++)
  {
    U0DBUF = *Data++;
    while(UTX0IF == 0)
    {
    UTX0IF = 0;
    }
  }
}

检测UTX0IF标志,只要为0,就一直死等;等到标志变成1的时候退出。
这就是所谓串口的查询工作方式:在上一步向发送缓冲区填写数据触发发送之后,在这里死等发送(完成)标志置位。
有些单片机可以查询更细致的标志,例如发送缓冲空标志、线路发送完成标志等等。

串口(UART0)初始化函数

/****************************************************************
串口(UART0)初始化函数:
****************************************************************/
void InitUart(unsigned long int baudrate)
{

    CLKCONCMD &= ~0x40;                           //0: 32 MHz XOSC 与操作,仅设置0位,其他位为1,与后保持不变,设置系统时钟源为32MHZ晶振
    while(CLKCONSTA & 0x40);                      //等待晶振稳定
    CLKCONCMD &= ~0x47;                           // ~0x47=1011 1000,2:0 CLKSPD 001 R/W Clock speed. Cannot be higher than system clock setting given by the OSC bit
                                                  //setting. Indicates current system-clock frequency 000: 32 MHz,设置系统主时钟频率为32MHZ
    PERCFG = 0x00;			          //位外设控制寄存器USART 0的IO位置;0为P0口位置;
    P0SEL = 0x0c;				  //P0用作串口,P0.7 to P0.0 function select
                                                  //0: General-purpose I/O  1: Peripheral function
                                                  //0x0c=0000 1100,P0_2,P0_3用作串口,外设功能
    P2DIR &= ~0XC0;                               //0XC0=1100 0000,~0XC0=0011 1111,与操作,设置0位,P0优先作为UART0
                                           //Port 0 peripheral priority control. These bits determine the order of priority in the case
                                        //when PERCFG assigns several peripherals to the same pins.
                                        //Detailed priority list:
                                        //00:
                                        //1st priority: USART 0
                                        //2nd priority: USART 1
                                        //3rd priority: Timer 1
   U0CSR |= 0X40;			  //允许接收
   switch(baudrate)
   {
   case 115200:
              U0GCR = 11;
              U0BAUD = 216;				  //波特率设为115200
              break;
   case 9600:
              U0GCR = 8;
              U0BAUD = 59;				  //波特率设为9600
              break;
   default:
              U0GCR = 8;
              U0BAUD = 59;				  //默认波特率设为9600
              break;
   }
   UTX0IF = 0;
   U0CSR |= 0x40;                          //允许接收
   IEN0 |= 0x84;			 //开总中断,允许接收中断
}

主函数体

/****************************************************************
主函数				
****************************************************************/
void main(void)
{	  
    InitUart(115200);           //串口初始化
    InitLed();
    UartState = UART0_RX; //串口0默认处于接收模式
    memset(RxData, 0, SIZE);
    
    while(1)
    {
      CmdPro(cmd);
    }
}

完整代码:

#include <ioCC2540.h>
#include <string.h>

#define uint unsigned int
#define uchar unsigned char

//定义控制灯的端口
#define LED1   P1_0  //P1_0口控制LED1
#define UART0_RX  1
#define UART0_TX  2
#define SIZE 51

char RxBuf;
char UartState;
uchar count;
char RxData[SIZE];  //存储发送字符
char cmd;
uint OnOffState;


void DelayMS(uint msec)
{
  uint i,j;

  for (i=0;i<msec; i++)
    for (j=0;j<1070;j++);
}

void InitLed(void)
{
  P1DIR |= 0x01;     //0x01=0000 0001 置1,或操作, 定义P1.0为输出
  LED1 = 0;         //LED1灯灭
}

void CmdPro(char MyCmd)
{
  switch(MyCmd)
  {
  case 'A':
    cmd = 0;
    LED1 = 1;
    OnOffState = 1;
    break;
  case 'B':
    cmd = 0;
    LED1 = 0;
    OnOffState = 0;
    break;
  case 'C':
    if(OnOffState)
    {
      LED1 = 0;
      DelayMS(1000);
      LED1 = 1;
      DelayMS(1000);
      LED1 = 0;
      DelayMS(1000);
      LED1 = 1;
      DelayMS(1000);
      LED1 = 0;
      OnOffState = 0;
    }
   break;
  default:
    break;
  }
}

/****************************************************************
串口(UART0)初始化函数:
****************************************************************/
void InitUart(unsigned long int baudrate)
{

    CLKCONCMD &= ~0x40;                           //0: 32 MHz XOSC 与操作,仅设置0位,其他位为1,与后保持不变,设置系统时钟源为32MHZ晶振
    while(CLKCONSTA & 0x40);                      //等待晶振稳定
    CLKCONCMD &= ~0x47;                           // ~0x47=1011 1000,2:0 CLKSPD 001 R/W Clock speed. Cannot be higher than system clock setting given by the OSC bit
                                                  //setting. Indicates current system-clock frequency 000: 32 MHz,设置系统主时钟频率为32MHZ
    PERCFG = 0x00;			          //位外设控制寄存器USART 0的IO位置;0为P0口位置;
    P0SEL = 0x0c;				  //P0用作串口,P0.7 to P0.0 function select
                                                  //0: General-purpose I/O  1: Peripheral function
                                                  //0x0c=0000 1100,P0_2,P0_3用作串口,外设功能
    P2DIR &= ~0XC0;                               //0XC0=1100 0000,~0XC0=0011 1111,与操作,设置0位,P0优先作为UART0
                                           //Port 0 peripheral priority control. These bits determine the order of priority in the case
                                        //when PERCFG assigns several peripherals to the same pins.
                                        //Detailed priority list:
                                        //00:
                                        //1st priority: USART 0
                                        //2nd priority: USART 1
                                        //3rd priority: Timer 1
   U0CSR |= 0X40;			  //允许接收
   switch(baudrate)
   {
   case 115200:
              U0GCR = 11;
              U0BAUD = 216;				  //波特率设为115200
              break;
   case 9600:
              U0GCR = 8;
              U0BAUD = 59;				  //波特率设为9600
              break;
   default:
              U0GCR = 8;
              U0BAUD = 59;				  //默认波特率设为9600
              break;
   }
   UTX0IF = 0;
   U0CSR |= 0x40;                          //允许接收
   IEN0 |= 0x84;			 //开总中断,允许接收中断
}

void UartSendString(char *Data,int len)
{
  uint i;

  for(i = 0;i<len;i++)
  {
    U0DBUF = *Data++;
    while(UTX0IF == 0)
    {
    UTX0IF = 0;
    }
  }
}


#pragma vector = URX0_VECTOR    //格式:#pragma vector = 中断向量,紧接着是中断处理程序
  __interrupt void UART0_ISR(void)
 {
   URX0IF = 0;                                 //UART0 TX中断标志初始置位0(清中断标志)
   cmd = U0DBUF;
 }

/****************************************************************
主函数
****************************************************************/
void main(void)
{
    InitUart(115200);           //串口初始化
    InitLed();
    UartState = UART0_RX; //串口0默认处于接收模式
    memset(RxData, 0, SIZE);

    while(1)
    {
      CmdPro(cmd);
    }
}

TIPS1:IAR显示行号

在这里插入图片描述

TIPS2:IAR编译出现 Fatal Error[e72]: Segment BANKED_CODE must be defined

IAR编译出现 Fatal Error[e72]: Segment BANKED_CODE must be defined in a segment definition option (-Z, -b or -P)****
是链接(Link)出错:
原因是IAR新版本使用旧版本文件
在这里插入图片描述
在这里插入图片描述

解决方法:

打开project->options->linker->config->override default
填入地址:
T O O L K I T D I R TOOLKIT_DIR TOOLKITDIR\config\devices\Texas Instruments\lnk51ew_cc2540F256_banked.xcl
选择banked的xcl文件即可,具体的文件可根据所用的芯片型号来选择。

串口的数据格式

头码1 | 头码2 | 长度 | 数据 | 校验
1BYTE | 1BYTE | 1BYTE | NBYTE | 1BYTE
头码1:0xAA
头码2:OxS5
长度为数据和校验总字节数
校验为长度字节和数据字节值求和,即和校验
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

打酱油的工程师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值