久久ER99热精品一区二区-久久精品99国产精品日本-久久精品免费一区二区三区-久久综合九色综合欧美狠狠

新聞中心

EEPW首頁 > 嵌入式系統 > 設計應用 > stm32 串口連續接收 發送的出錯的問題

stm32 串口連續接收 發送的出錯的問題

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

/*
* 串口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://cqxgywz.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);// 發送收到的數據
ReceiveFlag=1;
//USART_SendData(USART1,ReceivedData);// 注釋掉,放到主函數中異步發送試試
USART_ClearITPendingBit(USART1,USART_IT_RXNE); // 清除標志位
}
}

程序的本意是 將收到的數據原樣發送回去。
但是用串口調試助手調試時發現,一個字節一個字節發送沒有問題,要是一次發送多個多個字節,返回的數據就會出錯。
如下圖:
分析問題在于
發送的數據還沒有發送完成,新的數據又發送過來,
改進了新的接收中斷程序 當積累到一定的數據才發送。
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); // 發送收到的數據
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);
}
} // 注釋掉,放到主函數中異步發送試試
}
}
這樣發送沒有問題。
還有一個問題,stm32 的庫函數 USART_SendData() 有缺陷,
里面沒有判斷發送完成的標志,

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

如:

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)



評論


技術專區

關閉