鱼C论坛

 找回密码
 立即注册
查看: 1124|回复: 2

如何添加两个按键,一个控制启停,一个清零?

[复制链接]
发表于 2021-12-1 14:58:48 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
#ifndef __SEG_H

#define __SEG_H

void Seg_Tran(unsigned char *pucSeg_Buf,
        unsigned char *pucSeg_Code) ;

void Seg_Disp(unsigned char *pucSeg_Code,
        unsigned char ucSeg_Pos) ;

#endif
sfr P4= 0xC0;
sbit DAT = P4^0;
sbit OE = P4^1;
sbit LCK = P4^2;
sbit SCK = P4^3;
//代码转换: pucSeg_Buf- 显示字符串,pucSeg_ Code-显示字形码
void Seg_Tran(unsigned char *pucSeg_Buf,
        unsigned char *pucSeg_Code)
{
        unsigned char i, j=0, ucSeg_Code;
        for(i=0; i<4; i++, j++)
        {
                switch(pucSeg_Buf[j])

                {//低电平点亮段,段码[MS8...LSB]对应码顺序为[dp g f e d c b a]
                        case '0': ucSeg_Code =0xc0; break;                //11000000
                
                        case '1': ucSeg_Code =0xf9; break;     //11111001
                        
                        case '2': ucSeg_Code =0xa4; break;                //10100100
                        
                        case '3': ucSeg_Code = 0xb0; break;        //10110000
                        
                        case '4': ucSeg_Code = 0x99; break;                //10011001
                        
                        case '5': ucSeg_Code = 0x92; break;                //10010010

                        case '6': ucSeg_Code = 0x82; break;        //10000010
                        
                        case '7': ucSeg_Code = 0xf8; break;        //11111000
                        
                        case '8': ucSeg_Code = 0x80; break;                //10000000
                        
                        case '9': ucSeg_Code = 0x90; break;        //10010000
                        
                        case 'A': ucSeg_Code = 0x88; break;        //10001000
                        
                        case 'B': ucSeg_Code = 0x83; break;                //10000011
                        
                        case 'C': ucSeg_Code = 0xc6; break;                //11000110
                        
                        case 'D': ucSeg_Code = 0xA1; break;        //10100001
                        
                        case 'E': ucSeg_Code = 0x86; break;                //10000110
                        
                        case 'F': ucSeg_Code = 0x8E; break;        //10001110
                        
                        case 'H': ucSeg_Code = 0x89; break;        //10001001
                        
                        case 'I': ucSeg_Code =0xC7; break;                //11000111
                        
                        case '-': ucSeg_Code = 0xbf; break;                //10111111
                        
                        default: ucSeg_Code = 0xff;                                //11111111
                }
                if(pucSeg_Buf[j+i] == '.')
                {
                        ucSeg_Code &= 0x7f;
                        j++;
                }
                pucSeg_Code[i] = ucSeg_Code;
          }
        }
        //数码管显示:pucSeg_Code-显示字形码,ucSeg_Pos-显示位置
void Seg_Disp(unsigned char *pucSeg_Code,
        unsigned char ucSeg_Pos)
{
        unsigned char i;
        unsigned int temp;


        temp = (1<<(8+ucSeg_Pos)) + pucSeg_Code[ucSeg_Pos];
        LCK = 0;
        for(i=0;i<12;i++)
        {
                SCK = 0;
                if(temp & 0x800)
                        DAT = 1;
                else
                        DAT = 0;
                temp  <<= 1;
                SCK = 1;                                                                        //移位
        }
        LCK = 1;                                                                                //锁存
        OE = 0;
}                                                        
#include <reg51.h>
#include <STDIO.H>
#include "seg.h"
//sbit P04=P0^4;
//sbit P05=P0^5;

unsigned char ucSec = 0,ucMin =0;
unsigned char pucSeg_Buf[6], pucSeg_Code[4], ucSeg_Pos = 0;
unsigned int uims = 0, uiSeg_Dly = 0;

// T1初始化
void T1_Init (void)                                // 1毫秒@12.000MHz
{

        TL1=0x18;
        TH1=0xFC;                                        //设置定时初值高8位
        TR1=1;                                        // T1开始计时
        
}
// T1 处理

void T1_Proc(void)
{

        if(!TF1)                                        //定时时间未到
          return;
        TF1 = 0;                                        //清除时间到标志
        if(++uims == 1000)                        // 1s到
        {
                uims = 0;
                if(++ucSec == 60)                // 1min到
                        ucSec =0;
        }
        if((uims&3) == 0)                        //4ma显示1位
        {
                Seg_Disp(pucSeg_Code, ucSeg_Pos);
                if (++ucSeg_Pos == 4)        //循环显示
                        ucSeg_Pos = 0;
        }
        if(++uiSeg_Dly == 500)                //500ms 到
                uiSeg_Dly = 0;
        }
        //数码管处理(500ms刷新-次)
        void Seg_Proc (void)
        {
                if(uiSeg_Dly != 0)
                        return;
                uiSeg_Dly = 1;                        //500ms 到
                sprintf(pucSeg_Buf,"%02u%02u",\
                (unsigned int)ucMin,(unsigned int)ucSec);
                Seg_Tran (pucSeg_Buf, pucSeg_Code);
 }
//主函数
void main (void)
{
        T1_Init();

        while(1)
        {                                                                                   
                T1_Proc();
                Seg_Proc();
  }
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-12-1 15:19:10 | 显示全部楼层
两个不同的脚连接按键,分别进行判断按键连接的引脚电平是否有变化(低至高或高至低,看硬件连接),检测到变化后一般加15ms的防抖,然后再判断是否确实变化,确实变化后再分别对应相应的启停或清零功能
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-12-3 17:27:49 | 显示全部楼层
直接用两个外部中断,用分别由两个按钮触发,
按钮1负责“启停”,按钮“2”负责清零。
定义2个标志位:
int start_flag; //0:停止   1:开始
int zreo_flag; //0:无效   1:清零

(1)主函数首先进行初始化部分,然后while循环,
判断start_flag和zreo_flag的状态,
根据不同状态进行不同动作。
例如:
void main(void)
{
        BSP_Init();//硬件初始化
        Interrupt_Init(); //中断初始化
        //其他的什么初始化
        
        while(1)
        {
                if(start_flag == 1)
                {
                        Start(); //启动 
                        if(zreo_flag == 1)
                        {
                                Zero(); // 清零 
                        } 
                }
                else
                {
                        Close(); // 关闭 
                } 
        } 

} 

(2)按下按钮1,触发外部中断0:程序进入中断,判断start_flag的状态,为0则置1,为1则清零。
例如:
void EXTI0(void)
{
        if(start_flag == 1)
                start_flag = 0;
        else 
                start_flag = 1;

        // 清除中断状态标志位 !!!! 
}

(3)按下按钮2,触发外部中断1:程序进入中断,判断zreo_flag的状态,为0则置1,为1则清零。写法同(2)。

另外,注意控制启停的按钮的中断优先级应该高于清零的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-10 03:16

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表