基于CH32V307单片机的USART主机与U(S)ART多从机通讯

本文章介绍使用CH32V307单片机实现主机轮回接收从机传输的数据,并在串口软件显示。
您需要的资料:CH32V307单片机数据手册及例程
一、单片机串口部分简介

系统框图
由上图可知,CH32V307有8个串口(USART+UART)。
数据手册
由数据手册可知,USART有3个,USART1挂接在APB2总线上,USART2和USART2以及7个UART挂接在APB1总线上。
为了方便插拔引脚转接线,将数据手册中有关串口引脚陈列如下表格中。

串口引脚号串口名称
PA8USART1_CK
PA9USART1 _TX
PA10USART1_RX
PA11USART1_CTX
PA12USART1 _RTX
PA4USART2_CK
PA2USART2_TX
PA3USART2_RX
PA0USART2_CTX
PA1USART2_RTX
PB12USART3_CK
PB10USART3 _TX
PB11USART3_RX
PB13USART3_CTX
PB14USART3 _RTX
PC10UART4_TX
PC11UART4_RX
PC12UART5_TX
PD2UART5_RX
PC0UART6_TX
PC1UART6_RX
PC2UART7_TX
PC3UART7_RX
PC4UART8_TX
PC5UART8_RX

防止原有映射引脚被其它外设占用,手册中定义的串口复用引脚陈列如下。

串口引脚号(复用)串口名称
PA5/PA10USART1_CK
PB6/PB15USART1 _TX
PB7USART1_RX
USART1_CTX
PC5/PA9USART1 _RTX
PD7USART2_CK
PD5USART2_TX
PD6USART2_RX
PD3USART2_CTX
PD4USART2_RTX
PD10/PC12USART3_CK
PD8/PC10USART3 _TX
PD9/PC11USART3_RX
PD11USART3_CTX
USART3 _RTX
PB0UART4_TX
PB1UART4_RX
PE8UART5_TX
PE9/PB4UART5_RX
PE10UART6_TX
PE11UART6_RX
PE12/PA6UART7_TX
PE13 /PA7UART7_RX
PE14/PA14UART8_TX
PE15/PA15UART8_RX

二、通讯原理及实现

  1. Master程序为采集数据单片机烧录,Slave程序为数据发送单片机烧录;
  2. 主程序使6个串口中断周期性的开关,达到每次只接受一个Slave数据,达到周期性采集6个Slave数据的目的。最多可外接8路串口,本例程中USART1用来与PC串口通讯,UART8因器件不够暂未使用到。Slave均使用USART2,分别连接到Master剩余的6串口上。
  3. 若Master指定采集第x个Slave数据,则需先发送一个数据0作为启动Slave发送数据的请求命令,Slave判定请求命令正确后,在进行数据的发送。这种协议的约定,保证了Master接收Slave数据的完整性。(在Master接收到Slave数据后,可将原数据返回Slave做校验,本程序暂未实现,请读者自行尝试)
  4. 硬件连接如下,因为没有足够的usb供电,Slave取电为板载级联杜邦线方式。中间一块为Master采集板,周边六块为Slave数据发送板。

一个主机与六个从机
5. 程序如下

//双机通讯,使用USART

#include "debug.h"

/* Global define */
#define TxSize1    (size(TxBuffer1))
/* Global Variable */
u8 RxBuffer1 = 0; /* Send by UART2 */
u8 RequestData=0;//请求发送数据
u8 Rxfinish1 = 2;//先给个初始值,进入case 2,启动接收
//void USART1_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void USART2_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void USART3_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void UART4_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void UART5_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void UART6_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void UART7_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
//void UART8_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));

/*********************************************************************
 * @fn      USARTx_CFG
 *
 * @brief   Initializes the USART2 & USART3 peripheral.
 *
 * @return  none
 */
void USARTx_CFG(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure = {0};
    USART_InitTypeDef USART_InitStructure = {0};
    NVIC_InitTypeDef  NVIC_InitStructure = {0};

    RCC_APB1PeriphClockCmd( RCC_APB1Periph_USART2|RCC_APB1Periph_USART3|RCC_APB1Periph_UART4|RCC_APB1Periph_UART5|RCC_APB1Periph_UART6|RCC_APB1Periph_UART7|RCC_APB1Periph_UART8, ENABLE);
//    RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1, ENABLE);
    RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD, ENABLE);

