新闻  |   论坛  |   博客  |   在线研讨会
二维数组实现指示灯闪烁
0750long | 2009-04-11 09:17:37    阅读:1662   发布文章

二维数组实现指示灯闪烁

 

/*-----------------------------------------------------
 程序功能:LED 闪烁,用 Timer0 实现:
 闪烁速度从 0.5次/秒 到 4次/秒,
 再回到 0.5次/秒,变化的间隔数为8,每个速度维持时间为3秒,
 硬件引脚:P3_4

        问题:写入程序时,指示灯只闪烁3次,即没有运行到二维数组再赋数值的内容,二维数组运用不熟练。
-------------------------------------------------------*/

#include  <STC12C5410AD.h>    /* STC12C5410AD 的头文件,为MCU中各个硬件寄存器定个名称,以便C语言中使用*/

sbit   bWork_Disp = P3^4;  // 用主控显示的名称代替硬件

#define  LIGHT  0        // 亮逻辑值
#define  DARK  1        // 暗逻辑值

#define  TRUE     1
#define  FALSE     0

#define  LIGNT_HALF_C    1000
#define  LIGHT_ONE_C     500
#define  LIGHT_ONEHALF_C   333
#define  LIGHT_TWO_C     250
#define  LIGHT_TWOHALF_C   200
#define  LIGHT_THR_C     166
#define  LIGHT_THRHALF_C   142
#define  LIGHT_FOUR_C     125

#define  P3MODE0    0x10   // 00010000,P3.4 设置为开漏输出,其余均为标准 51 口;
#define  P3MODE1    0x10   // 00010000,

/* 定时器参数定义 */

#define  T0MODE0 0x00  // 0000 0000,Timer0工作在模式0 ,13位定时;
#define  T0MODE1 0x01  // 0000 0001,Timer0工作在模式1 ,16位定时;
#define  T0MODE2 0x02  // 0000 0010,Timer0工作在模式2 ,8 位自动重加载定时;
#define  T0MODE3 0x03  // 0000 0011,Timer0工作在模式3

#define  T0_TIMER 0x00  // Timer0 工作在定时器模式
#define  T0_COUNTER 0x04 // Timer0 工作在计数器模式
#define  T0_DISGATE 0x00 // Timer0 禁止INT0引脚控制
#define  T0_ENGATE 0x08 // Timer0 允许INT0引脚控制

#define  T1MODE1 0x10  // 0000 0001,Timer0工作在模式1 ,16位定时;


#define  TIME1ms_C  0xF8D0 /* 1ms 定时的加载值字节,对应 22.1184MHz 定时器12分频 */  
#define  TIME1msH_C 0xF8  /* 1ms 定时的加载值高字节 */
#define  TIME1msL_C 0xD0  /* 1ms 定时的加载值低字节 */

/* 中断处理参数定义 */
#define  EnINT0_C  0x01
#define  EnT0_C   0x02
 


/*********** 主程序 *****************/
bit g_1ms_flag;//中断标志

