1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226
| #include "reg52.h" #include "intrins.h"
typedef unsigned int u16; //对数据类型进行声明定义 typedef unsigned char u8;
//定义P0口的三个引脚,赋予不同的涵义 sbit DS= P0^1; //p0.1脚控制串行数据输入DS sbit SH = P0^0; //串行输入时钟SH sbit ST = P0^2; //存储寄存器时钟ST
//按键定义 sbit key_stop = P1^0; sbit key_star = P1^1; sbit key_fen = P1^2; sbit key_shi = P1^3; u8 code smgduan[17]={ // 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, // 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//共阴显示0~F的值 //0 1 2 3 4 5 6 7 8 9 A b C d E F - 0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90, 0x8C, 0xBF, 0xC6, 0xA1, 0x86, 0xFF, 0xbf };//共阳显示0~F的值
char duanMa[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};//选择1-8哪个数码管段 char duanZhi[8]={0,0,0xbf,0,0,0xbf,0,0}; //保存8个数码管的中每个数码管段的数值 0x40共阴,0xbf共阳:显示横杠
//num1:秒初始值 num2:分初始值 num3:时初始值 u16 miao=55,fen=59,shi=23; //秒、分、时高位低位 u8 miao_L, miao_H, fen_L, fen_H, shi_L, shi_H;
static int i = 0; //给中断计数使用
//函数声明 void SendTo595(char byteData); void display(); void keyscan(); //按键函数 void key\_delay(int xms); //按键延时函数 x ms /\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* \*函数名 :display \*功能 :对传入的时分秒进行处理计算,转化为七段数码管要显示的值 \*参数 :num1 秒 num2 分 num3 时 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/ void display() {
//先发送8位位码,后发送8位段码 //8位数码管需要发送8次 char i=0; //给单片机for循环使用,由于Keil4 把 变量定义放for里会报错,只能放函数体前面
//分离每个数字的个位和十位/ // static char shi1,ge1,shi2,ge2,shi3,ge3; // shi1=(char)miao/10; // ge1=(char)miao%10;
// shi2=(char)fen/10; // ge2=(char)fen%10;
// shi3=(char)shi/10; // ge3=(char)shi%10; ///=======
//保存段值/ duanZhi[7]=smgduan[miao_L]; duanZhi[6]=smgduan[miao_H]; duanZhi[3]=smgduan[fen_H]; duanZhi[4]=smgduan[fen_L]; duanZhi[1]=smgduan[shi_L]; duanZhi[0]=smgduan[shi_H]; ///=======
i=0; for(;i<8;i++) { SendTo595(duanMa[i]); //送段码,采用共阴就取反 SendTo595(duanZhi[i]); //送位码 /\*位移寄存器数据准备完毕,转移到存储寄存器\*/ ST = 0; //ST \_nop\_(); \_nop\_(); ST = 1; //检测到上升沿,让存储寄存器时钟变为高电平 } }
/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* \* 函 数 名 : TimerInit \* 函数功能 : 定时器0初始化 \* 参数 :无 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/ void TimerInit() { TMOD|=0X01; //选择为定时器0模式,工作方式1,仅用TR0打开启动。 TH0=0X3c; //给定时器赋初值,定时50ms 3CB0 TL0=0Xb0; //0X3CB0的十进制是15536 从15536计数到65536计数50000次 即50000us=50ms ET0=1; //打开定时器0中断允许 EA=1; //打开总中断 TR0=1; //打开定时器
}
/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* \* 函 数 名 : main \* 函数功能 : 主函数 \* 参数 :无 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/ void main() { TimerInit(); while(1) { display(); keyscan(); //按键函数 } }
/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* \*函数名 :SendTo595 \*功能 :串行发送8个比特(一个字节)的数据给595,再并行输出 \*参数 :byteData \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/ void SendTo595(char byteData) { char i=0; ST = 0; //ST for(;i<8;i++) { DS = byteData>>7; //DS取出最高位(第8位) byteData= byteData<<1; //将第7位移动到最高位
SH = 1; //上升沿,让串行输入时钟变为高电平,并延时2个时钟周期 \_nop\_(); \_nop\_();
SH = 0; //变为低电平,为下次准备 } }
/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* \* 函 数 名 : Timer0() \* 函数功能 : 定时器0中断函数 \* 参数 :无 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/ void Timer0() interrupt 1 { TL0 =(65536-50000)%256;//50ms预装载值 TH0 =(65536-50000)/256; i++; if(i==20)//20个50毫秒即一秒 { i=0; miao++; if(miao==60) { miao=0; fen++; if(fen==60)//定时一小时自动清零 { fen=0; shi++; if(shi==24) { shi=0; fen =0; miao = 0; } } } miao_L = miao%10; miao_H = miao/10;
fen_L = fen%10; fen_H = fen/10;
shi_L = shi%10; shi_H = shi/10; } // display(); } void keyscan(){ //按键函数
if(key_stop == 0){ key\_delay(10); if(key_stop == 0){ EA = 0; //关总中断,即停止 while(!key_stop); } }//key\_stop if(key_star == 0){ key\_delay(10); if(key_star == 0){ EA = 1; //开总中断 while(!key_star); } }//key\_star if(key_fen == 0){ key\_delay(10); if(key_fen == 0){ fen++; while(!key_fen); } }//key\_fen++ if(key_shi == 0){ key\_delay(10); if(key_shi == 0){ shi++; while(!key_shi); } }//key\_shi++ } void key\_delay(int xms){ //按键延时函数 x ms unsigned int i, j; for(i=0; i<xms; ++i) for(j=0; j<110; ++j) ; }//key\_delay
|