单片机的时钟按键程序

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

4个回答

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

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

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

你让它等待释放后才加1

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

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

我编了一个单片机的时钟程序,想要实现串口改变时间,可是不知道应该怎么编入串口求解答

这是我编的,其中串口的引入是错误的求改正 #include<reg51.h>#define uint unsigned int#define uchar unsigned char uchar hour,min,sec,temp;uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; void delay(uint z);void display(uchar a,uchar b,uchar c,uchar d,uchar e,uchar f);void time_change();void main(){ hour=00; min=0; sec=0; SCON=0x50; PCON = 0x00; TMOD=0x21; TH0=(65536-50000)/256; TL0=(65536-50000)%256; TH1=0xfd; TL1=0xfd; EA=1; ES=1; ET0=1; ET1=0; TR0=1; TR1=1; delay(50); while(1) { time_change(); display(table[hour/10],table[hour%10],table[min/10],table[min%10],table[sec/10],table[sec%10]); }}void display(uchar a,uchar b,uchar c,uchar d,uchar e,uchar f){ P1=0x01;P0=a;delay(2); P1=0x02;P0=b;delay(2); P1=0x08;P0=c;delay(2); P1=0x10;P0=d;delay(2); P1=0x40;P0=e;delay(2); P1=0x80;P0=f;delay(2); P1=0x04;P0=0xbf;delay(2); P1=0x20;P0=0xbf;delay(2);}void timer0() interrupt 1{ TH0=(65536-50000)/256; TL0=(65536-50000)%256; temp++; }void revdata(void) interrupt 4{ ES=0; if(RI==1){RI=0;hour=SBUF;}delay(50); if(RI==1){RI=0;min=SBUF;}delay(50); if(RI==1){RI=0;sec=SBUF;}delay(50); ES=1;}void delay(uint z){ uint j,k; for(j=z;j>0;j--) for(k=120;k>0;k--);}void time_change(){ if(temp>=20) { temp=0; sec++; if(sec>=60) { sec=0; min++; if(min>=60) { min=0; hour++; if(hour>=24) { hour=0; } } } }}

关于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--); }

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; //液晶复位端口

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

#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]; } } 程序如上 为什么按键会上下颠倒?

C51单片机 12Hz 1000ms延时程序(c语言)

哪位大神可以细致的讲讲51单片机中,12Hz晶振,延时计算程序的算法(1000ms最好)单片机小白表示没有学会呜呜呜~ 看一个延迟10ms程序的代码,for循环中的计算方法没有懂,不会计算 void delayms(uchar ms) { uchar i; while(ms--) { for(i=0;i<120;i++); } } 这个10ms的计算公式是怎样的,如果换成1000ms又该怎样计算ne

关于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); } } }

帮我改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单片机数字音乐盒的课设,要求用的是汇编语言,尽量代码解释清楚

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 ```

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; } } ```

单片机编程,实现P1.1引脚上输出周期为1s,占空比为20%的脉冲信号

用汇编,利用定时器零产生一基准定时配合软件计数来实现。如图,TH0和TL0的初值为什么设置成D8H和F0H![图片说明](https://img-ask.csdn.net/upload/201611/13/1479029093_936768.png)

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(); //刷新数码管显示,放在中断中保证及时刷新显示 } ```

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

是这样的,矩阵键盘那一部分已经完成了,就是显示这一块,比如想通过键盘输入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直接赋值不一样?) 又或者是阻塞非阻塞的问题?

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

请问大神们如何在这个程序里添加串口来改变时钟啊 #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; //对计数单元的清零,重新开始计数 } }

基于AT89C51和LCD1602的电子时钟

![图片说明](https://img-ask.csdn.net/upload/202006/09/1591690883_991194.png) 要求: 在第2行显示当前时间,可用按键调整时,分。 keil编程 可以帮我用c语言写一下代码吗?

单片机设计电子秒表at89c51 求仿真原理图

利用单片机的定时器/计数器定时和计数,并使用LED数码管显示计时的时间来制作一 个电子秒表。 设计要求 (1)能够多次计时; (2)能够查询计时时间

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); } }

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; } 下载程序到单片机后,数码管显示值自动跳转 且无规律 不知道哪里出错了?菜鸟求大神解答 万分感谢!

