通过中断来控制LED灯(STMF103C8+HAL库)
作者:互联网
呦呦鹿鸣
一、STM32中断介绍
1.1 中断概念
- 中断是由内核外部产生的,一般由硬件引起,比如外设中断和外部中断等。
1.2 中断全过程
- 中断发生:当CPU在处理某一事件A时,发生了另一事件B,请求CPU迅速去处理。
- 中断处理:CPU暂停当前的工作,转去处理事件B。
- 中断返回:当CPU将事件B处理完毕后,再回到事件A中被暂停的地方继续处理事件。
1.3 中断作用
- 速度匹配:可以解决快速的CPU与慢速的外部设备之间传送数据的矛盾。
- 分时操作:CPU可以分时为多个外部设备服务,提高计算机的利用率。
- 实时响应:CPU能够及时处理应用系统的随机事件,增强系统的实时性。
- 可靠性高:CPU可以处理设备故障及掉电等突发事件,提高系统可靠性。
1.4 中断优先级
- 处理器根据不同中断的重要程序设置不同的优先等级。不同优先级中断的处理原则是:高级中断可以打断低级中断;低级中断不能打断高级中断。如图所示:
二、HAL库的中断处理流程
- 第一步,跳转到该中断所对应的中断服务程序,每个引脚有自己的外部中断服务程序,对应关系如下图,比如外部中断线0,对应就是0引脚,如PA0,PB0,但这些不能同时设置
- 跳转到相应的外部中断服务程序,然后执行里面的函数
- 再跳转到外部中断通用处理函数
- 执行外部中断通用处理函数,调用回拨函数
- 接下来就是运行回拨函数了,如果我们有什么需要在中断时运行的程序,就在这里面写。
- 总体流程
三、高低电平控制控制LED灯亮和灭
- 进入STMCUBEX,选择新建项目
- 搜索F103C8,点击右侧的选项,创建新的项目
- 点击sys,将debug选项改为Serial Wire
- 然后在Rcc里的HSE选择Crystal/Ceramic Resonator
- 将PB0选为外部中断触发器,PA1是控制led灯的,和将它选择为GPIO_output就行了
- 选择PLLCLK,然后将后面的晶振频率最大值改为72M赫兹
- project里把toolchain那里改为MDK-ARM,版本选择最新的就行了,项目名和项目路径自己选择
- 选择生成初始化文件,然后选择生成代码就好了
- 打开项目,来到keil5,进入到mian.c里,接下来就是刚刚提到的在回调函数里写代码了,将回调函数重写一遍就行了,代码如下
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){
GPIO_PinState b0_pin = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0); // 读取b0的状态
b0_pin=1-b0_pin;
switch (GPIO_Pin){//判断引脚
case GPIO_PIN_0:
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1,1-b0_pin); // 将a1写入与b0相同的电位
break;
}
}
- 效果如图
四、中断实现串口通信
- 还是使用CUBEMX,新建项目的过程和上一个是一样的,接下来是RCC的设置,也是设置HSE
- SYS里也是选择serial Wire
- 选择UASRT1,将mode改为异步通信,选择下面的NVIC Setting,将enabled选上。
- project manager里的步骤也和上一个是一样的,接下来就是在keil5里打开项目,进入main.c文件,在里面定义如下数据,注意不是在main函数里,而是在头文件后
uint8_t aRxBuffer;//接收缓冲中断
uint8_t Uart1_RxBuff[256];//接收缓冲
uint8_t Uart1_Rx_Cnt=0;//接收缓冲计数
uint8_t cAlmStr[]="数据溢出(大于256)";
- 然后将HAL_UART_RxCpltCallback函数重写,和上面的回调函数是一个道理
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(Uart1_Rx_Cnt >= 255) //溢出判断
{
Uart1_Rx_Cnt = 0;
memset(Uart1_RxBuff,0x00,sizeof(Uart1_RxBuff));
HAL_UART_Transmit(&huart1, (uint8_t *)&cAlmStr, sizeof(cAlmStr),0xFFFF);
}
else
{
Uart1_RxBuff[Uart1_Rx_Cnt++] = aRxBuffer; //接收数据转存
if((Uart1_RxBuff[Uart1_Rx_Cnt-1] == 0x0A)||(Uart1_RxBuff[Uart1_Rx_Cnt-2] == 0x0D)) //判断结束位
{
HAL_UART_Transmit(&huart1, (uint8_t *)&Uart1_RxBuff, Uart1_Rx_Cnt,0xFFFF); //将收到的信息发送出去
Uart1_Rx_Cnt = 0;
memset(Uart1_RxBuff,0x00,sizeof(Uart1_RxBuff)); //清空数组
}
}
HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1); //再开启接收中断
}
- 然后在主函数写一个接收中断函数
int main(void)
{
//初始化
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART1_UART_Init();
//接收中断函数
HAL_UART_Receive_IT(&huart1,(uint8_t*)&aRxBuffer,1);
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
- 运行结果,可以看到发送什么就返回什么,但要注意要选择新行,或者在输入字符串后面跟一个enter键
五、总结
- 中断方式蛮好用的,设置了中断之后,在回调函数里写我们想要实现功能,当我们触发中断的时候就会实现功能,不过还是得注意中断也有优先级。
六、参考
【STM32CubeMX】HAL库中断方式UART串口通信
STM32之中断控制LED灯
标签:RxBuff,HAL,中断,Uart1,UART,GPIO,LED,STMF103C8 来源: https://blog.csdn.net/junseven164/article/details/121066120