iot-fan

联系: iotfan123#163.com
注意:
1,本博客之内容来源于网上收集以及相关技术人员提供,如果有侵犯到您的权益,请电邮我沟通;
2,本博客之内容乃分享,交流,学习,研究之目的,作者不对内容的真实性,有效性,及时性负责,也不对因本博客的任何内容导致的任何后果负责;
3,本博客之内容禁止转发到CSDN网站,转到别的网站请保留出处.

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

本文目的

  • 在实际的应用中,单独的空出一个串口做日志往往是奢侈的,使用非串口方式可靠的模拟串口输出日志是个很好的代替方法
  • 有时候,因为主频设置,导致使用串口外设输出,往往不能得到比较理想的高波特率,如ch585主频跑到78M下,因为串口通常有一定的过采样, 而单纯的使用定时器直接模拟TX并不需要这样做
  • 本文在ch5xx 系列蓝牙芯片上, 使用芯片的定时器配合DMA实现可靠的串口日志输出方式

适用芯片

  • CH5xx 蓝牙芯片
  • CH569/CH565(未验证)

实现

下面在ch585芯片上, 使用PB22引脚所在的TMR2输出作为示例

使用

    //传入主频78M,传入波特率2M
    ch5xx_t_uart_init(78000000,2000000);
    while(1) {
        ch5xx_t_uart_printf("check pb19 level:%u\r\n",GPIOB_ReadPortPin(GPIO_Pin_19)?1:0);
        DelayMs(1000);
    }

驱动代码

ch5xx_t_uart.h

#ifndef   __CH5XX_T_UART_H__
#define   __CH5XX_T_UART_H__


void ch5xx_t_uart_init(uint32_t sys_frq,uint32_t baudrate);
void ch5xx_t_uart_send_byte(uint8_t byte);
void ch5xx_t_uart_send(uint8_t *data,uint32_t len);


void ch5xx_t_uart_printf(char *fmt,...);

#endif //__CH5XX_T_UART_H__

ch5xx_t_uart.c

#include "CH58x_common.h"

#include <stdio.h>
#include <stdint.h>
#include <stdarg.h>

#include "ch5xx_t_uart.h"


static uint32_t timer_dma_buf[11];
static uint32_t bit_cnt;
void ch5xx_t_uart_init(uint32_t sys_frq,uint32_t baudrate)
{
    bit_cnt = sys_frq/baudrate;
    timer_dma_buf[0] = bit_cnt;
    timer_dma_buf[9] = 0;
    timer_dma_buf[10] = 0;

    GPIOB_SetBits(GPIO_Pin_22);
    GPIOB_ModeCfg(GPIO_Pin_22, GPIO_ModeOut_PP_5mA);

    TMR3_PWMInit(Low_Level, PWM_Times_1);
    TMR3_PWMCycleCfg(bit_cnt);
    TMR3_Disable();

    TMR3_PWMActDataWidth(0); //set default level
    TMR3_PWMEnable();
    TMR3_Enable();
    TMR3_ITCfg(ENABLE, RB_TMR_IE_DMA_END);
    R32_TMR3_DMA_BEG = (uint32_t)&timer_dma_buf[0];
    R32_TMR3_DMA_END = (uint32_t)&timer_dma_buf[10];

    ch5xx_t_uart_printf("ch5xx_timer uart init done\r\n");
}


__HIGH_CODE
void ch5xx_t_uart_send(uint8_t *data,uint32_t len)
{
    while(len) {
      ch5xx_t_uart_send_byte(*data);
      data ++;
      len --;
    }
}

__HIGH_CODE
void ch5xx_t_uart_send_byte(uint8_t byte)
{
    uint32_t *p = &timer_dma_buf[1];
    for(uint8_t j=0;j<8;j++) {
      if( byte & 0x01u) {
          *p = 0;
      }else {
          *p = bit_cnt;
      }
      byte >>=1;
      p++;
    }
    R32_TMR3_DMA_BEG = (uint32_t)&timer_dma_buf[0];
    TMR3_ClearITFlag(RB_TMR_IE_DMA_END);
    R8_TMR3_CTRL_DMA = RB_TMR_DMA_ENABLE;

    //wait dma end
    while(!TMR3_GetITFlag(RB_TMR_IF_DMA_END));
    //stop dma
    R8_TMR3_CTRL_DMA = 0;
}


void ch5xx_t_uart_printf(char *fmt,...)
{
    char buffer[128];
    va_list arg_ptr;
    va_start(arg_ptr,fmt);
    uint32_t len = vsnprintf(buffer,128,fmt,arg_ptr);
    va_end(arg_ptr);
    ch5xx_t_uart_send(buffer,len);
}
posted on 2024-09-30 16:40  iot-fan  阅读(71)  评论(0编辑  收藏  举报