本文目的
- 在实际的应用中,单独的空出一个串口做日志往往是奢侈的,使用非串口方式可靠的模拟串口输出日志是个很好的代替方法
- 有时候,因为主频设置,导致使用串口外设输出,往往不能得到比较理想的高波特率,如ch585主频跑到78M下,因为串口通常有一定的过采样, 而单纯的使用定时器直接模拟TX并不需要这样做
- 本文在ch5xx 系列蓝牙芯片上, 使用芯片的定时器可靠的串口日志输出方式
适用芯片
- CH5xx 蓝牙芯片
- CH569/CH565(未验证)
实现
使用
//传入主频78M,传入波特率2M
tuart_init(78000000,2000000);
while(1) {
tuart_printf("check pb19 level:%u\r\n",GPIOB_ReadPortPin(GPIO_Pin_19)?1:0);
DelayMs(1000);
}
驱动代码
ch5xx_tuart.h
#ifndef __CH5XX_TUART_H__
#define __CH5XX_TUART_H__
void tuart_init(uint32_t sys_frq,uint32_t baudrate);
void tuart_send(uint8_t *data,uint32_t len);
void tuart_send_byte(uint8_t byte);
//call after wakeup
void tuart_wakeup(void);
void tuart_printf(char *fmt,...);
#endif //__CH5XX_TUART_H__
ch5xx_tuart.c
#include <stdio.h>
#include <stdint.h>
#include <stdarg.h>
#include "CH59x_common.h"
#include "tuart.h"
static uint32_t bit_cnt;
void tuart_init(uint32_t sys_frq,uint32_t baudrate)
{
bit_cnt = sys_frq/baudrate;
GPIOA_SetBits(GPIO_Pin_9);
GPIOA_ModeCfg(GPIO_Pin_9, GPIO_ModeOut_PP_5mA);
TMR0_PWMInit(Low_Level, PWM_Times_1);
TMR0_PWMCycleCfg(bit_cnt);
TMR0_Disable();
TMR0_PWMActDataWidth(0); //set default level
TMR0_PWMEnable();
TMR0_Enable();
//tuart_printf("ch5xx_timer uart init done\r\n");
}
__HIGH_CODE void tuart_send(uint8_t *data,uint32_t len)
{
while(len) {
tuart_send_byte(*data);
data ++;
len --;
}
}
__HIGH_CODE void tuart_send_byte(uint8_t byte)
{
PFIC_DisableAllIRQ();
while(R8_TMR0_FIFO_COUNT ==8);
R32_TMR0_FIFO = bit_cnt;
for(uint8_t j=0;j<8;j++) {
while(R8_TMR0_FIFO_COUNT ==8);
R32_TMR0_FIFO = (byte&0x01)?0:bit_cnt;
byte >>=1;
}
while(R8_TMR0_FIFO_COUNT == 8);
R32_TMR0_FIFO = 0;
PFIC_EnableAllIRQ();
}
//call after wakeup
__HIGH_CODE void tuart_wakeup(void)
{
R32_TMR0_FIFO = 0;
R32_TMR0_FIFO = 0;
R32_TMR0_FIFO = 0;
}
void tuart_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);
tuart_send(buffer,len);
}

浙公网安备 33010602011771号