wanyhong 发表于 2021-10-5 22:47

沁恒CH57X系列使用普通GPIO模拟调试串口

本帖最后由 wanyhong 于 2021-10-10 23:59 编辑

#申请原创#@21小跑堂
@21小跑堂
@21小跑堂
@21小跑堂

最近要使用沁恒CH573F做一个项目,项目中使用的GPIO较多,只能对外有一路串口使用,而且需要接其他设备,所以开发过程中调试就是个**烦。
因为只是调试使用,所以只需要一个发送就可以,在本项目中我使用了一个普通的GPIO模拟串口发送,进行调试信息输出。

我们经常使用串口通讯,通常都是使用1位起始位,8位数据位,1位停止位,没有校验位 的形式传输。
以下两点是要特别注意的地方:
1、串口异步传输在空闲状态时都必须是高电平。第一位传输的是起始位,起始位会将原来空闲时的高电平拉成低电平,起始位用来来标识数据开始传输,提示接收方准备开始接收数据;
2、当接收方第一次检测到一个下降沿时,就表示接收到了起始位。起始位后就是8位的数据位,接收方在接收每一位数据的时候会采集几十次,如果结果都是低电平,则接收到的数据位0,如果结果都是高电平,则棘手到的数据位是1。1位停止位会将电平拉成高电平,以为接收下一个数据做准备。
结合以上协议就可以开始写代码了,下面我就直接贴代码:
#include<stdio.h>
#include<stdarg.h>

#define DATA_HIGH() GPIOB_SetBits(DEBUG_VCOM_PIN) //高电平DEBUG_VCOM_PIN PB14
#define DATA_LOW() GPIOB_ResetBits(DEBUG_VCOM_PIN) //低电平

/* 主时钟频率 36M
* 延时 (微秒)            波特率
    800             1200
    400             2400
    200             4800
    100             9600
    50            19200
*/

#define BAUD_DELAYUS 50

void SendByte(UINT8 val)
{
    UINT8 i = 0;
    DATA_LOW(); //起始位
    DelayUs(BAUD_DELAYUS);
    for(i = 0; i < 8; i++) //8位数据位
    {
      if(val & 0x01)
      DATA_HIGH();
      else
      DATA_LOW();
      DelayUs(BAUD_DELAYUS);
      val >>= 1;
    }
    DATA_HIGH(); //停止位
    DelayUs(BAUD_DELAYUS);
}

void PrintString(UINT8 *str)
{
    while(*str != 0)
    {
      SendByte(*str);
      str++;
    }
}

/******************************************************************************************
*** 函数名称: Log
*** 输入参数: 无
*** 返 回 值: 无
*** 说    明:自定义串口 printf功能
*** 功能说明:
*** 编者                                    时间                              版本
******************************************************************************************/
void Log(char *format, ...)
{
    uint8_t str;
    va_list ap;

    va_start(ap, format);                                       //初始化 ap 变量
    vsnprintf((char *)str, sizeof(str), format, ap);   //可变参数。用于向字符串中打印数据、数据格式用户自定义
    va_end(ap);                                                 //允许使用了 va_start 宏的带有可变参数的函数返回
    PrintString(str);
}
其中LOG函数就是常用的格式化输出,官方库将printf已经定义,这里自定义了格式化输出函数,以便区别于官方库,防止冲突,这里再贴几个宏定义,调试时使用起来更方便

#ifdef DEBUG
#define LOG(...) Log("\r\n%s(%d): %s", __FILE__, __LINE__, __VA_ARGS__)

#define LOG_FMT(fmt,...) \
    { \
      Log("\r\n%s(%d): ", __FILE__, __LINE__); \
      Log(fmt,__VA_ARGS__); \
    }
#else
#define LOG(...)
#define LOG_FMT(fmt,...)
#endif
工程配置中宏定义对DEBUG建议做如下设置:

最后我们来看下运行效果,波特率延时我使用的是50微秒,所以波特率设置为19200.





littlelida 发表于 2021-10-8 17:48

IO模拟串口?
这是~~~

wanyhong 发表于 2021-10-8 23:32

littlelida 发表于 2021-10-8 17:48
IO模拟串口?
这是~~~

是的

littlelida 发表于 2021-10-14 14:55

感觉很牛,但是为什么不直接用串口呢?
这个不像I2C,

htmlme 发表于 2021-11-12 17:01

以前msp430g2553没有就是用的模拟的。   

yujielun 发表于 2021-11-12 17:01

稳定性怎么样呢?      

typeof 发表于 2021-11-12 17:01

接收的写了吗?            

pl202 发表于 2021-11-12 17:02

这个使用中断了吗?         

eefas 发表于 2021-11-12 17:02

串口的发送和接收都写一个吧。   

dspmana 发表于 2021-11-12 17:02

沁恒CH57X没有串口吗?      

maqianqu 发表于 2021-11-12 17:02

模拟调试串口效果可以。      

wwppd 发表于 2021-11-12 17:02

这个能接受数据吗?         

jkl21 发表于 2021-11-12 17:03

可以使用串口扩展模块。         

usysm 发表于 2021-11-12 17:03

这个可以,可扩展很多个串口了。   
页: [1]
查看完整版本: 沁恒CH57X系列使用普通GPIO模拟调试串口