STM32-7 结合中断来做个红绿灯吧!

既然前几篇介绍了外部中断、Timer中断与USART,那接下来就结合这三种中断来模拟红绿灯出来吧。
这一次会用到定时器(TIM2)、外部中断还有一个USART。
设计想法 :
Timer :红绿灯有一定的时序,可以利用Timer中断来控制。
EXTI : 某些路口有行人按钮,当按下时会从闪黄灯转为正常红绿灯。
USART : 用来模拟路旁的号誌控制箱
首先先整理一下程式设计的想法

利用Timer中断来完成时序的控制当UART与EXTI同时触发,UART先行执行直到收到退出指令EXTI触发后回到预设红绿灯时序,经过n秒后回到闪黄灯
http://img2.58codes.com/2024/20146325teah6FoNqJ.png
http://img2.58codes.com/2024/20146325VLqrO5pY5J.png

实作

第一步先设定LED连接的GPIO脚位,这边我是连接PB13-15一样都设置GPIO_Output
http://img2.58codes.com/2024/20146325jYojvLhLOx.png
先来看看优先权如何设定,以上方设计的来看优先权会是USART→EXTI→Timer,在.ioc档当中可以去做设置。在这边中断分组选择4也就是4个bit全用来作为Preemption priority分级。
http://img2.58codes.com/2024/201463254FAffVj1TR.png
宣告几个全域变数之后会需要用到~

float timesec; //用来计算秒数的int mode = 0; //模式  0:闪黄灯(EXTI) 1:红绿灯(Timer) 2:控制箱(USART)char Rxbuf[1];char Txbuf[30];

之后可以将各中断回调函数先写好

外部中断 : 由闪黄灯进入红绿灯时序
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){if(GPIO_Pin == GPIO_PIN_13){mode = 1;}}
定时中断 : 控制三种灯号的时间变化
在这边首先选择TIM2,我设定为0.5s中断一次方便之后计算。
http://img2.58codes.com/2024/20146325ypZ8EY6Dxm.png
写入定时中断的函数,在这边因为定时器设定为0.5s,所以我对于秒数增加为0.5。
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){ if (htim->Instance == htim2.Instance) {timesec+=0.5; }}
USART : 模拟控制箱控制灯号,判断接收到哪种指令亮起对应灯号
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){if(huart->Instance == huart2.Instance){mode = 2;HAL_UART_Receive_IT(huart, (uint8_t*)&Rxbuf, 1);sprintf(Txbuf, "控制箱模式 : %c\r\n", Rxbuf[0]);HAL_UART_Transmit_IT(&huart2, (uint8_t*)&Txbuf, sizeof(Txbuf));}}
Trafficmode: 用来根据mode变数来选择对应的亮灯方式mode 0 : 闪黄灯mode 1 : 红绿灯,藉由外部中断触发进入模式1后启用定时器。到达总时长5秒后会切换为闪黄灯模式。mode 2 : 控制箱,在接收到电脑所传送的指令(R/G/Y/E)后亮起对应灯号。
void Trafficmode(int modex){switch(modex){case 0:HAL_GPIO_WritePin(GPIOB, GLED_Pin, RESET);HAL_GPIO_WritePin(GPIOB, RLED_Pin, RESET);HAL_GPIO_TogglePin(GPIOB, YLED_Pin);HAL_Delay(500);break;case 1:HAL_TIM_Base_Start_IT(&htim2); //Start Timer Interruptif(timesec>=0&&timesec<=1.5){HAL_GPIO_WritePin(GPIOB, YLED_Pin, RESET);HAL_GPIO_WritePin(GPIOB, RLED_Pin, RESET);HAL_GPIO_WritePin(GPIOB, GLED_Pin, SET);}else if(timesec>1.5&&timesec<=2.5){HAL_GPIO_WritePin(GPIOB, GLED_Pin, RESET);HAL_GPIO_WritePin(GPIOB, YLED_Pin, SET);}else if(timesec>2.5&&timesec<=5){HAL_GPIO_WritePin(GPIOB, YLED_Pin, RESET);HAL_GPIO_WritePin(GPIOB, RLED_Pin, SET);}else{HAL_TIM_Base_Stop_IT(&htim2);timesec=0;mode=0;}break;case 2:if(Rxbuf[0] == 0x47)  //G{HAL_GPIO_WritePin(GPIOB, YLED_Pin, RESET);HAL_GPIO_WritePin(GPIOB, RLED_Pin, RESET);HAL_GPIO_WritePin(GPIOB, GLED_Pin, SET);}else if(Rxbuf[0] == 0x59) //Y{HAL_GPIO_WritePin(GPIOB, YLED_Pin, SET);HAL_GPIO_WritePin(GPIOB, RLED_Pin, RESET);HAL_GPIO_WritePin(GPIOB, GLED_Pin, RESET);}else if(Rxbuf[0] == 0x52) //R{HAL_GPIO_WritePin(GPIOB, YLED_Pin, RESET);HAL_GPIO_WritePin(GPIOB, RLED_Pin, SET);HAL_GPIO_WritePin(GPIOB, GLED_Pin, RESET);}elsemode =0;}}

关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章