MySQL 8.0.19安装教程(windows 64位)

话不多说直接开干 目录 1-先去官网下载点击的MySQL的下载​ 2-配置初始化的my.ini文件的文件 3-初始化MySQL 4-安装MySQL服务 + 启动MySQL 服务 5-连接MySQL + 修改密码 先去官网下载点击的MySQL的下载 下载完成后解压 解压完是这个样子 配置初始化的my.ini文件的文件 ...

Python+OpenCV计算机视觉

Python+OpenCV计算机视觉系统全面的介绍。

Vue.js 2.0之全家桶系列视频课程

基于新的Vue.js 2.3版本, 目前新全的Vue.js教学视频,让你少走弯路,直达技术前沿! 1. 包含Vue.js全家桶(vue.js、vue-router、axios、vuex、vue-cli、webpack、ElementUI等) 2. 采用笔记+代码案例的形式讲解,通俗易懂

navicat(内含激活码)

navicat支持mysql的可视化操作,内涵激活码,不用再忍受弹框的痛苦。

HTML期末大作业

这是我自己做的HTML期末大作业,花了很多时间,稍加修改就可以作为自己的作业了,而且也可以作为学习参考

150讲轻松搞定Python网络爬虫

【为什么学爬虫?】 &nbsp; &nbsp; &nbsp; &nbsp;1、爬虫入手容易,但是深入较难,如何写出高效率的爬虫,如何写出灵活性高可扩展的爬虫都是一项技术活。另外在爬虫过程中,经常容易遇到被反爬虫,比如字体反爬、IP识别、验证码等,如何层层攻克难点拿到想要的数据,这门课程,你都能学到! &nbsp; &nbsp; &nbsp; &nbsp;2、如果是作为一个其他行业的开发者,比如app开发,web开发,学习爬虫能让你加强对技术的认知,能够开发出更加安全的软件和网站 【课程设计】 一个完整的爬虫程序,无论大小,总体来说可以分成三个步骤,分别是: 网络请求:模拟浏览器的行为从网上抓取数据。 数据解析:将请求下来的数据进行过滤,提取我们想要的数据。 数据存储:将提取到的数据存储到硬盘或者内存中。比如用mysql数据库或者redis等。 那么本课程也是按照这几个步骤循序渐进的进行讲解,带领学生完整的掌握每个步骤的技术。另外,因为爬虫的多样性,在爬取的过程中可能会发生被反爬、效率低下等。因此我们又增加了两个章节用来提高爬虫程序的灵活性,分别是: 爬虫进阶:包括IP代理,多线程爬虫,图形验证码识别、JS加密解密、动态网页爬虫、字体反爬识别等。 Scrapy和分布式爬虫:Scrapy框架、Scrapy-redis组件、分布式爬虫等。 通过爬虫进阶的知识点我们能应付大量的反爬网站,而Scrapy框架作为一个专业的爬虫框架,使用他可以快速提高我们编写爬虫程序的效率和速度。另外如果一台机器不能满足你的需求,我们可以用分布式爬虫让多台机器帮助你快速爬取数据。 &nbsp; 从基础爬虫到商业化应用爬虫,本套课程满足您的所有需求! 【课程服务】 专属付费社群+每周三讨论会+1v1答疑

三个项目玩转深度学习(附1G源码)

从事大数据与人工智能开发与实践约十年,钱老师亲自见证了大数据行业的发展与人工智能的从冷到热。事实证明,计算机技术的发展,算力突破,海量数据,机器人技术等,开启了第四次工业革命的序章。深度学习图像分类一直是人工智能的经典任务,是智慧零售、安防、无人驾驶等机器视觉应用领域的核心技术之一,掌握图像分类技术是机器视觉学习的重中之重。针对现有线上学习的特点与实际需求,我们开发了人工智能案例实战系列课程。打造:以项目案例实践为驱动的课程学习方式,覆盖了智能零售,智慧交通等常见领域,通过基础学习、项目案例实践、社群答疑,三维立体的方式,打造最好的学习效果。

基于STM32的电子时钟设计

时钟功能 还有闹钟功能,温湿度功能,整点报时功能 你值得拥有

学生成绩管理系统(PHP + MYSQL)

