新聞中心

        EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > stm32 串口連續(xù)接收 發(fā)送的出錯的問題

        stm32 串口連續(xù)接收 發(fā)送的出錯的問題

        作者: 時間:2016-11-17 來源:網(wǎng)絡 收藏
        上代碼:
        初始化部分:

        /*
        * 串口1 初始化
        */
        void USART1_Initial(void)
        {
        USART_InitTypeDef USART_InitStruct;
        GPIO_InitTypeDef GPIO_InitStructure;

        // 設置復用到串口的IO口 PA10 PA11

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //USART1 TX
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //復用推挽輸出
        GPIO_Init(GPIOA, &GPIO_InitStructure); //A端口

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //USART1 RX
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //復用開漏輸入
        GPIO_Init(GPIOA, &GPIO_InitStructure);


        RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//

        USART_DeInit(USART1); //首先復位

        /*!< This member configures the USART communication baud rate.
        The baud rate is computed using the following formula:
        - IntegerDivider = ((PCLKx) / (16 * (USART_InitStruct->USART_BaudRate)))
        - FractionalDivider = ((IntegerDivider - ((u32) IntegerDivider)) * 16) + 0.5 */
        USART_InitStruct.USART_BaudRate=2400;

        USART_InitStruct.USART_WordLength=USART_WordLength_8b;

        USART_InitStruct.USART_StopBits=USART_StopBits_1;

        USART_InitStruct.USART_Parity=USART_Parity_No;

        USART_InitStruct.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;

        USART_InitStruct.USART_HardwareFlowControl=USART_HardwareFlowControl_None;

        USART_Init(USART1, &USART_InitStruct);

        USART_ITConfig(USART1,USART_IT_RXNE,ENABLE); //USART1 接收中斷使能

        USART_Cmd(USART1,ENABLE); // USART1 模塊使能
        }

        本文引用地址:http://www.104case.com/article/201611/315503.htm
        中斷服務程序部分:

        void USART1_IRQHandler(void)
        {

        ITStatus ItState=RESET;
        ItState=USART_GetITStatus(USART1,USART_IT_RXNE);
        if(ItState==SET)
        {
        ReceivedData=USART_ReceiveData(USART1);// 發(fā)送收到的數(shù)據(jù)
        ReceiveFlag=1;
        //USART_SendData(USART1,ReceivedData);// 注釋掉,放到主函數(shù)中異步發(fā)送試試
        USART_ClearITPendingBit(USART1,USART_IT_RXNE); // 清除標志位
        }
        }

        程序的本意是 將收到的數(shù)據(jù)原樣發(fā)送回去。
        但是用串口調試助手調試時發(fā)現(xiàn),一個字節(jié)一個字節(jié)發(fā)送沒有問題,要是一次發(fā)送多個多個字節(jié),返回的數(shù)據(jù)就會出錯。
        如下圖:
        分析問題在于
        發(fā)送的數(shù)據(jù)還沒有發(fā)送完成,新的數(shù)據(jù)又發(fā)送過來,
        改進了新的接收中斷程序 當積累到一定的數(shù)據(jù)才發(fā)送。
        void USART1_IRQHandler(void)
        {
        int i=0;
        static unsigned char counter=0;
        ITStatus ItState=RESET;
        ItState=USART_GetITStatus(USART1,USART_IT_RXNE);
        if(ItState==SET)
        {
        USART_ClearITPendingBit(USART1,USART_IT_RXNE); // 清除標志位
        ReceivedData[counter]=USART_ReceiveData(USART1); // 發(fā)送收到的數(shù)據(jù)
        counter++;
        if(counter>=10)
        {
        ReceiveFlag=1;
        counter=0;
        for(i=0;i<10;i++)
        {
        USART_SendData(USART1,ReceivedData[i]);
        while(USART_GetFlagStatus(USART1,USART_FLAG_TC)== RESET);
        //while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)== RESET);
        }
        } // 注釋掉,放到主函數(shù)中異步發(fā)送試試
        }
        }
        這樣發(fā)送沒有問題。
        還有一個問題,stm32 的庫函數(shù) USART_SendData() 有缺陷,
        里面沒有判斷發(fā)送完成的標志,

        使用USART_SendData()函數(shù)非連續(xù)發(fā)送單個字符是沒有問題的;當連續(xù)發(fā)送字符時(兩個字符間沒有延時),就會發(fā)現(xiàn)發(fā)送緩沖區(qū)有溢出現(xiàn)象。若發(fā)送的數(shù)據(jù)量很小時,此時串口發(fā)送的只是最后一個字符,當發(fā)送數(shù)據(jù)量大時,就會導致發(fā)送的數(shù)據(jù)莫名其妙的丟失。

        如:

        1
        2
        for(TxCounter = 0;TxCounter RxCounter; TxCounter++)
        USART_SendData(USART1, RxBuffer[TxCounter]);

        解決辦法while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET)

        或者

        while(USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET)



        評論


        技術專區(qū)

        關閉
        主站蜘蛛池模板: 施秉县| 微山县| 襄樊市| 巴里| 丹巴县| 慈利县| 清水县| 杂多县| 江阴市| 鹤峰县| 华池县| 高青县| 金溪县| 灵璧县| 修水县| 汕尾市| 霍山县| 应用必备| 东辽县| 城固县| 会东县| 舒城县| 桐庐县| 西乡县| 柳州市| 宝清县| 玉树县| 镇江市| 玉溪市| 建始县| 米脂县| 阿拉善左旗| 朔州市| 襄城县| 萨迦县| 太仆寺旗| 延津县| 张家界市| 凤庆县| 宁蒗| 梁河县|