#include<stc89.h> 
#include<intrins.h>

#define uchar unsigned char
#define uint unsigned int
    
void sendchar(char ch) ; //发送数据
void Timer0Init(void); //中断

sbit LED1=P4^1;
sbit LED2=P2^7;
sbit KEY1=P0^4;
sbit KEY2=P0^5;
sbit KEY3=P0^6;
sbit KEY4=P0^7;
sbit KEY5=P0^2;
sbit KEY6=P0^3;
sbit DSA=P1^6;
sbit DSB=P1^7;//模拟串口数据发送端   
sbit CLK=P1^3;//模拟时钟控制端   
sbit WX1=P2^0;
sbit WX2=P2^1;
sbit WX3=P2^2;
sbit WX4=P2^3;
sbit JDQ=P2^5;

bit key_change_flg = 0; //按键按下的标志 0表示没有按下,1表示有按键按下
bit time_over_flg = 0;   //时间溢出标志位,0为初始,1表示溢出,执行中断。
bit cnt_change_flg = 1;    //继电器动作标志,0代表断开, 1代表吸合
bit one_sec_OK_Flg = 0; //一秒中断标志,1秒的中断结束。
//bit start_JDQCnt = 1;//1表示吸合,0表示断开
bit start_EN = 0;        //为1 开始按照设置时间进行吸合 和 断开  0:不进行吸合和断开
bit stop_yunxing = 1;//

unsigned char one_sec_cnt = 0;//计数变量,从0加到200,完成1秒钟的时间。
unsigned char keyNum = 0;//当前按下的按键代号 ,0表示没有,按键号从key1-6 
uint startTimeSec = 0;    //要启动的时间标准
//uint startTimeCnt = 0;    //启动计数
uint stopTimeSec = 0;    //要停止的时间标准
//uint stopTimeCnt = 0;    //停止计数
uint showNum = 0;        //要显示的数字

char code tab[]={0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f,0x01,0x09,0xff};//0-9全灭 //

void sendchar(char ch) //把代码发送到移位寄存器
{
    uchar i;
    DSA=1;
    for(i=0;i<8;i++)//8位数据传输完毕后才给数码管显示
    {
        DSB=ch&0x01; //P1^7=0000000x,DAT一直保持该状态,等时钟脉冲触发传递数值
        CLK=0;
        CLK=1; //这两句制造一个上升沿 CLK=1;
        ch>>=1;//DAT=ch&0x01和ch》》=1的功能是一次取出八位二进制ch的每一位赋值给74hc164
    }
    DSA = 0;
    //Delay20us();
}

void Delay20us()        //@12.000MHz
{
    unsigned char i;

_nop_();
    i = 7;
    while (--i);
}

void Delay3ms()        //@12.000MHz
{
    unsigned char i, j;

i = 6;
    j = 211;
    do
    {
        while (--j);
    } while (--i);
}

void display(uint number)//数码管显示函数
{
    uint qian,bai,shi,ge;
    
    number = number%10000;//这句话的意思?number的数值范围65535,五位数取余,将number限定在个位
    qian=number/1000;
    sendchar(tab[qian]);
    WX4 = 0;
    Delay3ms();
    WX4 = 1;
    
    bai=number%1000/100;
    sendchar(tab[bai]);
    WX3 = 0;
    Delay3ms();
    WX3 = 1;
    shi=number%100/10;
    sendchar(tab[shi]);
    WX2 = 0;
    Delay3ms();
    WX2 = 1;
    
    ge=number%10;
    sendchar(tab[ge]);
    WX1 = 0;
    Delay3ms();
    WX1 = 1;
}
//扫描一次按键
void readKey(void)
{
    if(0==KEY1)
    {
        Delay20us();//延时20us
        if(0==KEY1)//再次判断是0
        {
            while(0==KEY1);//等待按键抬起来
        }
        key_change_flg = 1;//按键按下的标志
        keyNum = 1; //当前按键按下的代号,这里为什么要加个这个代号?
    }
    else if(0==KEY2)
    {
        Delay20us();//延时20us
        if(0==KEY2)//再次判断是0
        {
            while(0==KEY2);//等待按键抬起来
        }
        key_change_flg = 1;
        keyNum = 2;
    }
    else if(0==KEY3)
    {
        Delay20us();//延时50us
        if(0==KEY3)//再次判断是0
        {
            while(0==KEY3);//等待按键抬起来
        }
        key_change_flg = 1;
        keyNum = 3;
    }
    else if(0==KEY4)
    {
        Delay20us();//延时20us
        if(0==KEY4)//再次判断是0
        {
            while(0==KEY4);//等待按键抬起来
        }
        key_change_flg = 1;
        keyNum = 4;
    }
    else if(0==KEY5)
    {
        Delay20us();//延时20us
        if(0==KEY5)//再次判断是0
        {
            while(0==KEY5);//等待按键抬起来
        }
        key_change_flg = 1;
        keyNum = 5;
    }
    else if(0==KEY6)
    {
        Delay20us();//延时20us
        if(0==KEY6)//再次判断是0
        {
            while(0==KEY6);//等待按键抬起来
        }
        key_change_flg = 1;
        keyNum = 6;
    }
}

