单片机的时钟按键程序

如何编写程序能让按键按下弹起来再加一,我的程序按键按下就会一直加,反应太快

4个回答

防抖,判断到端口高电平之后,延时10ms左右,再判断一次是否还是刚刚的高电平状态,如果是,再等待按键释放,即while(!key);。跳出这个循环之后就表示按键事件完成。
if(!key)
{
delay(10);//延迟10ms
if(!key)//再判断,防抖 {
while(key);//等待释放
LED = ~LED;
}
}

使用边沿触发。
如果按下是低电平,就用上升沿触发;
如果按下是高电平,就用下降沿触发。

用定时器扫描按键就可以可

你让它等待释放后才加1

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
其他相关推荐
关于51单片机制作时钟的问题?

用51单片机做时钟,我没用1302,就是一个简单的时钟,可以用6个数码管显示时分秒,可以用3个按键实现功能选择和加减。这些在开发板上都可以实现,之后我想在此基础上我想用AT24C02实现断电保护功能,当我的程序写完之后,发现无法实现,这个只能实现的是用按键控制的数字,比如我用按键将时间调成000019,之后让它自己往上加,然后我再断电,等我在上电的时候数码管上显示的还是000019,这个现象是属于断电保护还是代码出问题了,我有点不太清楚,代码如下,请求大家帮助。谢谢。 #include<reg52.h> sbit lsa=P2^2; sbit lsb=P2^3; sbit lsc=P2^4; sbit k1=P3^1; sbit k2=P3^0; sbit k3=P3^2; sbit SDA=P2^0; sbit SCL=P2^1; typedef unsigned int ui; typedef unsigned char uc; ui code shuju[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; ui disp[6]; ui num,shi,fen,miao; ui ss=0; void delay(ui i) { while(i--); } void Delay10us() { unsigned char a,b; for(b=1;b>0;b--) for(a=2;a>0;a--); } void I2cStart() { SDA=1; Delay10us(); SCL=1; Delay10us();//?????????SDA???????>4.7us SDA=0; Delay10us();//?????????>4us SCL=0; Delay10us(); } void I2cStop() { SDA=0; Delay10us(); SCL=1; Delay10us();//??????????4.7us SDA=1; Delay10us(); } void respons() { ui b; SCL=1; while(SDA)//????????????????豸??SDA???? { b++; if(b>200) //???????2000us???????????????????????????????? { SCL=0; Delay10us(); } } SCL=0; Delay10us(); } void I2cSendByte(unsigned char dat) { unsigned char a=0,b=0;//???255??????????????1us????????255us?? for(a=0;a<8;a++)//?????8λ???????λ??? { SDA=dat>>7; //?????????SCL=0??????????????SDA??? dat=dat<<1; Delay10us(); SCL=1; Delay10us();//???????>4.7us SCL=0; Delay10us();//??????4us } SDA=1; Delay10us(); SCL=0; Delay10us(); } unsigned char I2cReadByte() { unsigned char a=0,dat=0; SDA=1; //?????????????????SCL????0 Delay10us(); for(a=0;a<8;a++)//????8????? { SCL=1; Delay10us(); dat<<=1; dat|=SDA; Delay10us(); SCL=0; Delay10us(); } return dat; } void write_add(unsigned char addr,unsigned char dat) { I2cStart(); I2cSendByte(0xa0);//????д??????? respons(); I2cSendByte(addr);//?????д??????? respons(); I2cSendByte(dat); //???????? respons(); I2cStop(); } unsigned char read_add(unsigned char addr) { unsigned char num; I2cStart(); I2cSendByte(0xa0); //????д??????? respons(); I2cSendByte(addr); //???????????? respons(); I2cStart(); I2cSendByte(0xa1); //???????????? respons(); num=I2cReadByte(); //??????? I2cStop(); return num; } void init24c02() { SDA=1; Delay10us(); SCL=1; Delay10us(); miao=read_add(1); fen=read_add(2); shi=read_add(3); } void datapros() { disp[0]=shuju[miao%10]; disp[1]=shuju[miao/10]; disp[2]=shuju[fen%10]; disp[3]=shuju[fen/10]; disp[4]=shuju[shi%10]; disp[5]=shuju[shi/10]; } void display() { ui i; for(i=0;i<6;i++) { switch(i) { case(0): lsa=0;lsb=0;lsc=0;break; case(1): lsa=1;lsb=0;lsc=0;break; case(2): lsa=0;lsb=1;lsc=0;break; case(3): lsa=1;lsb=1;lsc=0;break; case(4): lsa=0;lsb=0;lsc=1;break; case(5): lsa=1;lsb=0;lsc=1;break; } P0=disp[i]; delay(100); P0=0x00; } } void init() { TMOD=0x01; TH0=0xfc; TL0=0x18; //1ms EA=1; TR0=1; ET0=1; } void key() { if(k1==0) { delay(100); { if(k1==0) { ss=ss+2; while(!k1); switch(ss) { case(2): lsa=0;lsb=0;lsc=0;TR0=0;break; case(4): lsa=0;lsb=1;lsc=0;break; case(6): lsa=0;lsb=0;lsc=1;break; case(8): ss=0;TR0=1;break; } } } } if(ss!=0) { if(k2==0) { delay(100); { if(k2==0) { while(!k2); if(ss==2) { miao++; if(miao==60) miao=0; write_add(1,miao); } if(ss==4) { fen++; if(fen==60) fen=0; write_add(2,fen); } if(ss==6) { shi++; if(shi==24) shi=0; write_add(3,shi); } } } } if(k3==0) { delay(100); if(k3==0) { while(!k3); if(ss==2) { miao--; if(miao==-1) miao=59; write_add(1,miao); } if(ss==4) { fen--; if(fen==-1) fen=59; write_add(2,fen); } if(ss==6) { shi--; if(shi==-1) shi=23; write_add(3,shi); } } } } } void main() { init(); init24c02(); while(1) { key(); datapros(); display(); } } void init0() interrupt 1 { TH0=0xfc; TL0=0x18; num++; if(num==1000) { miao++; num=0; if(miao==60) { miao=0; fen++; if(fen==60) { fen=0; shi++; if(shi==24) { shi=0; write_add(3,shi); } write_add(2,fen); } write_add(1,miao); } } }

基于凌阳单片机的数字时钟程序

以SPCE061A单片机为主控系统,通过硬件电路制作以及软件程序编制,设计一个多功能数字时钟,该时钟由时钟模块、语音模块、SPLC501液晶显示模块、按键模块、温度传感器DS18B20模块。该系统操作简单可以实现准确显示时间,整点报时,调整时间,温度显示,闹钟,秒表功能。该时钟功耗小,成本低,实用性强,系统具有一定的扩展性。

单片机编程按键与实际按键正好颠倒

#include<absacc.h> #define LEDLen 6 #define mode 0x03; #define CAddr XBYTE[0xe100]/* 控制字地址 */ #define OUTBIT XBYTE[0xe101]/* 位控制口 */ #define CLK164 XBYTE[0xe102]/* 段控制口(接164时钟位) */ #define DAT164 XBYTE[0xe102] /* 段控制口(接164数据位) */ #define IN XBYTE[0xe103] /* 键盘读入口 */ unsigned char LEDBuf[LEDLen]; /* 显示缓冲 */ code unsigned char LEDMAP[] = { /* 八段管显示码 */ 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71 }; void Delay(unsigned char CNT) { unsigned char i; while (CNT-- !=0) for (i=100; i !=0; i--); } void DisplayLED() { unsigned char i, j; unsigned char Pos; unsigned char LED; Pos = 0x20; /* 从左边开始显示 */ for (i = 0; i < LEDLen; i++) { OUTBIT = 0; /* 关所有八段管 */ LED = LEDBuf[i]; for (j = 0; j < 8; j++) { /* 送164 */ if (LED & 0x80) DAT164 = 1; else DAT164 = 0; CLK164 = CLK164|0x02; CLK164 = CLK164&0xfd; LED <<= 1; } OUTBIT = Pos; /* 显示一位八段管 */ Delay(1); Pos >>= 1; /* 显示下一位 */ } } code unsigned char KeyTable[] = { /* 键码定义 */ 0x00, 0x01, 0x04, 0x07 , 0x0f, 0x02, 0x05, 0x08, 0x0e, 0x03, 0x06, 0x09 , 0x0d, 0x0c, 0x0b, 0x0a , 0x10,0x11,0x12,0x13,0x14, 0x15,0x16, }; unsigned char TestKey() { OUTBIT = 0; /* 输出线置为0 */ return (~IN & 0x0f); /* 读入键状态 (高四位不用) */ } unsigned char GetKey() { unsigned char Pos; unsigned char i; unsigned char k; i = 6; Pos = 0x20; /* 找出键所在列 */ do { OUTBIT = ~ Pos; Pos >>= 1; k = ~IN & 0x0f; } while ((--i != 0) && (k == 0)); /* 键值 = 列 X 4 + 行 */ if (k != 0) { i *= 4; if (k & 2) i += 1; else if (k & 4) i += 2; else if (k & 8) i += 3; OUTBIT = 0; do Delay(10); while (TestKey()); /* 等键释放 */ return(KeyTable[i]); /* 取出键码 */ } else return(0xff); } void main() { CAddr = mode; LEDBuf[0] = 0xff; LEDBuf[1] = 0xff; LEDBuf[2] = 0xff; LEDBuf[3] = 0xff; LEDBuf[4] = 0x00; LEDBuf[5] = 0x00; while (1) { DisplayLED(); if (TestKey()) LEDBuf[5] = LEDMAP[GetKey() & 0x0f]; } } 程序如上 为什么按键会上下颠倒?

12864显示时钟,按键可调整时间的程序怎么写啊??

1.DB1~DB7是P0^0~P0^6 #define LCD_data P0 //数据口 sbit LCD_RS = P1^0; //寄存器选择输入 sbit LCD_RW = P1^1; //液晶读/写控制 sbit LCD_EN = P2^5; //液晶使能控制 sbit LCD_PSB = P1^2; //串/并方式控制 sbit LCD_RST = P1^4; //液晶复位端口

关于AT89C51单片机数字时钟的设计C语言程序warning问题

本人新手,还希望各位大大帮忙看下怎么解决 Build target 'Target 1' assembling STARTUP.A51... linking... *** WARNING L1: UNRESOLVED EXTERNAL SYMBOL SYMBOL: ?C_START MODULE: STARTUP.obj (?C_STARTUP) *** WARNING L2: REFERENCE MADE TO UNRESOLVED EXTERNAL SYMBOL: ?C_START MODULE: STARTUP.obj (?C_STARTUP) ADDRESS: 080AH Program Size: data=9.0 xdata=0 code=15 "t" - 0 Error(s), 2 Warning(s). 源程序如下: #include<reg52.h> #define uint unsigned int #define uchar unsigned char sbit QB1=P1^0; sbit QB2=P1^1; //数码管段选 sbit QB3=P1^2; sbit QB4=P1^3; sbit QB5=P1^4; sbit QB6=P1^5; sbit fm=P1^6; //蜂鸣器 sbit s1=P2^4; //s5按键,切换显示 sbit s2=P2^3; //s2按键,设置调时 sbit s3=P2^2; //s3按键,加1 sbit s4=P2^1; //s4按键,减1 sbit led1=P0^0; sbit led2=P0^1; sbit led3=P0^2; uchar count; uchar sec,minu,hour,day,week,mon; uchar n_sec,n_minu,n_hour; uint year; uchar set_2=1,set_1=1; uchar hs,hg,mis,mig,ss,sg; uchar nhs,nhg,nms,nmg,nss=0,nsg=0; uchar ms,mg,ds,dg,w; uchar code table[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80, 0X90,0X88,0X83,0XC6,0XA1,0X8E,0X86,0xbf}; //0~F,-,共阳 //uchar code tableyi[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d, //0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40};//0-F,-,共阴 uchar code table_d[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd, 0x87,0xff,0xef}; //0~9数组,带小数点 uchar table1[]={31,31,29,31,30,31,30,31,31,30,31,30,31}; //闰年 uchar table2[]={31,31,28,31,30,31,30,31,31,30,31,30,31}; //非闰年 void delay(uint); //延时函数 void timer0(); //走时中断函数 void jishi(); //计时函数 void key_change(); //切换显示按键函数 void key_set(); //设置时间按键函数 void disp(uchar,uchar,uchar,uchar,uchar,uchar); //显示函数 void zd_clock(); //整点报时函数 void nz_clock(); //闹钟函数 uchar incone(uchar); //加1函数 uchar decone(uchar); //减1函数 void set_time(); //设置时间函数 void set_clock(); //设置闹钟函数 void set_mdw(); //设置月日星期函数 void main() //主函数 { EA=1; ET0=1; TR0=1; TMOD=0x01; TH0=0x4c; //50ms初值 晶振11.0592 TL0=0x00; hour=23;minu=59;sec=49; //赋初值:11点59分0秒 n_hour=12;n_minu=56;n_sec=0; //闹钟赋初值12点1分0秒 year=2008;mon=5;day=14;week=3;//年月日星期赋初值2008年5月11日星期天;祝天下所有母亲节日快乐 while(1) { hs=hour/10; //时分秒HH.MM.SS hg=hour%10; mis=minu/10; mig=minu%10; ss=sec/10; sg=sec%10; ms=mon/10; //月日-星期MM.DD.-W mg=mon%10; ds=day/10; dg=day%10; w=week; nhs=n_hour/10; //闹钟定时HH.MM.SS nhg=n_hour%10; nms=n_minu/10; nmg=n_minu%10; nss=n_sec/10; nsg=n_sec%10; key_change(); //s4按键扫描 key_set(); //s2按键扫描 set_time(); //设置时间 set_mdw(); //设置月日星期 set_clock(); //设置闹钟 if(set_1==1) //正常走时显示 { disp(hs,hg,mis,mig,ss,sg); } if(set_1==2) //设置时间,LED1闪亮 { disp(hs,hg,mis,mig,ss,sg); if(sec%2==0) {led2=1;led3=1;led1=~led1;} // else // {led1=1;} } if(set_1==3) //正常显示月日-星期 { disp(ms,mg,ds,dg,16,w); } if(set_1==4) //设置月日-星期,LED2闪亮 { disp(ms,mg,ds,dg,16,w); if(sec%2==0) {led1=1;led3=1;led2=~led2;} // else // {led2=1;} } if(set_1==5) //正常显示定时 { disp(nhs,nhg,nms,nmg,nss,nsg); } if(set_1==6) //设置闹钟定时,LED3闪亮 { disp(nhs,nhg,nms,nmg,nss,nsg); if(sec%2==0) {led1=1;led2=1;led3=~led3;} // else // {led3=1;} } zd_clock(); //整点报时 nz_clock(); //闹钟 } } void timer0() interrupt 1 //50ms中断函数 { TMOD=0x01; TH0=0x4c; //50ms初值 晶振11.0592 TL0=0x00; count++; if(count==20) { count=0; sec++; jishi(); //调计时函数 } } void jishi() //计时函数 { if(sec==60) { sec=0; minu++; if(minu==60) { minu=0; hour++; if(hour==24) { hour=0; day++; week++; if(week==8) {week=0;} if(year%4==0&&year%100!=0||year%400==0) //闰年 { if(day==table1[mon]+1) { day=0; mon++; if(mon==13) {mon=0;year++;} } } else //非闰年 { if(day==table2[mon]+1) { day=0; mon++; if(mon==13) {mon=0;year++;} } } } } } } void key_change() //s1按键扫描 { if(s1==0) { delay(200); if(s1==0) { set_1++; while(!s1); if(set_1==7) {set_1=1;} } } } void key_set() //s2按键扫描 { if(s2==0) { delay(10); if(s2==0) { set_2++; while(!s2); if(set_2==4) {set_2=1;} } } } void disp(uchar a1,uchar a2,uchar a3,uchar a4,uchar a5,uchar a6) //显示函数 { QB1=1; QB2=0; QB3=0; QB4=0; QB5=0; QB6=0; P3=table[a1]; //段码送P0口 delay(10); //延时一小会 QB1=0; QB2=1; QB3=0; QB4=0; QB5=0; QB6=0; P3=table[a2]; //第2个数码管显示,带小数点 delay(10); QB1=0; QB2=0; QB3=1; QB4=0; QB5=0; QB6=0; P3=table[a3]; //第3个数码管显示 delay(10); QB1=0; QB2=0; QB3=0; QB4=1; QB5=0; QB6=0; P3=table[a4]; //第4个数码管显示,带小数点 delay(10); QB1=0; QB2=0; QB3=0; QB4=0; QB5=1; QB6=0; //第5个数码管显示 P3=table[a5]; delay(10); QB1=0; QB2=0; QB3=0; QB4=0; QB5=0; QB6=1; P3=table[a6]; //第6个数码管显示 delay(10); QB1=0; QB2=0; QB3=0; QB4=0; QB5=0; QB6=0; } void zd_clock() //整点报时函数 { if(minu==59&&(sec==53||sec==55||sec==57)) { fm=0; delay(5); fm=1; delay(5); } fm=0; if(minu==59&&sec==59) { fm=0; delay(5); fm=1; delay(5); fm=0; } } void nz_clock() //闹钟函数 { if(hour==n_hour&&minu==n_minu&&sec==n_sec) //if((sec%2==0)&&sec<30) { fm=0; delay(1); fm=1; delay(1); } } void set_time() //设置时间函数 { if(set_1==2) { if(set_2==1) { hour=incone(hour); if(hour==24) {hour=0;} // if(hour<0) // {hour=23;} hour=decone(hour); } if(set_2==2) { minu=incone(minu); if(minu==60) {minu=0;} // if(minu<0) // {minu=59;} minu=decone(minu); } } } void set_mdw() //设置月日星期函数 { if(set_1==4) { if(set_2==1) { mon=incone(mon); if(mon==13) {mon=1;} mon=decone(mon); // if(mon==0) // {mon=12;} } if(set_2==2) { day=incone(day); if(day==32) {day=0;} day=decone(day); // if(day==0) // {day=0;} } if(set_2==3) { week=incone(week); if(week==8) {week=0;} week=decone(week); // if(week==0) // {week=7;} } } } void set_clock() //设置闹钟函数 { if(set_1==6) { if(set_2==1) { n_hour=incone(n_hour); if(n_hour==24) {n_hour=0;} n_hour=decone(n_hour); if(n_hour==0) {n_hour=0;} } if(set_2==2) { n_minu=incone(n_minu); if(n_minu==60) {n_minu=0;} n_minu=decone(n_minu); if(n_minu==0) {n_minu=0;} } } } uchar incone(uchar n) //加1函数 { if(s3==0) { delay(200); if(s3==0) { n++; while(!s3); } } return(n); } uchar decone(uchar m) //减1函数 { if(s4==0) { delay(200); if(s4==0) { m--; while(!s4); if(m<0) {m=0;} } } return(m); } void delay(uint k) //延时函数 { uint i,j; for(i=k;i>0;i--) for(j=80;j>0;j--); }

