270597983 发表于 2015-6-6 15:10:03

用定时器中断代替for()循环和Delay()

以下代码怎么通过定时器中断代替fot()和Delay()???

#include <stc12c5a.h>
#include <intrins.h>


#defineNOP() _nop_(); _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_() /* 定义空指令 */


/*74HC595引脚控制*/
sbit MOSIO =P0^1;//串行数据线   //14脚
sbit R_CLK =P0^2;//数据并行输出控制//12脚
sbit S_CLK =P0^3;//串行时钟线//11脚

/*数码管位选控制*/
sbit ADDR0 = P1^3;   //第0位数码管
sbit ADDR1 = P1^2;   //第1位数码管
sbit ADDR2 = P1^1;   //第2位数码管

/*LED指示灯与IO口连接*/
sbit LED_R = P1^4;   //D1--红灯,压力偏压指示灯
sbit LED_G = P1^5;   //D2--绿灯,调超报警值设置
sbit LED_B = P1^6;   //D3--蓝灯,配合D1,D2指示压力超限

/*按键控制*/
sbit KEY_UP   = P4^1;             //独立键盘扫描 “+” 输入引脚
sbit KEY_DOWN = P4^5;             //独立键盘扫描 “-” 输入引脚
sbit KEY_OK   = P4^4;             //独立键盘扫描 “确认”输入引脚
sbit KEY_FUNCTION   = P4^6;       //独立键盘扫描 “设置”输入引脚

bit KeySta = 1;   //按键当前状态

unsigned char code LedChar[] = { //数码管字形码
                              ~0xC0, ~0xF9, ~0xA4, ~0xB0, ~0x99,
                              ~0x92, ~0x82, ~0xF8, ~0x80, ~0x90,
                                 0x77,0x7c,0x39,0x5e,0x79,0x71,0x3e
};

unsigned char LedBuff = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};   //数码管显示缓冲区,开始都不点亮

//全局变量

unsigned char i = 0; //动态扫描索引

void HC595SendData(unsigned char SendVal);

void SMG_Display();

void Delay2ms();
void Version();
void Sensor_Addres();
void Sensor_Type();
void Pressure_Eviation();
void Pressure_Overruns();
void Test();


void main()
{
    bit backup = 1;//按键值备份,保存前一次的扫描值
   
    EA = 1;    //使能总中断
    TMOD =0x01;
    TH0 = 0xf8;
    TL0 = 0xcd;
    ET0 = 1;   //使能T0中断
    TR0 = 1;   //启动T0

    Version();      
    Sensor_Addres();
    Sensor_Type();

    while(1)
    {   
      Test();
      if (KeySta != backup)
      {
            if (backup == 0)
            {
                Test();
                Sensor_Addres();
                Sensor_Type();
                Pressure_Overruns();
                Pressure_Eviation();
            }
            backup = KeySta;      
      }
      
    }
}

/***********************************************
函数名称:Version
功能:显示版本号V1.0
************************************************/
void Version()
{
    LED_R = 1;
    LED_G = 1;
    LedBuff = LedChar;               
    LedBuff = LedChar|0x80;
    LedBuff = LedChar;         
    for(i=0;i<167;i++)SMG_Display();
}

/***********************************************
函数名称:Sensor_Addres
功能:显示传感器地址号 00-30
备注:可以更改AT24C02保存
************************************************/
void Sensor_Addres()
{
    LED_R = 1;
    LED_G = 1;
    LedBuff = LedChar;   
    LedBuff = LedChar;   
    LedBuff = LedChar;      
    for(i=0;i<167;i++)SMG_Display();
}


/***********************************************
函数名称:Sensor_Type
功能:显示传感器类型号 01--04
备注:可以更改AT24C02保存
************************************************/
void Sensor_Type()
{
    LED_R = 1;
    LED_G = 1;
    LedBuff = LedChar;   
    LedBuff = LedChar;   
    LedBuff = LedChar;   
    for(i=0;i<167;i++)SMG_Display();
}
/***********************************************
函数名称:Pressure_Eviation
功能:   调整压力偏差范围00.0-60.0
备注:可以更改AT24C02保存
************************************************/
void Pressure_Eviation()
{
    LED_R = 0;
    LED_G = 1;
    LedBuff = LedChar;   
    LedBuff = LedChar|0x80;   
    LedBuff = LedChar;      
    for(i=0;i<167;i++)SMG_Display();
}
/***********************************************
函数名称:Pressure_Overruns
功能:   调整压力偏差范围00.0-60.0
备注:可以更改AT24C02保存
************************************************/
void Pressure_Overruns()
{
    LED_G = 0;
    LED_R = 1;
    LedBuff = LedChar;   
    LedBuff = LedChar|0x80;   
    LedBuff = LedChar;      
    for(i=0;i<167;i++)SMG_Display();
}

/***********************************************
函数名称:Test()
功能:   测试用
备注:
************************************************/
void Test()
{
    LED_G = 1;
    LED_R = 1;
    LedBuff = LedChar;   
    LedBuff = LedChar;   
    LedBuff = LedChar;      
    for(i=0;i<167;i++)SMG_Display();
}

/***********************************************
函数名称:SMG_Display
功能:显示功能
************************************************/
void SMG_Display()
{   
    ADDR2 = 0; ADDR1 = 1; ADDR0 = 1;HC595SendData(LedBuff);Delay2ms();HC595SendData(0);
    ADDR2 = 1; ADDR1 = 0; ADDR0 = 1;HC595SendData(LedBuff);Delay2ms();HC595SendData(0);
    ADDR2 = 1; ADDR1 = 1; ADDR0 = 0;HC595SendData(LedBuff);Delay2ms();HC595SendData(0);   
}


/*********************************************************************************************************
** 函数名称: HC595SendData
** 功能描述: 向SPI总线发送数据
*********************************************************************************************************/
void HC595SendData(unsigned char SendVal)
{
    unsigned char i;
               
    for(i=0;i<8;i++)
    {
      if((SendVal<<i)&0x80) MOSIO=1; //set dataline high0X80最高位与SendVal左移的最高位 进行逻辑运算
      else MOSIO=0;                                   // 如果为真 MOSIO = 1

      S_CLK=0;
      NOP();       //短暂延时产生一定宽度的脉冲信号
      NOP();       //短暂延时
      S_CLK=1;
    }
    R_CLK=0; //set dataline low
    NOP();//短暂延时
    NOP();//短暂延时
    R_CLK=1;         //
}

void Delay2ms()                //@11.0592MHz
{
        unsigned char i, j;

        _nop_();
        _nop_();
        i = 22;
        j = 128;
        do
        {
                while (--j);
        } while (--i);
}

/*T0中断服务函数,用于按键状态的扫描并消抖*/
void InterruptTimer0() interrupt 1
{
    static unsigned char keybuf =0xff;
   
    TH0 = 0xf8;
    TL0 = 0xcd;
    keybuf = (keybuf<<1)|KEY_OK;
    if(keybuf == 0x00)
    {
      KeySta = 0;
    }
    else if(keybuf == 0xff)
    {
      KeySta = 1;
    }
    else
    {}
}

grj0719 发表于 2015-6-6 16:40:47

任务分解。

hzyyl2008 发表于 2015-6-6 17:48:27

状态机?

a136498491 发表于 2015-6-6 19:23:18

同意3楼

augak 发表于 2015-6-6 23:22:57

建议楼主看看调度器的知识
页: [1]
查看完整版本: 用定时器中断代替for()循环和Delay()