做的是数据库课程设计,使用的php + MySQL,本来是黄金搭配也就没啥说的,推荐使用wamp服务器,里面有详细的使用说明,带有界面的啊!呵呵 不行的话,可以给我留言!

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

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

程序员的兼职技能课

获取讲师答疑方式: 在付费视频第一节(触摸命令_ALL)片头有二维码及加群流程介绍 限时福利 原价99元,今日仅需39元!购课添加小助手(微信号:itxy41)按提示还可领取价值800元的编程大礼包! 讲师介绍: 苏奕嘉&nbsp;前阿里UC项目工程师 脚本开发平台官方认证满级(六级)开发者。 我将如何教会你通过【定制脚本】赚到你人生的第一桶金? 零基础程序定制脚本开发课程,是完全针对零脚本开发经验的小白而设计,课程内容共分为3大阶段: ①前期将带你掌握Q开发语言和界面交互开发能力; ②中期通过实战来制作有具体需求的定制脚本; ③后期将解锁脚本的更高阶玩法,打通任督二脉; ④应用定制脚本合法赚取额外收入的完整经验分享,带你通过程序定制脚本开发这项副业,赚取到你的第一桶金!

实用主义学Python(小白也容易上手的Python实用案例)

原价169,限时立减100元! 系统掌握Python核心语法16点,轻松应对工作中80%以上的Python使用场景! 69元=72讲+源码+社群答疑+讲师社群分享会&nbsp; 【哪些人适合学习这门课程?】 1)大学生,平时只学习了Python理论,并未接触Python实战问题; 2)对Python实用技能掌握薄弱的人,自动化、爬虫、数据分析能让你快速提高工作效率; 3)想学习新技术,如:人工智能、机器学习、深度学习等,这门课程是你的必修课程; 4)想修炼更好的编程内功,优秀的工程师肯定不能只会一门语言,Python语言功能强大、使用高效、简单易学。 【超实用技能】 从零开始 自动生成工作周报 职场升级 豆瓣电影数据爬取 实用案例 奥运冠军数据分析 自动化办公:通过Python自动化分析Excel数据并自动操作Word文档,最终获得一份基于Excel表格的数据分析报告。 豆瓣电影爬虫:通过Python自动爬取豆瓣电影信息并将电影图片保存到本地。 奥运会数据分析实战 简介:通过Python分析120年间奥运会的数据,从不同角度入手分析,从而得出一些有趣的结论。 【超人气老师】 二两 中国人工智能协会高级会员 生成对抗神经网络研究者 《深入浅出生成对抗网络:原理剖析与TensorFlow实现》一书作者 阿里云大学云学院导师 前大型游戏公司后端工程师 【超丰富实用案例】 0)图片背景去除案例 1)自动生成工作周报案例 2)豆瓣电影数据爬取案例 3)奥运会数据分析案例 4)自动处理邮件案例 5)github信息爬取/更新提醒案例 6)B站百大UP信息爬取与分析案例 7)构建自己的论文网站案例

Java8零基础入门视频教程

这门课程基于主流的java8平台,由浅入深的详细讲解了java SE的开发技术,可以使java方向的入门学员,快速扎实的掌握java开发技术!

Python数据挖掘简易入门

&nbsp; &nbsp; &nbsp; &nbsp; 本课程为Python数据挖掘方向的入门课程,课程主要以真实数据为基础,详细介绍数据挖掘入门的流程和使用Python实现pandas与numpy在数据挖掘方向的运用,并深入学习如何运用scikit-learn调用常用的数据挖掘算法解决数据挖掘问题,为进一步深入学习数据挖掘打下扎实的基础。

零基础学C#编程—C#从小白到大咖

本课程从初学者角度出发,提供了C#从入门到成为程序开发高手所需要掌握的各方面知识和技术。 【课程特点】 1 由浅入深,编排合理; 2 视频讲解,精彩详尽; 3 丰富实例,轻松易学; 4 每章总结配有难点解析文档。 15大章节,228课时,1756分钟与你一同进步!

MySQL数据库面试题(2020最新版)

文章目录数据库基础知识为什么要使用数据库什么是SQL?什么是MySQL?数据库三大范式是什么mysql有关权限的表都有哪几个MySQL的binlog有有几种录入格式?分别有什么区别?数据类型mysql有哪些数据类型引擎MySQL存储引擎MyISAM与InnoDB区别MyISAM索引与InnoDB索引的区别?InnoDB引擎的4大特性存储引擎选择索引什么是索引?索引有哪些优缺点?索引使用场景(重点)...

