Chinaunix首页 | 论坛 | 博客
  • 博客访问: 166026
  • 博文数量: 73
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 235
  • 用 户 组: 普通用户
  • 注册时间: 2014-06-27 09:43
个人简介

为兴趣挑灯夜战

文章分类
文章存档

2018年(4)

2017年(7)

2016年(9)

2015年(4)

2014年(49)

分类: 嵌入式

2016-11-25 22:15:49

        经常会有这样的产品,它的运行受控于上位机,以下称其为设备。设备通过串口或是USB与上位机相连,通信指令格式为:
head
addr
length
cmd
data
check
0x02
0x00
n+1Byte
1Byte
nByte
1Byte
假设head固定为0x02,addr为0x00, length=cmd长度+data的长度。设备上有两个LED灯,一个是LED_RED,另一个是LED_GREEN,现在有这样的要求,用三个参数来实现对两个LED的控制,分别是:
data[0]:Select LED//选择LED
0x01 - Red LED.//data[0]为0x01时,代表指令是控制红色LED
0x02 - Green LED。//data[0]为0x02时,代表指令是控制绿色LED
0x03 - Both Red & Green LED//data[0]为0x03时,代表指令是控制绿色LED和红色LED
data[1]: Units of on time.Each unit is 100ms.//data[1]代表开启的时间
data[2]:Number of cycles to turn on/off the LED.The cycle time si one second.0xff will toggle the LED continually//data[2]代表开启LED的次数,开启周期是1秒,如果为0xff,则代表让选定的LED一直亮灭亮灭的闪烁。
下面来讲一下实现方法:
定义一个结构体
typedef struct
{
    u8 Count; //如果Count等于0xff,表示要一直闪烁
    u8 TimeON;//单位是100ms
    u8 TimeOFF;//单位是100ms
}LED_STATUS;

为两个LED各定义一个结构变量用来标记每个LED的运行状态。
LED_STATUS LedRed;
LED_STATUS LedGreen;


开一个10ms的定时器,在定时器里放入对这个两个结构状态判断的函数,通过LED的状态来对其进行控制。下面直接看代码,这样更直观:
此程序适用于所有单片机,只需要更改一下开关LED的那几个语句。

点击(此处)折叠或打开

  1. #ifndef __LED_H
  2. #define __LED_H

  3. //#include "MPC89x5x.H"
  4. #include <reg52.H>
  5. #include "TypeRedefine.h"

  6. #define LED_RED 0x01 //工作LEN,LED 1
  7. #define LED_GREEN 0x02 //电源LED, LED 2

  8. sbit LED_RED_CTR = P1^6;
  9. sbit LED_GREEN_CTR = P1^5;

  10. #define LED_ALL (LED_RED|LED_GREEN)
  11. #define CONTINUE 0xFF //continue


  12. typedef struct
  13. {
  14.     u8 Count; //如果Count等于0xff,表示要一直闪烁
  15.     u8 TimeON;//单位是100ms
  16.     u8 TimeOFF;//单位是100ms
  17. }LED_STATUS;

  18. extern LED_STATUS LedRed;
  19. extern LED_STATUS LedGreen;

  20. typedef struct
  21. {
  22.     u8 select;
  23.     u8 time;
  24.     u8 count;
  25. } LEDCMD;

  26. void LED_int(void);
  27. void LED_ON(u8 led);
  28. void LED_OFF(u8 led);

  29. extern u16 IdleCount;
  30. extern u8 LED_Control(u8 *LED_Cmd,u8 CmdType);//接收指令的函数
  31. extern void LEDControl(void);//放在10ms定时中断中队LED进行的函数

  32. #endif

