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

串口的编程技巧

发送函数分析

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
长度为数据和校验总字节数
校验为长度字节和数据字节值求和,即和校验
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/Medlar_CN/article/details/130724473