由于调试过程中发现Proteus 8有些许bug,串口中断采用STM32F103RCT6开发板进行讲解
前期准备:
- STM32CubeMX
- STM32F103RCT6开发板
- IDE Keil(MDK-ARM)
STM32CubeMX部分
1. 配置时钟
选择STM32F103RCTx系列芯片,配置时钟的同时会自动配置IO口引脚
将HCLK设置为最大频率72MHz
2.配置USART
选择:
USART1串口1
Baud Rate(波特率):115200 Bits/s
Work Length(传输数据长度): 8 Bit
Parity(奇偶校验位) : 无
STOP Bits(停止位) :1
Data Direction(数据方向) : 发送和接收都使能
设置完之后就会自动配置USART1_RX和USART1_TX两个引脚
接着在NVIC Settings一栏设置使能全局中断
3.配置IO口
将PC4,PC5,PB0,PB1设置为:
高电平
Output模式
既不上拉也不下拉
响应速度高
3. 工程生成
工程管理依旧是这几个选项,然后GENERATE CODE,STM32CubeMX部分完成。
MDK 5部分
· HAL_UART_Transmit();串口发送数据,使用超时管理机制
· HAL_UART_Receive();串口接收数据,使用超时管理机制
· HAL_UART_Transmit_IT();串口中断模式发送
· HAL_UART_Receive_IT();串口中断模式接收
· HAL_UART_Transmit_DMA();串口DMA模式发送
· HAL_UART_Transmit_DMA();串口DMA模式接收
· HAL_UART_IRQHandler(UART_HandleTypeDef *huart);
· HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart);
· HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart);
· HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);
· HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart);
· HAL_UART_ErrorCallback();串口接收错误函数
讲两个常用的函数
HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)//串口中断接收数据
UART_HandleTypeDef * huart:串口号
uint8_t * pData:存放数据的数组
uint16_t Size:接收的数据长度
设置数据存放位置,接收数据长度,然后使能串口接收中断。接收到数据时,会触发串口中断,再然后,串口中断函数处理,直到接收到指定长度数据,而后关闭中断,进入中断接收回调函数,不再触发接收中断。(只触发一次中断)
例:HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1);
HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart); //中断回调函数
中断进行完之后,并不会直接退出,而是会进入中断回调函数中,我们在其中写入代码即可
例:void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
用户自定义的代码
}
1. 重定义Printf函数
先在main.c添加
#include "stdio.h"
然后在stm32f1xx_hal.c中添加
#include "stm32f1xx_hal.h"
#include <stdio.h>
extern UART_HandleTypeDef huart1;
接着重写fgetc和fputc函数
int fputc(int ch, FILE *f)
{
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
return ch;
}
int fgetc(FILE *f)
{
uint8_t ch = 0;
HAL_UART_Receive(&huart1, &ch, 1, 0xffff);
return ch;
}
然后在while里就可使用Printf函数了
while (1)
{
printf("测试\r\n");
HAL_Delay(1000);
}
编译下载时需要选择相对应的下载器,勾选以下
打开串口助手,设置
波特率:115200
停止位:1
数据位:8
奇偶校验:无
可以看到Printf能正常使用
2. 重写中断回调函数
在usart.c文件中添加如下代码
#include "stdio.h"
#include "string.h"
#define RXBUFFERSIZE 256
char RxBuffer[RXBUFFERSIZE];
uint8_t aRxBuffer;
uint8_t Uart1_Rx_Cnt = 0;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
UNUSED(huart);
if(Uart1_Rx_Cnt >= 255)
{
Uart1_Rx_Cnt = 0;
memset(RxBuffer,0x00,sizeof(RxBuffer));
HAL_UART_Transmit(&huart1, (uint8_t *)"数据溢出", 10,0xFFFF);
}
else
{
RxBuffer[Uart1_Rx_Cnt++] = aRxBuffer;
if(aRxBuffer == '1')
{
HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_1);
}
else if(aRxBuffer == '2')
{
HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_0);
}
else if(aRxBuffer == '3')
{
HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_5);
}
else if(aRxBuffer == '4')
{
HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_4);
}
if((RxBuffer[Uart1_Rx_Cnt-1] == 0x0A)&&(RxBuffer[Uart1_Rx_Cnt-2] == 0x0D))
{
HAL_UART_Transmit(&huart1, (uint8_t *)&RxBuffer, Uart1_Rx_Cnt,0xFFFF);
while(HAL_UART_GetState(&huart1) == HAL_UART_STATE_BUSY_TX);
Uart1_Rx_Cnt = 0;
memset(RxBuffer,0x00,sizeof(RxBuffer));
}
}
HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1);
}
接着去main.c中加入 extern uint8_t aRxBuffer;
#include "stdio.h"
extern uint8_t aRxBuffer;
接着开启接收中断
HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1);
开启一次后进入中断回调函数,因为在中断回调函数中添加了此函数,即可一直等待发送数据以此进入中断
可以看到发送的数据被正常返回
接下来发送1 2 3 4看看灯是否能正常亮灭
本期工程文档——>Gitee
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)