多功能数字钟.zip

利用数字电子计数知识设计并制作的数字电子钟(含multisim仿真),该数字钟具有显示星期、24小时制时间、闹铃、整点报时、时间校准功能

极简JAVA学习营第四期(报名以后加助教微信:eduxy-1)

想学好JAVA必须要报两万的培训班吗? Java大神勿入 如果你: 零基础想学JAVA却不知道从何入手 看了一堆书和视频却还是连JAVA的环境都搭建不起来 囊中羞涩面对两万起的JAVA培训班不忍直视 在职没有每天大块的时间专门学习JAVA 那么恭喜你找到组织了,在这里有: 1. 一群志同道合立志学好JAVA的同学一起学习讨论JAVA 2. 灵活机动的学习时间完成特定学习任务+每日编程实战练习 3. 热心助人的助教和讲师及时帮你解决问题,不按时完成作业小心助教老师的家访哦 上一张图看看前辈的感悟: &nbsp; &nbsp; 大家一定迫不及待想知道什么是极简JAVA学习营了吧,下面就来给大家说道说道: 什么是极简JAVA学习营? 1. 针对Java小白或者初级Java学习者; 2. 利用9天时间,每天1个小时时间; 3.通过 每日作业 / 组队PK / 助教答疑 / 实战编程 / 项目答辩 / 社群讨论 / 趣味知识抢答等方式让学员爱上学习编程 , 最终实现能独立开发一个基于控制台的‘库存管理系统’ 的学习模式 极简JAVA学习营是怎么学习的? &nbsp; 如何报名? 只要购买了极简JAVA一:JAVA入门就算报名成功! &nbsp;本期为第四期极简JAVA学习营,我们来看看往期学员的学习状态: 作业看这里~ &nbsp; 助教的作业报告是不是很专业 不交作业打屁屁 助教答疑是不是很用心 &nbsp; 有奖抢答大家玩的很嗨啊 &nbsp; &nbsp; 项目答辩终于开始啦 &nbsp; 优秀者的获奖感言 &nbsp; 这是答辩项目的效果 &nbsp; &nbsp; 这么细致的服务,这么好的氛围,这样的学习效果,需要多少钱呢? 不要1999,不要199,不要99,只要9.9 是的你没听错,只要9.9以上所有就都属于你了 如果你: 1、&nbsp;想学JAVA没有基础 2、&nbsp;想学JAVA没有整块的时间 3、&nbsp;想学JAVA没有足够的预算 还等什么?赶紧报名吧,抓紧抢位,本期只招300人,错过只有等时间待定的下一期了 &nbsp; 报名请加小助手微信:eduxy-1 &nbsp; &nbsp;

Python可以这样学(第一季:Python内功修炼)

董付国系列教材《Python程序设计基础》、《Python程序设计(第2版)》、《Python可以这样学》配套视频,讲解Python 3.5.x和3.6.x语法、内置对象用法、选择与循环以及函数设计与使用、lambda表达式用法、字符串与正则表达式应用、面向对象编程、文本文件与二进制文件操作、目录操作与系统运维、异常处理结构。

Java基础知识面试题(2020最新版)

文章目录Java概述何为编程什么是Javajdk1.5之后的三大版本JVM、JRE和JDK的关系什么是跨平台性?原理是什么Java语言有哪些特点什么是字节码?采用字节码的最大好处是什么什么是Java程序的主类?应用程序和小程序的主类有何不同?Java应用程序与小程序之间有那些差别?Java和C++的区别Oracle JDK 和 OpenJDK 的对比基础语法数据类型Java有哪些数据类型switc...

机器学习实战系列套餐(必备基础+经典算法+案例实战)

机器学习实战系列套餐以实战为出发点,帮助同学们快速掌握机器学习领域必备经典算法原理并结合Python工具包进行实战应用。建议学习顺序:1.Python必备工具包:掌握实战工具 2.机器学习算法与实战应用:数学原理与应用方法都是必备技能 3.数据挖掘实战:通过真实数据集进行项目实战。按照下列课程顺序学习即可! 课程风格通俗易懂,用最接地气的方式带领大家轻松进军机器学习!提供所有课程代码,PPT与实战数据,有任何问题欢迎随时与我讨论。

