0.LED配置?
使用static修饰的变量具有内部链接属性,只能在当前文件中访问
一、基本概念与实验目的
实验目的:
1.轮询:定时器 不同时间 处理 不同任务 ,引出标志位,将中断函数中的处理提到主函数执行
2.事件驱动:增加按键中断,使其控制定时器的开关,同时控制LED亮灭
3.需求分析:按键中断优先级 应高于 定时器中断优先级
4.对于标志位:执行时,第一件事就是清除上次的标志位
二、CubeMx配置
1)增加LED输出配置(默认不亮),其余默认
三、函数编写
1.实验一:轮询按键中断标志,在主函数中控制定时器开关和LED亮灭
0)相关函数及变量定义
static volatile uint8_t ledStatus = 0;//使用static修饰的变量具有内部链接属性,只能在当前文件中访问
static volatile uint8_t timStatus = 0;
#define LED(STATUS) HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, (STATUS)?GPIO_PIN_RESET:GPIO_PIN_SET)//STATUS置1则为低电平
#define LED_TOGGLE() HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_1)//翻转电平
1)中断服务函数
static volatile uint8_t keyFlag = 0;
static volatile uint8_t timFlag = 0;
/*中断服务函数,在main前*/
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if(GPIO_Pin == GPIO_PIN_0)
{
keyFlag = 1;
}
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
static volatile uint32_t tim2Cnt = 0;
if(htim->Instance == TIM2)
{
tim2Cnt++;
if((tim2Cnt%100)==0)
{
timFlag = 1;
}
if((tim2Cnt%200)==0)
{
timFlag = 2;
}
if((tim2Cnt%300)==0)
{
timFlag = 3;
}
if((tim2Cnt%400)==0)
{
timFlag = 4;
}
if((tim2Cnt%500)==0)
{
timFlag = 5;
}
}
}
2) 在while中执行,开关定时器和控制LED亮灭,如果关闭定时器,则串口打印不执行
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
if(keyFlag)
{
keyFlag = 0;
ledStatus = !ledStatus;
timStatus = !timStatus;
LED(ledStatus);
if(timStatus)
{
HAL_TIM_Base_Start_IT(&htim2);
}
else
{
HAL_TIM_Base_Stop_IT(&htim2);
}
}
switch(timFlag)
{
case 1:
{
printf("The first[1] thing process: %d\r\n", HAL_GetTick());
timFlag = 0;
break;
}
case 2:
{
printf("The second[2] thing process: %d\r\n", HAL_GetTick());
timFlag = 0;
break;
}
case 3:
{
printf("The third[3] thing process: %d\r\n", HAL_GetTick());
timFlag = 0;
break;
}
case 4:
{
printf("The fourth[4] thing process: %d\r\n", HAL_GetTick());
timFlag = 0;
break;
}
case 5:
{
printf("The fifth[5] thing process: %d\r\n", HAL_GetTick());
timFlag = 0;
break;
}
default:break;
}
}
2.实验二:在按键中断服务中控制定时器开关和LED亮灭
1) 中断服务函数
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
static volatile uint8_t ledStatus = 0;
static volatile uint8_t timStatus = 0;
if(GPIO_Pin == GPIO_PIN_0)
{
keyFlag = 1;
ledStatus = !ledStatus;
timStatus = !timStatus;
LED(ledStatus);
if(timStatus)
{
HAL_TIM_Base_Start_IT(&htim2);
}
else
{
HAL_TIM_Base_Stop_IT(&htim2);
}
}
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
static volatile uint32_t tim2Cnt = 0;
if(htim->Instance == TIM2)
{
tim2Cnt++;
if((tim2Cnt%100)==0)
{
timFlag = 1;
}
if((tim2Cnt%200)==0)
{
timFlag = 2;
}
if((tim2Cnt%300)==0)
{
timFlag = 3;
}
if((tim2Cnt%400)==0)
{
timFlag = 4;
}
if((tim2Cnt%500)==0)
{
timFlag = 5;
}
}
}
2)main函数,while串口打印TIM轮询,若按键中断关闭TIM,则串口不显示
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
switch(timFlag)//用于定时器轮询,若按键控制其关闭,则不显示
{
case 1:
{
printf("The first[1] thing process: %d\r\n", HAL_GetTick());
timFlag = 0;
break;
}
case 2:
{
printf("The second[2] thing process: %d\r\n", HAL_GetTick());
timFlag = 0;
break;
}
case 3:
{
printf("The third[3] thing process: %d\r\n", HAL_GetTick());
timFlag = 0;
break;
}
case 4:
{
printf("The fourth[4] thing process: %d\r\n", HAL_GetTick());
timFlag = 0;
break;
}
case 5:
{
printf("The fifth[5] thing process: %d\r\n", HAL_GetTick());
timFlag = 0;
break;
}
default:break;
}
}