//    /* USART1 TX-->A.9  RX-->A.10 */
//    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
//    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
//    GPIO_Init(GPIOA, &GPIO_InitStructure);
//    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
//    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
//    GPIO_Init(GPIOA, &GPIO_InitStructure);
    /* USART2 TX-->A.2  RX-->A.3 */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    /* USART3 TX-->B.10  RX-->B.11 */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    /* UART4 TX-->C.10  RX-->C.11 */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOC, &GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOC, &GPIO_InitStructure);
    /* UART5 TX-->C.12  RX-->D.12 */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOC, &GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOD, &GPIO_InitStructure);
    /* UART6 TX-->C.0  RX-->C.1 */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOC, &GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOC, &GPIO_InitStructure);
    /* UART7 TX-->C.2  RX-->C.3 */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOC, &GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOC, &GPIO_InitStructure);
//    /* UART8 TX-->C.4  RX-->C.5 */
//    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
//    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
//    GPIO_Init(GPIOC, &GPIO_InitStructure);
//    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
//    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
//    GPIO_Init(GPIOC, &GPIO_InitStructure);

    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_Tx | USART_Mode_Rx;

//    USART_Init(USART1, &USART_InitStructure);
//    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
    USART_Init(USART2, &USART_InitStructure);
    USART_ITConfig(USART2, USART_IT_RXNE, DISABLE);//初始化全部关闭
    USART_Init(USART3, &USART_InitStructure);
    USART_ITConfig(USART3, USART_IT_RXNE, DISABLE);
    USART_Init(UART4, &USART_InitStructure);
    USART_ITConfig(UART4, USART_IT_RXNE, DISABLE);
    USART_Init(UART5, &USART_InitStructure);
    USART_ITConfig(UART5, USART_IT_RXNE, DISABLE);
    USART_Init(UART6, &USART_InitStructure);
    USART_ITConfig(UART6, USART_IT_RXNE, DISABLE);
    USART_Init(UART7, &USART_InitStructure);
    USART_ITConfig(UART7, USART_IT_RXNE, DISABLE);
//    USART_Init(UART8, &USART_InitStructure);
//    USART_ITConfig(UART8, USART_IT_RXNE, DISABLE);

//    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
//    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
//    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
//    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
//    NVIC_Init(&NVIC_InitStructure);
    NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    NVIC_InitStructure.NVIC_IRQChannel = UART4_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    NVIC_InitStructure.NVIC_IRQChannel = UART5_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    NVIC_InitStructure.NVIC_IRQChannel = UART6_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    NVIC_InitStructure.NVIC_IRQChannel = UART7_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
//    NVIC_InitStructure.NVIC_IRQChannel = UART8_IRQn;
//    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
//    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
//    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
//    NVIC_Init(&NVIC_InitStructure);

//    USART_Cmd(USART1, ENABLE);
    USART_Cmd(USART2, ENABLE);
    USART_Cmd(USART3, ENABLE);
    USART_Cmd(UART4, ENABLE);
    USART_Cmd(UART5, ENABLE);
    USART_Cmd(UART6, ENABLE);
    USART_Cmd(UART7, ENABLE);
//    USART_Cmd(UART8, ENABLE);
}
/*********************************************************************
 * @fn      main
 *
 * @brief   Main program.
 *
 * @return  none
 */
