您当前的位置:五五电子网电子知识单片机-工控设备源码-程序可预置的8位计数器程序的主要部分分析 正文
可预置的8位计数器程序的主要部分分析

可预置的8位计数器程序的主要部分分析

点击数:7685 次   录入时间:03-04 11:54:00   整理:http://www.55dianzi.com   源码-程序

    #include //器件配置文件

    #define uchar unsigned char //变量类型的宏定义

    #define uint unsigned int

    uchar code SEG7[10]={0x03,0x9f,0x25,0x0d,0x99, //0~9的数码管段码

    0x49,0x41,0x1f,0x01,0x09};

    uchar data cnt[8]; //在data区定义8位长度的数组,用来存放计数值

    uchar data pre_cnt[8]; //在data区定义8位长度的数组,用来存放预置值

    sbit drv=P3^4; //定义输出驱动端

    bit set_flag; //定义工作标志

    bit out_flag; //定义输出标志

    bit keydown_flag; //键按下标志

    /****************************************************************/

    void sCAN_key(void) //扫描S1~S8键子程序开始

    {uchar i,m=0x01; //定义两个字符型局部变量,并赋值0x01给m

    P3_6=0;P3_7=1; //禁止发送给显示器,消隐有效

    for(i=0;i<8;i++) //循环8次

    {

    SBUF=255-m;while(!TI);TI=0; //依次发送数据使IC2的输出从右至左的列线为0

    if(!P3_5)pre_cnt++; //若检测到P3.5为0,说明某列线送出0时与连接

    //该列线的按键被按下,数组中对应的存放单元加1

    m<<=1; //m的取值使从右向左的下一条列线为0

    } //扫描S1~S8键子程序结束

    //----------------------------------------------------------------------------------------

   



www.55dianzi.com

    for(i=0;i<8;i++) //循环8次

    {if(pre_cnt>9)pre_cnt=0;} //对数组中的8个单元进行调整,其范围为0~9

    }

    /*************************************************************/

    void dis_cnter(void) //显示计数器值子程序开始

    {uchar i; //定义字符型局部变量i

    P3_7=1;P3_6=1; //消隐有效,允许显示

    for(i=0;i<8;i++) //循环8次

    {SBUF=SEG7[cnt];while(!TI);TI=0;} //根据8个单元的计数值查表发送显示

    P3_7=0; //关闭消隐,正常显示

    } //显示计数器值子程序结束

    /****************************************************************/

    void cnter(void) //计数转换子程序开始

    {uchar i; //定义字符型局部变量i

    for(i=0;i<7;i++) //循环8次

    {if(cnt>9){cnt=0;cnt[i+1]++;}}//若计数器某位值大于9,则该位回0,

    //而高位被进位加1

    //------------------------------------

    if(cnt[7]>9){for(i=0;i<8;i++)cnt=0;}// 若计数器最高位值大于9,则计数器全清0

    } //计数转换子程序结束

    

www.55dianzi.com

    /******************************************************************/

    void pt_cnt(void) //输出控制子程序开始

    {

    if((cnt[0]==pre_cnt[0])&&(cnt[1]==pre_cnt[1])&&

    (cnt[2]==pre_cnt[2])&&(cnt[3]==pre_cnt[3])&&

    (cnt[4]==pre_cnt[4])&&(cnt[5]==pre_cnt[5])&&

    (cnt[6]==pre_cnt[6])&&(cnt[7]==pre_cnt[7])) //若计数值等于预置值

    out_flag=1; //输出标志置1

    else out_flag=0; //否则输出标志置0

    //=================================================

    if(out_flag)drv=0; //若输出标志为1,输出端(P3.4)置0,驱动光耦U2

    else drv=1; //否则输出端(P3.4)置1

    } //输出控制子程序结束

    /**********************************************************/

    void main(void) //主程序开始

    { IE=0x84; //开放CPU中断,开放外中断1的中断

    IT1=1; //置外中断1为边沿触发

    while(1) //无限循环

    {P3_6=0;P3_7=1; //禁止发送给显示器,消隐有效

    SBUF=0x00;while(!TI);TI=0; //向IC2发送0x00,使IC2输出为全0

    if((P3&0x24)!=0x24)keydown_flag=1; //检测P3.2、P3.5是否为高电平。

    //若不为高电平,说明有键按下,键被按下标志置1

    else keydown_flag=0; //否则,键被按下标志置0

    //-------------------------------------------------------------------------------

    SBUF=0xfe;while(!TI);TI=0; //向IC2发送0xfe

    if(!P3_2)set_flag=!set_flag; //若P3.2为0,说明S9键按下,标志set_flag取反

    //==================================================

    if(!set_flag){cnter();dis_cnter();pt_cnt();delay(100);}

    //若标志set_flag为0,调用计数、显示计数、输出控制的子程序

    else {sCAN_key();dis_pre_cnter();delay(10);}

    否则标志set_flag为1,调用扫描S1~S8键、显示预置值的子程序

    //=====================================================

    if(keydown_flag)delay(300); //因有键按下,调用延时300mS子程序,

    //以免调整键值的速度过快

    }

    } //主程序结束

    /***************************************************************/

    void extern_int1(void) interrupt 2 using 1 //外中断1服务子程序

    {

    cnt[0]++; //计数器的最低位加1

    }




本文关键字:程序  计数器  源码-程序单片机-工控设备 - 源码-程序