新手求助CH32V307串口无法进入空闲中断

我这里用的是CH32V307,写一个modbus从机,需要配合空闲中断判断数据帧有咩有结束,外部是通过458通信的,有几点疑问请大家帮忙看看哈。

1,发现无法进入空闲中断,只进入到了接受中断,

2,我看官方evk的代码示例都没有在中断里面清除标志,清除标志用USART_ClearFlag还是USART_ClearITPendingBit?

3,usart和uart都支持dma吗?

下面贴我的代码大家帮忙看看。


初始化:

void rs485_init(void)

{

    GPIO_InitTypeDef  GPIO_InitStructure = {0};

    USART_InitTypeDef USART_InitStructure = {0};


    RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART8, ENABLE);

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC, ENABLE);



    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

    GPIO_Init(GPIOB, &GPIO_InitStructure);

    RS485_READ_EN(true);


    /* 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 = 9600;

    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(UART8, &USART_InitStructure);


    NVIC_InitTypeDef NVIC_InitStructure;

    NVIC_InitStructure.NVIC_IRQChannel = UART8_IRQn;

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStructure);


    USART_ITConfig(UART8, USART_IT_RXNE | USART_IT_IDLE, ENABLE);

    USART_Cmd(UART8, ENABLE);//先使能串口 再使能中断

}


中断:

void UART8_IRQHandler(void)

{

    uint8_t revice = 0;

    if (USART_GetITStatus(UART8, USART_IT_IDLE) == SET)

    {

        USART_ClearFlag(UART8, USART_IT_IDLE);

        revice = UART8->STATR;

        revice = UART8->DATAR;

        printf("rs485_msg.rx_len: %d\r\n", rs485_msg.rx_len);

        printf_hex(rs485_msg.rx_buffer, rs485_msg.rx_len);

    }

    if (USART_GetITStatus(UART8, USART_IT_RXNE) == SET)

    {

        USART_ClearITPendingBit(UART8, USART_IT_RXNE);

        revice =  USART_ReceiveData(UART8);

        rs485_msg.rx_buffer[rs485_msg.rx_len++] = revice;

        printf("%02x",revice);


    }

}


您好,关于你的问题:

1、中断函数注意要加中断声明,如下图1;

2、中断标志位的清除要调用USART_ClearITPendingBit函数,如下图1;注意空闲中断标志位的清除是先读取STATR,再读取DATAR;

3、USART和UART是都支持DMA的。

后续若有问题,可通过邮箱(lzs@wch.cn)和我沟通。

image.png

图1


已经知道啥问题了,

    USART_ITConfig(UART8, USART_IT_IDLE, ENABLE);

    USART_ITConfig(UART8, USART_IT_RXNE , ENABLE);

在使能中断的时候要分开写,一起的话

    USART_ITConfig(UART8, USART_IT_RXNE | USART_IT_IDLE, ENABLE);

这样就触发不了空闲,很奇怪。



您好,对串口中断使能时是需要分开写的,具体可以看一下该函数里面的操作,都是对具体某一位进行配置的。若需要一起使能,可以使用寄存器操作方式。


嗯呢,谢谢了,知道了,可否发一份uart的dma收发的例子出来参考下呢。


您好,在CH32V307 EVT中有串口DMA收发的例程,你可以参考一下,EVT下载链接如下:

/downloads/CH32V307EVT_ZIP.html

 


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