int main(void)
{
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    Delay_Init();
    USART_Printf_Init(115200);
    USARTx_CFG(); /* USART2 & USART3 INIT */

    printf("DATA RECEIVED START! \r\n");

    //USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
    while(1)
    {

        switch (Rxfinish1)
        {
//        case 1:
//            printf("DATA RECEIVED FROM USART1 :%s\r\n",RxBuffer1);
        //            Rxfinish1=0;
//            USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);

//            break;
        case 2:
            printf("DATA RECEIVED FROM SLAVE_2 :%p\r\n",RxBuffer1);//打印Slave发送来的数据
            USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);//开启下一个Slave中断,准备接受数据
            USART_SendData(USART3, RequestData);//发送准备好接受命令请求,Slave收到校验后,就开启发送
            while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
            Delay_Ms(100);//给slave时间组织发送,时间太短会重新进入case 2.
            break;
        case 3:
            printf("DATA RECEIVED FROM SLAVE_3 :%p\r\n",RxBuffer1);
            USART_ITConfig(UART4, USART_IT_RXNE, ENABLE);
            USART_SendData(UART4, RequestData);
            while(USART_GetFlagStatus(UART4, USART_FLAG_TXE) == RESET);
            Delay_Ms(100);
            break;
        case 4:
            printf("DATA RECEIVED FROM SLAVE_4 :%p\r\n",RxBuffer1);
            USART_ITConfig(UART5, USART_IT_RXNE, ENABLE);
            USART_SendData(UART5, RequestData);
            while(USART_GetFlagStatus(UART5, USART_FLAG_TXE) == RESET);
            Delay_Ms(100);
            break;
        case 5:
            printf("DATA RECEIVED FROM SLAVE_5 :%p\r\n",RxBuffer1);
            USART_ITConfig(UART6, USART_IT_RXNE, ENABLE);
            USART_SendData(UART6, RequestData);
            while(USART_GetFlagStatus(UART6, USART_FLAG_TXE) == RESET);
            Delay_Ms(100);
            break;
        case 6:
            printf("DATA RECEIVED FROM SLAVE_6 :%p\r\n",RxBuffer1);
            USART_ITConfig(UART7, USART_IT_RXNE, ENABLE);
            USART_SendData(UART7, RequestData);
            while(USART_GetFlagStatus(UART7, USART_FLAG_TXE) == RESET);
            Delay_Ms(100);
            break;
        case 7:
            printf("DATA RECEIVED FROM SLAVE_7 :%p\r\n",RxBuffer1);
            USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
            USART_SendData(USART2, RequestData);
            while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
            Delay_Ms(100);
            break;
//        case 8:
//            printf("DATA RECEIVED FROM UART8 :%p\r\n",RxBuffer1);
//            Rxfinish1=0;
//            Delay_Ms(500);
//            USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
//            USART_SendData(USART3, RequestData);
//            while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
//            break;
        default:
            printf("DATA RECEIVED error%p\r\n");
            Delay_Ms(500);
            USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
            break;
        }

    }
}

/*********************************************************************
 * @fn      USART3_IRQHandler
 *
 * @brief   This function handles USART3 global interrupt request.
 *
 * @return  none
 */
//void USART1_IRQHandler(void)
//{
//    if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
 //   {
 //       RxBuffer1 = USART_ReceiveData(USART1);
  //      USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);
  //      Rxfinish1 = 1;
 //   }

//}

void USART2_IRQHandler(void)
{
    if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
    {
        RxBuffer1 = USART_ReceiveData(USART2);
        USART_ITConfig(USART2, USART_IT_RXNE, DISABLE);//关闭此中断
        Rxfinish1 = 2;
    }

}

void USART3_IRQHandler(void)
{
    if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)
    {
        RxBuffer1 = USART_ReceiveData(USART3);
        USART_ITConfig(USART3, USART_IT_RXNE, DISABLE);
        Rxfinish1 = 3;
    }

}

void UART4_IRQHandler(void)
{
    if(USART_GetITStatus(UART4, USART_IT_RXNE) != RESET)
    {
        RxBuffer1 = USART_ReceiveData(UART4);
        USART_ITConfig(UART4, USART_IT_RXNE, DISABLE);
        Rxfinish1 = 4;
    }

}

void UART5_IRQHandler(void)
{
    if(USART_GetITStatus(UART5, USART_IT_RXNE) != RESET)
    {
        RxBuffer1 = USART_ReceiveData(UART5);
        USART_ITConfig(UART5, USART_IT_RXNE, DISABLE);
        Rxfinish1 = 5;
    }

}

void UART6_IRQHandler(void)
{
    if(USART_GetITStatus(UART6, USART_IT_RXNE) != RESET)
    {
        RxBuffer1= USART_ReceiveData(UART6);
        USART_ITConfig(UART6, USART_IT_RXNE, DISABLE);
        Rxfinish1 = 6;
    }

}

void UART7_IRQHandler(void)
{
    if(USART_GetITStatus(UART7, USART_IT_RXNE) != RESET)
    {
        RxBuffer1 = USART_ReceiveData(UART7);
        USART_ITConfig(UART7, USART_IT_RXNE, DISABLE);
        Rxfinish1 = 7;
    }

}

