您好,欢迎访问三七文档
当前位置:首页 > 电子/通信 > 电子设计/PCB > 基于51单片机状态机矩阵键盘数码管动态显示的时钟系统
/******************************************************************************程序功能:基于状态机的线性反转扫描方法实现按键扫描数码管动态显示开发环境:KeiL4硬件环境:STC12C5A60S2,11.0592接线说明:单片机P1口接底板JP29,具体接法为:P10-L1,P11-L2,P12-L3,P13-L4,P14-L5,P15-L6,P16-L7,P17-L8单片机P20~P21接底板JP26,具体接法:P20-DS,P21-SHCP,P22-STCP跳线说明:J70实验现象:数码管动态显示时钟时间同时显示当前被按下的键值可通过矩阵键盘对时钟进行开关已经参数调试******************************************************************************/#includeREG52.htypedefunsignedcharuint8;typedefunsignedintuint16;#defineKEY_PORTP1//定义4x4键盘使用的单片机端口sbitSEG_DS=P2^0;//74HC595芯片的数据引脚sbitSEG_SHCP=P2^1;//74HC595芯片的控制引脚,上升沿移入数据sbitSEG_STCP=P2^2;//74HC595芯片的控制引脚,上升沿更新数据//*****************************************************************************//全局变量//*****************************************************************************charhour,min,sec;//秒分时uint8Clock_flag;//时钟开关标志位uint8ct_flag;//按键长按标志位//*****************************************************************************//反转法矩阵键盘的各个按键的计算值unsignedchartabLe[]={0xee,//00xed,//10xeb,//20xe7,//30xde,//40xdd,//50xdb,//60xd7,//70xbe,//80xbd,//90xbb,//100xb7,//110x7e,//120x7d,//130x7b,//140x77//15};//共阳数码管的编码,并将数据定义在CODE区unsignedcharcodeSeg_Data[]={0xc0,/*0*/0xF9,/*1*/0xA4,/*2*/0xB0,/*3*/0x99,/*4*/0x92,/*5*/0x82,/*6*/0xF8,/*7*/0x80,/*8*/0x90,/*9*/0x88,/*A*/0x83,/*b*/0xC6,/*C*/0xA1,/*d*/0x86,/*E*/0x8E,/*F*/};//数码管位选编码,控制显示8位中的第几位unsignedcharcodeSeg_Addr[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0xFF,//ALLON0x00//OFF};//*****************************************************************************//函数声明//*****************************************************************************voidSEG_Send595OneByte(unsignedcharucData);//向74HC595写入一个8位的数据//指定数码管显示定数字voidDispLayOneCharOnAddr(unsignedcharData,unsignedcharAddr);unsignedcharKey_Scan(void);//基于状态机的按键扫描voidParameter_Setting(uint8key_value_get);//按键参数设置voidTimer0Configuration();//定时器初始化voidCLOCK(void);//时钟运行函数//*****************************************************************************//*****************************************************************************//*****************************************************************************//定时器0中断服务函数//*****************************************************************************voidTimer0()interrupt1{uint8key_get,j;staticuint8i=0,key_value;staticuint16count=0;TH0=(65536-922)/256;TL0=(65536-922)%256;/***********************用户代码************************************/count++;if(962==count)//一秒运行一次时钟{if(Clock_flag)CLOCK();//时钟走一次count=0;//定时计数清零}switch(i){case0:i++;DispLayOneCharOnAddr(hour/10,0);//数码管动态显示第一位break;case1:i++;DispLayOneCharOnAddr(hour%10,1);//数码管动态显示第二位break;case2:i++;DispLayOneCharOnAddr(min/10,2);//数码管动态显示第三位break;case3:i++;DispLayOneCharOnAddr(min%10,3);//数码管动态显示第四位break;case4:i++;DispLayOneCharOnAddr(sec/10,4);//数码管动态显示第五位break;case5:i++;DispLayOneCharOnAddr(sec%10,5);//数码管动态显示第六位break;case6:i++;DispLayOneCharOnAddr(key_value,6);//数码管动态显示第七位break;case7:i++;//数码管动态显示第八位break;case8:i=0;key_get=Key_Scan();//状态机按键扫描每9ms进行一次扫描if(key_get)//按键没按下返回零{for(j=0;j16;j++){if(key_get==tabLe[j])//通过查表得出按键的号{key_value=j;break;}}Parameter_Setting(key_value);//按键参数调试函数输入按键号}break;default:break;}}//*****************************************************************************//主函数//*****************************************************************************voidmain(void){EA=0;//关总中断Timer0Configuration();//定时器0初始化1ms中断EA=1;//开总中断while(1)//循环等待中断到来{}}//*****************************************************************************//*****************************************************************************//向HC595发送一个字节voidSEG_Send595OneByte(unsignedcharucData){unsignedchari;for(i=0;i8;i++)//8位数据依次写入,先写最低位{SEG_DS=(ucData&0x80);//先读入高位x&0x80;SEG_SHCP=0;SEG_SHCP=1;SEG_SHCP=0;//SHCP引脚的上升沿移入数据ucData=1;//数据左移}}/*******************************************************函数功能:在指定位置显示一个数据参数说明:Data是要显示的数据,Addr是在第几位显示。Addr取值范围是0~9。Addr=0~7时,选择的是显示在第几位数码管上;Addr=8时,同时选中8位数码管,即打开所有数码管Addr=9时,关闭8位数码管8位数码管,左数依次为第0位,第1位...第7位。*******************************************************/voidDispLayOneCharOnAddr(unsignedcharData,unsignedcharAddr){SEG_Send595OneByte(Seg_Addr[Addr]);//显示在哪一个数码管上SEG_Send595OneByte(Seg_Data[Data]);//显示的数据SEG_STCP=0;SEG_STCP=1;//STCP引脚的上升沿更新数据SEG_STCP=0;}/******************************************************************************函数名称:Key_Scan函数功能:返回按键编码入口参数:无返回值:按键编码备注:无*******************************************************************************unsignedcharKey_Scan(void){staticunsignedcharst=0,i,key;//静态变量st状态位i长按计数key键值uint8L,H;//定义局部变量,用L得出低4位的值,用h得出高4位的值switch(st){//=========================================================================//状态0按键查询状态//=========================================================================case0:KEY_PORT=0x0f;//给P1赋值00001111L=KEY_PORT&0x0f;if(L!=0x0f)//按键按下{st=1;}//进入下一状态按键确认状态return0;break;//=========================================================================//状态1按键确认状态//=========================================================================case1:KEY_PORT=0x0f;//给P1赋值
本文标题:基于51单片机状态机矩阵键盘数码管动态显示的时钟系统
链接地址:https://www.777doc.com/doc-2536040 .html