串口数据接收过快时,检查包头校验位的代码就会报错,发慢一地就不会

2019-07-21 00:39发布

可能两条数据间隔太短,串口一次把多条当一条处理了,轻问各位大佬有什么办法解决 检验的 检验的
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
28条回答
余怡帆℡
1楼-- · 2019-07-21 22:07
nashui_sx 发表于 2019-5-28 09:26
看你好像是中断一股脑接收,一次读取全部512处理,肯定有问题呀  既然有包头,读取两个包头之间的处理   ...

[mw_shl_code=c,true]int UART_Read(int dev, unsigned char *buf, int size )
{
        int r_len;

        if( dev < 0 || dev >= UART_MAX ) return -1;
        if ( size <= 0 ) return 0;

        r_len = 0;

        while(uart_dev[dev].recv.Rd != uart_dev[dev].recv.Wr )
        {
                *buf = uart_dev[dev].recv.buf[uart_dev[dev].recv.Rd];
                uart_dev[dev].recv.Rd = (uart_dev[dev].recv.Rd+1) % BUFFER_LEN;
                buf++;
                if( ++r_len >= size ) return r_len;
        }

        return r_len;
}

int UART_Write( int dev, unsigned char *buf, int size )
{
#if OS_CRITICAL_METHOD == 3
        OS_CPU_SR  cpu_sr = 0;
#endif

        int w_len;

        if( dev < 0 ||dev >= UART_MAX ) return -1;
        if ( size <= 0 ) return 0;

        w_len = 0;

        while(uart_dev[dev].send.Rd != ((uart_dev[dev].send.Wr+1)%BUFFER_LEN))
        {
                uart_dev[dev].send.buf[uart_dev[dev].send.Wr] = *buf;
                uart_dev[dev].send.Wr = ( uart_dev[dev].send.Wr + 1 )%BUFFER_LEN;

                w_len++;
                if ( w_len >= size ) break;
                buf++;
        };
    #if 0
    if(DEV_UART3 == dev)
    {
        printf("^^^%d,%d^^^ ",uart_dev[dev].send.Rd,uart_dev[dev].send.Wr);
    }
    #endif

        OS_ENTER_CRITICAL();
        if ( uart_dev[dev].send.State == SEND_IDLE )
                {
                OS_EXIT_CRITICAL();

                uart_dev[dev].send.State = SENDING;
                //(*((volatile unsigned char *) uart_dev[dev].send.reg)) = uart_dev[dev].send.buf[uart_dev[dev].send.Rd];
                switch(dev)
                {
                case DEV_UART1:
                        USART_SendData(USART1,uart_dev[dev].send.buf[uart_dev[dev].send.Rd]);
                        #if 1
                        USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
                        #endif
                        break;
                case DEV_UART2:
                        USART_SendData(USART2,uart_dev[dev].send.buf[uart_dev[dev].send.Rd]);
                        #if 1
                        USART_ITConfig(USART2, USART_IT_TXE, ENABLE);
                        #endif
                        break;
                }

                return w_len;
        }
        OS_EXIT_CRITICAL();

        return w_len;
}


void USART1_IRQHandler(void)
{
        if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET){
                USART_ClearITPendingBit(USART1, USART_IT_RXNE);
                //接收数据
                //uart_dev[DEV_UART1].recv.buf[uart_dev[DEV_UART1].recv.Wr] = U1RBR;
                uart_dev[DEV_UART1].recv.buf[uart_dev[DEV_UART1].recv.Wr] = USART_ReceiveData(USART1);
                  uart_dev[DEV_UART1].recv.Wr = (uart_dev[DEV_UART1].recv.Wr +1)%BUFFER_LEN;
                  if(uart_dev[DEV_UART1].recv.Wr == uart_dev[DEV_UART1].recv.Rd ) {
                          uart_dev[DEV_UART1].recv.Rd = (uart_dev[DEV_UART1].recv.Rd +1)%BUFFER_LEN;
                  }
                //USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);


        }

        #if 1
        if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET){
        #else
        if(USART_GetITStatus(USART1, USART_IT_TC) != RESET){
                USART_ClearITPendingBit(USART1, USART_IT_TC);
        #endif
                //发送数据
                if(uart_dev[DEV_UART1].send.State == SENDING){
                        uart_dev[DEV_UART1].send.Rd = (uart_dev[DEV_UART1].send.Rd +1)%BUFFER_LEN;
                        if ( uart_dev[DEV_UART1].send.Rd == uart_dev[DEV_UART1].send.Wr) {
                                uart_dev[DEV_UART1].send.State = SEND_IDLE;
                        } else {
                                //U1THR = uart_dev[DEV_UART1].send.buf[uart_dev[DEV_UART1].send.Rd];
                                USART_SendData(USART1, uart_dev[DEV_UART1].send.buf[uart_dev[DEV_UART1].send.Rd]);
                        }
                }
                #if 1
                else{
                        USART_ITConfig(USART1, USART_IT_TXE, DISABLE);
                }
                #endif
        }
}


