⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fil12.c

📁 单片机学习系统附的实验源代码
💻 C
字号:
// 本实验采用c语言实现了数字钟实验,主要功能包括 用户设置时,分
// 考虑到键盘不多以及结构问题,本程序并没有实现一些复杂的功能。
// 采用模块化设计,用户要增加自己的功能也非常方便。
// 参见主程序的模块组织结构

#include <8051.h>
#define uchar unsigned char 
#define uint unsigned int

#define key1  P3_3    //键盘定义
#define key2  P3_4
#define key3  P3_5

#define segdata  P0   //数据 输出
#define sege  P2_7    //显示 选中
#define segb  P2_6    //位 选
#define segd  P2_5    //段 选

uchar flag; //键盘模式,=1增加,=0减少

// 这里定义了一组显示码表。前面的code 关键字表示,这组码表定义
// 在程序存储器区域,而不是采用数据存储器来定义;
// 在一般做这种固定数组时,都应该把他们放置在程序存储区。

uchar code disbuf_u[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
                       0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,
                       0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,
                       0x00,0x10,0x08,0x03,0x46,0x21,0x06,0x0e};
                               
uchar led_buf[6]; //段
uchar timead,t_s,t_m,t_h; //基准时间,秒,分,时

void reset();        //上电复位模块

void delay(uint ysz);//模糊延时

void led_buf_flush(void);//缓冲

void disp(void);//显示

void off_led(void);//关显示

void display(unsigned char disseg,unsigned char disdata);//显示输出

uchar keyb();  //键盘程序

void settimer();

void main()

{

	SP=0x50;    //设置堆栈
    reset();	
	while(1)
	{ 
		led_buf_flush();
		disp();
		off_led();
        settimer();
	}
}

 
void reset()
{
	TMOD = 0x1; //定时器T0模式1
	TL0  = 0x0cf;//定时初值
	TH0  = 0x3c;
	TR0  = 1;   //开始运行
	ET0  = 1;   //允许定时器T0中断
	EA   = 1;   //总的中断允许
	t_m  = 0;
	t_s  = 0;
	t_h  = 0;
	flag = 1;  //键盘模式
	P3_7 = 0;  //关闭蜂鸣器
	P0   = 0;  //关闭数码管显示
	P2   = 255;
}
 
//中断
void time0() interrupt 1 using 1
{
    TR0 = 0;
	TL0=0x0cf;
	TH0=0x3c;
	timead+=1;
	if(timead==20)                //12M==50ms延时,6M=100ms延时
	{
		timead=0;
		t_s += 1;                 //1s到了,把秒单元加1
		
		P1_0=~P1_0;               //同时闪烁p1.0/1两个灯
		P1_1=~P1_1;	
			
		if(t_s==60)               //一些进位的判断
		{
			t_s = 0,t_m ++;
			if(t_m ==60)
			   t_m =0,t_h ++;
		    if(t_h == 24)
			   t_h = 0;
		}
	
	}
	TR0 = 1;                 //开始计数,由于前面一些函数也需要占用时间
	                         //因此,需要在定时初值中减去这段时间的延时常数
}



//延时
void delay(uint ysz)
{
	while(ysz--){};
}
//设置时间
void settimer()
{
		switch(keyb())
		{
		   case 3:{
		             if(flag) 
		               {if(t_h != 23) t_h ++;}  //设置时
		             else 
		               {if(t_h !=0 ) t_h --;}
		           break;}
		           
		   case 2:{if(flag) 
		              {if(t_m != 59) t_m ++;}  //设置分
		           else 
		           	  {if(t_m !=0 ) t_m --;}
		           break;}	
		   case 1:{if(flag) flag = 0;          //设置模式切换
		           else  flag = 1;
		           break;}			           	   	   
		}
}

//显示缓冲区
void led_buf_flush(void)
{
	led_buf[0]=t_s%10;
	led_buf[1]=t_s/10;
	led_buf[2]=t_m%10;
	led_buf[3]=t_m/10;
	led_buf[4]=t_h%10;
	led_buf[5]=t_h/10;	
}

//显示刷新子程序
void disp()
{
    uchar i;
    for(i=0;i<6;i++)
    {
        display(i,led_buf[i]);    //调用输出显示
        
    }
}

//显示
//这里是显示子程序,入口参数为
// disseg  -> 位选 可选范围 0-7 一共8个数码管
// disdata -> 段选 可选范围 0-31 一个32个字符
//  段选 0-15  16个字符 为 "0"->"F"
//  段选 16-31 16个字符 为 "0."->"F."

void display(unsigned char disseg,unsigned char disdata)
{
    unsigned char dataf;
     dataf = 1;
     while(disseg)
     {
         dataf <<= 1;
         disseg--;
      }
      sege = 0;
	  segdata = dataf;             //这里首先把要显示的数据放到数据总线
	  segb = 1;                    //这里给出一个脉冲,数据送往位选端
	  segb = 0;
	  
      segdata = disbuf_u[disdata];
      segd = 1;                    //这里给出一个脉冲,数据送往段选端
      segd = 0;
      delay(50);
}

//关显示
void off_led(void)
{
      segdata = 255;
      segd = 1;                    //这里给出一个脉冲,数据送往段选端
      segd = 0;
}

uchar keyb()
{
    uchar key,keytmp;

    key1 = 1;   //将输出线拉高
    key2 = 1;
    key3 = 1;

    key = P3 ;  //读回来
    key = key & 0x38;           //获得键盘结果
    if(key == 56 ) return 0;   //如果用户没有按键返回 0  
    else
     { 
       keytmp = key;    
       delay(1000);              //判断是不是干扰
       key = P3;
       key = key & 0x38;
       if (key != keytmp ) return 0;  //是干扰,返回 0
          else                        //不是干扰,等待用户释放按键
            {                
                  do{ 
                      key1 = 1;       //输出拉高
                      key2 = 1;
                      key3 = 1;
                    key = P3 & 0x38;  //读回来
                   }while(key != 56 );   //等待用户释放 
                    P1_2 = 1;             //用户释放以后,清除p1.0指示灯
                   switch(keytmp)
                      {
                         case 24: return 3;//返回用户按键结果
                         case 40: return 2;
                         case 48: return 1;
                       }         
                  
             }

   
      }
    
    return 0;
    
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -