CH32V307 中断实现串口发送 求助

CH32V307似乎没有提供串口中断发送的例程。

我自己写了个环形缓冲,但是不知道为什么有稳定性问题。 求助

#define DEBUG_UART_BUF_SIZE 64
#define DEBUG_UART_BUF_MASK DEBUG_UART_BUF_SIZE-1

uint8_t debug_uart_tx_buffer [DEBUG_UART_BUF_SIZE];
//uint8_t debug_uart_rx_buffer [DEBUG_UART_BUF_SIZE];
volatile size_t debug_uart_tx_head;
volatile size_t debug_uart_tx_tail;
volatile size_t debug_uart_tx_fill;
typedef enum { READY = 0,SENDING = 1} UART_TX_Buf_Status;
volatile UART_TX_Buf_Status  debug_uart_tx_status;


void USART_Printf_Init(uint32_t baudrate)
{
    GPIO_InitTypeDef  GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef  NVIC_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, 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);

    USART_InitStructure.USART_BaudRate = baudrate;
    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; //Tx only as we are doing debug

    USART_Init(USART1, &USART_InitStructure);
    USART_Cmd(USART1, ENABLE);

    //USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
    //Enable the TX interrupt, so when the data is taken to the shift register of the
    // peripheral, we can put in the next byte.

    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 14;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    debug_uart_tx_head=0;
    debug_uart_tx_tail=0;
    debug_uart_tx_fill=0;
    debug_uart_tx_status = READY;
    
}


void USART1_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));

void USART1_IRQHandler(void)
{
    if(USART_GetITStatus(USART1, USART_IT_TXE) == SET)
    {
        //Interrupt handler for trasmit 
        //USART1_send_char_from_buffer();
        //USART_ITConfig(USART1, USART_IT_TXE, ENABLE);

        debug_uart_tx_head=(debug_uart_tx_head+1)&DEBUG_UART_BUF_MASK;
        debug_uart_tx_fill--;
        
        if (debug_uart_tx_fill == 0)
        {
            // If there is no pending data, stop transmission.
            USART_ITConfig(USART1, USART_IT_TXE, DISABLE);
            debug_uart_tx_status = READY; 
        }
        else{
            // If there is still pending data, transmit the next byte.
            USART_SendData(USART1, debug_uart_tx_buffer[debug_uart_tx_head]);
        }
    }
}


void USART1_putchar(char c){
    while (debug_uart_tx_fill >= DEBUG_UART_BUF_SIZE);
    debug_uart_tx_buffer[debug_uart_tx_tail] = c;
    debug_uart_tx_tail=(debug_uart_tx_tail+1)&DEBUG_UART_BUF_MASK;
    debug_uart_tx_fill++;
    if (debug_uart_tx_status == READY)
    {
        debug_uart_tx_status = SENDING;
        USART_SendData(USART1, debug_uart_tx_buffer[debug_uart_tx_head]);
        USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
    }
}

具体表现为前面二三十个字节的发送都没问题,但是后来debug_uart_tx_head 跑到tail前面去了,导致乱码。不知道是什么原因。

您好,若要使用串口发送中断,可在发送数据时开启TXE中断,在发送完成后立即关闭TXE中断。注意关于清除TXE中断标志位,注意对USART_DATAR的写操作,将该位清零,即先读状态寄存器在读数据寄存器可对该位清零。使用环形缓冲区,注意对头和尾以及缓冲区长度大小的处理,若需要,可留一个邮箱,可给你发一个对环形缓冲区的讲解处理,你可参考一下。



能不能帮忙给我一个环形缓冲区的讲解,谢谢,我的邮箱 个人信息保护,已隐藏


您好,可以直接网上搜索环形缓冲区,会有很多专业的讲解和参考例程,可以参考一下,本人也是参考该类讲解进行理解应用的


只有登录才能回复,可以选择微信账号登录