STM32F103中断控制灯与串口通信
一、STM32中断
1.中断
CPU执行程序时,由于发生了某种随机的事件(外部或内部),引起CPU暂时中断正在运行的程序,转去执行一段特殊的服务程序(中断服务子程序或中断处理程序),以处理该事件,该事件处理完后又返回被中断的程序继续执行,这一过程称为中断。引发中断的称为中断源。
比如:看电视时突然门铃响,那么门铃响就相当于中断源。有些中断还能够被其他高优先级的中断所中断,那么这种情况又叫做中断的嵌套。
STM32F10x芯片有84个中断通道,包括 16 个内核中断和 68 个可屏蔽中断,这些中断通道已按照不同优先级顺序固定分配给相应的外部设备。
抢占优先级:高抢占式优先级的中断事件会打断当前的主程序/中断程序的运行。中断嵌套。
响应优先级:在抢占式优先级相同的情况下,高响应优先级的中断优先被响应。不能嵌套,只能等待低响应优先级中断执行完成才能得到响应。
规则:先抢占优先级,后响应优先级;抢占式优先级决定是否会有中断嵌套。
2.NVIC介绍
NVIC英文全称是Nested Vectored Interrupt Controller:中文意思就是嵌套向量中断控制器,它属于M3内核的一个外设,控制着芯片的 中断相关功能。由于ARM给NVIC预留了非常多的功能,但对于使用M3内核设计芯片的公司可能就不需要这么多功能,于是就需要在NVIC上裁剪。ST公司的STM32F103芯片内部中断数量就是NVIC裁剪后的结果。 中断控制相关寄存器在固件库core_cm3.h文件NVIC结构体内。可打开任意库函数工程即可查看到。
二、控制LED灯亮和灭
1.CubMX配置
- SYS、RCC、GPIO配置如下
- 时钟配置如下
2.Keil添加代码
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;
}
}
三、串口通信
1.配置CubMX
- SYS、RCC配置如上
- USART1配置如下
2.Keil代码添加
数据定义
uint8_t aRxBuffer;//接收缓冲中断
uint8_t Uart1_RxBuff[256];//接收缓冲
uint8_t Uart1_Rx_Cnt=0;//接收缓冲计数
uint8_t cAlmStr[]="数据溢出(大于256)";
函数添加
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); //再开启接收中断
}
在main函数里面添加
//接收中断函数
HAL_UART_Receive_IT(&huart1,(uint8_t*)&aRxBuffer,1);
注意
烧录时一定要注意Boot0置1和置0,不然就不能完成实验。