打印
[单片机芯片]

沁恒MCU CH32V103串口通信应用及代码实现

[复制链接]
49|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
万图|  楼主 | 2024-10-4 14:43 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
最近我在项目中使用了沁恒的CH32V103 MCU,主要任务是实现一个简单的串口通信功能,用于与PC进行数据传输。为了让这个过程更加稳定,我选择了中断方式来接收数据,并在发送时加入了回显功能。以下是我的代码实现,分享出来供大家参考。

串口通信功能描述:
  • 使用UART1作为通信接口,波特率设置为115200。
  • 接收数据后立即回显给PC,确保数据完整性。
  • 通过中断方式接收数据,避免使用轮询方式占用CPU资源。

代码实现:
#include "ch32v10x.h"
#include <stdio.h>

#define RX_BUFFER_SIZE 128   // 接收缓冲区大小

char rxBuffer[RX_BUFFER_SIZE];  // 接收数据缓冲区
volatile uint8_t rxIndex = 0;   // 当前接收数据的索引

void USART1_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);  // 开启USART1和GPIOA时钟

    // 配置USART1的TX引脚
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;            // TX引脚
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;      // 复用推挽输出
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    // 配置USART1的RX引脚
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;           // RX引脚
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  // 浮空输入
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    // 初始化USART1
    USART_InitStructure.USART_BaudRate = 115200;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    USART_Init(USART1, &USART_InitStructure);

    USART_Cmd(USART1, ENABLE);  // 使能USART1

    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);  // 开启接收中断
    NVIC_EnableIRQ(USART1_IRQn);   // 开启USART1中断
}

void USART1_IRQHandler(void)
{
    if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
    {
        char received = USART_ReceiveData(USART1);  // 读取接收到的数据
        if (rxIndex < RX_BUFFER_SIZE - 1)
        {
            rxBuffer[rxIndex++] = received;  // 保存数据到缓冲区
        }
        // 回显收到的数据
        USART_SendData(USART1, received);
        while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);  // 等待发送完成
    }
}

int main(void)
{
    USART1_Init();  // 初始化串口1

    while (1)
    {
        // 主循环可以处理其他任务,串口通信通过中断进行
    }
}

主要功能说明:
  • USART1_Init函数:该函数用于初始化串口1,包括配置GPIO引脚,设置波特率等串口参数,并开启接收中断。
  • USART1_IRQHandler函数:串口1的中断服务程序,当接收到数据时,进入中断,并将数据保存到接收缓冲区内,同时回显该数据给发送端。
  • 主函数main:在主循环中无需轮询接收数据,中断自动处理串口接收。程序可以执行其他任务,通信效率更高。

结语:这个简单的串口通信示例可以直接应用于基于沁恒CH32V103的项目,适合需要高效串口数据传输的场景。如果有任何疑问或改进建议,欢迎交流!

使用特权

评论回复
沙发
公羊子丹| | 2024-10-4 14:43 | 只看该作者
哇!这代码写得真清晰,正好我也在搞CH32V103,拿来用用!

使用特权

评论回复
板凳
周半梅| | 2024-10-4 14:43 | 只看该作者
正愁怎么处理串口回显功能,你这份代码来的太及时了,感谢!

使用特权

评论回复
地板
帛灿灿| | 2024-10-4 14:44 | 只看该作者
我试了一下,串口中断真的很方便,不用再占用CPU轮询了!

使用特权

评论回复
5
童雨竹| | 2024-10-4 14:44 | 只看该作者
这个USART的配置部分一直让我头疼,看到你的代码终于搞懂了!

使用特权

评论回复
6
Wordsworth| | 2024-10-4 14:44 | 只看该作者
你这个代码能不能扩展成多个串口一起使用?我现在有两个设备要同时通信。

使用特权

评论回复
7
Pulitzer| | 2024-10-4 14:45 | 只看该作者
代码运行的很顺畅,想问一下你有没有做过DMA传输的?

使用特权

评论回复
8
Bblythe| | 2024-10-4 14:45 | 只看该作者
中断方式确实比轮询高效很多,省了不少麻烦,感谢分享!

使用特权

评论回复
9
Uriah| | 2024-10-4 14:45 | 只看该作者
波特率115200这个挺常用的,有时候调低一点会更稳定,试过吗?

使用特权

评论回复
10
Clyde011| | 2024-10-4 14:45 | 只看该作者
你用这个MCU还有啥其他外设用过吗?我想看看能不能加个I2C进去。

使用特权

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

本版积分规则

27

主题

3613

帖子

0

粉丝