STM32串口实验
实验阶段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); } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?
2016-10-15 OrCAD搭建Access数据库