<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

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

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

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

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

          // 設(shè)置復(fù)用到串口的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; //復(fù)用推挽輸出
          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; //復(fù)用開漏輸入
          GPIO_Init(GPIOA, &GPIO_InitStructure);


          RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//

          USART_DeInit(USART1); //首先復(fù)位

          /*!< 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.ex-cimer.com/article/201611/315503.htm
          中斷服務(wù)程序部分:

          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); // 清除標(biāo)志位
          }
          }

          程序的本意是 將收到的數(shù)據(jù)原樣發(fā)送回去。
          但是用串口調(diào)試助手調(diào)試時(shí)發(fā)現(xiàn),一個(gè)字節(jié)一個(gè)字節(jié)發(fā)送沒有問題,要是一次發(fā)送多個(gè)多個(gè)字節(jié),返回的數(shù)據(jù)就會(huì)出錯(cuò)。
          如下圖:
          分析問題在于
          發(fā)送的數(shù)據(jù)還沒有發(fā)送完成,新的數(shù)據(jù)又發(fā)送過來,
          改進(jìn)了新的接收中斷程序 當(dāng)積累到一定的數(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); // 清除標(biāo)志位
          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ā)送沒有問題。
          還有一個(gè)問題,stm32 的庫函數(shù) USART_SendData() 有缺陷,
          里面沒有判斷發(fā)送完成的標(biāo)志,

          使用USART_SendData()函數(shù)非連續(xù)發(fā)送單個(gè)字符是沒有問題的;當(dāng)連續(xù)發(fā)送字符時(shí)(兩個(gè)字符間沒有延時(shí)),就會(huì)發(fā)現(xiàn)發(fā)送緩沖區(qū)有溢出現(xiàn)象。若發(fā)送的數(shù)據(jù)量很小時(shí),此時(shí)串口發(fā)送的只是最后一個(gè)字符,當(dāng)發(fā)送數(shù)據(jù)量大時(shí),就會(huì)導(dǎo)致發(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)



          評(píng)論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();