//按键按下后的处理
void keyCmd(void) //按键执行的任务函数
{
    switch(keyNum)
    {
    case 0://没有按键按下
        break;
    case 1://1号按键按下,启动时间+
        startTimeSec++;
        if(startTimeSec>120)
        {
            startTimeSec = 0;      //这里让时间从0开始累加
        }
        showNum = startTimeSec;  //显示时间为当前的值
        break;
        
    case 2:                    //启动时间-
         if(startTimeSec>0)
        {
            startTimeSec--;
        }
        showNum = startTimeSec;
        break;
    case 3:    
        if(stopTimeSec>0)  //停止时间-
        {
            stopTimeSec--;
        }
        showNum = stopTimeSec;
        break;
    case 4:         //停止时间+
        
        stopTimeSec++;
        if(stopTimeSec>120)
        {
            stopTimeSec = 0; 
        }
        showNum = stopTimeSec;
        break;
    case 5:                    //my 启动继电器吸合动作按键
        start_EN = 1;        
        showNum = startTimeSec;
        JDQ = 1;//缺继电器吸合
        LED1 = 0;
        LED2 = 1;
        one_sec_cnt = 0;
        one_sec_OK_Flg = 0;
        break;
    case 6:                  //my 关闭继电器动作
        start_EN = 0;
        JDQ=0;    
        LED1 = 1;
        LED2 = 0;
        break;
    default:
        break;
    }
    
    //display(startTimeSec);
}

/* Timer2 interrupt routine */
void tm2_isr() interrupt 5
{
    TF2 = 0;
    
    time_over_flg = 1;//时间溢出标志
    
    one_sec_cnt++;    //1秒定时变量
    if(one_sec_cnt>=200)
    {
        one_sec_cnt = 0;
        one_sec_OK_Flg = 1;//立1秒到的标志
    }
    
}

void Timer2Init(void)        //5毫秒@12.000MHz
{
    T2MOD = 0;        //初始化模式寄存器
    T2CON = 0;        //初始化控制寄存器
    TL2 = 0x78;        //设置定时初始值
    TH2 = 0xEC;        //设置定时初始值
    RCAP2L = 0x78;        //设置定时重载值
    RCAP2H = 0xEC;        //设置定时重载值
    TR2 = 1;        //定时器2开始计时
    ET2 = 1;                        //enable timer2 interrupt
    EA = 1;                         //open global interrupt switch
}

void main()
{    
        
    Timer2Init();
    JDQ = 0;
    LED1 = 1;
    LED2 = 0;
    WX1=1;
    WX2=1;
    WX3=1;
    WX4=1;
    
    showNum = 0000;
    
    while(1)
    {
        /***********数码管扫描**************/
        if(1==time_over_flg)
        {
            time_over_flg = 0;
            display(showNum);
        }

readKey();                    //读取按键

if(1==key_change_flg)        //按键处理
        {
            key_change_flg = 0;
            keyCmd();
        }
        if(1==start_EN)//if(1==start_JDQCnt)                        //继电器吸合 关闭控制
        {
            if(one_sec_OK_Flg)
            {
                one_sec_OK_Flg = 0;
                if(1==cnt_change_flg)//吸合区间  //计数--
                {
                    if(showNum>0)
                    {
                        showNum--;
                    }
                    else
                    {
                        showNum = stopTimeSec;
                        cnt_change_flg = 0;
                        LED1 = 1;
                        JDQ = 0;//缺继电器断开
                    }
                }
                else        //断开区间
                {
                    if(showNum>0)
                    {
                        showNum--;
                    }
                    else
                    {
                        showNum = startTimeSec;
                        cnt_change_flg = 1;
                        LED1 = 0;
                        JDQ = 1;//缺继电器吸合
                    }
                }
            }
        }
}
}

