打印
[RISC-V MCU 应用开发]

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

[复制链接]
3979|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 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[256];
    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,

使用特权

评论回复
5
htmlme| | 2021-11-12 17:01 | 只看该作者
以前msp430g2553没有就是用的模拟的。   

使用特权

评论回复
6
yujielun| | 2021-11-12 17:01 | 只看该作者
稳定性怎么样呢?      

使用特权

评论回复
7
typeof| | 2021-11-12 17:01 | 只看该作者
接收的写了吗?            

使用特权

评论回复
8
pl202| | 2021-11-12 17:02 | 只看该作者
这个使用中断了吗?           

使用特权

评论回复
9
eefas| | 2021-11-12 17:02 | 只看该作者
串口的发送和接收都写一个吧。   

使用特权

评论回复
10
dspmana| | 2021-11-12 17:02 | 只看该作者
沁恒CH57X没有串口吗?        

使用特权

评论回复
11
maqianqu| | 2021-11-12 17:02 | 只看该作者
模拟调试串口效果可以。        

使用特权

评论回复
12
wwppd| | 2021-11-12 17:02 | 只看该作者
这个能接受数据吗?         

使用特权

评论回复
13
jkl21| | 2021-11-12 17:03 | 只看该作者
可以使用串口扩展模块。           

使用特权

评论回复
14
usysm| | 2021-11-12 17:03 | 只看该作者
这个可以,可扩展很多个串口了。   

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

5

主题

18

帖子

1

粉丝