你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32 点灯丨V2.0.0

[复制链接]
STMCU小助手 发布时间:2021-1-14 16:15
STM32 点灯丨V2.0.0
接着昨天完成的功能,今天来让咱们的程序进化,怎么用LED灯来提示故障码?
闪烁,咱们已经做了,比较简单。那么提示故障码又该如何做呢?
这个也不算难,就是在闪烁的基础上,加上了次数。
我这里,把LED的功能写成了一个函数,方便以后使用。
写程序,我一般都是直接在原来的工程上修改的。这次我是在正点原子的定时器例程上修改的,因为上面有些东西可以直接用。
我们还是用昨天的硬件,就是挂载在PB5的LED,初始化还是和昨天一样,还加了定时器的初始化。
  1. void TIM3_Int_Init(u16 arr,u16 psc)
  2. {
  3.     TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  4.   NVIC_InitTypeDef NVIC_InitStructure;

  5.   RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能
  6.   
  7.   //定时器TIM3初始化
  8.   TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值  
  9.   TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
  10.   TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
  11.   TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
  12.   TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位

  13.   TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能指定的TIM3中断,允许更新中断

  14.   //中断优先级NVIC设置
  15.   NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  //TIM3中断
  16.   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级0级
  17.   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //从优先级3级
  18.   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
  19.   NVIC_Init(&NVIC_InitStructure);  //初始化NVIC寄存器


  20.   TIM_Cmd(TIM3, ENABLE);  //使能TIMx           
  21. }

  22. void TIM3_IRQHandler(void)   //TIM3中断
  23. {
  24.   if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)  //检查TIM3更新中断发生与否
  25.     {
  26.         SysTimerFlag = 1;
  27.         TIM_ClearITPendingBit(TIM3, TIM_IT_Update);  //清除TIMx更新中断标志
  28.     }
  29. }
复制代码

我还做了一个函数来获取这个时间标志,这个标志的功能,是让我的程序跑在10ms的循环里
  1. u8 GetTimerFlag(void)
  2. {
  3.   if(SysTimerFlag)
  4.   {
  5.     SysTimerFlag = 0;
  6.     return 1;
  7.   }
  8.   return 0;
  9. }
复制代码

每获取一次,就将标志清零。
最后,就是今天的主角了,为了方便,我用了宏定义将LED的引脚定义出来
  1. #define LED PBout(5)    // PB5
复制代码

这样就比原来省事多了。
然后就是LED的功能了,我这里用结构体将LED的一些参数进行了封装,方便管理,结构体是真的好用,大家可以多用用。
  1. typedef struct
  2. {
  3.     u16 Err_num;  //故障代码
  4.     u8  Type;     //LED的类型,0:常亮,1:闪烁,2:故障提示
  5.     u8  Enable;   //使能led
  6. }LED_t;

  7. LED_t  s_LED;
复制代码

因为要让LED闪烁,这就要关心一下它闪烁的频率,我这里为了以后维护方便,也用宏将它定义出来
  1. #define  FLASH_FREQ     30        //闪烁频率,单位10ms
复制代码

最后,主要功能的实现,我也做成了函数,只要将这个函数放到一个每10ms执行一次的循环里就可以了
  1. //10ms
  2. void LED_Lib(void)
  3. {
  4.     static u32 s_Cnt;
  5.     static bool  Flash;
  6.     static u32 ErrCnt;
  7.    
  8.     s_Cnt = (s_Cnt +1)%(FLASH_FREQ * 1000);
  9.     switch(s_LED.Type)
  10.     {
  11.         case 0 :
  12.             LED = !s_LED.Enable;  //赋值给IO口
  13.             break;        
  14.         case 1:
  15.             if(s_Cnt % FLASH_FREQ == 0)  //500ms,闪烁一次
  16.             {
  17.                 Flash = !Flash;  //0灭,1:亮
  18.                
  19.                 LED = !(s_LED.Enable & Flash) ;  //赋值给IO口
  20.             }        
  21.             break;
  22.         case 2:
  23.             if(s_Cnt % FLASH_FREQ == 0)  //间隔500ms
  24.             {
  25.                 Flash = !Flash;  //翻转
  26.                 if(Flash == 1)
  27.                     ErrCnt++;
  28.                 if(ErrCnt > s_LED.Err_num)
  29.                 {
  30.                     ErrCnt++;
  31.                     Flash = 0;
  32.                     if(ErrCnt > s_LED.Err_num + 2)//灭两个周期
  33.                         ErrCnt = 0;
  34.                 }
  35.                 LED = !(s_LED.Enable & Flash) ;  //赋值给IO口            
  36.             }
  37.             break;
  38.         default:
  39.             break;            
  40.     }   
  41. }
复制代码

我这里用到了布尔定义,大家要用这个关键词时,要在文件里包含它的头文件进来
  1. #include "stdbool.h"
复制代码

然后就是主函数了,由于我这里只有这个功能,主函数比较简单
  1. int main(void)
  2. {   
  3.   delay_init();                                //延时函数初始化   
  4.   NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
  5.    LED_Init();                                  //LED端口初始化
  6.   TIM3_Int_Init(99,7199);                         //10Khz的计数频率,计数到100为10ms  
  7.      while(1)
  8.   {
  9.         if(GetTimerFlag())
  10.         {
  11.             LED_Lib();
  12.         }
  13.   }   
  14. }   
复制代码

到这里,程序就写完了,我们可以验证了。大家要主要,刷了程序,直接上电是不亮的,因为当前,s_LED的参数全都是0,所以不亮。我们需要进入Debug,然后手动给s_LED的参数赋值。
实际应用的时候,只要在需要将这个结构体放到头文件里,然后包含到需要的文件里,在需要的时候给这几个参数赋值就好,程序只要走到这段函数里,都会是用最新的参数来执行。
下面是测试,拍得不好,请见谅。
5.1.png
文章出处: Yue無缺

收藏 评论0 发布时间:2021-1-14 16:15

举报

0个回答

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版