历史上的今天
返回首页

历史上的今天

今天是:2024年10月10日(星期四)

正在发生

2018年10月10日 | STM32学习笔记---基于UCOSII的EXTI外部按键中断实验

2018-10-10 来源:eefocus

继做了基于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外部按键中断实验


推荐阅读

史海拾趣

固驰(GUERTE)公司的发展小趣事

随着产品质量的不断提升和技术的持续创新,固驰电子开始积极拓展国内外市场。公司产品不仅畅销国内市场,为美的、格力、艾美特等知名企业配套,还大量出口至韩国、俄罗斯、美国、加拿大、德国等国家和地区。这一过程中,固驰电子凭借其优良的品质、满意的价格和完善的服务赢得了国内外客户的一致好评,品牌影响力显著提升。

AMD(超微)公司的发展小趣事

随着产品质量的不断提升和技术的持续创新,固驰电子开始积极拓展国内外市场。公司产品不仅畅销国内市场,为美的、格力、艾美特等知名企业配套,还大量出口至韩国、俄罗斯、美国、加拿大、德国等国家和地区。这一过程中,固驰电子凭借其优良的品质、满意的价格和完善的服务赢得了国内外客户的一致好评,品牌影响力显著提升。

Emmoco公司的发展小趣事

在稳固了电子元器件和模块市场地位后,Emmoco开始寻求多元化发展。公司利用自身的技术优势和市场经验,逐步拓展产品线,涉足智能家居、物联网等领域。通过不断的技术创新和市场拓展,Emmoco成功实现了产品线的多元化,为客户提供更加全面和多样化的解决方案。

Ford Aerospace & Communications Corp公司的发展小趣事

在20世纪20年代,亨利·福特不仅专注于汽车制造业,还展现了对航空技术的浓厚兴趣。他资助了威廉·布什纳尔·斯道特(Willam Bushnell Stout)的飞机研发项目,这标志着福特向航空领域的初步探索。斯道特设计的福特三发飞机(后被称为“铁皮鹅”)虽未直接成为商业成功的典范,但它为福特汽车公司积累了宝贵的航空技术经验,也为后续可能的航空通信项目奠定了基础。

圣邦微电子(Fangtek)公司的发展小趣事

在汽车制造领域,福特一直是技术创新的领导者。20世纪60年代,福特开始将电子设备集成到汽车中,包括车载电话、导航系统以及早期的娱乐系统。这些创新不仅提升了驾驶的便捷性和舒适性,也预示着未来汽车电子化、智能化的趋势。虽然这些技术并不直接属于航空通信范畴,但它们展示了福特在电子技术应用方面的前瞻性和实力。

Fortiming Corporation公司的发展小趣事

背景:2001年9月5日,Fortiming Corporation在内华达州正式成立(来源:企查查)。在成立之初,公司就明确了自己的市场定位——专注于提供高质量的石英晶振、晶体振荡器等频率控制产品。

发展:面对当时竞争激烈的电子行业,Fortiming凭借其对技术的深刻理解和对市场需求的敏锐洞察,迅速在石英晶振领域站稳脚跟。公司不仅注重产品研发,还积极引进先进生产设备,提升产品质量和生产效率。

问答坊 | AI 解惑

GPRS模块通讯问题

我用模块进行gprs连接的时候,状态总是显示 connecting,不知道是什么原因,哪位朋友能帮帮忙,指教一下啊?…

查看全部问答>

有谁做过电调啊? 最近需要驱动马达, 求高手帮忙!

有刷无刷的都行,,  最好是能把原理图和PCB板图以及程序都共享出来。。    太需要这个东东了。。    最好是用AVR单片机的。。…

查看全部问答>

电动车跷跷板控制系统

本帖最后由 paulhyde 于 2014-9-15 09:24 编辑  …

查看全部问答>

视频拍立得

视频拍立得,像经典的Polaroid相机一样,按下快门拍摄一段美好时光,就可以即刻吐出一张可以播放动态视频的“照片”,与亲朋好友一起分享。这种视频照片包含触摸显示屏、存储单元和微型电池,在摄影完成后的瞬间将数据写入电子相片的存储器。 这听 ...…

查看全部问答>

2416IROM用2G_SD卡引导的地址

用2416的IROM将2G SD卡上的Bootloader.nb0加载到stepstone,但一直加载不上,流程是按S3C2450_IROM_ApplicationNote_Rev003.pdf 上做的,觉得加载的地址总是不对,想看下有谁知道的。…

查看全部问答>

两个线程之间的切换所需要的时间

请教大家一个线程的切换问题:请高手们指点指点    在我的程序中用到好几个线程,而且在线程中频繁用到SLEEP()延时函数, 这样可能会造成线程间的频繁切换,可能会使软件的运行效率降低, 我想知道两个线程之间的切换需要多少时间 ...…

查看全部问答>

flash中数据存储可靠性问题

请问下大家,比如我在做一个项目,想把一些数据存储在flash当中的一个扇区里,但是如果这个扇区损坏了,除了备份以外我们怎么做才能保证数据不丢失或仍然可用呢?软件或硬件的方法都可以,大家帮忙讨论下,谢谢大家…

查看全部问答>

关于以太网中断处理函数

如题!为什么在stellar_interrupt()这个函数中,只有在接收到数据时才处理接收和发送队列?发送队列为什么要依托于接收数据才能对其处理…

查看全部问答>

哪位用过STM32的0x4000_0000的位空间(0x4200_0000?)

                                  …

查看全部问答>

多任务环境下STM32的FSMC总线上多个外设不能同时访问

STM32的外部总线上挂了一个MD9000A+一个SRAM。跑ucos+lwip. 不使用外部SRAM。所有的都OK,程序非常稳定. 但是只要把系统的堆空间放到外部SRAM,LWIP的TCP连接立刻就无法连接成功了。 那把堆空间放在片内,把LWIP的源文件的的变量全都分配到 ...…

查看全部问答>