void USART2_IRQHandler(void)
{
        if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET){
                USART_ClearITPendingBit(USART2, USART_IT_RXNE);
                //接收数据
                //uart_dev[DEV_UART1].recv.buf[uart_dev[DEV_UART1].recv.Wr] = U1RBR;
                uart_dev[DEV_UART2].recv.buf[uart_dev[DEV_UART2].recv.Wr] = USART_ReceiveData(USART2);
                  uart_dev[DEV_UART2].recv.Wr = (uart_dev[DEV_UART2].recv.Wr +1)%BUFFER_LEN;
                  if(uart_dev[DEV_UART2].recv.Wr == uart_dev[DEV_UART2].recv.Rd ) {
                          uart_dev[DEV_UART2].recv.Rd = (uart_dev[DEV_UART2].recv.Rd +1)%BUFFER_LEN;
                  }
                //USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);
        }

        #if 1
        if(USART_GetITStatus(USART2, USART_IT_TXE) != RESET){
        #else
        if(USART_GetITStatus(USART1, USART_IT_TC) != RESET){
                USART_ClearITPendingBit(USART1, USART_IT_TC);
        #endif
                //发送数据
                if(uart_dev[DEV_UART2].send.State == SENDING){
                        uart_dev[DEV_UART2].send.Rd = (uart_dev[DEV_UART2].send.Rd +1)%BUFFER_LEN;
                        if ( uart_dev[DEV_UART2].send.Rd == uart_dev[DEV_UART2].send.Wr) {
                                uart_dev[DEV_UART2].send.State = SEND_IDLE;
                        } else {
                                //U1THR = uart_dev[DEV_UART1].send.buf[uart_dev[DEV_UART1].send.Rd];
                                USART_SendData(USART2, uart_dev[DEV_UART2].send.buf[uart_dev[DEV_UART2].send.Rd]);
                        }
                }
                #if 1
                else{
                        USART_ITConfig(USART2, USART_IT_TXE, DISABLE);
                }
                #endif
        }
[/mw_shl_code]
余怡帆℡
2楼-- · 2019-07-21 23:58
nashui_sx 发表于 2019-5-28 09:26
看你好像是中断一股脑接收,一次读取全部512处理,肯定有问题呀  既然有包头,读取两个包头之间的处理   ...

数据有一条是不定长的,大佬看看我的串口处理代码,同事给的
余怡帆℡
3楼-- · 2019-07-22 05:20
 精彩回答 2  元偷偷看……
nashui_sx
4楼-- · 2019-07-22 07:36
余怡帆℡ 发表于 2019-5-28 10:05
数据有一条是不定长的,大佬看看我的串口处理代码,同事给的

各种方案都能解决,看你是对旧代码大刀阔斧的改还是修修补补
大刀阔斧就用空闲中断,小改这个已经有fifo处理了,你usartproess先查询帧头位置,读取第二个帧头前的长度就好了
yklstudent
5楼-- · 2019-07-22 11:12
 精彩回答 2  元偷偷看……
IoTCatcher
6楼-- · 2019-07-22 17:12
本帖最后由 IoTCatcher 于 2019-5-28 11:58 编辑
余怡帆℡ 发表于 2019-5-28 08:50
请问这要怎么实现啊
看了下你的串口读写, 已经有fifo功能了.app分析数据的时候, 一位一位取试试.

一周热门 更多>