void main(void)
{
 unsigned int uiDisp_time_val;  //每次显示时间值
 unsigned int uiDisp_time_val_cnt;    //显示时间值计数
 unsigned int uiDisp_freq;        //显示频率
 unsigned int uiDisp_freq_cnt;           //显示频率计数
  
 bit bCur_disp_stat;       //记忆当前所处状态
 
 unsigned char ucWork_stat_cnt; //工作状态计数器
// unsigned char ucWork_time_freq_cnt;      //工作显示状态计数,即每个状态所有对应的值
 
 unsigned int code a_Disp_ctrl[16][2]={LIGNT_HALF_C,3,
                      LIGHT_ONE_C,6,
                      LIGHT_ONEHALF_C,9,
                      LIGHT_TWO_C,12,
                      LIGHT_TWOHALF_C,15,
                                      LIGHT_THR_C,18,
                                      LIGHT_THRHALF_C,21,
                                      LIGHT_FOUR_C,24,
                                      LIGHT_FOUR_C,24,
                                      LIGHT_THRHALF_C,21,
                                      LIGHT_THR_C,18,
                                      LIGHT_TWOHALF_C,15,
                                      LIGHT_TWO_C,12,
                                      LIGHT_ONEHALF_C,9,
                                      LIGHT_ONE_C,6,
                                      LIGNT_HALF_C,3,
                                   };
 
 
 // 初始化硬件
 P3M0 = P3MODE0;    // P3 口初始化
 P3M1 = P3MODE1;

 /* 初始化定时器 */
 
 TMOD = T0MODE1;    // Timer0 工作在模式1 ,16位定时
 AUXR = AUXR&CLR_T0X12_C;  // Timer0 工作在12分频
  
    TCON=0;                   //未使用外部中断,所以不用定义中断的触发方式
  
    TH0 = 0xF8;  
  TL0 = 0xCC;
  TR0 = TRUE;
 
  //初始化中断
  IE = EnT0_C;    // 此处只允许 Timer0 中断
 

 
 //初始化
 ucWork_stat_cnt=0;
 
 bWork_Disp=LIGHT;    //点亮
 bCur_disp_stat=LIGHT;//记忆当前状态亮
  
 uiDisp_time_val=a_Disp_ctrl[ucWork_stat_cnt][0];//显示时间
 uiDisp_time_val_cnt=uiDisp_time_val;
 
 uiDisp_freq=a_Disp_ctrl[ucWork_stat_cnt][1];//显示次数 
 uiDisp_freq_cnt=uiDisp_freq;
 
 //ucWork_time_freq_cnt=a_Disp_ctrl[ucWork_stat_cnt];//显示状态控制
  
 g_1ms_flag=0;
 EA=1;
 
 while(1)
 {
  if(g_1ms_flag==1)
   {
    g_1ms_flag=0;

     if(uiDisp_time_val_cnt!=0)
      {
       uiDisp_time_val_cnt--;
       //初始化为0.5次/秒
            
       if(uiDisp_time_val_cnt==0) 
             {
             if(bCur_disp_stat==LIGHT)
               {
                  bWork_Disp=DARK;    //熄灭
            bCur_disp_stat=DARK;
            uiDisp_time_val_cnt=uiDisp_time_val;

                   uiDisp_freq--;
                 if(uiDisp_freq==0)
                 {
                  uiDisp_time_val_cnt=0;
                 
                   ucWork_stat_cnt++;
                    if(ucWork_stat_cnt>=16)
                    {
                      ucWork_stat_cnt=0;
                     }
                   uiDisp_freq=a_Disp_ctrl[ucWork_stat_cnt][1];
                   uiDisp_time_val=a_Disp_ctrl[ucWork_stat_cnt][0];
//                   ucWork_time_freq_cnt=a_Disp_ctrl[ucWork_stat_cnt];
                   }
                 
               }
               else
               { 
                  bWork_Disp=LIGHT;    //点亮
            bCur_disp_stat=LIGHT;
            uiDisp_time_val_cnt=uiDisp_time_val;

                    uiDisp_freq--;
                 if(uiDisp_freq==0)
                 {
                  uiDisp_time_val_cnt=0;
                 
                  ucWork_stat_cnt++;
                   if(ucWork_stat_cnt>=16)
                    {
                      ucWork_stat_cnt=0;
                    }
                   uiDisp_freq=a_Disp_ctrl[ucWork_stat_cnt][1];
                   uiDisp_time_val=a_Disp_ctrl[ucWork_stat_cnt][0];
//                   ucWork_time_freq_cnt=a_Disp_ctrl[ucWork_stat_cnt];
                   }                   
               }
                                              
              }
                           
            }


   }
 }
}

//一毫秒中断定时器
void  Timer0_Int(void) interrupt 1 using 1
{
 TH0=TIME1msH_C;
 TL0=TIME1msL_C;
 g_1ms_flag = TRUE;
}

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
推荐文章
最近访客