x
x

【单片机到嵌入式之路】序列之3:苦逼的CPU

发布时间:2016-2-17 08:42    发布者:designapp
关键词: 嵌入式 , CPU
  软件平台
  硬件平台:单片机
  编译环境:keil
  二、苦逼的CPU
  【事故起因】:单片机是单核的,所以在做多线程问题的时候,我们要考虑的太多。但是大部分人都会让单片机一直工作,比如while死循环,然后就抱怨单片机太简单了,只能点灯,其它的事情就不行了。
  【现场分析】:1.单片机是单核的;
  2.做多线程,方法两种:a.上操作系统,b.仿操作系统;
  3.自己想释放单片机的CPU,但是格局有限,就怪单片机;
  4.要想马儿跑,必须给马儿吃草。要想单片机多工作,必须优化代码,多下功夫。
  【案例列举】:单灯闪烁
  void main(void)
  {
  LED_Init(); //LED初始化
  while(1)
  {
  LED = ON; //LED亮
  Delay_Ms(1000); //延时1s
  LED = OFF; //LED灭
  Delay_Ms(1000); //延时1s
  }
  }
  【案例分析】:单灯闪烁分析
  声明几点:1.如果你只用单片机作为单灯闪烁,那么单片机就完全可以;
  2.如果你不想玩那么高级,那么单机这样也是OK的;
  3.如果你想玩高级的,那么肯定不行。
  分析:咋一看,程序没有什么问题,但是暗藏玄机。
  1.程序被死循环卡死;
  2.死循环里面就是一个产生2s周期的频率,那么灯就是2s闪烁一次;
  3.单片机就这样被你“征服”了。但是你这是把单片机浪费了。
  这是单片机CPU的苦啊,他是没有口啊,有口要骂人的哦!O(∩_∩)O哈哈~
  三、单片机CPU的苦衷——请释放CPU
  1.硬件电路分析
  


  用上面的电路来做分析,当P1口为低电平的时候,LED灯才亮,高电平则灭。
  1.软件分析
  由硬件可以知道,我们可以通过宏定义来对接口进行简单的定义
  #define LED_Light P1 //LED灯端口
  #define LED_ON() LED_Light = 0x00 //LED灯亮
  #define LED_OFF() LED_Light = 0xFF //LED灯灭
  现在端口也定义好了,下面单片机要哭诉了。
  3.你误解了单片机
  单片机其实可以干很多活,结果你误解了。
  为了让单片机不白忙活我们可以通过两种方式来实现LED灯闪烁:a.定时器中断,b.计时+标志位。
  A.定时器中断
  定时器中断大家都知道,这里就不说了,就是产生xms的中断就可以了。
  B.计时+标志位
  计时+标志位太有用了,这一下帮单片机洗清沉冤了。我们只要产生一个对200ms的时间,然后对该时间进行计数到了5次,然后就清0该计数值,同时反转LED灯的状态即可。
  代码部分:
  unsigned int LedTimeCount = 0 ; //LED计数器
  unsigned char LedStatus = 0 ; //LED状态标志, 0表示亮,1表示熄灭
  /***************************************
  * 函数描述:LED灯线程处理函数
  * 输入参数:No
  * 返 回 值:No
  * 说 明:通过标志位来实现LED的反转
  * 修改记录:
  ****************************************/
  void LEDThread_Process(void)
  {
  if(0 == LedStatus) //如果LED的状态为0,则点亮LED
  {
  LED_ON() ; //点亮LED灯
  }
  else //否则熄灭LED
  {
  LED_OFF() ;
  }
  }
  /***************************************
  * 函数描述:计时和标志位函数
  * 输入参数:No
  * 返 回 值:No
  * 说 明:状态标志位改变
  * 修改记录:
  ****************************************/
  void LEDStatus_Change(void)
  {
  if(Sys_200MS) //系统200ms时标到
  {
  Sys_200MS = 0 ;
  LedTimeCount ++ ; //LED计数器加1
  if(LedTimeCount >= 5) //计数达到5,即1s到了,改变LED的状态。
  {
  LedTimeCount = 0 ;
  LedStatus = ! LedStatus;
  }
  }
  }
  /***************************************
  * 函数描述:主函数
  * 输入参数:No
  * 返 回 值:No
  * 说 明:
  * 修改记录:
  ****************************************/
  void main(void)
  {
  while(1)
  {
  LEDThread_Process() ;
  LEDStatus_Change() ;
  }
  }
  通过上面的程序就可以释放单片机的CPU。因为LED灯亮灭是有标志位(LedStatus)来决定,而标志位由计数器(LedTimeCount)来决定,两个函数都没有绑架单片机的CPU,所以单片机的CPU是自由的。终于洗冤了。O(∩_∩)O哈哈~
  到此结束!!! 谢谢阅读,欢迎拍砖!!!!
                               
               
本文地址:https://www.eechina.com/thread-160803-1-1.html     【打印本页】

本站部分文章为转载或网友发布,目的在于传递和分享信息,并不代表本网赞同其观点和对其真实性负责;文章版权归原作者及原出处所有,如涉及作品内容、版权和其它问题,我们将根据著作权人的要求,第一时间更正或删除。
您需要登录后才可以发表评论 登录 | 立即注册

厂商推荐

  • Microchip视频专区
  • KSZ989x系列交换机应用设计要点培训教程
  • 初学者在电源电路设计中常犯的错误(以及如何避免)
  • AOE | 时钟与时序(5/7):什么是稳定性?
  • AOE | 时钟与时序(3/7):什么是时钟相位?
  • 贸泽电子(Mouser)专区

相关视频

关于我们  -  服务条款  -  使用指南  -  站点地图  -  友情链接  -  联系我们
电子工程网 © 版权所有   京ICP备16069177号 | 京公网安备11010502021702
快速回复 返回顶部 返回列表