以51单片机为核心的时钟,在LED显示器上显示当前的时间:

显示格式为“时时:分分:秒秒”。 用4个功能键操作来设置当前时间。功能键K1~K4功能如下。 K1—进入设置现在的时间。 K2—设置小时(按一次,小时增1)。 K3—设置分钟(按一次,分钟增1)。 K4—确认完成设置。 程序执行后工作指示灯闪动,表示程序开始执行,LED显示“00:00:00”,然后开始计时。 本题可以考虑用LCD(比如:LCD1602)来实现显示,则显示更加清楚。

小白关于单片机数码管动态显示的问题

数码管的动态显示是利用人眼的暂留效应产生动态效果的,那让正在动态显示的数码管,比如在倒计时,突然停下来,是只显示一位数吗?

帮我改C语言代码(51单片机LCD1602显示时间从k1这些按键控制变成矩阵按键控制)

帮我改C语言代码,51单片机LCD1602显示时间从k1这些按键控制变成矩阵按键控制(现在是可以用k1这些按键来修改了) 原理图: ![图片说明](https://img-ask.csdn.net/upload/201912/22/1577010044_884857.png) ![图片说明](https://img-ask.csdn.net/upload/201912/22/1577010062_997331.png) 下面是代码: ``` //下面是main.c代码 /******************************************************************************* * 实验名 : 万年历实验 * 使用的IO : * 实验效果 :1602显示时钟,按K3进入时钟设置,按K1选择设置的时分秒日月,按K2选择 *选择设置加1。 * 注意 : *******************************************************************************/ #include<reg51.h> #include"lcd.h" #include"ds1302.h" sbit K1=P3^1; sbit K2=P3^0; sbit K3=P3^2; sbit K4=P3^3; //管脚接线 void Int0Configuration(); void LcdDisplay(); unsigned char SetState,SetPlace; void Delay10ms(void); //误差 0us /******************************************************************************* * 函数名 : main * 函数功能 : 主函数 * 输入 : 无 * 输出 : 无 *******************************************************************************/ void main() { unsigned char i; Int0Configuration(); LcdInit(); Ds1302Init(); while(1) { if(SetState==0) { Ds1302ReadTime(); } else { if(K1==0) //检测按键K1是否按下 { Delay10ms(); //消除抖动 if(K1==0) { SetPlace++; if(SetPlace>=7) SetPlace=0; } while((i<50)&&(K1==0)) //检测按键是否松开 { Delay10ms(); i++; } i=0; } if(K2==0) //检测按键K2是否按下 { Delay10ms(); //消除抖动 if(K2==0) { TIME[SetPlace]++; if((TIME[SetPlace]&0x0f)>9) //换成BCD码。 { TIME[SetPlace]=TIME[SetPlace]+6; } if((TIME[SetPlace]>=0x60)&&(SetPlace<2)) //分秒只能到59 { TIME[SetPlace]=0; } if((TIME[SetPlace]>=0x24)&&(SetPlace==2)) //小时只能到23 { TIME[SetPlace]=0; } if((TIME[SetPlace]>=0x32)&&(SetPlace==3)) //日只能到31 { TIME[SetPlace]=0; } if((TIME[SetPlace]>=0x13)&&(SetPlace==4)) //月只能到12 { TIME[SetPlace]=0; } if((TIME[SetPlace]>=0x7)&&(SetPlace==5)) //周只能到7 { TIME[SetPlace]=1; } // if(SetPlace==5) //月只能到12 // { // TIME[SetPlace]=; // } } while((i<50)&&(K2==0)) //检测按键是否松开 { Delay10ms(); i++; } i=0; } } LcdDisplay(); } } /******************************************************************************* * 函数名 : LcdDisplay() * 函数功能 : 显示函数 * 输入 : 无 * 输出 : 无 *******************************************************************************/ void LcdDisplay() { LcdWriteCom(0x80+0X40); LcdWriteData('0'+TIME[2]/16); //时 LcdWriteData('0'+(TIME[2]&0x0f)); LcdWriteData('-'); LcdWriteData('0'+TIME[1]/16); //分 LcdWriteData('0'+(TIME[1]&0x0f)); LcdWriteData('-'); LcdWriteData('0'+TIME[0]/16); //秒 LcdWriteData('0'+(TIME[0]&0x0f)); LcdWriteCom(0x80); LcdWriteData('2'); LcdWriteData('0'); LcdWriteData('0'+TIME[6]/16); //年 LcdWriteData('0'+(TIME[6]&0x0f)); LcdWriteData('-'); LcdWriteData('0'+TIME[4]/16); //月 LcdWriteData('0'+(TIME[4]&0x0f)); LcdWriteData('-'); LcdWriteData('0'+TIME[3]/16); //日 LcdWriteData('0'+(TIME[3]&0x0f)); LcdWriteCom(0x8D); LcdWriteData('0'+(TIME[5]&0x07)); //星期 } /******************************************************************************* * 函数名 : Int0Configuration() * 函数功能 : 配置外部中断0 * 输入 : 无 * 输出 : 无 *******************************************************************************/ void Int0Configuration() { //设置INT0 IT0=1;//跳变沿出发方式(下降沿) EX0=1;//打开INT0的中断允许。 EA=1;//打开总中断 } /******************************************************************************* * 函数名 : Int0() * 函数功能 : 外部中断0 中断函数 * 输入 : 无 * 输出 : 无 *******************************************************************************/ void Int0() interrupt 0 { Delay10ms(); if(K3==0) { SetState=~SetState; SetPlace=0; Ds1302Init(); } } /******************************************************************************* * 函数名 : Delay10ms * 函数功能 : 延时函数,延时10ms * 输入 : 无 * 输出 : 无 *******************************************************************************/ void Delay10ms(void) //误差 0us { unsigned char a,b,c; for(c=1;c>0;c--) for(b=38;b>0;b--) for(a=130;a>0;a--); } //下面为ds1302.c代码 #include"ds1302.h" //---DS1302写入和读取时分秒的地址命令---// //---秒分时日月周年 最低位读写位;-------// uchar code READ_RTC_ADDR[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d}; uchar code WRITE_RTC_ADDR[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c}; //---DS1302时钟初始化2013年1月1日星期二12点00分00秒。---// //---存储顺序是秒分时日月周年,存储格式是用BCD码---// uchar TIME[7] = {0, 0, 0x12, 0x01, 0x01, 0x02, 0x13}; /******************************************************************************* * 函 数 名 : Ds1302Write * 函数功能 : 向DS1302命令(地址+数据) * 输 入 : addr,dat * 输 出 : 无 *******************************************************************************/ void Ds1302Write(uchar addr, uchar dat) { uchar n; RST = 0; _nop_(); SCLK = 0;//先将SCLK置低电平。 _nop_(); RST = 1; //然后将RST(CE)置高电平。 _nop_(); for (n=0; n<8; n++)//开始传送八位地址命令 { DSIO = addr & 0x01;//数据从低位开始传送 addr >>= 1; SCLK = 1;//数据在上升沿时,DS1302读取数据 _nop_(); SCLK = 0; _nop_(); } for (n=0; n<8; n++)//写入8位数据 { DSIO = dat & 0x01; dat >>= 1; SCLK = 1;//数据在上升沿时,DS1302读取数据 _nop_(); SCLK = 0; _nop_(); } RST = 0;//传送数据结束 _nop_(); } /******************************************************************************* * 函 数 名 : Ds1302Read * 函数功能 : 读取一个地址的数据 * 输 入 : addr * 输 出 : dat *******************************************************************************/ uchar Ds1302Read(uchar addr) { uchar n,dat,dat1; RST = 0; _nop_(); SCLK = 0;//先将SCLK置低电平。 _nop_(); RST = 1;//然后将RST(CE)置高电平。 _nop_(); for(n=0; n<8; n++)//开始传送八位地址命令 { DSIO = addr & 0x01;//数据从低位开始传送 addr >>= 1; SCLK = 1;//数据在上升沿时,DS1302读取数据 _nop_(); SCLK = 0;//DS1302下降沿时,放置数据 _nop_(); } _nop_(); for(n=0; n<8; n++)//读取8位数据 { dat1 = DSIO;//从最低位开始接收 dat = (dat>>1) | (dat1<<7); SCLK = 1; _nop_(); SCLK = 0;//DS1302下降沿时,放置数据 _nop_(); } RST = 0; _nop_(); //以下为DS1302复位的稳定时间,必须的。 SCLK = 1; _nop_(); DSIO = 0; _nop_(); DSIO = 1; _nop_(); return dat; } /******************************************************************************* * 函 数 名 : Ds1302Init * 函数功能 : 初始化DS1302. * 输 入 : 无 * 输 出 : 无 *******************************************************************************/ void Ds1302Init() { uchar n; Ds1302Write(0x8E,0X00); //禁止写保护,就是关闭写保护功能 for (n=0; n<7; n++)//写入7个字节的时钟信号:分秒时日月周年 { Ds1302Write(WRITE_RTC_ADDR[n],TIME[n]); } Ds1302Write(0x8E,0x80); //打开写保护功能 } /******************************************************************************* * 函 数 名 : Ds1302ReadTime * 函数功能 : 读取时钟信息 * 输 入 : 无 * 输 出 : 无 *******************************************************************************/ void Ds1302ReadTime() { uchar n; for (n=0; n<7; n++)//读取7个字节的时钟信号:分秒时日月周年 { TIME[n] = Ds1302Read(READ_RTC_ADDR[n]); } } //下面是lcd.c代码 #include"lcd.h" /******************************************************************************* * 函 数 名 : Lcd1602_Delay1ms * 函数功能 : 延时函数,延时1ms * 输 入 : c * 输 出 : 无 * 说 名 : 该函数是在12MHZ晶振下,12分频单片机的延时。 *******************************************************************************/ void Lcd1602_Delay1ms(uint c) //误差 0us { uchar a,b; for (; c>0; c--) { for (b=199;b>0;b--) { for(a=1;a>0;a--); } } } /******************************************************************************* * 函 数 名 : LcdWriteCom * 函数功能 : 向LCD写入一个字节的命令 * 输 入 : com * 输 出 : 无 *******************************************************************************/ #ifndef LCD1602_4PINS //当没有定义这个LCD1602_4PINS时 void LcdWriteCom(uchar com) //写入命令 { LCD1602_E = 0; //使能 LCD1602_RS = 0; //选择发送命令 LCD1602_RW = 0; //选择写入 LCD1602_DATAPINS = com; //放入命令 Lcd1602_Delay1ms(1); //等待数据稳定 LCD1602_E = 1; //写入时序 Lcd1602_Delay1ms(5); //保持时间 LCD1602_E = 0; } #else void LcdWriteCom(uchar com) //写入命令 { LCD1602_E = 0; //使能清零 LCD1602_RS = 0; //选择写入命令 LCD1602_RW = 0; //选择写入 LCD1602_DATAPINS = com; //由于4位的接线是接到P0口的高四位,所以传送高四位不用改 Lcd1602_Delay1ms(1); LCD1602_E = 1; //写入时序 Lcd1602_Delay1ms(5); LCD1602_E = 0; // Lcd1602_Delay1ms(1); LCD1602_DATAPINS = com << 4; //发送低四位 Lcd1602_Delay1ms(1); LCD1602_E = 1; //写入时序 Lcd1602_Delay1ms(5); LCD1602_E = 0; } #endif /******************************************************************************* * 函 数 名 : LcdWriteData * 函数功能 : 向LCD写入一个字节的数据 * 输 入 : dat * 输 出 : 无 *******************************************************************************/ #ifndef LCD1602_4PINS void LcdWriteData(uchar dat) //写入数据 { LCD1602_E = 0; //使能清零 LCD1602_RS = 1; //选择输入数据 LCD1602_RW = 0; //选择写入 LCD1602_DATAPINS = dat; //写入数据 Lcd1602_Delay1ms(1); LCD1602_E = 1; //写入时序 Lcd1602_Delay1ms(5); //保持时间 LCD1602_E = 0; } #else void LcdWriteData(uchar dat) //写入数据 { LCD1602_E = 0; //使能清零 LCD1602_RS = 1; //选择写入数据 LCD1602_RW = 0; //选择写入 LCD1602_DATAPINS = dat; //由于4位的接线是接到P0口的高四位,所以传送高四位不用改 Lcd1602_Delay1ms(1); LCD1602_E = 1; //写入时序 Lcd1602_Delay1ms(5); LCD1602_E = 0; LCD1602_DATAPINS = dat << 4; //写入低四位 Lcd1602_Delay1ms(1); LCD1602_E = 1; //写入时序 Lcd1602_Delay1ms(5); LCD1602_E = 0; } #endif /******************************************************************************* * 函 数 名 : LcdInit() * 函数功能 : 初始化LCD屏 * 输 入 : 无 * 输 出 : 无 *******************************************************************************/ #ifndef LCD1602_4PINS void LcdInit() //LCD初始化子程序 { LcdWriteCom(0x38); //开显示 LcdWriteCom(0x0c); //开显示不显示光标 LcdWriteCom(0x06); //写一个指针加1 LcdWriteCom(0x01); //清屏 LcdWriteCom(0x80); //设置数据指针起点 } #else void LcdInit() //LCD初始化子程序 { LcdWriteCom(0x32); //将8位总线转为4位总线 LcdWriteCom(0x28); //在四位线下的初始化 LcdWriteCom(0x0c); //开显示不显示光标 LcdWriteCom(0x06); //写一个指针加1 LcdWriteCom(0x01); //清屏 LcdWriteCom(0x80); //设置数据指针起点 } #endif ```

51单片机多功能时钟程序 LCD显示温度,实物显示不了。

实物LCD1602显示温度为0,其他信息正常显示,仿真一切正常,若将显示温度的函数单独提取成文件,则正常显示温度,不知道怎么改 PS只需看主函数,LCD1602.h和temp.h就行 ``` #include"key.h" #include"lcd1602.h" #include"ds1302.h" #include"naozhong.h" #include"temp.h" #include"nongli.h" #include "intrins.h" #define uchar unsigned char #define uint unsigned int uchar flag_nl,temperature; /*在LCD1602的坐标(x, y)位置显示星期*/ void LcdShowWeek(uchar x, uchar y, uchar dat) { uchar addr; if (y == 0) { addr = 0x00 + x; //第一行的x位置显示 } else { addr = 0x40 + x; //第二行x的位置显示 } LCD1602WriteCmd(addr + 0x80); switch(dat) { case 1:LCD1602WriteData('M');//星期数为1时,显示 LCD1602WriteData('O'); LCD1602WriteData('N'); break; case 2:LCD1602WriteData('T');//星期数据为2时显示 LCD1602WriteData('U'); LCD1602WriteData('E'); break; case 3:LCD1602WriteData('W');//星期数据为3时显示 LCD1602WriteData('E'); LCD1602WriteData('D'); break; case 4:LCD1602WriteData('T');//星期数据为4是显示 LCD1602WriteData('H'); LCD1602WriteData('U'); break; case 5:LCD1602WriteData('F');//星期数据为5时显示 LCD1602WriteData('R'); LCD1602WriteData('I'); break; case 6:LCD1602WriteData('S');//星期数据为6时显示 LCD1602WriteData('T'); LCD1602WriteData('A'); break; case 7:LCD1602WriteData('S');//星期数据为7时显示 LCD1602WriteData('U'); LCD1602WriteData('N'); break; } } /*显示温度*/ void LcdTimeDisplay(int temp) //lcd显示 { unsigned char datas[]={0,0}; //定义数组,室温比较小,所以只显示两位温度 float tp; if(temp< 0) //当温度值为负数 { LCD1602WriteCmd(0x80+0x0c); //写地址 LCD1602WriteData('-'); temp=temp-1; temp=~temp; tp=temp; temp=tp*0.0625*100+0.5; } else { LCD1602WriteCmd(0x80+0x0c); //写地址 LCD1602WriteData('+'); tp=temp; temp=tp*0.0625*100+0.5; } datas[0] = temp / 10000; datas[1] = temp % 10000 / 1000; datas[2] = temp % 1000 / 100; datas[3] = temp % 100 / 10; datas[4] = temp % 10; LCD1602WriteCmd(0x8d); //写地址 LCD1602WriteData('0'+datas[1]); //十位 Delay_nms(1); LCD1602WriteCmd(0x8e); //写地址 LCD1602WriteData('0'+datas[2]); //个位 Delay_nms(1); } /*初始化计时器*/ void Timer0Init() { EA = 1; //开总中断 TMOD = 0X01; //定时器0、工作方式1 ET0 = 1; //开定时器0中断 TR0 = 1; //允许定时器0定时 } /*读取DS1302中的时间*/ void Ds1302ReadTime() { miao = Ds1302Read(READ_RTC_ADDR[0]); //读秒 fen = Ds1302Read(READ_RTC_ADDR[1]); //读分 shi = Ds1302Read(READ_RTC_ADDR[2]); //读时 ri = Ds1302Read(READ_RTC_ADDR[3]); //读日 yue = Ds1302Read(READ_RTC_ADDR[4]); //读月 week = Ds1302Read(READ_RTC_ADDR[5]); //读星期 nian = Ds1302Read(READ_RTC_ADDR[6]); //读年 Conversion(0,nian,yue,ri); //农历转换 n_nian = year_moon ; n_yue = month_moon ; n_ri = day_moon ; } void DS1302ShowPart() //LCD显示时间、温度 { LcdShowWeek(12,1,week); LcdShowNum(2,1,shi); LcdShowNum(5,1,fen); LcdShowNum(8,1,miao); if(flag_nl == 0) //显示阳历 { LcdShowNum(2,0,nian); LcdShowNum(5,0,yue); LcdShowNum(8,0,ri); } else { LcdShowNum(2,0,n_nian); LcdShowNum(5,0,n_yue); LcdShowNum(8,0,n_ri); } } /*时钟+*/ void Inc_Time() { if(bit_flag == 1) //设置年 { nian+=0x01; if((nian & 0x0f) >= 0x0a) nian = (nian & 0xf0) + 0x10; if(nian >= 0x9a) nian = 1; } if(bit_flag == 2) //设置月 { yue+=0x01; if((yue & 0x0f) >= 0x0a) yue = (yue & 0xf0) + 0x10; if(yue >= 0x13) yue = 1; } if(bit_flag == 3) //设置日 { ri+=0x01; if((ri & 0x0f) >= 0x0a) ri = (ri & 0xf0) + 0x10; if(ri >= 0x32) ri = 0; } if(bit_flag == 4) //设置星期 { week+=0x01; if((week & 0x0f) >= 0x0a) week = (week & 0xf0) + 0x10; if(week >= 0x08) week = 1; } if(bit_flag == 5) //设置时 { shi+=0x01; if((shi & 0x0f) >= 0x0a) shi = (shi & 0xf0) + 0x10; ///***shi & 0xf0低四位清零,(shi & 0xf0) + 0x10向高位进1(高四位加1)***/// if(shi >= 0x24) shi = 0; } if(bit_flag == 6) //设置分 { fen+=0x01; if((fen & 0x0f) >= 0x0a) fen = (fen & 0xf0) + 0x10; if(fen >= 0x60) fen = 0; } if(bit_flag == 7) //设置秒 { miao+=0x01; if((miao & 0x0f) >= 0x0a) miao = (miao & 0xf0) + 0x10; if(miao >= 0x60) miao = 0; } } /*时钟-*/ void Dec_Time() { if(bit_flag == 1) { if(nian == 0x01) nian = 0x9a; if((nian & 0x0f) == 0x00) nian = (nian | 0x0a) - 0x10; nian -- ; } if(bit_flag == 2) { if(yue == 0x01) yue = 0x13; if((yue & 0x0f) == 0x00) yue = (yue | 0x0a) - 0x10; yue -- ; } if(bit_flag == 3) { if(ri == 0x01) ri = 0x32; if((ri & 0x0f) == 0x00) ri = (ri | 0x0a) - 0x10; ri -- ; } if(bit_flag == 4) //设置星期 { if(week == 0x01) week = 0x08; if((week & 0x0f) == 0x00) week = (week | 0x0a) - 0x10; week -- ; } if(bit_flag == 5) //设置时 { if(shi == 0x00) shi = 0x24; if((shi & 0x0f) == 0x00) shi = (shi | 0x0a) - 0x10; ///***如果个位为0,高四位减1***/// shi -- ; } if(bit_flag == 6) //设置分 { if(fen == 0x00) fen = 0x5a; if((fen & 0x0f) == 0x00) fen = (fen | 0x0a) - 0x10; fen -- ; } if(bit_flag == 7) { if(miao == 0x00) miao = 0x5a; if((miao & 0x0f) == 0x00) miao = (miao | 0x0a) - 0x10; miao -- ; } } /*具体按键功能*/ void KeyAction() { if (KeyValue == 1) { mode_flag++; if(mode_flag == 1) // 设置时钟 { bit_flag=1; //设置位为年的十位 LcdShowStr(0,0,"20 - - C"); LcdShowStr(0,1," : : "); } if(mode_flag == 2) //设置闹钟 { bit_flag = 1; //设置位为时的十位 LcdShowStr(0,0," set alarm "); LcdShowStr(0,1,"ON "); } if(mode_flag > 2) //回到正常显示 { mode_flag = 0; bit_flag = 0; write_guangbiao(2,0,0); //关闭光标 Int_1602_Dis(); //初始化液晶显示 } } if(KeyValue == 2) //选择键 { flag_200ms = 1; if(mode_flag == 1) //设置时间 { bit_flag ++; //设置位右移 if(bit_flag > 7) bit_flag= 1; } if(mode_flag == 2) //设置闹钟 { bit_flag ++; if(bit_flag > 5) bit_flag = 1; } } if(mode_flag == 1) { if(KeyValue == 3) //加 { Inc_Time(); } if(KeyValue == 4) //减 { Dec_Time(); } LcdShowNum(2,0,nian); //显示时间 LcdShowNum(5,0,yue); LcdShowNum(8,0,ri); LcdShowWeek(12,1,week); LcdShowNum(2,1,shi); LcdShowNum(5,1,fen); LcdShowNum(8,1,miao); LcdTimeDisplay(temperature); switch(bit_flag) // 光标显示 { case 1: write_guangbiao(2,0,1); break; case 2: write_guangbiao(5,0,1); break; case 3: write_guangbiao(8,0,1); break; case 4: write_guangbiao(12,1,1); break; case 5: write_guangbiao(2,1,1); break; case 6: write_guangbiao(5,1,1); break; case 7: write_guangbiao(8,1,1); break; } SetTimetoDS1302(); } /***************设置闹钟*********************/ if(mode_flag == 2) { if(bit_flag == 1) //设置闹钟开关 { if(KeyValue == 3) { alarm_open = 1; //闹钟功能开 } if(KeyValue == 4) { alarm_open = 0; //闹钟功能关 } } if(alarm_open == 1) { LcdShowStr(0,1,"ON "); } else { LcdShowStr(0,1,"OFF"); } if(bit_flag == 2) //设置第一个闹钟时 { if(KeyValue == 3) //加 { shi1+=0x01; if((shi1 & 0x0f) >= 0x0a) shi1 = (shi1 & 0xf0) + 0x10; if(shi1 >= 0x24) shi1 = 0; } if(KeyValue == 4) //减 { if(shi1 == 0x00) shi1 = 0x5a; if((shi1 & 0x0f) == 0x00) shi1 = (shi1 | 0x0a) - 0x10; shi1 -- ; } } if(bit_flag == 3) //设置第一个闹钟分 { if(KeyValue == 3) //加 { fen1+=0x01; if((fen1 & 0x0f) >= 0x0a) fen1 = (fen1 & 0xf0) + 0x10; if(fen1 >= 0x60) fen1 = 0; } if(KeyValue == 4) //减 { if(fen1 == 0x00) fen1 = 0x5a; if((fen1 & 0x0f) == 0x00) fen1 = (fen1 | 0x0a) - 0x10; fen1 -- ; } } if(bit_flag == 4) //设置第二个闹钟时 { if(KeyValue == 3) //加 { shi2+=0x01; if((shi2 & 0x0f) >= 0x0a) shi2 = (shi2 & 0xf0) + 0x10; if(shi2 >= 0x24) shi2 = 0; } if(KeyValue == 4) //减 { if(shi2 == 0x00) shi2 = 0x5a; if((shi2 & 0x0f) == 0x00) shi2 = (shi2 | 0x0a) - 0x10; shi2 -- ; } } if(bit_flag == 5) //设置第二个闹钟分 { if(KeyValue == 3) //加 { fen2+=0x01; if((fen2 & 0x0f) >= 0x0a) fen2 = (fen2 & 0xf0) + 0x10; if(fen2 >= 0x60) fen2 = 0; } if(KeyValue == 4) //减 { if(fen2 == 0x00) fen2 = 0x5a; if((fen2 & 0x0f) == 0x00) fen2 = (fen2 | 0x0a) - 0x10; fen2 -- ; } } LcdShowNum(4,1,shi1); LcdShowNum(7,1,fen1); LcdShowNum(10,1,shi2); LcdShowNum(13,1,fen2); switch(bit_flag) // 光标显示 { case 1: write_guangbiao(0,1,1); break; case 2: write_guangbiao(4,1,1); break; case 3: write_guangbiao(7,1,1); break; case 4: write_guangbiao(10,1,1); break; case 5: write_guangbiao(13,1,1); break; } } } void main() { InitLCD1602(); InitDS1302(); Timer0Init(); //初始化定时器 Int_1602_Dis(); Delay_nms(500); while(1) { KeyDown(); if(KeyValue<10) { if(beep_flag ==0) //闹钟不响的状态下可以设置 { KeyAction(); } else { beep_flag= 0; //按下任意键可关闭闹钟 beep = 1; Ds1302ReadTime(); } if(mode_flag == 0) { if(KeyValue == 4) { flag_nl = ~flag_nl; //切换农历和阳历的显示标志位 if(flag_nl == 1) LcdShowStr(0,0,"N "); } } } if(mode_flag == 0) { Ds1302ReadTime(); //读时间 DS1302ShowPart(); LcdTimeDisplay(Ds18b20ReadTemp()); } naozhong_alarm(); //闹钟报警函数 Delay_nms(1); } } /**************定时器0中断程序*****************/ void Timer0() interrupt 1 { static uchar value; TH0 = 0X3C; TL0 = 0XB0; //50ms value ++; if((value % 2) == 0) //100ms flag_100ms = 1; } /****************************************************************/ #ifndef _temp_H_ #define _temp_H_ #include <reg51.h> //---重定义关键词---// #ifndef uchar #define uchar unsigned char #endif #ifndef uint #define uint unsigned int #endif uchar temp; //--定义使用的IO口--// sbit DSPORT=P3^7; /******************************************************************************* * 函 数 名 : Delay1ms * 函数功能 : 延时函数 * 输 入 : 无 * 输 出 : 无 *******************************************************************************/ void Delay1ms(uint y) { uint x; for( ; y>0; y--) { for(x=110; x>0; x--); } } /******************************************************************************* * 函数名 : Ds18b20Init * 函数功能 : 初始化 * 输入 : 无 * 输出 : 初始化成功返回1,失败返回0 *******************************************************************************/ unsigned char Ds18b20Init() { unsigned int i; DSPORT=0; //将总线拉低480us~960us i=70; while(i--);//延时642us DSPORT=1; //然后拉高总线,如果DS18B20做出反应会将在15us~60us后总线拉低 i=0; while(DSPORT) //等待DS18B20拉低总线 { i++; if(i>5000)//等待>5MS return 0;//初始化失败 } return 1;//初始化成功 } /******************************************************************************* * 函数名 : Ds18b20WriteByte * 函数功能 : 向18B20写入一个字节 * 输入 : com * 输出 : 无 *******************************************************************************/ void Ds18b20WriteByte(unsigned char dat) { unsigned int i,j; for(j=0;j<8;j++) { DSPORT=0; //每写入一位数据之前先把总线拉低1us i++; DSPORT=dat&0x01; //然后写入一个数据,从最低位开始 i=6; while(i--); //延时68us,持续时间最少60us DSPORT=1; //然后释放总线,至少1us给总线恢复时间才能接着写入第二个数值 dat>>=1; } } /******************************************************************************* * 函数名 : Ds18b20ReadByte * 函数功能 : 读取一个字节 * 输入 : com * 输出 : 无 *******************************************************************************/ unsigned char Ds18b20ReadByte() { unsigned char byte,bi; unsigned int i,j; for(j=8;j>0;j--) { DSPORT=0;//先将总线拉低1us i++; DSPORT=1;//然后释放总线 i++; i++;//延时6us等待数据稳定 bi=DSPORT; //读取数据,从最低位开始读取 /*将byte左移一位,然后与上右移7位后的bi,注意移动之后移掉那位补0。*/ byte=(byte>>1)|(bi<<7); i=4; //读取完之后等待48us再接着读取下一个数 while(i--); } return byte; } /******************************************************************************* * 函数名 : Ds18b20ChangTemp * 函数功能 : 让18b20开始转换温度 * 输入 : com * 输出 : 无 *******************************************************************************/ void Ds18b20ChangTemp() { Ds18b20Init(); Delay1ms(1); Ds18b20WriteByte(0xcc); //跳过ROM操作命令 Ds18b20WriteByte(0x44); //温度转换命令 // Delay1ms(100); //等待转换成功,而如果你是一直刷着的话,就不用这个延时了 } /******************************************************************************* * 函数名 : Ds18b20ReadTempCom * 函数功能 : 发送读取温度命令 * 输入 : com * 输出 : 无 *******************************************************************************/ void Ds18b20ReadTempCom() { Ds18b20Init(); Delay1ms(1); Ds18b20WriteByte(0xcc); //跳过ROM操作命令 Ds18b20WriteByte(0xbe); //发送读取温度命令 } /******************************************************************************* * 函数名 : Ds18b20ReadTemp * 函数功能 : 读取温度 * 输入 : com * 输出 : 无 *******************************************************************************/ int Ds18b20ReadTemp() { int temp=0; unsigned char tmh,tml; Ds18b20ChangTemp(); //先写入转换命令 Ds18b20ReadTempCom(); //然后等待转换完后发送读取温度命令 tml=Ds18b20ReadByte(); //读取温度值共16位,先读低字节 tmh=Ds18b20ReadByte(); //再读高字节 temp=tmh; temp<<=8; temp|=tml; return temp; } #endif /************************************************************************/ #ifndef _lcd1602_H_ #define _lcd1602_H_ #include<reg51.h> #define LCD1602_DB P0 #define uchar unsigned char #define uint unsigned int #define LCD1602_4PINS //引脚定义 sbit LCD1602_RS = P2^6; sbit LCD1602_RW = P2^5; sbit LCD1602_EN = P2^7; uchar code table_num[]="0123456789abcdefg"; /*延时函数,延时1ms*/ void Lcd1602_Delay1ms(uint c) //误差 0us { uchar a,b; for (; c>0; c--) { for (b=199;b>0;b--) { for(a=1;a>0;a--); } } } /*LCD1602写命令*/ void LCD1602WriteCmd(uchar cmd) { LCD1602_RS = 0; LCD1602_RW = 0; LCD1602_EN = 0; LCD1602_DB = cmd; Lcd1602_Delay1ms(1); //等待数据稳定 LCD1602_EN = 1;//高脉冲 Lcd1602_Delay1ms(5); //等待数据稳定 LCD1602_EN = 0;//关闭液晶输出 LCD1602_DB = cmd<<4; Lcd1602_Delay1ms(1); LCD1602_EN = 1;//高脉冲 Lcd1602_Delay1ms(5); //等待数据稳定 LCD1602_EN = 0;//关闭液晶输出 } void LCD1602WriteData(uchar dat) { LCD1602_RS = 1; LCD1602_RW = 0; LCD1602_EN = 0; LCD1602_DB = dat;//送入数据 Lcd1602_Delay1ms(1); LCD1602_EN = 1;//高脉冲 Lcd1602_Delay1ms(5); LCD1602_EN = 0;//关闭液晶输出 LCD1602_DB = dat<<4; Lcd1602_Delay1ms(1); LCD1602_EN = 1;//高脉冲 Lcd1602_Delay1ms(5); LCD1602_EN = 0;//关闭液晶输出 } /*液晶初始化*/ void InitLCD1602() { LCD1602WriteCmd(0x32); LCD1602WriteCmd(0x28); LCD1602WriteCmd(0x0C); //开显示不显示光标 LCD1602WriteCmd(0x06); //写入字符时字符指针++且光标++ LCD1602WriteCmd(0x01); //显示清屏 } /*在LCD1602的坐标(x, y)位置显示str*/ void LcdShowStr(uchar x, uchar y, uchar * str) { uchar addr; if (y == 0) { addr = 0x00 + x; //第一行的x位置显示 } else { addr = 0x40 + x; //第二行x的位置显示 } LCD1602WriteCmd(addr + 0x80); while (*str != '\0') { LCD1602WriteData(*str++); } } /*在LCD1602的坐标(x, y)位置显示十进制数*/ void LcdShowNum(uchar x, uchar y, uchar dat) { uchar addr; if (y == 0) { addr = 0x00 + x; //第一行的x位置显示 } else { addr = 0x40 + x; //第二行x的位置显示 } LCD1602WriteCmd(addr + 0x80); LCD1602WriteData(table_num[dat/16]); LCD1602WriteData(table_num[dat%16]); } /*光标控制函数*/ void write_guangbiao(uchar x,uchar y,uchar dat) { if(y==0) LCD1602WriteCmd(0x80+x); else LCD1602WriteCmd(0x80+0x40+x); if(dat == 1) LCD1602WriteCmd(0x0f); //显示光标并且闪烁 else LCD1602WriteCmd(0x0c); //关闭光标 } /*屏幕初始化函数*/ void Int_1602_Dis() { LcdShowStr(0,0,"20 - - C"); LcdShowStr(0,1," : : "); } #endif /**********************************************************/ #ifndef _naozhong_H_ #define _naozhong_H_ sbit beep=P1^5; unsigned char alarm_open; //闹钟功能标志 unsigned char fen1=0x00,shi1=0x00,fen2=0x00,shi2=0x00; //两个闹钟变量的定义 unsigned char beep_flag;//闹钟开关标志 bit flag_100ms; unsigned char alarm_open=0; /*************闹钟报警函数***************/ void naozhong_alarm() { static unsigned char t,r; if(flag_100ms == 1) //100ms执行一次 { flag_100ms = 0; if(alarm_open == 1) //如果闹钟打开 { if((miao == 0) && (fen == fen1) && (shi == shi1)) { beep_flag = 1; //有报警 打开蜂鸣器响的标志位 } if(((miao == 0) && (fen == fen2) && (shi == shi2))) { beep_flag = 1; //有报警 打开蜂鸣器响的标志位 } if(beep_flag == 1) //闹钟以被打开 { beep = ~beep; Delay_nms(10); r ++; if(r >= 10) { r = 0; t++; if(t >= 60) { t = 0; beep_flag = 0; beep = 1; } } } } } } #endif /******************************************************/ #ifndef _key_H_ #define _key_H_ #include <reg51.h> #define uchar unsigned char #define uint unsigned int uchar KeyValue; //用来存放读取到的键值 uchar mode_flag; //模式标志 uchar bit_flag; //位标志 bit flag_200ms; void Delay_nms(unsigned int c) //延时1ms { unsigned char a,b; for (; c>0; c--) { for (b=199;b>0;b--) { for(a=1;a>0;a--); } } } //判断按键是否按下 并得到键值 void KeyDown() { static uchar key_new; KeyValue = 20; //按键值还原 P3 |= 0xff; //对应的按键IO口输出为1 if((P3 & 0xff) != 0xff) //按键按下 { Delay_nms(1); //按键消抖动 if(((P3 & 0xff) != 0xff) && (key_new == 1)) { //确认是按键按下 key_new = 0; switch(P3 & 0xff) { case 0xfe: KeyValue = 4; break; //得到按键值 case 0xfd: KeyValue = 3; break; //得到按键值 case 0xfb: KeyValue = 2; break; //得到按键值 case 0xf7: KeyValue = 1; break; //得到按键值 } } } else key_new = 1; } #endif /**********************************************************************/ #ifndef _nongli_H_ #define _nongli_H_ #include <intrins.h> //公历年对应的农历数据,每年三字节, //格式第一字节BIT7-4 位表示闰月月份,值为0 为无闰月,BIT3-0 对应农历第1-4 月的大小 //第二字节BIT7-0 对应农历第5-12 月大小,第三字节BIT7 表示农历第13 个月大小 //月份对应的位为1 表示本农历月大(30 天),为0 表示小(29 天). //第三字节BIT6-5 表示春节的公历月份,BIT4-0 表示春节的公历日期 //********阳历转换阴历表************************************ code unsigned char year_code[597]={ 0x04,0xAe,0x53, //1901 0 0x0A,0x57,0x48, //1902 3 0x55,0x26,0xBd, //1903 6 0x0d,0x26,0x50, //1904 9 0x0d,0x95,0x44, //1905 12 0x46,0xAA,0xB9, //1906 15 0x05,0x6A,0x4d, //1907 18 0x09,0xAd,0x42, //1908 21 0x24,0xAe,0xB6, //1909 0x04,0xAe,0x4A, //1910 0x6A,0x4d,0xBe, //1911 0x0A,0x4d,0x52, //1912 0x0d,0x25,0x46, //1913 0x5d,0x52,0xBA, //1914 0x0B,0x54,0x4e, //1915 0x0d,0x6A,0x43, //1916 0x29,0x6d,0x37, //1917 0x09,0x5B,0x4B, //1918 0x74,0x9B,0xC1, //1919 0x04,0x97,0x54, //1920 0x0A,0x4B,0x48, //1921 0x5B,0x25,0xBC, //1922 0x06,0xA5,0x50, //1923 0x06,0xd4,0x45, //1924 0x4A,0xdA,0xB8, //1925 0x02,0xB6,0x4d, //1926 0x09,0x57,0x42, //1927 0x24,0x97,0xB7, //1928 0x04,0x97,0x4A, //1929 0x66,0x4B,0x3e, //1930 0x0d,0x4A,0x51, //1931 0x0e,0xA5,0x46, //1932 0x56,0xd4,0xBA, //1933 0x05,0xAd,0x4e, //1934 0x02,0xB6,0x44, //1935 0x39,0x37,0x38, //1936 0x09,0x2e,0x4B, //1937 0x7C,0x96,0xBf, //1938 0x0C,0x95,0x53, //1939 0x0d,0x4A,0x48, //1940 0x6d,0xA5,0x3B, //1941 0x0B,0x55,0x4f, //1942 0x05,0x6A,0x45, //1943 0x4A,0xAd,0xB9, //1944 0x02,0x5d,0x4d, //1945 0x09,0x2d,0x42, //1946 0x2C,0x95,0xB6, //1947 0x0A,0x95,0x4A, //1948 0x7B,0x4A,0xBd, //1949 0x06,0xCA,0x51, //1950 0x0B,0x55,0x46, //1951 0x55,0x5A,0xBB, //1952 0x04,0xdA,0x4e, //1953 0x0A,0x5B,0x43, //1954 0x35,0x2B,0xB8, //1955 0x05,0x2B,0x4C, //1956 0x8A,0x95,0x3f, //1957 0x0e,0x95,0x52, //1958 0x06,0xAA,0x48, //1959 0x7A,0xd5,0x3C, //1960 0x0A,0xB5,0x4f, //1961 0x04,0xB6,0x45, //1962 0x4A,0x57,0x39, //1963 0x0A,0x57,0x4d, //1964 0x05,0x26,0x42, //1965 0x3e,0x93,0x35, //1966 0x0d,0x95,0x49, //1967 0x75,0xAA,0xBe, //1968 0x05,0x6A,0x51, //1969 0x09,0x6d,0x46, //1970 0x54,0xAe,0xBB, //1971 0x04,0xAd,0x4f, //1972 0x0A,0x4d,0x43, //1973 0x4d,0x26,0xB7, //1974 0x0d,0x25,0x4B, //1975 0x8d,0x52,0xBf, //1976 0x0B,0x54,0x52, //1977 0x0B,0x6A,0x47, //1978 0x69,0x6d,0x3C, //1979 0x09,0x5B,0x50, //1980 0x04,0x9B,0x45, //1981 0x4A,0x4B,0xB9, //1982 0x0A,0x4B,0x4d, //1983 0xAB,0x25,0xC2, //1984 0x06,0xA5,0x54, //1985 0x06,0xd4,0x49, //1986 0x6A,0xdA,0x3d, //1987 0x0A,0xB6,0x51, //1988 0x09,0x37,0x46, //1989 0x54,0x97,0xBB, //1990 0x04,0x97,0x4f, //1991 0x06,0x4B,0x44, //1992 0x36,0xA5,0x37, //1993 0x0e,0xA5,0x4A, //1994 0x86,0xB2,0xBf, //1995 0x05,0xAC,0x53, //1996 0x0A,0xB6,0x47, //1997 0x59,0x36,0xBC, //1998 0x09,0x2e,0x50, //1999 294 0x0C,0x96,0x45, //2000 297 0x4d,0x4A,0xB8, //2001 0x0d,0x4A,0x4C, //2002 0x0d,0xA5,0x41, //2003 0x25,0xAA,0xB6, //2004 0x05,0x6A,0x49, //2005 0x7A,0xAd,0xBd, //2006 0x02,0x5d,0x52, //2007 0x09,0x2d,0x47, //2008 0x5C,0x95,0xBA, //2009 0x0A,0x95,0x4e, //2010 0x0B,0x4A,0x43, //2011 0x4B,0x55,0x37, //2012 0x0A,0xd5,0x4A, //2013 0x95,0x5A,0xBf, //2014 0x04,0xBA,0x53, //2015 0x0A,0x5B,0x48, //2016 0x65,0x2B,0xBC, //2017 0x05,0x2B,0x50, //2018 0x0A,0x93,0x45, //2019 0x47,0x4A,0xB9, //2020 0x06,0xAA,0x4C, //2021 0x0A,0xd5,0x41, //2022 0x24,0xdA,0xB6, //2023 0x04,0xB6,0x4A, //2024 0x69,0x57,0x3d, //2025 0x0A,0x4e,0x51, //2026 0x0d,0x26,0x46, //2027 0x5e,0x93,0x3A, //2028 0x0d,0x53,0x4d, //2029 0x05,0xAA,0x43, //2030 0x36,0xB5,0x37, //2031 0x09,0x6d,0x4B, //2032 0xB4,0xAe,0xBf, //2033 0x04,0xAd,0x53, //2034 0x0A,0x4d,0x48, //2035 0x6d,0x25,0xBC, //2036 0x0d,0x25,0x4f, //2037 0x0d,0x52,0x44, //2038 0x5d,0xAA,0x38, //2039 0x0B,0x5A,0x4C, //2040 0x05,0x6d,0x41, //2041 0x24,0xAd,0xB6, //2042 0x04,0x9B,0x4A, //2043 0x7A,0x4B,0xBe, //2044 0x0A,0x4B,0x51, //2045 0x0A,0xA5,0x46, //2046 0x5B,0x52,0xBA, //2047 0x06,0xd2,0x4e, //2048 0x0A,0xdA,0x42, //2049 0x35,0x5B,0x37, //2050 0x09,0x37,0x4B, //2051 0x84,0x97,0xC1, //2052 0x04,0x97,0x53, //2053 0x06,0x4B,0x48, //2054 0x66,0xA5,0x3C, //2055 0x0e,0xA5,0x4f, //2056 0x06,0xB2,0x44, //2057 0x4A,0xB6,0x38, //2058 0x0A,0xAe,0x4C, //2059 0x09,0x2e,0x42, //2060 0x3C,0x97,0x35, //2061 0x0C,0x96,0x49, //2062 0x7d,0x4A,0xBd, //2063 0x0d,0x4A,0x51, //2064 0x0d,0xA5,0x45, //2065 0x55,0xAA,0xBA, //2066 0x05,0x6A,0x4e, //2067 0x0A,0x6d,0x43, //2068 0x45,0x2e,0xB7, //2069 0x05,0x2d,0x4B, //2070 0x8A,0x95,0xBf, //2071 0x0A,0x95,0x53, //2072 0x0B,0x4A,0x47, //2073 0x6B,0x55,0x3B, //2074 0x0A,0xd5,0x4f, //2075 0x05,0x5A,0x45, //2076 0x4A,0x5d,0x38, //2077 0x0A,0x5B,0x4C, //2078 0x05,0x2B,0x42, //2079 0x3A,0x93,0xB6, //2080 0x06,0x93,0x49, //2081 0x77,0x29,0xBd, //2082 0x06,0xAA,0x51, //2083 0x0A,0xd5,0x46, //2084 0x54,0xdA,0xBA, //2085 0x04,0xB6,0x4e, //2086 0x0A,0x57,0x43, //2087 0x45,0x27,0x38, //2088 0x0d,0x26,0x4A, //2089 0x8e,0x93,0x3e, //2090 0x0d,0x52,0x52, //2091 0x0d,0xAA,0x47, //2092 0x66,0xB5,0x3B, //2093 0x05,0x6d,0x4f, //2094 0x04,0xAe,0x45, //2095 0x4A,0x4e,0xB9, //2096 0x0A,0x4d,0x4C, //2097 0x0d,0x15,0x41, //2098 0x2d,0x92,0xB5, //2099 }; ///月份数据表 code unsigned int day_code[12]={0x00,0x1f,0x3b,0x5a,0x78,0x97,0xb5,0xd4,0xf3,0x111,0x130,0x14e}; bit c_moon; //世纪 unsigned char year_moon,month_moon,day_moon; //判断农历月的大月或小月,如果该月为大返回1,为小返回0 bit get_moon_day(unsigned char month_p,unsigned int table_addr) { unsigned char temp; switch (month_p){ case 1:{temp=year_code[table_addr]&0x08; if (temp==0)return(0);else return(1);} case 2:{temp=year_code[table_addr]&0x04; if (temp==0)return(0);else return(1);} case 3:{temp=year_code[table_addr]&0x02; if (temp==0)return(0);else return(1);} case 4:{temp=year_code[table_addr]&0x01; if (temp==0)return(0);else return(1);} case 5:{temp=year_code[table_addr+1]&0x80; if (temp==0) return(0);else return(1);} case 6:{temp=year_code[table_addr+1]&0x40; if (temp==0)return(0);else return(1);} case 7:{temp=year_code[table_addr+1]&0x20; if (temp==0)return(0);else return(1);} case 8:{temp=year_code[table_addr+1]&0x10; if (temp==0)return(0);else return(1);} case 9:{temp=year_code[table_addr+1]&0x08; if (temp==0)return(0);else return(1);} case 10:{temp=year_code[table_addr+1]&0x04; if (temp==0)return(0);else return(1);} case 11:{temp=year_code[table_addr+1]&0x02; if (temp==0)return(0);else return(1);} case 12:{temp=year_code[table_addr+1]&0x01; if (temp==0)return(0);else return(1);} case 13:{temp=year_code[table_addr+2]&0x80; if (temp==0)return(0);else return(1);} } return(0); } /* 函数功能:输入BCD阳历数据,输出BCD阴历数据(只允许1901-2099年) 调用函数示例:Conversion(c_sun,year_sun,month_sun,day_sun) 如:计算2004年10月16日Conversion(0,0x4,0x10,0x16); c_sun,year_sun,month_sun,day_sun均为BCD数据,c_sun为世纪标志位,c_sun=0为21世 纪,c_sun=1为19世纪 调用函数后,原有数据不变,读c_moon,year_moon,month_moon,day_moon得出阴历BCD数据 */ void Conversion(bit c,unsigned char year,unsigned char month,unsigned char day)//公历日期 { //c=0 为21世纪,c=1 为19世纪 输入输出数据均为BCD数据 unsigned char temp1,temp2,temp3,month_p; unsigned int temp4,table_addr; bit flag2,flag_y; temp1=year/16; //BCD->hex 先把数据转换为十六进制 temp2=year%16; year=temp1*10+temp2; temp1=month/16; temp2=month%16; month=temp1*10+temp2; temp1=day/16; temp2=day%16; day=temp1*10+temp2; //定位数据表地址 if(c==0){ table_addr=(year+0x64-1)*0x03; //19..年 } else { table_addr=(year-1)*0x03; } //取当年春节所在的公历月份 temp1=year_code[table_addr+2]&0x60; temp1=_cror_(temp1,5); //取当年春节所在的公历日 temp2=year_code[table_addr+2]&0x1f; // 计算当年春年离当年元旦的天数,春节只会在公历1月或2月 if(temp1==0x01){ temp3=temp2-1; } else{ temp3=temp2+0x1f-1; } // 计算当年春年离当年元旦的天数完成 //计算公历日离当年元旦的天数 temp4=day_code[month-1]+day-1; if ((year%0x04==0)||((year%0x64)&&(year%0x190))) //闰年 { if((month>0x02)) //月份超过2 temp4+=1; } //判断公历日在春节前还是春节后 if (temp4>=temp3) { //公历日在春节后或就是春节当日使用下面代码进行运算 temp4-=temp3; month=0x01; month_p=0x01; //month_p为农历月份指向,公历日在春节前或就是春节当日month_p指向首月 flag2=get_moon_day(month_p,table_addr); //检查该农历月为大小还是小月,大月返回1,小月返回0 flag_y=0; if(flag2==0) temp1=0x1d; //小月29天 else temp1=0x1e; //大月30天 temp2=year_code[table_addr]&0xf0; temp2=_cror_(temp2,4); //从数据表中取该年的闰月月份,如为0则该年无闰月 while(temp4>=temp1){ temp4-=temp1; month_p+=1; if(month==temp2) { flag_y=~flag_y; //闰了该月,月份数值不加 if(flag_y==0) month+=1; } else month+=1; flag2=get_moon_day(month_p,table_addr); if(flag2==0) temp1=0x1d; else temp1=0x1e; } day=temp4+1; } else { //公历日在春节前使用下面代码进行运算 temp3-=temp4; if (year==0x00) //是否在21世纪 {year=0x63;c=1;} else year-=1; table_addr-=0x03; month=0x0c; temp2=year_code[table_addr]&0xf0; //闰月月份 temp2=_cror_(temp2,4); if (temp2==0) //无闰月 month_p=0x0c; //指向12月 else month_p=0x0d; // 指向13月 //month_p为月份指向,如果当年有闰月,一年有十三个月,月指向13,无闰月指向12 flag_y=0; flag2=get_moon_day(month_p,table_addr); if(flag2==0) temp1=0x1d; else temp1=0x1e; while(temp3>temp1) { temp3-=temp1; month_p-=1; if(flag_y==0) month-=1; if(month==temp2) flag_y=~flag_y; flag2=get_moon_day(month_p,table_addr); if(flag2==0) temp1=0x1d; else temp1=0x1e; } day=temp1-temp3+1; } c_moon=c; //HEX->BCD ,运算结束后,把数据转换为BCD数据 temp1=year/10; temp1=_crol_(temp1,4); temp2=year%10; year_moon=temp1|temp2; temp1=month/10; temp1=_crol_(temp1,4); temp2=month%10; month_moon=temp1|temp2; temp1=day/10; temp1=_crol_(temp1,4); temp2=day%10; day_moon=temp1|temp2; } #endif ```

汇编语言时钟闹钟 急急急

求一个用汇编语言编写的表盘时钟,有闹钟功能 ![图片说明](https://img-ask.csdn.net/upload/201512/10/1449730453_336800.jpg)

51单片机矩阵键盘与八位共阴数码管问题求指点

目标是实现根据矩阵键盘输入内容显示对应的数字(0到f),如按下S1->S8会显示0->7八个数字,在上述情况下按下S9后会显示1->8八位数,再按下S10后会显示2->9;按S16清除数码管显示内容; 出现问题:当八位数码管都有数字时按下下一个按键后会覆盖最后一位,但第一位不会被移出显示屏;![图片说明](https://img-ask.csdn.net/upload/201703/28/1490663857_889903.jpg)![图片说明](https://img-ask.csdn.net/upload/201703/28/1490663880_521750.jpg)![图片说明](https://img-ask.csdn.net/upload/201703/28/1490663898_329589.jpg) ``` // 内容:如计算器输入数据形式相同 从右至左 使用行列扫描方法 ------------------------------------------------*/ #include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义 #include <intrins.h> #define KeyPort P2 sbit LATCH = P1^2; //SER 串行数据 sbit SRCLK= P1^1; //SCK 串行时钟信号 sbit SER = P1^0; //ST 锁存输出信号 unsigned char code dofly_DuanMa[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f, 0x77,0x7c,0x39,0x5e,0x79,0x71};// 显示段码值0~F unsigned char code dofly_WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码 unsigned char TempData[10]; //存储显示值的全局变量 void DelayUs2x(unsigned char t);//us级延时函数声明 void DelayMs(unsigned char t); //ms级延时 void Display(unsigned char FirstBit,unsigned char Num);//数码管显示函数 unsigned char KeyScan(void);//键盘扫描 unsigned char KeyPro(void); void Init_Timer0(void);//定时器初始化 /*------------------------------------------------ 主函数 ------------------------------------------------*/ void main (void) { unsigned char num,i,j; unsigned char temp[8]; Init_Timer0(); while (1) //主循环 { num=KeyPro(); if(num!=0xff) { if(i<8) { temp[i]=dofly_DuanMa[num]; for(j=0;j<=i;j++) TempData[7-i+j]=temp[j]; } i++; if(i==8)//多出一个按键输入为了清屏 原本应该为8 { i=0; if(j==500) { j=0; num++; if(num==9) num=0; } } } } /*------------------------------------------------ uS延时函数,含有输入参数 unsigned char t,无返回值 unsigned char 是定义无符号字符变量,其值的范围是 0~255 这里使用晶振12M,精确延时请使用汇编,大致延时 长度如下 T=tx2+5 uS ------------------------------------------------*/ void DelayUs2x(unsigned char t) { while(--t); } /*------------------------------------------------ mS延时函数,含有输入参数 unsigned char t,无返回值 unsigned char 是定义无符号字符变量,其值的范围是 0~255 这里使用晶振12M,精确延时请使用汇编 ------------------------------------------------*/ void DelayMs(unsigned char t) { while(t--) { //大致延时1mS DelayUs2x(245); DelayUs2x(245); } } /*------------------------------------------------ 发送字节程序 ------------------------------------------------*/ void hc595SendByte(unsigned char dat) { unsigned char i; for(i=0; i<8; i++) { SRCLK=0; SER=dat&0x80; dat<<=1; SRCLK=1; } } /*------------------------------------------------ 发送双字节程序 595级联,n个595,就需要发送n字节后锁存 ------------------------------------------------*/ void Send2Byte(unsigned char dat1,unsigned char dat2) { hc595SendByte(dat1); hc595SendByte(dat2); } /*------------------------------------------------ 595锁存程序 595级联发送数据后,锁存有效 ------------------------------------------------*/ void Out595(void) { LATCH=1; _nop_(); LATCH=0; } /*------------------------------------------------ 显示函数,用于动态扫描数码管 输入参数 FirstBit 表示需要显示的第一位,如赋值2表示从第三个数码管开始显示 如输入0表示从第一个显示。 Num表示需要显示的位数,如需要显示99两位数值则该值输入2 ------------------------------------------------*/ void Display(unsigned char FirstBit,unsigned char Num) { static unsigned char i=0; Send2Byte(dofly_WeiMa[i+FirstBit],TempData[i]); Out595(); i++; if(i==Num) i=0; } /*------------------------------------------------ 定时器初始化子程序 ------------------------------------------------*/ void Init_Timer0(void) { TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响 //TH0=0x00; //给定初值 //TL0=0x00; EA=1; //总中断打开 ET0=1; //定时器中断打开 TR0=1; //定时器开关打开 } /*------------------------------------------------ 定时器中断子程序 ------------------------------------------------*/ void Timer0_isr(void) interrupt 1 { TH0=(65536-2000)/256; //重新赋值 2ms TL0=(65536-2000)%256; Display(0,8); // 调用数码管扫描 } /*------------------------------------------------ 按键扫描函数,返回扫描键值 ------------------------------------------------*/ unsigned char KeyScan(void) //键盘扫描函数,使用行列逐级扫描法 { unsigned char Val; KeyPort=0xf0;//高四位置高,低四位拉低 if(KeyPort!=0xf0)//表示有按键按下 { DelayMs(10); //去抖 if(KeyPort!=0xf0) { //表示有按键按下 KeyPort=0xfe; //检测第一行 if(KeyPort!=0xfe) { Val=KeyPort&0xf0; Val+=0x0e; while(KeyPort!=0xfe); DelayMs(10); //去抖 while(KeyPort!=0xfe); return Val; } KeyPort=0xfd; //检测第二行 if(KeyPort!=0xfd) { Val=KeyPort&0xf0; Val+=0x0d; while(KeyPort!=0xfd); DelayMs(10); //去抖 while(KeyPort!=0xfd); return Val; } KeyPort=0xfb; //检测第三行 if(KeyPort!=0xfb) { Val=KeyPort&0xf0; Val+=0x0b; while(KeyPort!=0xfb); DelayMs(10); //去抖 while(KeyPort!=0xfb); return Val; } KeyPort=0xf7; //检测第四行 if(KeyPort!=0xf7) { Val=KeyPort&0xf0; Val+=0x07; while(KeyPort!=0xf7); DelayMs(10); //去抖 while(KeyPort!=0xf7); return Val; } } } return 0xff; } /*------------------------------------------------ 按键值处理函数,返回扫键值 ------------------------------------------------*/ unsigned char KeyPro(void) { switch(KeyScan()) { case 0x7e:return 0;break;//0 按下相应的键显示相对应的码值 case 0x7d:return 1;break;//1 case 0x7b:return 2;break;//2 case 0x77:return 3;break;//3 case 0xbe:return 4;break;//4 case 0xbd:return 5;break;//5 case 0xbb:return 6;break;//6 case 0xb7:return 7;break;//7 case 0xde:return 8;break;//8 case 0xdd:return 9;break;//9 case 0xdb:return 10;break;//a case 0xd7:return 11;break;//b case 0xee:return 12;break;//c case 0xed:return 13;break;//d case 0xeb:return 14;break;//e case 0xe7:return 15;break;//f default:return 0xff;break; } } ```

按键中断一直死循环,咋搞?

1、C语言编写的KL26Z256芯片,Blue Chip -Blazar-bata实验板,编写的外部按键中断,初始化完毕就进入中断,退出后又进入中断,没有错误信息 2、初始化代码: void main (void){ SIM_SCGC5|=((1<<9)+(1<<10));//PORTA、B时钟 GPIOA_PDDR &= ~0x83020;//左侧按键对应PTA19、12、5、13通道读 asm("CPSIE i");//中断总开关 NVIC_ISER |= 0x40000000;//PORTA中断子开关 //键按下时中断,其他为下降沿中断 PORTA_PCR19 = 0x0A0102; PORTA_PCR5 = 0x0A0102; PORTA_PCR12 = 0x0A0102; PORTA_PCR13 = 0x080102; } //外部中断子程序 void PORTA_IRQHandler(void) { delay();//延时消抖 //按键设置时长加a if((GPIOA_PDIR & 0x80000)==0){ ........ } //清除中断标志位 PORTA_PCR1|=0x01000000; PORTA_PCR5|=0x01000000; PORTA_PCR12|=0x01000000; PORTA_PCR13|=0x01000000; } 3、第一次写,望大佬们多多包涵指正,感谢

51单片机十字路口交通灯设计 求问

明天就要课设答辩了 影响着自己毕业。求大神帮我讲解一下这个程序 谢谢了 ``` #include <reg51.h> #include<absacc.h> #define COM XBYTE[0xCFE9] #define DAT XBYTE[0xCFE8] void Init_8279(void); void led_display(void); void Key_Scan(void); void key_action(void); void led_init_status(void); void delay(void); unsigned char led_buf[8]; //数码管显示缓冲数组 unsigned char KeyVal = 0x00; //当前按键的键值 unsigned char led_char[17] = { //数码管数字真值表 0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71, }; sbit R_LED1 = P1^0; sbit G_LED1 = P1^1; sbit Y_LED1 = P1^2; sbit Y_LED3 = P1^3; sbit R_LED2 = P1^4; sbit G_LED2 = P1^5; sbit Y_LED2 = P1^6; sbit Y_LED4 = P1^7; int main(void) { TMOD = 0x01; //定时器模式设置 TH0 = 0xfc; TL0 = 0x18; TR0 = 1; EA = 1; //总中断使能 ET0 = 1; //定时器中断0使能 Init_8279(); while(1) { Key_Scan(); //按键扫描函数 } } void Init_8279(void) { COM = 0xd1; //总清除命令 do { ACC = COM; } //读取8279状态 while(ACC^7 == 1); //等待清除结束 COM = 0x00; //8个字符显示,左入口;,双键锁定 COM = 0x2a; //时钟分频 } //数码管显示函数,实现数码管动态扫描 void led_display(void) { static unsigned char j = 0; //静态局部变量,只初始化一次, COM = 0x82 + j; //发送显示地址,0x80为左一,程序里0x80,0x81数码管未使用,j = 0时,显示0x82位置的数码管,j=1时83,。。。 DAT = led_buf[j]; //依次把缓冲数组的内容显示 j++; if(j >= 4) //四个数码管 j = 0; } //按键扫描函数, 主循环调用 void Key_Scan(void) { unsigned char temp = 0; while((temp & 0x0f) == 0) //没有检测到按键程序停在这里,中断服务函数负责完成其他工作 { temp = COM; } //能执行到此处说明检测到了按键 COM = 0x40; //读按键值命令 KeyVal = DAT; //取键值 KeyVal &= 0x0f; //取低4位 KeyVal += 1; //因为按下第一个按键时,得到的键值位0x00,加一为了后面方便操作 key_action(); //检测到按键,并执行相应动作 } unsigned long sec_1s = 0; //全局时间,赋值多少当前秒是多少 unsigned char xingren = 0; unsigned char sec_1s_bak = 0; unsigned char bianhuan = 40; void key_action(void) {if(KeyVal == 0x01) {xingren = 1; sec_1s_bak = sec_1s; sec_1s = 0; } if(KeyVal == 0x02) {bianhuan = 40; sec_1s = 0; } if(KeyVal == 0x03) {bianhuan = 20; sec_1s = 0; } if(KeyVal == 0x04) {bianhuan = 10; sec_1s = 0; } } unsigned long ms2 = 0; //2ms计数 bit dir = 1; void InterruptTimer0() interrupt 1 { TH0 = 0xfc; //重新装在定时器的值 TL0 = 0x18; ms2++; //进来一次表示2ms if(ms2 >= 500) //累计500次则表示1s { ms2 = 0; //归零 sec_1s++; //1s计数器 加一 if(xingren == 1) { R_LED1 = 0; G_LED1 = 1; Y_LED1 = 1; Y_LED3 = 1; R_LED2 = 0; G_LED2 = 1; Y_LED2 = 1; Y_LED4 = 1; led_buf[2] = led_char[0]; led_buf[3] = led_char[10 - sec_1s]; if(sec_1s == 9) { xingren = 0; P1 = 0XFF; sec_1s = sec_1s_bak; } } else if(sec_1s >= 0 && sec_1s <= bianhuan) { if(dir) { R_LED1 = 0; G_LED2 = 0; } else { R_LED2 = 0; G_LED1 = 0; } led_buf[2] = led_char[(bianhuan + 1 - sec_1s)/10]; led_buf[3] = led_char[(bianhuan + 1 - sec_1s)%10]; } else if(sec_1s >= bianhuan && sec_1s <= bianhuan + 4) { R_LED1 = 1; G_LED1 = 1; Y_LED1 = 0; Y_LED3 = 0; R_LED2 = 1; G_LED2 = 1; Y_LED2 = 0; Y_LED4 = 0; led_buf[0] = led_char[0]; led_buf[1] = led_char[4 - sec_1s%10]; if(sec_1s == bianhuan + 4) { sec_1s = 0; dir = ~dir; Y_LED1 = 1; Y_LED3 = 1; Y_LED2 = 1; Y_LED4 = 1; } } } led_display(); //刷新数码管显示,放在中断中保证及时刷新显示 } ```

C51单片机程控滤波器的程序

#include <reg52.h> #include "i2c.h" #include "delay.h" #include "display.h" #include "key.h" #define AddWr 0x90 #define AddRd 0x91 sbit P00=P0^0; sbit P01=P0^1; sbit P02=P0^2; sbit P03=P0^3; sbit P04=P0^4; extern bit ack; unsigned char ReadADC(unsigned char Chl); /*------------------------------------------------ 读AD转值程序 输入参数 Chl 表示需要转换的通道,范围从0-3 返回值范围0-255 ------------------------------------------------*/ unsigned char ReadADC(unsigned char Chl) { unsigned char Val; Start_I2c(); SendByte(AddWr); if(ack==0)return(0); SendByte(0x40|Chl); if(ack==0)return(0); Start_I2c(); SendByte(AddWr+1); if(ack==0)return(0); Val=RcvByte(); NoAck_I2c(); Stop_I2c(); return(Val); } /*------------------------------------------------ 主程序 ------------------------------------------------*/ main() { unsigned char Chl; unsigned char num=0; P35=0; Init_Timer0(); P3 = 0x0F; //按键初始化 0000 1111 while (1) //主循环 { KeyScan(); /*按键控制电压输出0~2V变化 并在数码管上显示*/ DelayMs(100); Display(0,4); num=ReadADC(0);/*AD转换 I/O口输出实时电压变化*/ DelayMs(100); ShowData(ReadADC(Chl),TempData); Display(0,4); P00=SetDACOut(ReadADC(Chl)); /*5个I/O口分别输出5v电压*/ P01=SetDACOut(ReadADC(Chl)); P02=SetDACOut(ReadADC(Chl)); P03=SetDACOut(ReadADC(Chl)); P04=SetDACOut(ReadADC(Chl)); } } #include "i2c.h" #include "delay.h" #define _Nop() _nop_() //定义空指令 bit ack; //应答标志位 sbit SDA=P3^6; sbit SCL=P3^7; /*------------------------------------------------ 启动总线 ------------------------------------------------*/ void Start_I2c() { SDA=1; //发送起始条件的数据信号——SCL为高电平期间,SDA由高电平变为低电平 _Nop(); SCL=1; _Nop(); //起始条件建立时间大于4.7us,延时 _Nop(); _Nop(); _Nop(); _Nop(); SDA=0; //发送起始信号 _Nop(); //起始条件锁定时间大于4μ _Nop(); _Nop(); _Nop(); _Nop(); SCL=0; //钳住I2C总线,准备发送或接收数据 _Nop(); _Nop(); } /*------------------------------------------------ 结束总线 ------------------------------------------------*/ void Stop_I2c() { SDA=0; //发送结束条件的数据信号——SCL为高电平期间,SDA由低电平变为高电平 _Nop(); //发送结束条件的时钟信号 SCL=1; //结束条件建立时间大于4μ _Nop(); _Nop(); _Nop(); _Nop(); _Nop(); SDA=1; //发送I2C总线结束信号 _Nop(); _Nop(); _Nop(); _Nop(); } /*---------------------------------------------------------------- 字节数据传送函数 函数原型: void SendByte(unsigned char c); 功能: 将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对 此状态位进行操作.(不应答或非应答都使ack=0 假) 发送数据正常,ack=1; ack=0表示被控器无应答或损坏。 ------------------------------------------------------------------*/ void SendByte(unsigned char c) { unsigned char BitCnt; for(BitCnt=0;BitCnt<8;BitCnt++) //要传送的数据长度为8位 { if((c<<BitCnt)&0x80)SDA=1; //判断发送位&是二进制运算符,c左移后和1000000相与, else SDA=0; //例如C=10101010,那么 1 0 1 0 1 0 1 0&1 0 0 0 0 0 0 0=1 0 0 0 0 0 0 0 此时if语句判断为真,则sda =1;发送出去 _Nop();//接着执行循环,C在左移一位后为 0 1 0 1 0 1 0 0和0x80相与结果为 0 0 0 0 0 0 0 0 if语句判断为0,则sda=0 发送出去。 SCL=1; //置时钟线为高,通知被控器开始接收数据位 _Nop(); _Nop(); //保证时钟高电平周期大于4μ _Nop(); _Nop(); _Nop(); SCL=0; } _Nop(); _Nop(); SDA=1; //8位发送完后释放数据线,准备接收应答位 _Nop(); _Nop(); SCL=1; _Nop(); _Nop(); _Nop(); if(SDA==1)ack=0; else ack=1; //判断是否接收到应答信号 SCL=0; _Nop(); _Nop(); } /******************************************* * 设置DAC输出值 * DA转换 * ********************************************/ bit SetDACOut(unsigned char Val) { Start_I2c(); //启动总线 SendByte(0x90); //发送器件地址 if(ack==0) return 1; SendByte(0x40); //写入控制字节 if(ack==0) return 1; SendByte(Val); if(ack==0) return 1; Stop_I2c(); //结束总线 return 0; } /*---------------------------------------------------------------- 字节数据传送函数 函数原型: unsigned char RcvByte(); 功能: 用来接收从器件传来的数据,并判断总线错误(不发应答信号), 发完后请用应答函数。 ------------------------------------------------------------------*/ unsigned char RcvByte() { unsigned char retc; unsigned char BitCnt; retc=0; SDA=1; //置数据线为输入方式 for(BitCnt=0;BitCnt<8;BitCnt++) { _Nop(); SCL=0; //置时钟线为低,准备接收数据位 _Nop(); _Nop(); //时钟低电平周期大于4.7us _Nop(); _Nop(); _Nop(); SCL=1; //置时钟线为高使数据线上数据有效 _Nop(); _Nop(); retc=retc<<1; if(SDA==1)retc=retc+1; //读数据位,接收的数据位放入retc中 _Nop(); _Nop(); } SCL=0; _Nop(); _Nop(); return(retc); } /*---------------------------------------------------------------- 应答子函数 原型: void Ack_I2c(void); ----------------------------------------------------------------*/ /*void Ack_I2c(void) { SDA=0; _Nop(); _Nop(); _Nop(); SCL=1; _Nop(); _Nop(); //时钟低电平周期大于4μ _Nop(); _Nop(); _Nop(); SCL=0; //清时钟线,钳住I2C总线以便继续接收 _Nop(); _Nop(); }*/ /*---------------------------------------------------------------- 非应答子函数 原型: void NoAck_I2c(void); ----------------------------------------------------------------*/ void NoAck_I2c(void) { SDA=1; _Nop(); _Nop(); _Nop(); SCL=1; _Nop(); _Nop(); //时钟低电平周期大于4μ _Nop(); _Nop(); _Nop(); SCL=0; //清时钟线,钳住I2C总线以便继续接收 _Nop(); _Nop(); } /*---------------------------------------------------------------- 向无子地址器件发送字节数据函数 函数原型: bit ISendByte(unsigned char sla,ucahr c); 功能: 从启动总线到发送地址,数据,结束总线的全过程,从器件地址sla. 如果返回1表示操作成功,否则操作有误。 注意: 使用前必须已结束总线。 ----------------------------------------------------------------*/ /*bit ISendByte(unsigned char sla,unsigned char c) { Start_I2c(); //启动总线 SendByte(sla); //发送器件地址 if(ack==0)return(0); SendByte(c); //发送数据 if(ack==0)return(0); Stop_I2c(); //结束总线 return(1); } */ /*---------------------------------------------------------------- 向有子地址器件发送多字节数据函数 函数原型: bit ISendStr(unsigned char sla,unsigned char suba,ucahr *s,unsigned char no); 功能: 从启动总线到发送地址,子地址,数据,结束总线的全过程,从器件 地址sla,子地址suba,发送内容是s指向的内容,发送no个字节。 如果返回1表示操作成功,否则操作有误。 注意: 使用前必须已结束总线。 ----------------------------------------------------------------*/ /*bit ISendStr(unsigned char sla,unsigned char suba,unsigned char *s,unsigned char no) { unsigned char i; for(i=0;i<no;i++) { Start_I2c(); //启动总线 SendByte(sla); //发送器件地址 if(ack==0)return(0); SendByte(suba); //发送器件子地址 if(ack==0)return(0); SendByte(*s); //发送数据 if(ack==0)return(0); Stop_I2c(); //结束总线 DelayMs(1); //必须延时等待芯片内部自动处理数据完毕 s++; suba++; } return(1); } */ /*---------------------------------------------------------------- 向无子地址器件读字节数据函数 函数原型: bit IRcvByte(unsigned char sla,ucahr *c); 功能: 从启动总线到发送地址,读数据,结束总线的全过程,从器件地 址sla,返回值在c. 如果返回1表示操作成功,否则操作有误。 注意: 使用前必须已结束总线。 ----------------------------------------------------------------*/ /*bit IRcvByte(unsigned char sla,unsigned char *c) { Start_I2c(); //启动总线 SendByte(sla+1); //发送器件地址 if(ack==0)return(0); *c=RcvByte(); //读取数据 NoAck_I2c(); //发送非就答位 Stop_I2c(); //结束总线 return(1); } */ /*---------------------------------------------------------------- 向有子地址器件读取多字节数据函数 函数原型: bit ISendStr(unsigned char sla,unsigned char suba,ucahr *s,unsigned char no); 功能: 从启动总线到发送地址,子地址,读数据,结束总线的全过程,从器件 地址sla,子地址suba,读出的内容放入s指向的存储区,读no个字节。 如果返回1表示操作成功,否则操作有误。 注意: 使用前必须已结束总线。 ----------------------------------------------------------------*/ /*bit IRcvStr(unsigned char sla,unsigned char suba,unsigned char *s,unsigned char no) { unsigned char i; Start_I2c(); //启动总线 SendByte(sla); //发送器件地址 if(ack==0)return(0); SendByte(suba); //发送器件子地址 if(ack==0)return(0); Start_I2c(); SendByte(sla+1); if(ack==0)return(0); for(i=0;i<no-1;i++) { *s=RcvByte(); //发送数据 Ack_I2c(); //发送就答位 s++; } *s=RcvByte(); NoAck_I2c(); //发送非应位 Stop_I2c(); //结束总线 return(1); } */ #include"key.h" #include"delay.h" #include"i2c.h" #include"display.h" sbit S17=P3^3; //独立按键 sbit S18=P3^2; sbit S19=P3^1; sbit S20=P3^0; unsigned char TempData[8]; /*------------------------------------------------ 按键扫描函数,返回扫描键值 程控放大倍数 ------------------------------------------------*/ unsigned char KeyScan() { static unsigned char volt = 0; if(!S20) //如果检测到低电平,说明按键按下 { /*sbit S20=P3^0; 依次-6*/ DelayMs(10); //延时去抖,一般10-20ms if(!S20) //再次确认按键是否按下,没有按下则退出 { while(!S20);//如果确认按下按键等待按键释放,没有释放则一直等待 { if(volt<255) /*不同按键输出的不同电压不懂*/ { volt=volt+500; SetDACOut(volt*0.51);//转换为AD输出值 TempData[8]=volt*0.51; ShowData((unsigned char)(volt*0.51),TempData); Display(0,4); } } return (1); } } if(!S19) //如果检测到低电平,说明按键按下 { /*依次+6*/ DelayMs(10); //延时去抖,一般10-20ms if(!S19) //再次确认按键是否按下,没有按下则退出 { while(!S19);//如果确认按下按键等待按键释放,没有释放则一直等待 { if(volt>0) { volt=volt-500; SetDACOut(volt*0.51); TempData[8]=volt*0.51; ShowData((unsigned char)(volt*0.51),TempData); Display(0,4); } } return (2); } } if(!S18) //如果检测到低电平,说明按键按下 { /*乱跳????*/ DelayMs(10); //延时去抖,一般10-20ms if(!S18) //再次确认按键是否按下,没有按下则退出 { while(!S18);//如果确认按下按键等待按键释放,没有释放则一直等待 { if(volt<255) { volt=volt+100; SetDACOut(volt*0.51); TempData[8]=volt*0.51; ShowData((unsigned char)(volt*0.51),TempData); Display(0,4); } } return (3); } } if(!S17) //如果检测到低电平,说明按键按下 { /*乱跳????*/ DelayMs(10); //延时去抖,一般10-20ms if(!S17) //再次确认按键是否按下,没有按下则退出 { while(!S17);//如果确认按下按键等待按键释放,没有释放则一直等待 { if(volt>0) { volt=volt-100; SetDACOut(volt*0.51); TempData[8]=volt*0.51; ShowData((unsigned char)(volt*0.51),TempData); Display(0,4); } } return (4); } } return 0; } 下载程序到单片机后,数码管显示值自动跳转 且无规律 不知道哪里出错了?菜鸟求大神解答 万分感谢!

51单片机数码管动态显示的问题

我想比如在数码管输出5201314的话,采用动态刷新,用delay函数,但是现在发现一个问题,我把delay的时间设置的越短越不抖动,但为什么不加delay却显示不对了呢?我认为不加delay就是delay的时间无限短,那不应该显示的更清楚更不抖动么?好疑惑 #include<reg52.h> sbit duan=P2^6; sbit wei=P2^7; //#define a 200 void delay(unsigned int i) { while(--i); } void main() { while(1) { P0=0xfe; wei=1; wei=0; P0=0x6D; duan=1; duan=0; //delay(a); P0=0xfd; wei=1; wei=0; P0=0x5B; duan=1; duan=0; //delay(a); P0=0xfb; wei=1; wei=0; P0=0x3f; duan=1; duan=0; //delay(a); P0=0xf7; wei=1; wei=0; P0=0x06; duan=1; duan=0; //delay(a); P0=0xef; wei=1; wei=0; P0=0x4f; duan=1; duan=0; //delay(a); P0=0xdf; wei=1; wei=0; P0=0x06; duan=1; duan=0; //delay(a); P0=0xbf; wei=1; wei=0; P0=0x66; duan=1; duan=0; //delay(a); } }

lcd设计电子时钟protues ,keil编程

以AT89C51单片机为核心的时钟,在LCD显示器上显示当前的时间:使用字符型LCD显示器显示当前时间。显示格式为“时时:分分:秒秒”。用4个功能键操作来设置当前时间。功能键K1~K4功能如下。 K1—进入设置现在的时间。 K2—设置小时。 K3—设置分钟。 K4—确认完成设置。 程序执行后工作指示灯LED闪动,表示程序开始执行,LCD显示“00:00:00”,然后开始计时。c语言编程

如何通过串口修改时钟的时间

请问大神们如何在这个程序里添加串口来改变时钟啊 #include<reg51.h> #include<absacc.h> #define uchar unsigned char #define uint unsigned int /*七段共阴管显示定义*/ //此表为 LED 的字模, 共阴数码管 0-9 - uchar code dispcode[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40}; //段码控制 /*定义并初始化变量*/ uchar seconde=0;//秒 uchar minite=0;//分 uchar hour=12; //时 uchar mstcnt=0;//定时器计数,定时50ms,mstcnt满20,秒加1 uchar shi=0;//闹铃功能 uchar fen=0; uchar bjcs;//报警次数 sbit P1_0=P1^0; //second 调整定义 sbit P1_1=P1^1; //minite调整定义 sbit P1_2=P1^2; //hour调整定义 sbit P1_5=P3^0; //整点报时 sbit P1_3=P1^3; //闹铃功能,调整时间 sbit P1_6=P1^6; //调整时 sbit P1_7=P1^7; //调整分 sbit P1_4=P1^4; //关闭闹铃 /*函数声明*/ void delay(uint k ); //延时子程序 void time_pro( ); //时间处理子程序 void display( ); //显示子程序 void keyscan( ); //键盘扫描子程序 /*延时子程序*/ void delay (uint k) { uchar j; while((k--)!=0) { for(j=0;j<125;j++) {;} } } /*时间处理子程序*/ void time_pro(void) { if(seconde==60) { seconde=0; minite++; if(minite==60) { minite=0; hour++; if(hour==24) { hour=0; } } } } /*显示子程序*/ void display(void) { if(P1_3==1) { P2=0XFE; P0=dispcode[seconde%10];//秒个位 delay(1); P2=0XFD; P0=dispcode[seconde/10];//秒十位 delay(1); P2=0XFB; P0=dispcode[10];//间隔符 - delay(1); P2=0XF7; P0=dispcode[minite%10];//分个位 delay(1); P2=0XEF; P0=dispcode[minite/10];//分十位 delay(1); P2=0XDF; P0=dispcode[10];//间隔符 - delay(1); P2=0XBF; P0=dispcode[hour%10];//时个位 delay(1); P2=0X7F; P0=dispcode[hour/10];//时十位 delay(1); } } /*键盘扫描子程序*/ void keyscan(void) { if(P1_0==0)//秒位的调整 { delay(30); if(P1_0==0) { seconde++; if(seconde==60) { seconde=0; } } delay(250); } if(P1_1==0)//分位的调整 { delay(30); if(P1_1==0) { minite++; if(minite==60) { minite=0; } } delay(250); } if(P1_2==0)//时位的调整 { delay(30); if(P1_2==0) { hour++; if(hour==24) { hour=0; } } delay(250); } } /*整点报警*/ void zhengdian (void) { if((seconde==0)&(minite==0))//整点报时 { P1_5=0; delay(1000); P1_5=1; } } /*定时闹钟*/ void dingshi(void) { if(P1_3==0)//按住P1_3BU不松,显示闹铃设置界面,分别按P1_6、P1_7设置闹铃时间。 { P2=0XFE; P0=dispcode[0];//秒个位 delay(1); P2=0XFD; P0=dispcode[0];//秒十位 delay(1); P2=0XFB; P0=dispcode[10];//间隔符 - delay(1); P2=0XF7; P0=dispcode[fen%10];//分个位 delay(1); P2=0XEF; P0=dispcode[fen/10];//分十位 delay(1); P2=0XDF; P0=dispcode[10];//间隔符 - delay(1); P2=0XBF; P0=dispcode[shi%10];//时个位 delay(1); P2=0X7F; P0=dispcode[shi/10];//时十位 delay(1); } if(P1_6==0)//设定时 { delay(30); if(P1_6==0) { shi++; if(shi==24) { shi=0; } } delay(250); } if(P1_7==0)//设定分 { delay(30); if(P1_7==0) { fen++; if(fen==60) { fen=0; } } delay(250); } if((hour==shi)&(minite==fen)&(seconde==0))//闹铃时间到,报警六十次。 { for(bjcs=0;bjcs<60;bjcs++) { P1_5=0; delay(500); P1_5=1; delay(500); } } } /*主函数*/ void main(void) { P1=0XFF; TMOD = 0x11; //time0为定时器,方式1 TH0=0x3c; //预置计数初值,50ms TL0=0xb0; EA=1; //总中断开 ET0=1; //允许定时器0中断 TR0=1; //开启定时器0 while (1) { keyscan(); //按键扫描 dingshi();//定时闹钟 zhengdian();//整点报时 display(); //显示时间 } } void timer0(void) interrupt 1 //定时器0方式1,50ms中断一次 { TH0=0x3c; //手动加载计数脉冲次数 TL0=0xb0; TMOD=0x11; mstcnt++; //用于计算时间,每隔50ms加1 if(mstcnt==20)//mstcnt满20即为一秒 { seconde++;//秒+1 time_pro( ); //时间处理 mstcnt=0; //对计数单元的清零,重新开始计数 } }

矩阵键盘按键输入多位数的显示问题

是这样的,矩阵键盘那一部分已经完成了,就是显示这一块,比如想通过键盘输入125,先按1,应该显示001;再按2,显示012;最后按5,显示125。但是问题是先后分别显示的是111、222、555。显示部分的代码如下: 数码管显示部分的时钟是1KHZ; key_data=4'hb或4'hc或4'ha是我定义的功能键; 按理key_data_reg0、key_data_reg1、key_data_reg2、key_data_reg3的变化应该如下: 按下c键(设置按键):key_data_reg0=0 key_data_reg1=0 key_data_reg2=0 key_data_reg3=0 按下1键: key_data_reg0=1 key_data_reg1=0 key_data_reg2=0 key_data_reg3=0 按下2键: key_data_reg0=2 key_data_reg1=1 key_data_reg2=0 key_data_reg3=0 按下5键: key_data_reg0=5 key_data_reg1=2 key_data_reg2=1 key_data_reg3=0 按下a键(确认按键):key_data_reg0=a key_data_reg1=5 key_data_reg2=2 key_data_reg3=1 ``` module display( clk , rst_n , key_data , sel , seg ); //输入信号定义 input clk ; input rst_n ; input[3:0] key_data ; //输出信号定义 output sel ; output seg ; //输出信号reg定义 reg[2:0] sel ; //数码管的位选信号 reg[7:0] seg ; //数码段的段选信号 //中间信号定义 reg[3:0] disp_data ; //单个数码管要显示的数据 reg[3:0] key_data_reg0 ; reg[3:0] key_data_reg1 ; reg[3:0] key_data_reg2 ; reg[3:0] key_data_reg3 ; always @(posedge clk or negedge rst_n)begin if(rst_n == 1'b0)begin sel <= 3'b110; end else if(sel == 3'b110)begin sel <= 3'b101; end else if(sel == 3'b101)begin sel <= 3'b011; end else begin sel <= 3'b110; end end always@(key_data)begin if(rst_n==1'b0)begin key_data_reg0 <= 4'd0; key_data_reg1 <= 4'd0; key_data_reg2 <= 4'd0; key_data_reg3 <= 4'd0; end else if(key_data == 4'hb | key_data == 4'hc)begin key_data_reg0 <= 4'd0; key_data_reg1 <= 4'd0; key_data_reg2 <= 4'd0; key_data_reg3 <= 4'd0; end else begin key_data_reg0 <= key_data; key_data_reg1 <= key_data_reg0; key_data_reg2 <= key_data_reg1; key_data_reg3 <= key_data_reg2; end end always @(posedge clk or negedge rst_n)begin //将对应位数的值赋给对应位数码管 case(sel) 3'b110: disp_data <= key_data_reg1 ; 3'b101: disp_data <= key_data_reg2 ; 3'b011: disp_data <= key_data_reg3; default: disp_data <= 4'b0000; endcase end always @(posedge clk or negedge rst_n)begin //数码管显示表 if(rst_n == 1'b0)begin seg = 8'b11000000; end else begin case(disp_data) 4'd0:seg = 8'b11000000; 4'd1:seg = 8'b11111001; 4'd2:seg = 8'b10100100; 4'd3:seg = 8'b10110000; 4'd4:seg = 8'b10011001; 4'd5:seg = 8'b10010010; 4'd6:seg = 8'b10000010; 4'd7:seg = 8'b11111000; 4'd8:seg = 8'b10000000; 4'd9:seg = 8'b10010000; default:seg = 8'b10001110; endcase end end endmodule ``` 单纯的对这段代码进行了仿真,如图结果应该是正确的,但是到板子上就不对了。 怀疑是时序问题,但是对时序问题不知如何下手(可能实际按键输入值key_data与我仿真时给key_data直接赋值不一样?) 又或者是阻塞非阻塞的问题?

51单片机关于EEPROM的读和写的问题

```#include "reg52.h" //此文件中定义了单片机的一些特殊功能寄存器 #include"temp.h" #include"i2c.h" typedef unsigned int u16; //对数据类型进行声明定义 typedef unsigned char u8; sbit LSA=P2^2; sbit LSB=P2^3; sbit LSC=P2^4; sbit k1=P3^1; sbit k2=P3^0; sbit k3=P3^2; sbit k4=P3^3; //定义按键端口 int temp; char xianshizhi=0; u16 zhuangtai=0; u8 DisplayData[8]; u8 code smgduan[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; /******************************************************************************* * 函 数 名 : delay * 函数功能 : 延时函数,i=1时,大约延时10us *******************************************************************************/ void delay(u16 i) { while(i--); } /******************************************************************************* * 函 数 名 : datapros() * 函数功能 : 温度读取处理转换函数 * 输 入 : temp * 输 出 : 无 *******************************************************************************/ void datapros(int temp) { float tp; if(temp< 0) { DisplayData[0] = 0x40; temp=temp-1; temp=~temp; tp=temp; temp=tp*0.0625*100+0.5; } else { DisplayData[0] = 0x00; tp=temp; temp=tp*0.0625*100+0.5; } DisplayData[1] = smgduan[temp / 10000]; DisplayData[2] = smgduan[temp % 10000 / 1000]; DisplayData[3] = smgduan[temp % 1000 / 100] | 0x80; DisplayData[4] = smgduan[temp % 100 / 10]; DisplayData[5] = smgduan[temp % 10]; } /******************************************************************************* * 函数名 :DigDisplay() * 函数功能 :数码管显示函数 * 输入 : 无 * 输出 : 无 *******************************************************************************/ void DigDisplay() { u8 i; for(i=0;i<6;i++) { switch(i) //位选,选择点亮的数码管, { case(0): LSA=0;LSB=0;LSC=0; break;//显示第0位 case(1): LSA=1;LSB=0;LSC=0; break;//显示第1位 case(2): LSA=0;LSB=1;LSC=0; break;//显示第2位 case(3): LSA=1;LSB=1;LSC=0; break;//显示第3位 case(4): LSA=0;LSB=0;LSC=1; break;//显示第4位 case(5): LSA=1;LSB=0;LSC=1; break;//显示第5位 } P0=DisplayData[5-i];//发送数据 delay(100); //间隔一段时间扫描 P0=0x00;//消隐 } } void Int1Init() { //设置INT1 IT1=1;//跳变沿出发方式(下降沿) EX1=1;//打开INT1的中断允许。 EA=1;//打开总中断 } //这块是按键记忆函数 摁下K1键记忆当前温度值 K2是显示写入EEPROM的温度值 K3是对温度值加1 K4是对当前显示的值清零 //K4的意义后期可以改一下 # void Keypros() { int i=0,j,temp,tp; int num; if(k1==0) { delay(1000); //消抖处理 if(k1==0) { //zhuangtai=0; temp=Ds18b20ReadTemp(); if(temp< 0) { DisplayData[0] = 0x40; temp=temp-1; temp=~temp; tp=temp; temp=tp*0.0625*100+0.5; } else { DisplayData[0] = 0x00; tp=temp; temp=tp*0.0625*100+0.5; } At24c02Write(1,temp); //在地址1内写入数据num } while(!k1); } if(k2==0) { delay(1000); //消抖处理 if(k2==0) { //zhuangtai=2; num=At24c02Read(1); //读取EEPROM地址1内的数据保存在num中 //num=temp; DisplayData[1] = smgduan[num / 10000]; DisplayData[2] = smgduan[num % 10000 / 1000]; DisplayData[3] = smgduan[num % 1000 / 100] | 0x80; DisplayData[4] = smgduan[num % 100 / 10]; DisplayData[5] = smgduan[num% 10]; for(i;i<500;i++){ DigDisplay(); } //Int1Init(); } while(!k2); } } /******************************************************************************* * 函 数 名 : main * 函数功能 : 主函数 * 输 入 : 无 * 输 出 : 无 *******************************************************************************/ void main() { while(1) { datapros(Ds18b20ReadTemp()); //数据处理函数 DigDisplay();//数码管显示函数 Keypros(); } } ``` **接下来是EEPROM函数** #include"i2c.h" /******************************************************************************* * 函数名 : Delay10us() * 函数功能 : 延时10us * 输入 : 无 * 输出 : 无 *******************************************************************************/ void Delay10us() { unsigned char a,b; for(b=1;b>0;b--) for(a=2;a>0;a--); } /******************************************************************************* * 函数名 : I2cStart() * 函数功能 : 起始信号:在SCL时钟信号在高电平期间SDA信号产生一个下降沿 * 输入 : 无 * 输出 : 无 * 备注 : 起始之后SDA和SCL都为0 *******************************************************************************/ void I2cStart() { SDA=1; Delay10us(); SCL=1; Delay10us();//建立时间是SDA保持时间>4.7us SDA=0; Delay10us();//保持时间是>4us SCL=0; Delay10us(); } /******************************************************************************* * 函数名 : I2cStop() * 函数功能 : 终止信号:在SCL时钟信号高电平期间SDA信号产生一个上升沿 * 输入 : 无 * 输出 : 无 * 备注 : 结束之后保持SDA和SCL都为1;表示总线空闲 *******************************************************************************/ void I2cStop() { SDA=0; Delay10us(); SCL=1; Delay10us();//建立时间大于4.7us SDA=1; Delay10us(); } /******************************************************************************* * 函数名 : I2cSendByte(unsigned char dat) * 函数功能 : 通过I2C发送一个字节。在SCL时钟信号高电平期间,保持发送信号SDA保持稳定 * 输入 : num * 输出 : 0或1。发送成功返回1,发送失败返回0 * 备注 : 发送完一个字节SCL=0,SDA=1 *******************************************************************************/ unsigned char I2cSendByte(unsigned char dat) { unsigned char a=0,b=0;//最大255,一个机器周期为1us,最大延时255us。 for(a=0;a<8;a++)//要发送8位,从最高位开始 { SDA=dat>>7; //起始信号之后SCL=0,所以可以直接改变SDA信号 dat=dat<<1; Delay10us(); SCL=1; Delay10us();//建立时间>4.7us SCL=0; Delay10us();//时间大于4us } SDA=1; Delay10us(); SCL=1; while(SDA)//等待应答,也就是等待从设备把SDA拉低 { b++; if(b>200) //如果超过2000us没有应答发送失败,或者为非应答,表示接收结束 { SCL=0; Delay10us(); return 0; } } SCL=0; Delay10us(); return 1; } /******************************************************************************* * 函数名 : I2cReadByte() * 函数功能 : 使用I2c读取一个字节 * 输入 : 无 * 输出 : dat * 备注 : 接收完一个字节SCL=0,SDA=1. *******************************************************************************/ unsigned char I2cReadByte() { unsigned char a=0,dat=0; SDA=1; //起始和发送一个字节之后SCL都是0 Delay10us(); for(a=0;a<8;a++)//接收8个字节 { SCL=1; Delay10us(); dat<<=1; dat|=SDA; Delay10us(); SCL=0; Delay10us(); } return dat; } /******************************************************************************* * 函数名 : void At24c02Write(unsigned char addr,unsigned char dat) * 函数功能 : 往24c02的一个地址写入一个数据 * 输入 : 无 * 输出 : 无 *******************************************************************************/ void At24c02Write(unsigned char addr,unsigned char dat) { I2cStart(); I2cSendByte(0xa0);//发送写器件地址 I2cSendByte(addr);//发送要写入内存地址 I2cSendByte(dat); //发送数据 I2cStop(); } /******************************************************************************* * 函数名 : unsigned char At24c02Read(unsigned char addr) * 函数功能 : 读取24c02的一个地址的一个数据 * 输入 : 无 * 输出 : 无 *******************************************************************************/ unsigned char At24c02Read(unsigned char addr) { unsigned char num; I2cStart(); I2cSendByte(0xa0); //发送写器件地址 I2cSendByte(addr); //发送要读取的地址 I2cStart(); I2cSendByte(0xa1); //发送读器件地址 num=I2cReadByte(); //读取数据 I2cStop(); return num; } ## 程序烧录之后温度能正常显示,可以实现记忆,但是就是无法记忆当前的温度值![图片说明](https://img-ask.csdn.net/upload/201905/24/1558630299_754452.jpg)![图片说明](https://img-ask.csdn.net/upload/201905/24/1558630312_935153.jpg) 请那位大神帮忙看一下Keypros()那块的代码,还有为什么会出现这种情况

在中国程序员是青春饭吗?

今年,我也32了 ,为了不给大家误导,咨询了猎头、圈内好友,以及年过35岁的几位老程序员……舍了老脸去揭人家伤疤……希望能给大家以帮助,记得帮我点赞哦。 目录: 你以为的人生 一次又一次的伤害 猎头界的真相 如何应对互联网行业的「中年危机」 一、你以为的人生 刚入行时,拿着傲人的工资,想着好好干,以为我们的人生是这样的: 等真到了那一天,你会发现,你的人生很可能是这样的: ...

程序员请照顾好自己,周末病魔差点一套带走我。

程序员在一个周末的时间,得了重病,差点当场去世,还好及时挽救回来了。

和黑客斗争的 6 天!

互联网公司工作,很难避免不和黑客们打交道,我呆过的两家互联网公司,几乎每月每天每分钟都有黑客在公司网站上扫描。有的是寻找 Sql 注入的缺口,有的是寻找线上服务器可能存在的漏洞,大部分都...

点沙成金:英特尔芯片制造全过程揭密

“亚马逊丛林里的蝴蝶扇动几下翅膀就可能引起两周后美国德州的一次飓风……” 这句人人皆知的话最初用来描述非线性系统中微小参数的变化所引起的系统极大变化。 而在更长的时间尺度内,我们所生活的这个世界就是这样一个异常复杂的非线性系统…… 水泥、穹顶、透视——关于时间与技艺的蝴蝶效应 公元前3000年,古埃及人将尼罗河中挖出的泥浆与纳特龙盐湖中的矿物盐混合,再掺入煅烧石灰石制成的石灰,由此得来了人...

上班一个月,后悔当初着急入职的选择了

最近有个老铁,告诉我说,上班一个月,后悔当初着急入职现在公司了。他之前在美图做手机研发,今年美图那边今年也有一波组织优化调整,他是其中一个,在协商离职后,当时捉急找工作上班,因为有房贷供着,不能没有收入来源。所以匆忙选了一家公司,实际上是一个大型外包公司,主要派遣给其他手机厂商做外包项目。**当时承诺待遇还不错,所以就立马入职去上班了。但是后面入职后,发现薪酬待遇这块并不是HR所说那样,那个HR自...

女程序员,为什么比男程序员少???

昨天看到一档综艺节目,讨论了两个话题:(1)中国学生的数学成绩,平均下来看,会比国外好?为什么?(2)男生的数学成绩,平均下来看,会比女生好?为什么?同时,我又联想到了一个技术圈经常讨...

副业收入是我做程序媛的3倍,工作外的B面人生是怎样的?

提到“程序员”,多数人脑海里首先想到的大约是:为人木讷、薪水超高、工作枯燥…… 然而,当离开工作岗位,撕去层层标签,脱下“程序员”这身外套,有的人生动又有趣,马上展现出了完全不同的A/B面人生! 不论是简单的爱好,还是正经的副业,他们都干得同样出色。偶尔,还能和程序员的特质结合,产生奇妙的“化学反应”。 @Charlotte:平日素颜示人,周末美妆博主 大家都以为程序媛也个个不修边幅,但我们也许...

如果你是老板,你会不会踢了这样的员工?

有个好朋友ZS,是技术总监,昨天问我:“有一个老下属,跟了我很多年,做事勤勤恳恳,主动性也很好。但随着公司的发展,他的进步速度,跟不上团队的步伐了,有点...

我入职阿里后,才知道原来简历这么写

私下里,有不少读者问我:“二哥,如何才能写出一份专业的技术简历呢?我总感觉自己写的简历太烂了,所以投了无数份,都石沉大海了。”说实话,我自己好多年没有写过简历了,但我认识的一个同行,他在阿里,给我说了一些他当年写简历的方法论,我感觉太牛逼了,实在是忍不住,就分享了出来,希望能够帮助到你。 01、简历的本质 作为简历的撰写者,你必须要搞清楚一点,简历的本质是什么,它就是为了来销售你的价值主张的。往深...

外包程序员的幸福生活

今天给你们讲述一个外包程序员的幸福生活。男主是Z哥,不是在外包公司上班的那种,是一名自由职业者,接外包项目自己干。接下来讲的都是真人真事。 先给大家介绍一下男主,Z哥,老程序员,是我十多年前的老同事,技术大牛,当过CTO,也创过业。因为我俩都爱好喝酒、踢球,再加上住的距离不算远,所以一直也断断续续的联系着,我对Z哥的状况也有大概了解。 Z哥几年前创业失败,后来他开始干起了外包,利用自己的技术能...

C++11:一些微小的变化(新的数据类型、template表达式内的空格、nullptr、std::nullptr_t)

本文介绍一些C++的两个新特性,它们虽然微小,但对你的编程十分重要 一、Template表达式内的空格 C++11标准之前建议在“在两个template表达式的闭符之间放一个空格”的要求已经过时了 例如: vector&lt;list&lt;int&gt; &gt;; //C++11之前 vector&lt;list&lt;int&gt;&gt;; //C++11 二、nullptr ...

优雅的替换if-else语句

场景 日常开发,if-else语句写的不少吧??当逻辑分支非常多的时候,if-else套了一层又一层,虽然业务功能倒是实现了,但是看起来是真的很不优雅,尤其是对于我这种有强迫症的程序"猿",看到这么多if-else,脑袋瓜子就嗡嗡的,总想着解锁新姿势:干掉过多的if-else!!!本文将介绍三板斧手段: 优先判断条件,条件不满足的,逻辑及时中断返回; 采用策略模式+工厂模式; 结合注解,锦...

深入剖析Springboot启动原理的底层源码,再也不怕面试官问了!

大家现在应该都对Springboot很熟悉,但是你对他的启动原理了解吗?

离职半年了,老东家又发 offer,回不回?

有小伙伴问松哥这个问题,他在上海某公司,在离职了几个月后,前公司的领导联系到他,希望他能够返聘回去,他很纠结要不要回去? 俗话说好马不吃回头草,但是这个小伙伴既然感到纠结了,我觉得至少说明了两个问题:1.曾经的公司还不错;2.现在的日子也不是很如意。否则应该就不会纠结了。 老实说,松哥之前也有过类似的经历,今天就来和小伙伴们聊聊回头草到底吃不吃。 首先一个基本观点,就是离职了也没必要和老东家弄的苦...

为什么你不想学习?只想玩?人是如何一步一步废掉的

不知道是不是只有我这样子,还是你们也有过类似的经历。 上学的时候总有很多光辉历史,学年名列前茅,或者单科目大佬,但是虽然慢慢地长大了,你开始懈怠了,开始废掉了。。。 什么?你说不知道具体的情况是怎么样的? 我来告诉你: 你常常潜意识里或者心理觉得,自己真正的生活或者奋斗还没有开始。总是幻想着自己还拥有大把时间,还有无限的可能,自己还能逆风翻盘,只不是自己还没开始罢了,自己以后肯定会变得特别厉害...

为什么程序员做外包会被瞧不起?

二哥,有个事想询问下您的意见,您觉得应届生值得去外包吗?公司虽然挺大的,中xx,但待遇感觉挺低,马上要报到,挺纠结的。

当HR压你价,说你只值7K,你该怎么回答?

当HR压你价,说你只值7K时,你可以流畅地回答,记住,是流畅,不能犹豫。 礼貌地说:“7K是吗?了解了。嗯~其实我对贵司的面试官印象很好。只不过,现在我的手头上已经有一份11K的offer。来面试,主要也是自己对贵司挺有兴趣的,所以过来看看……”(未完) 这段话主要是陪HR互诈的同时,从公司兴趣,公司职员印象上,都给予对方正面的肯定,既能提升HR的好感度,又能让谈判气氛融洽,为后面的发挥留足空间。...

面试:第十六章:Java中级开发(16k)

HashMap底层实现原理,红黑树,B+树,B树的结构原理 Spring的AOP和IOC是什么?它们常见的使用场景有哪些?Spring事务,事务的属性,传播行为,数据库隔离级别 Spring和SpringMVC,MyBatis以及SpringBoot的注解分别有哪些?SpringMVC的工作原理,SpringBoot框架的优点,MyBatis框架的优点 SpringCould组件有哪些,他们...

面试阿里p7,被按在地上摩擦,鬼知道我经历了什么?

面试阿里p7被问到的问题(当时我只知道第一个):@Conditional是做什么的?@Conditional多个条件是什么逻辑关系?条件判断在什么时候执...

面试了一个 31 岁程序员,让我有所触动,30岁以上的程序员该何去何从?

最近面试了一个31岁8年经验的程序猿,让我有点感慨,大龄程序猿该何去何从。

【阿里P6面经】二本,curd两年,疯狂复习,拿下阿里offer

二本的读者,在老东家不断学习,最后逆袭

大三实习生,字节跳动面经分享,已拿Offer

说实话,自己的算法,我一个不会,太难了吧

程序员垃圾简历长什么样?

已经连续五年参加大厂校招、社招的技术面试工作,简历看的不下于万份 这篇文章会用实例告诉你,什么是差的程序员简历! 疫情快要结束了,各个公司也都开始春招了,作为即将红遍大江南北的新晋UP主,那当然要为小伙伴们做点事(手动狗头)。 就在公众号里公开征简历,义务帮大家看,并一一点评。《启舰:春招在即,义务帮大家看看简历吧》 一石激起千层浪,三天收到两百多封简历。 花光了两个星期的所有空闲时...

《经典算法案例》01-08:如何使用质数设计扫雷(Minesweeper)游戏

我们都玩过Windows操作系统中的经典游戏扫雷(Minesweeper),如果把质数当作一颗雷,那么,表格中红色的数字哪些是雷(质数)?您能找出多少个呢?文中用列表的方式罗列了10000以内的自然数、质数(素数),6的倍数等,方便大家观察质数的分布规律及特性,以便对算法求解有指导意义。另外,判断质数是初学算法,理解算法重要性的一个非常好的案例。

《Oracle Java SE编程自学与面试指南》最佳学习路线图(2020最新版)

正确选择比瞎努力更重要!

面试官:你连SSO都不懂,就别来面试了

大厂竟然要考我SSO,卧槽。

微软为一人收购一公司?破解索尼程序、写黑客小说,看他彪悍的程序人生!...

作者 | 伍杏玲出品 | CSDN(ID:CSDNnews)格子衬衫、常掉发、双肩包、修电脑、加班多……这些似乎成了大众给程序员的固定标签。近几年流行的“跨界风”开始刷新人们对程序员的...

终于,月薪过5万了!

来看几个问题想不想月薪超过5万?想不想进入公司架构组?想不想成为项目组的负责人?想不想成为spring的高手,超越99%的对手?那么本文内容是你必须要掌握的。本文主要详解bean的生命...

我说我懂多线程,面试官立马给我发了offer

不小心拿了几个offer,有点烦

自从喜欢上了B站这12个UP主,我越来越觉得自己是个废柴了!

不怕告诉你,我自从喜欢上了这12个UP主,哔哩哔哩成为了我手机上最耗电的软件,几乎每天都会看,可是吧,看的越多,我就越觉得自己是个废柴,唉,老天不公啊,不信你看看…… 间接性踌躇满志,持续性混吃等死,都是因为你们……但是,自己的学习力在慢慢变强,这是不容忽视的,推荐给你们! 都说B站是个宝,可是有人不会挖啊,没事,今天咱挖好的送你一箩筐,首先啊,我在B站上最喜欢看这个家伙的视频了,为啥 ,咱撇...

立即提问
相关内容推荐