1. 程式人生 > 其它 >104-CH32V307(WCH微控制器)學習開發-串列埠

104-CH32V307(WCH微控制器)學習開發-串列埠

<p><iframe name="ifd" src="https://mnifdv.cn/resource/cnblogs/LearnCH32V307VCT6" frameborder="0" scrolling="auto" width="100%" height="1500"></iframe></p>

串列埠1

void uart_init(u32 bound1){
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA
|RCC_APB2Periph_GPIOB|RCC_APB2Periph_USART1|RCC_APB2Periph_AFIO , ENABLE); //USART1_TX GPIOA.9 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);
//USART1_RX GPIOA.10初始化 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIOA, &GPIO_InitStructure); //USART 初始化設定 USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字長為8位資料格式 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_InitStructure.USART_BaudRate = bound1;//串列埠波特率 USART_Init(USART1, &USART_InitStructure); //初始化串列埠1 /*中斷優先順序配置*/ NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); //根據指定的引數初始化VIC暫存器 USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//開啟串列埠接受中斷 USART_Cmd(USART1, ENABLE); //使能串列埠 } //串列埠中斷服務程式 __attribute__((interrupt("WCH-Interrupt-fast"))) void USART1_IRQHandler(void) { u8 Res; if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) { Res =USART_ReceiveData(USART1); //讀取接收到的資料 } }

串列埠傳送資料

void usart_send_bytes(USART_TypeDef *USARTx, char *c,uint32_t cnt)
{
    while(cnt--)
    {
        USART_SendData(USARTx, *c++);
        while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET );
    }
}


usart_send_bytes(USART1, "11223344", 4);//傳送資料

串列埠1,2,3

void uart_init(u32 bound1,u32 bound2,u32 bound3){
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2|RCC_APB1Periph_USART3, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_USART1|RCC_APB2Periph_AFIO , ENABLE);

    //串列埠引腳
    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_IPU;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    //串列埠引腳
    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_IPU;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    //串列埠引腳
    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_IPU;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    //USART 初始化設定
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字長為8位資料格式
    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_InitStructure.USART_BaudRate = bound1;//串列埠波特率
    USART_Init(USART1, &USART_InitStructure); //初始化串列埠1

    USART_InitStructure.USART_BaudRate = bound2;//串列埠波特率
    USART_Init(USART2, &USART_InitStructure); //初始化串列埠2

    USART_InitStructure.USART_BaudRate = bound3;//串列埠波特率
    USART_Init(USART3, &USART_InitStructure); //初始化串列埠3

    /*串列埠--1*/
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure); //根據指定的引數初始化VIC暫存器

    /*串列埠--2*/
    NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure); //根據指定的引數初始化VIC暫存器

    /*串列埠--3*/
    NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//開啟串列埠接受中斷
    USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//開啟串列埠接受中斷
    USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);//開啟串列埠接受中斷

    USART_Cmd(USART1, ENABLE);                    //使能串列埠
    USART_Cmd(USART2, ENABLE);                    //使能串列埠
    USART_Cmd(USART3, ENABLE);                    //使能串列埠
}


//串列埠中斷服務程式
__attribute__((interrupt("WCH-Interrupt-fast")))
void USART1_IRQHandler(void)
{
    u8 Res;
    if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
    {
        Res =USART_ReceiveData(USART1); //讀取接收到的資料
    }
}

//串列埠中斷服務程式
__attribute__((interrupt("WCH-Interrupt-fast")))
void USART2_IRQHandler(void)
{
    u8 Res;
    if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
    {
        Res =USART_ReceiveData(USART2); //讀取接收到的資料
    }
}

//串列埠中斷服務程式
__attribute__((interrupt("WCH-Interrupt-fast")))
void USART3_IRQHandler(void)
{
    u8 Res;
    if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)
    {
        Res =USART_ReceiveData(USART3); //讀取接收到的資料
    }
}

串列埠4

void uart_init(u32 bound4){
    //GPIO埠設定
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2|RCC_APB1Periph_USART3|RCC_APB1Periph_UART4, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC|RCC_APB2Periph_USART1|RCC_APB2Periph_AFIO , ENABLE);

    //串列埠引腳
    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_IPU;
    GPIO_Init(GPIOC, &GPIO_InitStructure);


    //USART 初始化設定
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字長為8位資料格式
    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_InitStructure.USART_BaudRate = bound4;//串列埠波特率
    USART_Init(UART4, &USART_InitStructure); //初始化串列埠

    /*串列埠--4*/
    NVIC_InitStructure.NVIC_IRQChannel = UART4_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    USART_ITConfig(UART4, USART_IT_RXNE, ENABLE);//開啟串列埠接受中斷

    USART_Cmd(UART4, ENABLE);                    //使能串列埠
}



//串列埠中斷服務程式
__attribute__((interrupt("WCH-Interrupt-fast")))
void UART4_IRQHandler(void)
{
    u8 Res;
    if(USART_GetITStatus(UART4, USART_IT_RXNE) != RESET)
    {
        Res =USART_ReceiveData(UART4); //讀取接收到的資料
        USART_SendData(UART4, Res);//返回接收的資料
    }
}

串列埠5

void uart_init(u32 bound5){
    //GPIO埠設定
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2|RCC_APB1Periph_USART3|RCC_APB1Periph_UART4|RCC_APB1Periph_UART5, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD|RCC_APB2Periph_USART1|RCC_APB2Periph_AFIO , ENABLE);

    //串列埠引腳
    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_2;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_Init(GPIOD, &GPIO_InitStructure);


    //USART 初始化設定
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字長為8位資料格式
    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_InitStructure.USART_BaudRate = bound5;//串列埠波特率
    USART_Init(UART5, &USART_InitStructure); //初始化串列埠

    /*串列埠--5*/
    NVIC_InitStructure.NVIC_IRQChannel = UART5_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    USART_ITConfig(UART5, USART_IT_RXNE, ENABLE);//開啟串列埠接受中斷

    USART_Cmd(UART5, ENABLE);                    //使能串列埠
}


//串列埠中斷服務程式
__attribute__((interrupt("WCH-Interrupt-fast")))
void UART5_IRQHandler(void)
{
    u8 Res;
    if(USART_GetITStatus(UART5, USART_IT_RXNE) != RESET)
    {
        Res =USART_ReceiveData(UART5); //讀取接收到的資料
        USART_SendData(UART5, Res);
    }
}

串列埠6,7,8根據串列埠4,5修改就可以

            TX , RX

串列埠6(PC0, PC1)

串列埠7(PC2, PC3)

串列埠8(PC4, PC5)

我提供了一套標準的資料處理方案

1,提供的例程是串列埠1和串列埠2接收到什麼資料就返回什麼資料

2,我這邊自己實現了延時函式,所以把官方的遮蔽了

3,printf我這邊也改了(中斷髮送,不會阻塞)

4,串列埠1和串列埠2接收資料都是使用環形佇列接收

4,串列埠1判斷接收完一條資料使用的是自帶的空閒中斷

5,串列埠2判斷接收完一條資料是使用定時器自定義的空閒時間

6,串列埠1傳送資料可以使用中斷方式