//void UART8_IRQHandler(void)
//{
//    if(USART_GetITStatus(UART8, USART_IT_RXNE) != RESET)
//    {
//        RxBuffer1 = USART_ReceiveData(UART8);
//        USART_ITConfig(UART8, USART_IT_RXNE, DISABLE);
//        Rxfinish1 = 8;
//    }
//
//}


  1. Slave程序
//双机通讯,使用USART

#include "debug.h"
/* Global Variable */
u8 TxBuffer2 = 6;//这是发送的数据,可以分别配置Slave为不同的值
u8 RequestData=0;//检测请求命令是否正确
u8 RxBuffer2=0;
u8 Rxfinish2;
void USART2_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
/*********************************************************************
 * @fn      USARTx_CFG
 *
 * @brief   Initializes the USART2 & USART3 peripheral.
 *
 * @return  none
 */
void USARTx_CFG(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure = {0};
    USART_InitTypeDef USART_InitStructure = {0};
    NVIC_InitTypeDef  NVIC_InitStructure = {0};

    RCC_APB1PeriphClockCmd( RCC_APB1Periph_USART2, ENABLE);
    RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE);

    /* USART2 TX-->A.2  RX-->A.3 */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    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_Tx | USART_Mode_Rx;

    USART_Init(USART2, &USART_InitStructure);
    USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);

    NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    USART_Cmd(USART2, ENABLE);
}

/*********************************************************************
 * @fn      main
 *
 * @brief   Main program.
 *
 * @return  none
 */
int main(void)
{
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    Delay_Init();
    USART_Printf_Init(115200);
    USARTx_CFG(); /* USART2 & USART3 INIT */


    while(1)
    {
        if(RxBuffer2==RequestData)//校验数据请求命令
        {
            USART_SendData(USART2, TxBuffer2);//向Master发送数据
            while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
        }

    }
}

void USART2_IRQHandler(void)
{
    if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)//等待接受Master数据请求命令
    {
        RxBuffer2 = USART_ReceiveData(USART2);

    }
}

在这里插入图片描述
注:主机先上电,从机再上电,否则数据接收混乱,正在处理这个问题。

  • 5
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
对于 ch32v307vct6 芯片来说,配置串口需要以下步骤: 1. 确定串口配置参数,包括波特率、数据位、校验位和停止位等。 2. 配置 GPIO,将对应的引脚设置为串口功能。 3. 配置串口控制器,包括设置波特率、数据位、校验位和停止位等参数,以及开启串口发送和接收中断。 4. 编写相应的串口发送和接收函数,用于向串口发送数据和接收数据。 下面是一个简单的示例代码,演示如何配置 ch32v307vct6 的串口: ```c #include "ch32v307.h" #define UART_TX_PIN GPIO_Pin_10 #define UART_RX_PIN GPIO_Pin_11 void uart_init(uint32_t baud_rate, uint8_t data_bits, uint8_t parity, uint8_t stop_bits) { // 使能 GPIO 时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 配置 GPIO 引脚为复用功能 GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = UART_TX_PIN | UART_RX_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); // 使能 USART 时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); // 配置 USART 参数 USART_InitTypeDef USART_InitStructure; USART_InitStructure.USART_BaudRate = baud_rate; USART_InitStructure.USART_WordLength = data_bits; USART_InitStructure.USART_Parity = parity; USART_InitStructure.USART_StopBits = stop_bits; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USART2, &USART_InitStructure); // 开启 USART 中断 USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); // 使能 USART USART_Cmd(USART2, ENABLE); } void uart_send_byte(uint8_t byte) { while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, byte); } uint8_t uart_receive_byte(void) { while (USART_GetFlagStatus(USART2, USART_FLAG_RXNE) == RESET); return USART_ReceiveData(USART2); } ``` 在上面的代码中,我们首先定义了 UART_TX_PIN 和 UART_RX_PIN 分别表示串口发送和接收引脚所在的 GPIO 引脚号。 然后,在 uart_init 函数中,我们依次进行了 GPIO 配置、USART 配置和中断配置等操作。其中,baud_rate、data_bits、parity 和 stop_bits 分别表示波特率、数据位、校验位和停止位等参数。 最后,我们分别定义了 uart_send_byte 和 uart_receive_byte 两个函数,用于向串口发送数据和接收数据。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值