对初始工程的设置

未使用外部外部晶振

参考:关闭CH32的外部晶振

PA1,PA2默认是外接晶振使用,必须关闭外部晶振,才可以配置为普通IO使用

  1. 修改系统定义

在文件User\system_ch32v00x.c中,将开头的定义修改成如下

/* 
* Uncomment the line corresponding to the desired System clock (SYSCLK) frequency (after 
* reset the HSI is used as SYSCLK source).
* If none of the define below is enabled, the HSI is used as System clock source. 
*/

//#define SYSCLK_FREQ_8MHz_HSI    8000000
//#define SYSCLK_FREQ_24MHZ_HSI   HSI_VALUE
#define SYSCLK_FREQ_48MHZ_HSI   48000000
//#define SYSCLK_FREQ_8MHz_HSE    8000000
//#define SYSCLK_FREQ_24MHz_HSE   HSE_VALUE
//#define SYSCLK_FREQ_48MHz_HSE   48000000

只保留#define SYSCLK_FREQ_48MHZ_HSI 48000000,其他全部注释。这样PA1和PA2就可以当作普通引脚使用。

配置串口,开启中断接收

串口的默认引脚:USART1 TX-->D.5 RX-->D.6

  1. 初始化代码:

注意修改波特率 USART_InitStructure.USART_BaudRate = 230400;// 波特率设置为115200,其他的参数按需设置。


/*********************************************************************
 * @fn      USARTx_CFG
 *
 * @brief   初始化USART1外设配置,使用中断模式接收
 *
 * @return  none
 */
void USARTx_CFG(void)
{
    GPIO_InitTypeDef GPIO_InitStructure = {0};   // GPIO初始化结构体
    USART_InitTypeDef USART_InitStructure = {0}; // USART初始化结构体
    NVIC_InitTypeDef NVIC_InitStructure = {0};   // NVIC初始化结构体

    // 使能GPIOD和USART1时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_USART1, ENABLE);

    /* USART1 TX-->D.5   RX-->D.6 */
    // 配置USART1的TX引脚(PD5)为复用推挽输出
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_30MHz; // GPIO速度设置为30MHz
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;   // 复用推挽输出模式
    GPIO_Init(GPIOD, &GPIO_InitStructure);

    // 配置USART1的RX引脚(PD6)为浮空输入
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; // 浮空输入模式
    GPIO_Init(GPIOD, &GPIO_InitStructure);

    // 配置USART1通信参数
    USART_InitStructure.USART_BaudRate = 230400;                                    // 波特率设置为115200
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;                     // 8位数据位
    USART_InitStructure.USART_StopBits = USART_StopBits_1;                          // 1位停止位
    USART_InitStructure.USART_Parity = USART_Parity_No;                             // 无奇偶校验位
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 无硬件流控
    USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;                 // 使能发送和接收模式

    // 初始化USART1
    USART_Init(USART1, &USART_InitStructure);

    // 配置USART1接收中断
    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

    // 配置NVIC中断优先级
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    // 使能USART1
    USART_Cmd(USART1, ENABLE);
}
  1. 开启对应的中断服务函数
/*********************************************************************
 * @fn      USART1_IRQHandler
 *
 * @brief   USART1中断服务函数
 *
 * @return  none
 */
void USART1_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void USART1_IRQHandler(void)
{
    if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
    {
        // 读取接收到的数据
        u8 data = USART_ReceiveData(USART1);

        // 解析协议数据
        ParseProtocolData(data);
    }
}

其中的数据处理部分

        // 读取接收到的数据
        u8 data = USART_ReceiveData(USART1);

        // 解析协议数据
        ParseProtocolData(data);

需要替换成业务需要的代码!

使用阻塞的方式发送数据


/*********************************************************************
 * @fn      USART_SendData_Block
 *
 * @brief   阻塞方式发送数据
 *
 * @param   data - 要发送的数据指针
 * @param   len - 要发送的数据长度
 *
 * @return  none
 */
void USART_SendData_Block(u8 *data, u16 len)
{
    u16 i;
    for (i = 0; i < len; i++)
    {
        // 等待发送缓冲区为空
        while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET)
        {
        }
        // 发送数据
        USART_SendData(USART1, data[i]);
    }
    // 等待发送完成
    while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
    {
    }
}