欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136
標題:
這個單片機LCD1602程序仿真的時候為什么顯示都是問號?
[打印本頁]
作者:
junxi8
時間:
2023-4-20 13:29
標題:
這個單片機LCD1602程序仿真的時候為什么顯示都是問號?
1.png
(40.51 KB, 下載次數: 24)
下載附件
2023-4-20 15:14 上傳
#include<reg52.h>//52單片機頭文件,規(guī)定了52單片機的寄存器和IO口等
#include<intrins.h>//_nop_空指令及左右循環(huán)移位子函數庫
#define uchar unsigned char//宏定義
#define uint unsigned int//宏定義
sbit lcd_rs=P2^0;//定義選數據寄存器選指令寄存器控制端
sbit lcd_rw=P2^1;//定義下面通過lcd_rw來操作P2^5口,1602讀寫選擇端
sbit lcd_en=P2^2;//定義下面通過lcd_en來操作P2^7口,1602液晶使能控制端
sbit DS_rst=P3^4;//DS1302復位
sbit DS_sck=P3^5;//定義時鐘總線
sbit DS_io=P3^6;//定義DS1302數據總線
sbit s1=P1^0;//定義設置按鈕
sbit s2=P1^1;//定義調時按鈕
sbit s3=P1^2;//定義確定按鈕
sbit s4=P1^3;//定義鬧鐘調整按鈕
sbit ACC0=ACC^0;//累加器
sbit ACC7=ACC^7;
sbit BELL=P1^6; //喇叭
char fen,shi,miao,ri,yue,nian,zhou,s1num,s2num,s4num,flag1,flag2,lshi,lfen;
uchar code table[]={" 2022- - W "};//要寫入1602液晶的數據
uchar code table1[]={" : : T : "};//字庫中的字可直接以外加""號的形式直接寫入
uchar code table2[]={" Welcome To Lcd!"};//歡迎界面
uchar code table3[]={"Happy Every Day!"}; //歡迎界面
/*******************************************************************************
時函數,z的取值為這個函數的延時ms數,delay(200);大約延時200ms. delay(500);大約延時500ms
*******************************************************************************/
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
/*********************蜂鳴器函數************************************************/
void didi()
{
uchar i;
for(i=0;i<60;i++)
{
BELL = 0;
delay(1);
BELL = 1;
delay(1);
}
}
/*******************向1602液晶中寫一個指令**************************************/
void write_com(uchar com)
{
lcd_rw=0; //lcd_rw為讀寫控制端,lcd_rw=0,這里可不寫
lcd_rs=0; //液晶rs接口為0時,寫指令,rs為1時寫數據
P0=com; //將要寫的指令賦給P0口,
delay(5); //由1602讀寫操作時序圖,先將指令賦給P0口,延時后將使能
lcd_en=1; // 端lcd_en置高,再延時一段時間,然后將lcd_en置低,這樣指令
delay(5); // 就寫入到LCD了
lcd_en=0;
}
/****************************向液晶寫數據***************************************/
void write_data(uchar date)//與寫指令類似,這里lcd_rs設為1
{
lcd_rs=1;
lcd_rw=0;
P0=date;
delay(5);
lcd_en=1;
delay(5);
lcd_en=0;
}
/*****************************初使化1602液晶************************************/
void init_1602()
{
lcd_en=0;
nian=22;
yue=6;
ri=21;
zhou=5;
shi=13;
fen=59;
miao=59;
s1num=0;
s2num=0;
s4num=0;
lshi=7;
lfen=59;
write_com(0x38);//設置LCD為16*2顯示、5*7點陣、8位數據接口模式
write_com(0x0c);//開顯示、不顯示光標
write_com(0x06);//寫一個字符后,地址指針加1
write_com(0x01);//顯示清0
}
/*******************************************************************************/
void gudingtime_1602()
{
uchar num;
write_com(0x80);//將指針指向初始位置
for(num=0;num<16;num++)//循環(huán)函數,用于將" 2022- - "寫入液晶
write_data(table[num]);
write_com(0x80+0x40);//將指針指向1602液晶的第二行
for(num=0;num<16;num++)//功能與上同,用于將" : : T : "寫入
write_data(table1[num]);
}
/**************************顯示歡迎界面函數*************************************/
void displaystar(void)
{
uchar i;
write_com(0x80);
for(i=0;i<16;i++)
write_data(table2[i]);
write_com(0x80+0x40);
for(i=0;i<16;i++)
write_data(table3[i]);
}
/***************************顯示時間、日期子函數*********************************/
void write_sfm(uchar add,uchar time)//用于在1602上顯示年、月、日、時、分、秒。Add為顯示位置,time為要顯示的內容
{
uchar shiwei,gewei;
shiwei=time/16; //將從DS1302中讀取的BCD碼數據轉化成10進制個位和10
gewei=time%16; //進制十位
write_com(add+0x80);//定義顯示在液晶的什么位置
write_data(0x30+shiwei);//由1602液晶字庫可知,0~9的數據碼分別對應0x30~0x39
write_data(0x30+gewei); //初使化中設定了寫一個字符后,地址指針加1,因此這里
} // 不用重新光標寫位
/**************************顯示周子函數*****************************************/
void write_zhou(uchar time1)//用于在1602上顯示周信息,與顯示
{ //時間日期子函數類似
uchar gewei;
gewei=time1%16;//一周七天,因此只需個位
write_com(0x80+14);//初始位置加13個
write_data(0x30+gewei);
}
/***************************寫數據字節(jié)子函數************************************/
void Input_1byte(uchar TD)//寫一字節(jié)數據
{
uchar i;
ACC=TD;
for(i=8;i>0;i--)
{
DS_io=ACC0;
DS_sck=1;
DS_sck=0;
ACC=ACC>>1; //右移一位
}
}
/*************************讀數據字節(jié)子函數**************************************/
uchar Output_1byte(void)//讀一字節(jié)數據
{
uchar i;
for(i=8;i>0;i--)
{
ACC=ACC>>1;
ACC7=DS_io;
DS_sck=1;
DS_sck=0;
}
return(ACC);
}
/***************************寫DS1302數據函數***********************************/
void write_1302(uchar DS_ADD,uchar DS_DAT)//寫操作
{
DS_rst=0;
DS_sck=0;
DS_rst=1;
Input_1byte(DS_ADD);
Input_1byte(DS_DAT);
DS_sck=1;
DS_rst=0;
}
/***************************讀DS1302數據函數***********************************/
uchar read_1302(uchar DS_ADD)//讀操作
{
uchar DS_INF;
DS_rst=0;
DS_sck=0;
DS_rst=1;
Input_1byte(DS_ADD);
DS_INF=Output_1byte();
DS_sck=1;
DS_rst=0;
return(DS_INF);
}
/*************************初始化DS1302子函數***********************************/
void inital_1302()
{
write_1302(0x8e,0x00);//禁止寫保護
write_1302(0x90,0xaa);//定義充電
write_1302(0x80,0x53);//秒
write_1302(0x84,0x13);//時
write_1302(0x82,0x43);//分
write_1302(0x8c,0x12);//年
write_1302(0x88,0x06);//月
write_1302(0x86,0x03);//日
write_1302(0x8a,0x06);//星期
write_1302(0xc0,0x08);//鬧鐘小時初始化
write_1302(0xfc,0x00);//鬧鐘分鐘初始化
write_1302(0x8e,0x80);//開保護
}
/********************************************************************************
掃描函數
********************************************************************************/
void keyscan()
{
if(s1==0&&s4num==0) //按鍵1按下且s4再次之前未曾按過
{
delay(5);
if(s1==0&&s4num==0)
{
flag1=1;
s1num++;
while(!s1);didi();
if(s1num==1)
{
write_com(0x80+0x40+8);//光標移動到**位置
write_com(0x0f);//顯示光標
}
if(s1num==2)
{
write_1302(0x8e,0x00);//禁止寫保護
write_1302(0x80,miao);//寫入秒信息
write_1302(0x8e,0x80);//開寫保護
write_com(0x80+0x40+5);
}
if(s1num==3)
{
write_1302(0x8e,0x00);
write_1302(0x82,fen);
write_1302(0x8e,0x80);
write_com(0x80+0x40+2);
}
if(s1num==4)
{
write_1302(0x8e,0x00);
write_1302(0x88,yue);
write_1302(0x8e,0x80);
write_com(0x80+13);
}
if(s1num==5)
{
write_1302(0x8e,0x00);
write_1302(0x84,shi);
write_1302(0x8e,0x80);
write_com(0x80+10);
}
if(s1num==6)
{
write_1302(0x8e,0x00);
write_1302(0x86,ri);
write_1302(0x8e,0x80);
write_com(0x80+7);
}
if(s1num==7)
{
write_1302(0x8e,0x00);
write_1302(0x8c,nian);
write_1302(0x8e,0x80);
write_com(0x80+4);
}
if(s1num==8)
{
flag1=0;
s1num=0;
write_1302(0x8e,0x00);
write_1302(0x8a,zhou);
write_1302(0x8e,0x80);
write_com(0x0c);//不顯示光標
}
}
}
/*******************************************************************************/
if(s1num!=0&&s4num==0)//按鍵1按下*次且s4再次之前未曾按過
{
if(s2==0)
{
delay(5);
if(s2==0)
{
while(!s2);didi();
if(s1num==1)
{
int x1,x2;
x1=miao%16;
x2=miao/16;
x1++;
if(x1==10)
{
x1=0;
x2++;
if(x2>=6)
x2=0;
}
miao=x1+x2*16;
write_sfm(7+0x40,miao);//將修改的數送到1602顯示
write_com(0x80+0x40+8);//挪回光標
}
if(s1num==2)
{
int x3,x4;
x3=fen%16;
x4=fen/16;
x3++;
if(x3==10)
{
x3=0;
x4++;
if(x4>=6)
x4=0;
}
fen=x3+x4*16;
write_sfm(4+0x40,fen);
write_com(0x80+0x40+5);
}
if(s1num==3)
{
int x5,x6;
x5=shi%16;
x6=shi/16;
x5++;
if(x6>=2&&x5>=4)
{
x5=0;
x6=0;
}
if(x5==10)
{
x5=0;
x6++;
}
shi=x5+x6*16;
write_sfm(1+0x40,shi);
write_com(0x80+0x40+2);
}
if(s1num==4)
{
zhou++;
if(zhou==8)
zhou=1;
write_zhou(zhou);
write_com(0x80+13);
}
if(s1num==5)
{
int x5,x6;
x5=ri%16;
x6=ri/16;
x5++;
if(x6>=3&&x5>=1)
{
x5=1;
x6=0;
}
if(x5==10)
{
x5=0;
x6++;
}
ri=x5+x6*16;
write_sfm(9,ri);
write_com(0x80+10);
}
if(s1num==6)
{
int x5,x6;
x5=yue%16;
x6=yue/16;
x5++;
if(x6>=1&&x5>=3)
{
x5=1;
x6=0;
}
if(x5==10)
{
x5=0;
x6++;
}
yue=x5+x6*16;
write_sfm(6,yue);
write_com(0x80+7);
}
if(s1num==7)
{
int x5,x6;
x5=nian%16;
x6=nian/16;
x5++;
if(x6>=2&&x5>=1)
{
x5=1;
x6=0;
}
if(x5==10)
{
x5=0;
x6++;
}
nian=x5+x6*16;
write_sfm(3,nian);
write_com(0x80+4);
}
}
}
}
/*******************************************************************************/
if(s1num!=0||s4num!=0)// 在調整模式下
{
if(s3==0)//如果確定鍵按下
{
delay(5);
if(s3==0) //延時并重新檢測S3是否按下,用于差小誤差
{
if(s1num!=0)
{
while(!s3);didi();//在松手時將調整后的時間、日期及周信息寫入DS1302,退出調整模式并隱藏光標,按鍵次數清0
write_1302(0x8e,0x00);
write_1302(0x80,miao);
write_1302(0x84,shi);
write_1302(0x82,fen);
write_1302(0x8a,zhou);
write_1302(0x8c,nian);//年
write_1302(0x88,yue);//月
write_1302(0x86,ri);
write_1302(0x8e,0x80);
flag1=0;
write_com(0x0c);
s1num=0;
}
if(s4num!=0)
{
while(!s3);didi();//在松手時將調整后的時間、日期及周信息寫入DS1302,退出調整模式并隱藏光標,按鍵次數清0
write_1302(0x8e,0x00);
write_1302(0xc0,lshi);
write_1302(0xfc,lfen);
write_1302(0x8e,0x80);
flag2=0;
s4num=0;
write_com(0x0c);
}
}
}
}
if(s4==0&&s1num==0)//按鍵4按下*次且s1再次之前未曾按過
{
delay(5);
if(s4==0&&s1num==0)
{
s4num++;
flag2=1;
while(!s4);didi();
if(s4num==1)
{
write_com(0x80+0x40+14);
write_com(0x0f);
}
if(s4num==2)
{
write_1302(0x8e,0x00);//禁止寫保護
write_1302(0xfc,lfen);//鬧鐘初始化
write_1302(0x8e,0x80);//開寫保護
write_com(0x80+0x40+11);
}
if(s4num==3)
{
s4num=0;
flag2=0;
write_1302(0x8e,0x00);//禁止寫保護
write_1302(0xc0,lshi);//鬧鐘初始化
write_1302(0x8e,0x80);//開寫保護
write_com(0x0c);//不顯示光標
}
}
}
if(s4num!=0&&s1num==0)
{
if(s2==0)
{
delay(5);
if(s2==0)
{
while(!s2);didi();
if(s4num==1)
{
int x1,x2;
x1=lfen%16;
x2=lfen/16;
x1++;
if(x1==10)
{
x1=0;
x2++;
if(x2>=6)
x2=0;
}
lfen=x1+x2*16;
write_sfm(13+0x40,lfen);
write_com(0x80+0x40+14);
}
if(s4num==2)
{
int x5,x6;
x5=lshi%16;
x6=lshi/16;
x5++;
if(x6>=2&&x5>=4)
{
x5=0;
x6=0;
}
if(x5==10)
{
x5=0;
x6++;
}
lshi=x5+x6*16;
write_sfm(10+0x40,lshi);
write_com(0x80+0x40+11);
}
}
}
}
}
void laba()
{
if((shi==lshi)&&(fen==lfen)&&(miao<=10&&miao>=0))//當鬧鐘的時和分分別與時鐘的時和分相等時,鬧鐘時間到,蜂鳴器鳴響,鳴響10s
{
didi();
}
}
void main()
{
init_1602();
delay(5);
displaystar();//初始化1602后馬上顯示歡迎語句
delay(5000);//讓歡迎界面停留一段時間
gudingtime_1602();//顯示液晶固定不變部分
inital_1302();
lshi=read_1302(0xc1);//從ds1302里面的RAM讀取鬧鐘時,此處不放在while(1)大循環(huán)里面是因為ds1302里面的RAM里的數據是不變的只需讀取一次
lfen=read_1302(0xfd);//從ds1302里面的RAM讀取鬧鐘分
write_sfm(0x40+11,lshi);//將鬧鐘時送到1602顯示
write_sfm(0x40+14,lfen);//將鬧鐘分送到1602顯示
while(1)
{
keyscan();
laba();
if(flag1==0&&flag2==0)//只有當不在調整的時候才從DS1302里面讀取數據并且送到1602上顯示
{
miao=read_1302(0x81);//先讀出,再送到1602顯示,不斷循環(huán)操作,使1602動態(tài)顯示時間的走動
fen=read_1302(0x83);
shi=read_1302(0x85);
ri=read_1302(0x87);
yue=read_1302(0x89);
zhou=read_1302(0x8b);
nian=read_1302(0x8d);
write_sfm(6+0x40,miao);
write_sfm(3+0x40,fen);
write_sfm(0+0x40,shi);
write_sfm(9,ri);
write_sfm(6,yue);
write_sfm(3,nian);
write_zhou(zhou);
}
}
}
復制代碼
作者:
yzwzfyz
時間:
2023-4-20 15:43
讀通顯示屏的顯示原理就清楚了,下次遇到任意顯示就都能明白了。
仔細讀手冊吧。
歡迎光臨 (http://www.raoushi.com/bbs/)
Powered by Discuz! X3.1