打印
[应用相关]

UART收发-中断方式接收-重定向printf函数

[复制链接]
442|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
wakayi|  楼主 | 2021-8-4 15:39 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
(一)配置串口

波特率:115200
数据长度:8bit
停止位:1位
校验位:无


使用特权

评论回复
沙发
wakayi|  楼主 | 2021-8-4 15:40 | 只看该作者
(二)配置串口接收中断

设置中断分组为第二组,使能串口中断,串口中断优先级设置成主优先级3,次优先级0:


使用特权

评论回复
板凳
wakayi|  楼主 | 2021-8-4 15:40 | 只看该作者
(三)修改代码
在函数MX_USART1_UART_Init中添加如下代码,使能串口中断:

HAL_UART_Receive_IT(&huart1, RecvBuffer, 1);                // 使能接收中断



然后覆写接收中断回调函数:

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
        if (huart->Instance == huart1.Instance)
        {
                HAL_UART_Transmit(&huart1, RecvBuffer, 1, 0xFFFF);                // 将收到的数据在发回去
                HAL_UART_Receive_IT(&huart1, RecvBuffer, 1);                        // 再次使能接收中断
        }
}


然后添加如下代码重定向printf函数:

#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
PUTCHAR_PROTOTYPE
{
        HAL_UART_Transmit(&huart1, (uint8_t *) &ch, 1, 100);
        return ch;
}




效果如下图:



使用特权

评论回复
地板
wakayi|  楼主 | 2021-8-4 15:40 | 只看该作者
(四)使printf函数可以打印浮点数

项目->属性:


使用特权

评论回复
5
wakayi|  楼主 | 2021-8-4 15:40 | 只看该作者
(五)重新实现printf函数
void debug_printf(const void* fmt, ...)
{
        static char buf[1024];
    va_list ap;
    va_start(ap, fmt);
    vsprintf(buf, (char *)fmt, ap);
    va_end(ap);
    HAL_UART_Transmit(&huart1, (uint8_t *)buf, strlen(buf), 100);
}


使用特权

评论回复
6
wakayi|  楼主 | 2021-8-4 15:41 | 只看该作者
(六)串口接收与处理
#define UART1_RX_LEN 0xFF                                 // 串口一次接受数据的最大长度
uint8_t UART1_RX_BUF[UART1_RX_LEN];                // 串口接收缓存
uint8_t UART1_RX_BYTE = 0;                                // 串口中断接收一个字节
uint16_t UART1_RX_STA = 0;                                // 串口接受状态,第15位表示接收到了换行符,第14为表示接收到了回车符,第0~7位表示本次接收到的数据长度




void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
        if (huart->Instance == huart1.Instance)
        {
                if ((UART1_RX_STA & 0x8000) == 0)                        // 接收未完毕
                {
                        if (UART1_RX_STA & 0x4000)                                // 接收到了回车符
                        {
                                if (UART1_RX_BYTE == '\n')                        // 本次接受到的是换行符
                                        UART1_RX_STA |= 0x8000;                        // 标记接收结束
                                else
                                        UART1_RX_STA = 0;                                // 否则接收错误,状态置为初始
                        }
                        else
                        {
                                if (UART1_RX_BYTE == '\r')                        // 本次接收到的是回车符
                                        UART1_RX_STA |= 0x4000;                        // 标记接收到了回车符
                                else
                                {
                                        UART1_RX_BUF[UART1_RX_STA & 0x3FFF] = UART1_RX_BYTE;        // 本次接收到的是数据
                                        if (UART1_RX_STA++ >= UART1_RX_LEN)                                                // 连续接收到的数据高于最大接收长度,则视为接收错误
                                                UART1_RX_STA = 0;                                                                        // 状态置为初始
                                }
                        }
                }
                HAL_UART_Receive_IT(&huart1, &UART1_RX_BYTE, 1);                                        // 再次使能接收中断
        }
}

/**
* 串口1接收处理函数
*/
void UART1_RecvHandler(void)
{
        if (UART1_RX_STA & 0x8000)                                                        // 有数据收到
        {
                UART1_RX_BUF[UART1_RX_STA & 0x3FFF] = '\0';                // 添加结束符
                printf("%s\r\n", UART1_RX_BUF);                                        // 串口打印出来
                UART1_RX_STA = 0;                                                                // 状态置为初始
        }
}



使用特权

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

本版积分规则

78

主题

3853

帖子

1

粉丝