BLE Mesh RTL8762C 小米模组串口通信

1. 参考 《外设的初始化》文档

主要分为如下几个部分:

  • 使能外设的时钟信号
  • 设置外设的引脚复用与 PAD
  • 设置外设初始化参数 使能外设

2. 核心代码片段

1. 串口初始化

  // 实际上是 RCC_PeriphClockCmd(APBPeriph_UART1, APBPeriph_UART1_CLOCK, DISABLE);
  // 先关闭 PWM_UART 的时钟。
  // 官方demo里面对于GPIO引脚均如此使用
  UART_DeInit(PWM_UART);

  
  /* turn on UART1 clock */
  RCC_PeriphClockCmd(APBPeriph_UART1, APBPeriph_UART1_CLOCK, ENABLE);

  /* pinmux config 引脚复用配置*/
  Pinmux_Config(PWM_UART_TX_PIN, UART1_TX);
  Pinmux_Config(PWM_UART_RX_PIN, UART1_RX);

  /* pad config 配置引脚的pad状态 */
  Pad_Config(PWM_UART_TX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_LOW);
  Pad_Config(PWM_UART_RX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_LOW);

  /* uart init 初始化uart参数 */
  UART_InitTypeDef uartInitStruct;
  UART_StructInit(&uartInitStruct);
  
  // 波特率说明: 9600Hz 8bit
  uartInitStruct.ovsr_adj = 0x24A;
  uartInitStruct.div = 271;
  uartInitStruct.ovsr = 10;

  uartInitStruct.parity = UART_PARITY_NO_PARTY;
  
  // 在桢结尾传输2个停止位
  uartInitStruct.stopBits = UART_STOP_BITS_2;
  uartInitStruct.wordLen = UART_WROD_LENGTH_8BIT;
  uartInitStruct.dmaEn = UART_DMA_DISABLE;
  uartInitStruct.rxTriggerLevel = 16;                // 1~29
  
  // 该UART接收FIFO的数据个数小于设置的阈值,设置触发接收超时中断的超时时间值
  uartInitStruct.idle_time = UART_RX_IDLE_2BYTE;     // idle interrupt wait time

  uartInitStruct.TxWaterlevel = 15;                  // Better to equal TX_FIFO_SIZE(16)- GDMA_MSize
  uartInitStruct.RxWaterlevel = 1;                   // Better to equal GDMA_MSize
  uartInitStruct.TxDmaEn = DISABLE;
  uartInitStruct.RxDmaEn = DISABLE;
  UART_Init(PWM_UART, &uartInitStruct);

  /* enable rx interrupt and line status interrupt 接收中断,接收总线错误中断,uart空闲中断*/
  UART_INTConfig(PWM_UART, UART_INT_RD_AVA | UART_INT_LINE_STS | UART_INT_IDLE, ENABLE);

  /*  Enable UART IRQ  */
  NVIC_InitTypeDef nvic_init_struct;
  nvic_init_struct.NVIC_IRQChannel = PWM_UART_IRQ;
  nvic_init_struct.NVIC_IRQChannelCmd = ENABLE;
  nvic_init_struct.NVIC_IRQChannelPriority = 3;     // 中断优先级 : 0最高
  NVIC_Init(&nvic_init_struct);

    // pwm_UART1_handle 为uart1 中断处理函数
  RamVectorTableUpdate(Uart1_VECTORn, pwm_UART1_handle);  

2. 串口发送实现

使用串口开发板,连接RX引脚到 RTL8762C的TX引脚。就可以看到下面的打印日志。

  /* Send demo string test*/
char *demoStr = "### Welcome to use RealTek Bumblebee ###\r\n";
uint8_t demoStrLen = strlen(demoStr);
memcpy(String_Buf, demoStr, demoStrLen);
uart_senddata_continuous(PWM_UART, String_Buf, demoStrLen);

/**
 * @brief  UARt send data continuous.
 * @param  No parameter.
 * @return void
 */
static void uart_senddata_continuous(UART_TypeDef *UARTx, const uint8_t *pSend_Buf, uint16_t vCount) {
  uint8_t count;

  while (vCount / UART_TX_FIFO_SIZE > 0) {
    while (UART_GetFlagState(UARTx, UART_FLAG_THR_EMPTY) == 0)
      ;
    for (count = UART_TX_FIFO_SIZE; count > 0; count--) {
      UARTx->RB_THR = *pSend_Buf++;
    }
    vCount -= UART_TX_FIFO_SIZE;
  }

  while (UART_GetFlagState(UARTx, UART_FLAG_THR_EMPTY) == 0)
    ;
  while (vCount--) {
    UARTx->RB_THR = *pSend_Buf++;
  }
}

3. 中断函数处理

可以处理发送结束中断,接收中断,错误中断。

处理逻辑取决于业务实现。后续待补充。

static void pwm_UART1_handle(void) {
  uint8_t rx_data;
  uint32_t int_status;
  uint32_t line_error;
  uint8_t fifo_len;

  /* read interrupt id */
  int_status = UART_GetIID(UART1);
  /* disable interrupt 处理中断的时候,禁用中断 */
  UART_INTConfig(UART, UART_INT_RD_AVA | UART_INT_LINE_STS, DISABLE);

// 如果是收到RX 完成的中断
  if (UART_GetFlagState(UART, UART_FLAG_RX_IDLE) == SET) {
    UART_INTConfig(UART, UART_INT_IDLE, DISABLE);
    DBG_DIRECT("UART0_FLAG_RX_IDLE: %d", pwm_uart_msg.len);
    // TODO 
    UART_INTConfig(UART, UART_INT_IDLE, ENABLE);
  }

  switch (int_status) {
    /* tx fifo empty */
    case UART_INT_ID_TX_EMPTY:
      /* do nothing  发送完成中断 */
      break;
    /* rx data valiable */
    case UART_INT_ID_RX_LEVEL_REACH:
    case UART_INT_ID_RX_TMEOUT:
      fifo_len = UART_GetRxFIFOLen(UART);
      for (uint8_t i = 0; i < fifo_len; ++i) {
        UART_ReceiveData(UART, &rx_data, 1);
        pwm_uart_msg.data[pwm_uart_msg.len] = rx_data;
        pwm_uart_msg.len += 1;
        if (pwm_uart_msg.len >= PWM_UART_DATA_MAX_LEN) {
          // pwm_send_uart_msg(&pwm_uart_msg);
          pwm_uart_msg.len = 0;
        }
      }
      break;
    /* receive line status interrupt */
    case UART_INT_ID_LINE_STATUS:
      line_error = UART->LSR;
      // printe("data_uart_isr Line status error, fail = %d!", line_error);
      break;
    default:
      break;
  }

  /* enable interrupt again */
  UART_INTConfig(UART, UART_INT_RD_AVA | UART_INT_LINE_STS, ENABLE);
  return;
}

4. 中断源

待使能或失能的uart中断源

5. 中断标识

/** @defgroup UART_Interrupt_Identifier UART Interrupt Identifier
  * @{
  */

// UART接收总线错误中断
#define UART_INT_ID_LINE_STATUS                     ((uint16_t)(0x03 << 1))

//  rx trigger level reached interrupt
#define UART_INT_ID_RX_LEVEL_REACH                  ((uint16_t)(0x02 << 1))

#define UART_INT_ID_RX_TMEOUT                       ((uint16_t)(0x06 << 1))

#define UART_INT_ID_TX_EMPTY                        ((uint16_t)(0x01 << 1))
#define UART_INT_ID_MODEM_STATUS                    ((uint16_t)(0x00 << 1))

  • 10
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

专注和坚持是最好的导师

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

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

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

打赏作者

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

抵扣说明:

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

余额充值