實驗階段1,定時器計時1s觸發中斷,在中斷中往外發送數據
定時器設定為36000分頻,周期設定為2000,並開啟中斷,配置代碼如下
tim_timebase_struct.TIM_CounterMode = TIM_CounterMode_Up; tim_timebase_struct.TIM_ClockDivision = TIM_CKD_DIV1; tim_timebase_struct.TIM_Prescaler = DEBUG_UART_TX_TIM_PSC; tim_timebase_struct.TIM_Period = DEBUG_UART_TX_TIM_PERIOD; TIM_TimeBaseInit(DEBUG_UART_TX_TIM, &tim_timebase_struct); TIM_Cmd(DEBUG_UART_TX_TIM, ENABLE); TIM_ITConfig(DEBUG_UART_TX_TIM, TIM_IT_Update, ENABLE);
串口配置與PC端調試助手設置一致即可,一般都配置為無硬件流控,無奇偶校驗,1位停止位,八位數據位
usart_struct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; usart_struct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; usart_struct.USART_Parity = USART_Parity_No; usart_struct.USART_StopBits = USART_StopBits_1; usart_struct.USART_WordLength = USART_WordLength_8b; usart_struct.USART_BaudRate = DEBUG_UART_BAUDRATE; USART_Init(DEBUG_UART, &usart_struct); USART_Cmd(DEBUG_UART, ENABLE);
中斷服務函數中還是常規的檢測中斷標志位然后清除中斷標志位
void DEBUG_UART_TX_TIM_IRQ_HANDLER(void) { if(TIM_GetITStatus(DEBUG_UART_TX_TIM, TIM_IT_Update) != RESET) { TIM_ClearITPendingBit(DEBUG_UART_TX_TIM, TIM_IT_Update); printf("hello\r\n"); } }
串口發送函數使用了輸出流重定向,需要在魔術棒配置中勾選使用微庫(Use MicroLIB)
int fputc(int ch, FILE* stream) { while(USART_GetFlagStatus(DEBUG_UART, USART_FLAG_TXE) == RESET); USART_SendData(DEBUG_UART, ch); return ch; }
實驗階段2,通過按鍵觸發外部中斷的方式來產生一次數據發送,按鍵GPIO配置為一般輸出,下拉即可,並且需要調用一個函數將GPIO連接到EXTI
gpio_struct.GPIO_Mode = GPIO_Mode_IN; gpio_struct.GPIO_PuPd = GPIO_PuPd_DOWN; gpio_struct.GPIO_Speed = GPIO_Speed_Level_1; gpio_struct.GPIO_Pin = PUSHBUTTON_PIN; GPIO_Init(PUSHBUTTON_GPIO, &gpio_struct); SYSCFG_EXTILineConfig(PUSHBUTTON_EXTI_PORTSOURCE, PUSHBUTTON_EXTI_PINSOURCE);
本實驗使用的是ST官方的NUCLEO開發板,MCU型號為STM32F303RE,使用標准庫開發,串口的GPIO配置如下
gpio_struct.GPIO_Mode = GPIO_Mode_AF; gpio_struct.GPIO_OType = GPIO_OType_PP; gpio_struct.GPIO_PuPd = GPIO_PuPd_NOPULL; gpio_struct.GPIO_Speed = GPIO_Speed_Level_1; gpio_struct.GPIO_Pin = DEBUG_UART_TX | DEBUG_UART_RX; GPIO_Init(DEBUG_UART_GPIO, &gpio_struct); GPIO_PinAFConfig(DEBUG_UART_GPIO, DEBUG_UART_TX_PINSOURCE, GPIO_AF_7); GPIO_PinAFConfig(DEBUG_UART_GPIO, DEBUG_UART_RX_PINSOURCE, GPIO_AF_7);
中斷服務函數如下
void PUSHBUTTON_IRQ_HANDLER(void) { if(EXTI_GetITStatus(PUSHBUTTON_EXTI_LINE) != RESET) { EXTI_ClearITPendingBit(PUSHBUTTON_EXTI_LINE); printf("Push button clicked!!\r\n"); } }
該實驗功能點有一個明顯BUG,即外部中斷可能會連續觸發,導致一次按鍵可能導致重復發送數據
---***---該BUG為硬件消抖做的不好所致,在官方的NUCLEO64開發板上有BUG,但在野火MINI板上運行OK
實驗階段3,做一個接受回傳的功能,開啟串口中斷,在中斷中將收到的數據進行回傳
void DEBUG_UART_IRQ_HANDLER(void) { if(USART_GetITStatus(DEBUG_UART, USART_IT_RXNE) != RESET) { USART_ClearITPendingBit(DEBUG_UART, USART_IT_RXNE); uint16_t data = USART_ReceiveData(DEBUG_UART); USART_SendData(DEBUG_UART, data); } }