微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > stm32 串口连续接收 发送的出错的问题

stm32 串口连续接收 发送的出错的问题

时间: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 模块使能
}

中断服务程序部分:

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)

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top