74HCD164实现四位共阳数码管的动态扫描与六个按键实现继电器的通断程序相关推荐

  1. 利用四位共阳数码管显示小数

    目录 前言 实现过程 思路 具体方法 其他代码 效果 利用数码管显示舵机的实际转速 总结 前言 前段时间利用TMS320F2335实现了对四位共阳数码管的控制(链接在这),不过当时只实现了利用数码管显 ...

  2. 使用TMS320F28335控制四位共阳数码管

    目录 1 要实现的功能 2 数码管的原理 2.1 数码管发光显示原理 2.2 数码管控制原理 3 功能实现过程 3.1 GPIO配置 3.2 数字显示 3.3 显示控制 3.4 其他代码 4 调试修改 ...

  3. 四位共阳极数码管显示函数_新手求助四位共阳数码管显示函数

    #include #include "DS1302.H" sbit K_S = P1^0;    //显示模式sbit K_M = P1^1;    //修改sbit K_I = ...

  4. STM32共阳数码管编程分享

    开篇简介 相信玩过单片机的人都不会对数码管感到陌生!这次的分享也是近期在做的一个小项目里面用到的实例,代码均是自编.自测,保质保量?相信对各位初学者能起到快速上手的作用.(主控基于STM32F103Z ...

  5. c语言一位共阳数码管编程,求一个共阳四位数码管滚动显示1234的程序

    /******************************************************************************* * 文件名: 数码管 * 描  述: ...

  6. 四位共阳极数码管显示函数_【项目8-任务10-小组13】利用四位数码管实现动态扫描显示...

    学习任务 1.四位数码管的电路结构与显示原理 (什么是位选.什么是段选.共阴与共阳的区别.显示4位数字,需要多少条口线?显示n位数字呢?) 2.Arduino直接连接四位数码管实现四位阿拉伯数字显示 ...

  7. 共阳数码管段码表_C51编程7数码管显示原理

    如果将单片机的比喻计算的主机,而按键相当于电脑的输入设备(键盘或者鼠标),那么LED灯可以作为输出设备的显示器:如果8位数据,使用8个LED显示数据表示,相当于是以二进制显示数据,非常不利于阅读. 为 ...

  8. 【小白米日志】树莓派3b+四位共阴数码管的连接和驱动

    [小白米日志]树莓派3b+四位共阴数码管的连接和驱动 所需材料 数码管的简介 GPIO连接 代码 演示 所需材料 笔记本电脑:通过ssh控制树莓派. 树莓派3b+:装好系统,打开ssh. 四位共阴 数 ...

  9. 四位共阳极数码管显示函数_数码管模块.doc

    数码管模块 数码管 1.概 述 数码管模块采用四位共阳极数码管,用于显示数字和少数特殊字符.可以在机器人项目中使用该模块,用于显示速度.时间.分数.温度.距离等传感器的值.同时,Makeblock提供 ...

最新文章

  1. Java并发编程的基础-线程的终止
  2. 面向对象:包装类、对象处理、类成员
  3. python删除指定行_关于csv:删除python中的特定行和对应文件
  4. pygame render怎么显示中文_Pygame游戏——贪吃蛇(完结)
  5. 函数参数传递、数组指针、二级指针、左值、引用
  6. gitlab的用户使用手册
  7. c语言编程顺序查找例题,C语言典型编程例题.doc
  8. C++ 连接数据库的入口和获取列数、数据
  9. 虚拟化--vsphere排错组件归纳
  10. hive如何确定map数量和reduce数量?
  11. 树上10只鸟,开枪打死1只,还剩几只?
  12. 查看java/jdk版本
  13. 飞思卡尔单片机编程与c语言,飞思卡尔单片机C语言编程(中文).pdf
  14. Matlab fftshift and ifftshift and some confusions
  15. laravel文档工具
  16. FastReport VCL 2022.3
  17. 欧美html游戏安卓,HTML5 Games - Rated M or for 18+ only
  18. “TikTok+独立站”模式熟了?看Anker如何玩转社交私域流量导流独立站?
  19. 异步通信之IOCP详解
  20. 技术人员如何看待新技术?

热门文章

  1. 【ExcelPlanet】电商母婴用品购买情况分析
  2. 本地计算机无法启动wireless,Windows无法启动Wireless PAN DHCP Server服务的解决方法
  3. qq udp tcp机制
  4. 水面波纹.shader
  5. 邮件标题中有 垃圾邮件 字样
  6. 1123549878
  7. 震撼众人,全网疯传的华为内部网络协议神仙笔记究竟有何魅力?
  8. 我用 Python 写了个基金涨跌通知助手!投了五百翻了四倍
  9. 苹果MacBook选购指南,Macbook Air和Pro如何选?
  10. 写给自己的第一篇博文