继做了基于UCOSII的IWDG独立看门狗实验后,继续进行第25个实验-基于UCOSII的EXTI外部按键中断实验,此实验在基于UCOSII的IWDG实验基础上添加EXTI而来,三个按键,分别按下串口输出按键信息!在多任务下添加了IWDG独立看门狗。
//EXTI按键任务----------------------------------------
static void Task_EXTI(void* p_arg)
{
(void) p_arg;
while(1)
{ //看门狗更新设置喂狗操作
IWDGSET();
TESTKEY();
OSTimeDlyHMSM(0, 0, 0, 10);
}
}
unsigned char KEY=4;//外部中断标志
unsigned char EXTIFLAG=0;//外部中断标志
EXTI_InitTypeDef EXTI_InitStructure;
//EXTI口设置初始化
void EXTI_Config(void)
{
//声明GPIO类型,EXTI类型
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
//启动GPIOB,GPIOD的时钟,
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO|RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOE , ENABLE);
//初始化按键端口引脚
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_2|GPIO_Pin_3; //COL1,2,3
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //口线翻转速度为50MHz
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; //COL4
GPIO_Init(GPIOE, &GPIO_InitStructure);
//设置按键初始值为高电平
GPIO_SetBits(GPIOC, GPIO_Pin_5|GPIO_Pin_2|GPIO_Pin_3);
GPIO_SetBits(GPIOE, GPIO_Pin_6);
//初始化中断线
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //下拉输入
GPIO_Init(GPIOE, &GPIO_InitStructure);
//初始化外部中断EXTI
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource2);
EXTI_InitStructure.EXTI_Line = EXTI_Line2; //PE2 作为键盘的行线。检测状态
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //中断
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
GPIO_SetBits(GPIOE, GPIO_Pin_2); //起始值为高电平
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void EXTI_KEY(void)
{
if(EXTIFLAG==1)
{
//判断是否是PC5按下
GPIO_ResetBits(GPIOC, GPIO_Pin_5);
GPIO_SetBits(GPIOC, GPIO_Pin_2);
GPIO_SetBits(GPIOC, GPIO_Pin_3);
GPIO_SetBits(GPIOE, GPIO_Pin_6);
Delay(0XBF);
if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2)==0)
{
Delay(0XBF);
if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2)==0)
{
while(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2)==0);
KEY=0;
goto out_exit;
}
}
//判断是否是PC2按下
GPIO_SetBits(GPIOC, GPIO_Pin_5);
GPIO_ResetBits(GPIOC, GPIO_Pin_2);
GPIO_SetBits(GPIOC, GPIO_Pin_3);
GPIO_SetBits(GPIOE, GPIO_Pin_6);
Delay(0XBF);
if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2)==0)
{
Delay(0XBF);
if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2)==0)
{
while(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2)==0);
KEY=1;
goto out_exit;
}
}
//判断是否是PC3按下
GPIO_SetBits(GPIOC, GPIO_Pin_5);
GPIO_SetBits(GPIOC, GPIO_Pin_2);
GPIO_ResetBits(GPIOC, GPIO_Pin_3);
GPIO_SetBits(GPIOE, GPIO_Pin_6);
Delay(0XBF);
if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2)==0)
{
Delay(0XBF);
if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2)==0)
{
while(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2)==0);
KEY=2;
goto out_exit;
}
}
//判断是否是PE6按下
GPIO_SetBits(GPIOC, GPIO_Pin_5);
GPIO_SetBits(GPIOC, GPIO_Pin_2);
GPIO_SetBits(GPIOC, GPIO_Pin_3);
GPIO_ResetBits(GPIOE, GPIO_Pin_6);
Delay(0XBF);
if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2)==0)
{
Delay(0XBF);
if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2)==0)
{
while(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2)==0);
KEY=3;
goto out_exit;
}
}
out_exit:;
EXTIFLAG=0;
}
}
void TESTKEY(void)
{
EXTI_KEY();
GPIO_ResetBits(GPIOC, GPIO_Pin_2);
GPIO_ResetBits(GPIOC, GPIO_Pin_3);
GPIO_ResetBits(GPIOC, GPIO_Pin_5);
GPIO_ResetBits(GPIOE, GPIO_Pin_6);
switch(KEY)
{
case 0:
USART_OUT(USART1,"r***你按下了K1****n");
KEY=4;
break;
case 1:
USART_OUT(USART1,"r***你按下了K2****n");
KEY=4;
break;
case 2:
USART_OUT(USART1,"r***你按下了K3****n");
KEY=4;
break;
default:break;
}
}
////////////////键盘行线2中断
void EXTI2_IRQHandler(void)
{
OS_CPU_SR cpu_sr;
OS_ENTER_CRITICAL(); //保存全局中断标志,关总中断
//存放中断嵌套的层数(0~255)
OSIntNesting++; //OSSemPost(NMEA_MBOX);
OS_EXIT_CRITICAL(); //恢复全局中断标志
if(EXTI_GetITStatus(EXTI_Line2) != RESET) //判别是否有键按下
{
EXTI_ClearITPendingBit(EXTI_Line2);
EXTIFLAG=1; //标志
}
//脱离中断函数
OSIntExit(); //在os_core.c文件里定义,如果有更高优先级的任务就绪了,则执行一次任务切换
}
在此试验中修正了以前实验多任务下任务调度问题,比如ADC试验中优先级问题,TOUCH试验中优先级问题,还有在每个任务WHILE(1)中添加延时OSTimeDlyHMSM(0, 0, 0, 10); 此函数可以任务调度,还有就是在中断函数中,每个中断写成了
void XXXXX_IRQHandler(void)
{
OS_CPU_SR cpu_sr;
OS_ENTER_CRITICAL(); //保存全局中断标志,关总中断
//存放中断嵌套的层数(0~255)
OSIntNesting++; //OSSemPost(NMEA_MBOX);
OS_EXIT_CRITICAL(); //恢复全局中断标志
XXXXXX中断处理XXXXXXXXX
//脱离中断函数
OSIntExit(); //在os_core.c文件里定义,如果有更高优先级的任务就绪了,则执行一次任务切换
}
结果演示.....
![[转载]STM32学习笔记---基于UCOSII的EXTI外部按键中断实验 [转载]STM32学习笔记---基于UCOSII的EXTI外部按键中断实验](https://8.eewimg.cn/news/uploadfile/2018/1010/20181010080049911.jpg?imageView2/2/w/550)
上一篇:STM32与通常ARM的区别
下一篇:stm32之nRF24L01无线模块(1):SPI2到SPI1的移植
推荐阅读
史海拾趣



ASM10DTBD-S664






京公网安备 11010802033920号