Java面试题大全(2020版)

发现网上很多Java面试题都没有答案,所以花了很长时间搜集整理出来了这套Java面试题大全,希望对大家有帮助哈~ 本套Java面试题大全,全的不能再全,哈哈~ 一、Java 基础 1. JDK 和 JRE 有什么区别? JDK:Java Development Kit 的简称,java 开发工具包,提供了 java 的开发环境和运行环境。 JRE:Java Runtime Environ...

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

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

深度学习原理+项目实战+算法详解+主流框架(套餐)

深度学习系列课程从深度学习基础知识点开始讲解一步步进入神经网络的世界再到卷积和递归神经网络,详解各大经典网络架构。实战部分选择当下最火爆深度学习框架PyTorch与Tensorflow/Keras,全程实战演示框架核心使用与建模方法。项目实战部分选择计算机视觉与自然语言处理领域经典项目,从零开始详解算法原理,debug模式逐行代码解读。适合准备就业和转行的同学们加入学习! 建议按照下列课程顺序来进行学习 (1)掌握深度学习必备经典网络架构 (2)深度框架实战方法 (3)计算机视觉与自然语言处理项目实战。(按照课程排列顺序即可)

HoloLens2开发入门教程

本课程为HoloLens2开发入门教程,讲解部署开发环境,安装VS2019,Unity版本,Windows SDK,创建Unity项目,讲解如何使用MRTK,编辑器模拟手势交互,打包VS工程并编译部署应用到HoloLens上等。

几率大的Redis面试题(含答案)

本文的面试题如下: Redis 持久化机制 缓存雪崩、缓存穿透、缓存预热、缓存更新、缓存降级等问题 热点数据和冷数据是什么 Memcache与Redis的区别都有哪些? 单线程的redis为什么这么快 redis的数据类型,以及每种数据类型的使用场景,Redis 内部结构 redis的过期策略以及内存淘汰机制【~】 Redis 为什么是单线程的,优点 如何解决redis的并发竞争key问题 Red...

MFC一站式终极全套课程包

该套餐共包含从C小白到C++到MFC的全部课程,整套学下来绝对成为一名C++大牛!!!

【数据结构与算法综合实验】欢乐连连看(C++ & MFC)案例

这是武汉理工大学计算机学院数据结构与算法综合实验课程的第三次项目:欢乐连连看(C++ & MFC)迭代开发代码。运行环境:VS2017。已经实现功能:开始游戏、消子、判断胜负、提示、重排、计时、帮助。

YOLOv3目标检测实战:训练自己的数据集

YOLOv3是一种基于深度学习的端到端实时目标检测方法,以速度快见长。本课程将手把手地教大家使用labelImg标注和使用YOLOv3训练自己的数据集。课程分为三个小项目:足球目标检测(单目标检测)、梅西目标检测(单目标检测)、足球和梅西同时目标检测(两目标检测)。 本课程的YOLOv3使用Darknet,在Ubuntu系统上做项目演示。包括:安装Darknet、给自己的数据集打标签、整理自己的数据集、修改配置文件、训练自己的数据集、测试训练出的网络模型、性能统计(mAP计算和画出PR曲线)和先验框聚类。 Darknet是使用C语言实现的轻型开源深度学习框架,依赖少,可移植性好,值得深入探究。 除本课程《YOLOv3目标检测实战:训练自己的数据集》外,本人推出了有关YOLOv3目标检测的系列课程,请持续关注该系列的其它课程视频,包括: 《YOLOv3目标检测实战:交通标志识别》 《YOLOv3目标检测:原理与源码解析》 《YOLOv3目标检测:网络模型改进方法》 敬请关注并选择学习!

u-boot-2015.07.tar.bz2

uboot-2015-07最新代码,喜欢的朋友请拿去

相关热词 c# 不能序列化继承类 c# char* 调用 c# 开发dll模板 c#添加控件到工具箱 c#控制台组合数 编程计算猴子吃桃问题c# c# wpf 背景透明 随机抽取号码软件c# c# 开发环境 c# 属性和字段
立即提问