实验阶段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 "); } }
串口发送函数使用了输出流重定向,需要在魔术棒配置中勾选使用微库(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!! "); } }
该实验功能点有一个明显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); } }