微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 硬件工程师文库 > 由浅入深,蓝牙4.0/BLE协议栈开发攻略大全(4)

由浅入深,蓝牙4.0/BLE协议栈开发攻略大全(4)

时间:07-25 来源:电子发烧友 点击:

,实现都在hal_lcd.c中。

  第十八节 协议栈UART实验

  协议栈中已经用了串口的驱动,我们要做的只是对串口进行初始化,然后就可以进行串口数据的收发了。

  用使用串口,第一步,需要打开使能串口功能,通过配置工程来实现,这里注意,我们现在不使用USB的CDC类来实现串口,所以HAL_UART_USB=FALSE。

  HAL_UART=TRUE

  HAL_UART_USB=FALSE

  要使用串口必须先初始化相应的串口,那该如何初始化呢?在Hal_uart.h文件中我们可以看到如下函数。

  uint8 HalUARTOpen(uint8 port, halUARTCfg_t *config);

  这个函数就是用来初始化串口的,这个函数有两个参数,第一个指定串口号,第二个是串口的配置参数。我们来看看这个结构体的定义:

  typedef struct

  {

  bool configured; // 配置与否

  uint8 baudRate; // 波特率

  bool flowControl; // 流控制

  uint16 flowControlThreshold;

  uint8 idleTimeout; // 空闲时间

  halUARTBufControl_t rx; // 接收

  halUARTBufControl_t tx; // 发送

  bool intEnable; // 中断使能

  uint32 rxChRvdTime; // 接收数据时间

  halUARTCBack_t callBackFunc; // 回调函数

  }halUARTCfg_t;

  这个结构体成员很多,但是我们在使用串口的时候并不需要使用所有的成员。

  void Serial_Init(void)

  {

  halUARTCfg_t SerialCfg = {0};

  SerialCfg.baudRate = HAL_UART_BR_115200; // 波特率

  SerialCfg.flowControl = HAL_UART_FLOW_OFF; // 流控制

  SerialCfg.callBackFunc = SerialCb; // 回调函数

  SerialCfg.intEnable = TRUE;

  SerialCfg.configured = TRUE;

  HalLcdWriteString( "Open Uart0", HAL_LCD_LINE_5 ); // 在第5行显示启动信息

  HalUARTOpen(HAL_UART_PORT_0, &SerialCfg);

  HalUARTWrite(HAL_UART_PORT_0, "Hello MT254xBoard\r\n", osal_strlen("Hello MT254xBoard\r\n"));

  }

  在串口回调函数中我们只做一件事,将串口接收到的数据显示到LCD中并且原样的从串口输出。回调函数的实现如下:

  static void SerialCb( uint8 port, uint8 events )

  {

  uint8 RxBuf[64]={0};

  if((events & HAL_UART_TX_EMPTY)||( events & HAL_UART_TX_FULL )) // 发送区满或者空

  {

  return;

  }

  uint16 usRxBufLen = Hal_UART_RxBufLen(HAL_UART_PORT_0); // 读取接收据量

  usRxBufLen = MIN(64,usRxBufLen);

  uint16 readLen = HalUARTRead(HAL_UART_PORT_0, RxBuf, usRxBufLen);

  HalUARTWrite(HAL_UART_PORT_0, RxBuf, usRxBufLen);

  }

  实验现象,从实验现象中可以看到,一开始在串口中输出了一个标志字符串,然后我们通过串口发送了0123456789,然后数据原样的从串口输出了,这和我们预期的结果是一样的。

  

  但是我们发现LCD上的显示和我们预期的不一样,LCD上只显示了6789,前面的数据并没有显示,这是怎么一回事呢?进行单步调试可以发现,我们发送一次数据,回调函数被回调了两次,第一次回调只接受到了012345,第二次回调接收到了6789,而在LCD上的显示第二次覆盖了第一次的显示,所以我们会看到这种现象,解决的办法,我们需要定义一个数据帧的时间间隔,当接收数据的间隔超过了此间隔就认为接收结束。

  

  下面我们改写接收处理,我们在接收到数据后开启定时器,定时5ms这样,当接收间隔大于5ms后,我们就可以在定时事件中处理串口接收到的数据。

  static void SerialCb( uint8 port, uint8 events )

  {

  if((events & HAL_UART_TX_EMPTY)||( events & HAL_UART_TX_FULL )) // 发送区满或者空

  {

  return;

  }

  uint16 usRxBufLen = Hal_UART_RxBufLen(HAL_UART_PORT_0); // 读取接收据量

  if(usRxBufLen)

  {

  usRxBufLen = MIN(128,usRxBufLen);

  uint16 readLen = HalUARTRead(HAL_UART_PORT_0, &SerialRxBuf[RxIndex], usRxBufLen); // 读取数据到缓冲区

  RxIndex += readLen;

  readLen %= 128;

  osal_start_timerEx(simpleBLEPeripheral_TaskID, UART_EVENT, 5); // 启动定时器

  }

  }

  事件处理代码:

  if ( events & UART_EVENT )

  {

  HalLcdWriteString( (char*)SerialRxBuf, HAL_LCD_LINE_6 ); // 在第5行显示启动信息

  HalUARTWrite(HAL_UART_PORT_0, SerialRxBuf, osal_strlen(SerialRxBuf));

  osal_memset(SerialRxBuf, 0, 128);

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top