点击(此处)折叠或打开

  1. #include "LED.h"
  2. #include "cmd.h"

  3. LED_STATUS LedRed;
  4. LED_STATUS LedGreen;

  5. void LED_int(void)
  6. {
  7.     LED_RED_CTR=1;
  8.     LED_GREEN_CTR=1;
  9. }

  10. void LED_ON(u8 led)
  11. {
  12.     switch(led)
  13.     {
  14.         case LED_RED:
  15.             LED_RED_CTR=0;
  16.             break;
  17.         case LED_GREEN:
  18.             LED_GREEN_CTR=0;
  19.             break;
  20.         case LED_ALL:
  21.             LED_RED_CTR=0;
  22.          LED_GREEN_CTR=0;

  23.             break;        
  24.         default: break;
  25.     }
  26. }

  27. void LED_OFF(u8 led)
  28. {
  29.     switch(led)
  30.     {
  31.         case LED_RED:
  32.             LED_RED_CTR=1;
  33.             break;
  34.         case LED_GREEN:
  35.             LED_GREEN_CTR=1;
  36.             break;
  37.         case LED_ALL:
  38.             LED_RED_CTR=1;
  39.          LED_GREEN_CTR=1;

  40.             break;        
  41.         default: break;
  42.     }
  43. }

  44. void LEDControl(void)
  45. {
  46.     static u16 R_Times=0,G_Times=0;
  47.     
  48.     if(LedRed.Count==CONTINUE)
  49.     {
  50.         R_Times++;
  51.         if(R_Times<(LedRed.TimeON*10)){
  52.             LED_ON(LED_RED);
  53.         }else if(R_Times>(LedRed.TimeON*10) && R_Times<100){//tick的单位是10ms,100相当于1s        
  54.             LED_OFF(LED_RED);
  55.         }else if(R_Times>100){    
  56.             R_Times=0;        
  57.         }
  58.     }else if(LedRed.Count>0)
  59.     {
  60.         R_Times++;
  61.         if(R_Times<(LedRed.TimeON*10)){
  62.             LED_ON(LED_RED);
  63.         }else if(R_Times>(LedRed.TimeON*10) && R_Times<100){//tick的单位是10ms,100相当于1s        
  64.             LED_OFF(LED_RED);
  65.         }else if(R_Times>100){    
  66.             R_Times=0;    
  67.             LedRed.Count--;            
  68.         }
  69.     }else if(LedRed.Count==0)
  70.     {
  71.         LED_OFF(LED_RED);
  72.     }    
  73.      
  74.     if(LedGreen.Count==CONTINUE)
  75.     {
  76.         G_Times++;
  77.         if(G_Times<(LedGreen.TimeON*10)){
  78.             LED_ON(LED_GREEN);
  79.         }else if(G_Times>(LedGreen.TimeON*10) && G_Times<100){//tick的单位是10ms,100相当于1s        
  80.             LED_OFF(LED_GREEN);
  81.         }else if(G_Times>100){    
  82.             G_Times=0;        
  83.         }
  84.     }else if(LedGreen.Count>0)
  85.     {
  86.         G_Times++;
  87.         if(G_Times<(LedGreen.TimeON*10)){
  88.             LED_ON(LED_GREEN);
  89.         }else if(G_Times>(LedGreen.TimeON*10) && G_Times<100){//tick的单位是10ms,100相当于1s        
  90.             LED_OFF(LED_GREEN);
  91.         }else if(G_Times>100){    
  92.             G_Times=0;
  93.             LedGreen.Count--;
  94.         }
  95.     }else if(LedGreen.Count==0)
  96.     {
  97.         LED_OFF(LED_GREEN);
  98.     }                 
  99. }

  100. /////////////////////////////////////////////////////////////////////////////////////////////////////
  101. //函数名:LED_Control
  102. //功能能:控制LED亮灭
  103. /////////////////////////////////////////////////////////////////////////////////////////////////////
  104. u8 LED_Control(u8 *LED_Cmd,u8 CmdType)
  105. {    
  106.     LEDCMD *pLED_Cmd=(LEDCMD*)LED_Cmd;
  107.     
  108.     if(!pLED_Cmd)
  109.         return MI_CommandErr;//parameter error
  110.     
  111.     if(CmdType==4)//新指令格式
  112.     {
  113.         if(pLED_Cmd->select==0 || pLED_Cmd->select>3 || pLED_Cmd->time==0 || pLED_Cmd->time>10)
  114.             return MI_CommandErr;//parameter error
  115.         if(pLED_Cmd->select==1)
  116.         {
  117.             LedRed.Count=pLED_Cmd->count;
  118.             LedRed.TimeON=pLED_Cmd->time;
  119.         }else if(pLED_Cmd->select==2)
  120.         {
  121.             LedGreen.Count=pLED_Cmd->count;
  122.             LedGreen.TimeON=pLED_Cmd->time;
  123.         }else if(pLED_Cmd->select==3)
  124.         {
  125.             LedRed.Count=pLED_Cmd->count;
  126.             LedRed.TimeON=pLED_Cmd->time;
  127.             
  128.             LedGreen.Count=pLED_Cmd->count;
  129.             LedGreen.TimeON=pLED_Cmd->time;
  130.         }
  131.     }   
  132.        
  133.     return MI_OK ;    
  134. }

点击(此处)折叠或打开

  1. //22.1184MHz delay 10ms
  2. void init_trmer0()
  3. {
  4.     /////////10ms     
  5.     AUXR &= 0x7F;        //定时器时钟12T模式
  6.     TMOD &= 0xF0;        //设置定时器模式
  7.     TMOD |= 0x01;        //设置定时器模式
  8.     TL0 = 0x00;        //设置定时初值
  9.     TH0 = 0xB8;        //设置定时初值
  10.     TF0 = 0;        //清除TF0标志
  11.     TR0 = 1;        //定时器0开始计时
  12.     ET0 = 1;            // enable Timer0 interrupt
  13.     EA  = 1;
  14.     
  15. }

  16. //// 10ms
  17. void Timer0(void) interrupt 1 //using 1
  18. {     
  19.     TF0 = 0;           //清除TF0标志
  20.     TL0 = 0x00;        //设置定时初值
  21.     TH0 = 0xB8;        //设置定时初值
  22.     
  23.     LEDControl();
  24. }



阅读(850) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~