閑言少敘,先上代碼,大家看下面這段代碼沒有問題?
// Note: USART demo code runs on STM32F030
#include "main.h"
static __IO uint32_t TimingDelay;
RCC_ClocksTypeDef RCC_Clocks;
uint8_t uart_buffer;
// GPIO Configuration
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_1); // Tx PA9
GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_1); // Rx PA10
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; // USART1_TX | USART1_RX
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_1;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
// USART Configuration
void USART_Configuration(void)
{
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 115200;
//USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
USART_Init(USART1,&USART_InitStructure);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
USART_Cmd(USART1,ENABLE);
}
// Interrupt Configuration
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
// USART1 interrupt Config
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
// USART1 Interrupt Handler
void USART1_IRQHandler (void)
{
static uint8_t i = 0;
if(USART_GetITStatus(USART1,USART_IT_RXNE)!= RESET)
{// Clear Receive Data Register Not Empty Flag
USART_ClearITPendingBit(USART1,USART_IT_RXNE);
uart_buffer[i++] = USART_ReceiveData(USART1);
if(i == 100)
i = 0;
}
}
int main(void)
{
static uint8_t ch;
// Init a 1ms timer interrupt, for Delay function implementation.
RCC_GetClocksFreq(&RCC_Clocks);
SysTick_Config(RCC_Clocks.HCLK_Frequency / 1000);
// Enable USART1 and GPIOA clock
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA,ENABLE);
GPIO_Configuration();
USART_Configuration();
NVIC_Configuration();
ch = 'A';
while(1)
{
Delay(50);
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
USART_SendData(USART1, ch);
ch++;
}
}
/**
* @brief Inserts a delay time.
* @param nTime: specifies the delay time length, in 1 ms.
* @retval None
*/
void Delay(__IO uint32_t nTime)
{
TimingDelay = nTime;
while(TimingDelay != 0);
}
/**
* @brief Decrements the TimingDelay variable.
* @param None
* @retval None
*/
void TimingDelay_Decrement(void)
{
if(TimingDelay != 0x00)
{
TimingDelay--;
}
}
它可以在 STM32F030 上調試通過的發送測試程序,發送采用接收循環??,接收到接收的數據存入協議。
有很多比較認真的實戰派的同學估計會下載子上跑一跑,它確實能跑通,看起來也沒什么問題。很多教程甚至官方的都是類似的處理方法。
這確實是在某個像馬坑里有馬兒跑出來的馬兒,然后跑著一個人跑出來,跑出來連挖挖挖出來。 ,莫名更新了它的死機。查來查去,查去查來,發現問題。解決起來不容易啊,一個去開,拆代碼,想都。。。
所以同學們不要輕視任何一段代碼啊!
非常快的時候,如果對方接收到數據的時候,可以自己發送接收數據的時間,或者對方正在發送的數據發送給對方。 ,會導致超出標志位的置位。這個標志位一置,原來就亂了。所以,在程序中一定要對異常情況的處理。甚至覺得發生的異常也不要置之不理。(一想為什么要填充Flash的空白區域?在正常情況代碼永遠不會跑到空白區域下是吧。)
對串口異常的處理也可以參考下面的處理函數。當然可以在主程序中處理,以便在代碼中斷的情況下正常運行。
// USART1 Interrupt Handler
void USART1_IRQHandler (void)
{
static uint8_t i = 0;
if(USART_GetFlagStatus(USART1, USART_FLAG_ORE) != RESET)
{// Clear Overrun Error Flag
USART_ClearFlag(USART1, USART_FLAG_ORE);
}
else if(USART_GetFlagStatus(USART1, USART_FLAG_NE) != RESET)
{// Clear Noise Error Flag
USART_ClearFlag(USART1, USART_FLAG_NE);
}
else if(USART_GetFlagStatus(USART1, USART_FLAG_FE) != RESET)
{// Clear Framing Error Flag
USART_ClearFlag(USART1, USART_FLAG_FE);
}
else if(USART_GetFlagStatus(USART1, USART_FLAG_PE) != RESET)
{// Clear Parity Error Flag
USART_ClearFlag(USART1, USART_FLAG_PE);
}
else if(USART_GetITStatus(USART1,USART_IT_RXNE)!= RESET)
{// Clear Receive Data Register Not Empty Flag
USART_ClearITPendingBit(USART1,USART_IT_RXNE);
uart_buffer[i++] = USART_ReceiveData(USART1);
if(i == 100)
i = 0;
}
}
審核編輯:劉清
評論
查看更多