標題: 51單片機萬年歷C語言 [打印本頁]
作者: linyuac123 時間: 2018-11-8 10:45
標題: 51單片機萬年歷C語言
#include <reg51.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
uchar buf1;
uchar buf2;
uchar buf3;
uchar tt;
uchar n=0; //鍵順序嗎
uchar dis_buf; //顯示緩存
uchar temp;
uchar key;
uchar enter;
void delay0(uchar x); //x*0.14MS
sbit LCD_RW = P2^5;
sbit LCD_RS = P2^6;
sbit LCD_EN = P2^7;
sbit DQ=P3^7;
sbit RQ=P1^5;
uchar data disdata[5];
uint tvalue;//溫度值
uchar tflag;//溫度正負標志
uchar cdis1[16] = {"T: C "};
uchar cdis2[16] = {"H: C L: C "};
uchar cdis3[16];
#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};
/*************************************************************/
/* */
/* 延時子程序 */
/* */
/*************************************************************/
void delay(uchar x)
{ uchar j;
while((x--)!=0)
{ for(j=0;j<125;j++)
{;}
}
}
/*************************************************************/
/* */
/*檢查LCD忙狀態(tài) */
/*lcd_busy為1時,忙,等待。lcd-busy為0時,閑,可寫指令與數(shù)據(jù) */
/* */
/*************************************************************/
bit lcd_busy()
{
bit result;
LCD_RS = 0;
LCD_RW = 1;
LCD_EN = 1;
delayNOP();
result = (bit)(P0&0x80);
LCD_EN = 0;
return(result);
}
/*******************************************************************/
/* */
/*寫指令數(shù)據(jù)到LCD */
/*RS=L,RW=L,E=高脈沖,D0-D7=指令碼。 */
/* */
/*******************************************************************/
void lcd_wcmd(uchar cmd)
{
while(lcd_busy());
LCD_RS = 0;
LCD_RW = 0;
LCD_EN = 0;
_nop_();
_nop_();
P0 = cmd;
delayNOP();
LCD_EN = 1;
delayNOP();
LCD_EN = 0;
}
/*******************************************************************/
/* */
/*寫顯示數(shù)據(jù)到LCD */
/*RS=H,RW=L,E=高脈沖,D0-D7=數(shù)據(jù)。 */
/* */
/*******************************************************************/
void lcd_wdat(uchar dat)
{
while(lcd_busy());
LCD_RS = 1;
LCD_RW = 0;
LCD_EN = 0;
P0 = dat;
delayNOP();
LCD_EN = 1;
delayNOP();
LCD_EN = 0;
}
/*************************************************************/
/* */
/* LCD初始化設(shè)定 */
/* */
/*************************************************************/
void lcd_init()
{
delay(15);
lcd_wcmd(0x38); //16*2顯示,5*7點陣,8位數(shù)據(jù)
delay(5);
lcd_wcmd(0x38);
delay(5);
lcd_wcmd(0x38);
delay(5);
lcd_wcmd(0x0C); //顯示開,關(guān)光標
delay(5);
lcd_wcmd(0x06); //移動光標
delay(5);
lcd_wcmd(0x01); //清除LCD的顯示內(nèi)容
delay(5);
}
/*************************************************************/
/* */
/* 設(shè)定顯示位置 */
/* */
/*************************************************************/
void lcd_pos(uchar pos)
{
lcd_wcmd(pos | 0x80); //數(shù)據(jù)指針=80+地址變量
}
/*************************************************************/
/* */
/* 鍵掃描子程序 (4*3 的矩陣) P1.4 P1.5 P1.6 P1.7為行 */
/* P1.1 P1.2 P1.3為列 */
/* */
/*************************************************************/
void keyscan(void)
{
P1=0xF0; //高四位輸入 行為高電平 列為低電平
delay(1);
temp=P1; //讀P1口
temp=temp&0xF0; //屏蔽低四位
temp=~((temp>>4)|0xF0);
if(temp==1) // p1.4 被拉低
key=0;
else if(temp==2) // p1.5 被拉低
key=1;
else if(temp==4) // p1.6 被拉低
key=2;
else if(temp==8)
key=0;
P1=0x0F; //低四位輸入 列為高電平 行為低電平
delay(1);
temp=P1; //讀P1口
temp=temp&0x0F;
temp=~(temp|0xF0);
if(temp==1) // p1.1 被拉低
key=key+0;
else if(temp==2) // p1.2 被拉低
key=key+2;
else if(temp==4) // p1.3 被拉低
key=key+4;
else if(temp==8)
key=key+8;
dis_buf = key; //鍵值入顯示緩存
if(dis_buf>9) //轉(zhuǎn)換為ASCII碼
dis_buf = dis_buf+0x37;
else
dis_buf = dis_buf+0x30;
}
/*************************************************************/
/* */
/*判斷鍵是否按下 */
/* */
/*************************************************************/
void keydown(void)
{
P1=0xF0;
if(P1!=0xF0) //判斷按鍵是否按下 如果按鈕按下 會拉低P1其中的一個端口
{
delay(10);
if(P1!=0xF0)
{
keyscan();
P1=0xF0;
while(P1!=0xF0);
if(dis_buf=='A')
enter=1;
if(enter==0)
{
if(n==4)
n=0;
if(dis_buf!='B')
{
cdis3[n]=dis_buf;
n++;
}
}
if(dis_buf=='B')
enter=0;
}
}
}
/******************************ds1820程序***************************************/
void delay_18B20(unsigned int i)//延時1微秒
{
while(i--);
}
void ds1820rst()/*ds1820復位*/
{ unsigned char x=0;
DQ = 1; //DQ復位
delay_18B20(4); //延時
DQ = 0; //DQ拉低
delay_18B20(100); //精確延時大于480us
DQ = 1; //拉高
delay_18B20(40);
}
uchar ds1820rd()/*讀數(shù)據(jù)*/
{ unsigned char i=0;
unsigned char dat = 0;
for (i=8;i>0;i--)
{ DQ = 0; //給脈沖信號
dat>>=1;
DQ = 1; //給脈沖信號
if(DQ)
dat|=0x80;
delay_18B20(10);
}
return(dat);
}
void ds1820wr(uchar wdata)/*寫數(shù)據(jù)*/
{unsigned char i=0;
for (i=8; i>0; i--)
{ DQ = 0;
DQ = wdata&0x01;
delay_18B20(10);
DQ = 1;
wdata>>=1;
}
}
read_temp()/*讀取溫度值并轉(zhuǎn)換*/
{uchar a,b;
ds1820rst();
ds1820wr(0xcc);//*跳過讀序列號*/
ds1820wr(0x44);//*啟動溫度轉(zhuǎn)換*/
ds1820rst();
ds1820wr(0xcc);//*跳過讀序列號*/
ds1820wr(0xbe);//*讀取溫度*/
a=ds1820rd();
b=ds1820rd();
tvalue=b;
tvalue<<=8;
tvalue=tvalue|a;
if(tvalue<0x0fff)
tflag=0;
else
{tvalue=~tvalue+1;
tflag=1;
}
tvalue=tvalue*(0.625);//溫度值擴大10倍,精確到1位小數(shù)
return(tvalue);
}
/*******************************************************************/
void ds1820disp()//溫度值顯示
{ uchar flagdat;
disdata[0]=tvalue/1000+0x30;//百位數(shù)
disdata[1]=tvalue%1000/100+0x30;//十位數(shù)
disdata[2]=tvalue%100/10+0x30;//個位數(shù)
disdata[3]=tvalue%10+0x30;//小數(shù)位
if(tflag==0)
flagdat=0x20;//正溫度不顯示符號
else
flagdat=0x2d;//負溫度顯示負號:-
if(disdata[0]==0x30)
{disdata[0]=0x20;//如果百位為0,不顯示
if(disdata[1]==0x30)
{disdata[1]=0x20;//如果百位為0,十位為0也不顯示
}
}
lcd_pos(5);
lcd_wdat(flagdat);//顯示符號位
lcd_pos(6);
lcd_wdat(disdata[1]);//顯示十位
lcd_pos(7);
lcd_wdat(disdata[2]);//顯示個位
lcd_pos(8);
lcd_wdat(0x2e);//顯示小數(shù)點
lcd_pos(9);
lcd_wdat(disdata[3]);//顯示小數(shù)位
}
/*************蜂鳴器*********************************/
void fengming1(uchar tt)
{ if(tt!=1)
{
tt--;
RQ=1;
delay(100);
RQ=0;
delay(100);
}
}
void fengming2(uchar tt)
{ if(tt!=1)
{
tt--;
RQ=1;
delay(1000);
RQ=0;
delay(1000);
}
}
/*************************************************************/
/* */
/* 主程序 */
/* */
/*************************************************************/
main()
{
uchar m;
enter=0;
P0=0xFF; //置P0口
P1=0xFF; //置P1口
delay(10); //延時
lcd_init(); //初始化LCD
lcd_pos(0); //設(shè)置顯示位置為第一行的第1個字符
m = 0;
while(cdis1[m] != '\0')
{ //顯示字符
lcd_wdat(cdis1[m]);
m++;
}
lcd_pos(0x40); //設(shè)置顯示位置為第二行第1個字符
m = 0;
while(cdis2[m] != '\0')
{
lcd_wdat(cdis2[m]); //顯示字符
m++;
}
dis_buf = 0x2d; //顯示字符"-"
while(1)
{
read_temp();//讀取溫度
ds1820disp();//顯示
keydown();
lcd_pos(0x43);
for(m=0;m<2;m++)
{
lcd_wdat(cdis3[m]);
}
lcd_pos(0x4d);
for(m=2;m<4;m++)
{
lcd_wdat(cdis3[m]);
}
if(enter==1)
{
buf1=cdis3[0]*10+cdis3[1];
buf2=cdis3[2]*10+cdis3[3];
buf3=disdata[1]*10+disdata[2];
if(buf1 < buf3)
{fengming1(100); }
if(buf2 > buf3)
{fengming2(100); }
}
}
}
作者: admin 時間: 2018-11-8 14:34
補全原理圖或者詳細說明一下電路連接即可獲得100+黑幣
| 歡迎光臨 (http://m.raoushi.com/bbs/) |
Powered by Discuz! X3.1 |