久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2426|回復: 4
收起左側

求大神看一下 自己做的萬年歷 最高溫度顯示為16

[復制鏈接]
ID:258570 發表于 2017-12-13 00:36 | 顯示全部樓層 |閱讀模式
/**
程序功能:顯示年月日,時分秒,星期,溫度
*/
#include <reg52.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit RS=P2^5;//數據命令選擇端
sbit RW=P2^6;//讀寫選擇端
sbit E=P2^7;//控制使能端
sbit DQ=P1^0;

sbit RST=P2^4;//片選輸入信號端
sbit IO=P2^3;//串行時鐘輸入端
sbit CLK=P2^2;//串行數據輸入輸出端

uchar str1[16];
uchar str2[16];
uchar str3[16];
uchar second,minute,hour,day,month,year,week,yearH=20;


sbit select=P3^2;//選擇調整部分按鈕
sbit up=P3^1;//加按鈕
sbit down=P3^0;//減按鈕
void jisuan();
void jisuan1();
void display();
void gettemp();
//temp:臨時變量,用于保存要寫入ds1302的內容
//count:調整部分計數,1:年,2:月,3:日,
//                   4:時,5:分,6:秒,7:星期,8:退出調整
//done:調整標志,1:調整,0:不調整
//flag:時鐘停止標志,1:走,0:停
//up_flag:加按鍵操作標志;down_flag:減按鍵操作標志
uchar temp=0x00,count=8,flag,done,up_flag,down_flag;
uchar t,flag_t;
void delay(uint x){//毫秒級的延時
    uint i,j;
    for(i=0;i<x;i++)
        for(j=0;j<120;j++);
}
//////////////////1602操作////////////////////////////
uint checkBusy(){//檢查忙標志
    uchar temp;
    P0=0xff;//I/O口準備
    RS=0;//選擇指令寄存器
    RW=1;//選擇讀模式
    E=1;//使能LCD
    _nop_();_nop_();_nop_();_nop_();//延時        
    temp=P0&0x80;//取忙標志
    E=0;//禁止LCD
    if(temp!=0x00)return 1;//忙返回1
    else return 0;//不忙返回0
}
void writeIR(uchar cmd){//寫指令
    while(checkBusy());//檢查忙狀態
    RS=0;//選擇指令模式
    RW=0;//選擇寫模式
    E=0;//禁止LCD
    P0=cmd;//寫入命令字
    _nop_();_nop_();_nop_();_nop_();//延時       
    E=1;//使能LCD
    _nop_();_nop_();_nop_();_nop_();//延時
    E=0;//禁止LCD
}
void writecom(uchar com)
{
        checkBusy();
       
        RS=0;
        RW=0;
        E=0;
        P0=com;
        delay(3);
        E=1;
        delay(3);
        E=0;
}
void writeDDR(uchar dat){//寫數據
    while(checkBusy());//檢查忙狀態
    RS=1;//選擇數據模式
    RW=0;//選擇寫模式
    E=0;//禁止LCD
    P0=dat;//寫入數據
    _nop_();_nop_();_nop_();_nop_();//延時
    E=1;//使能LCD
    _nop_();_nop_();_nop_();_nop_();//延時
    E=0;//禁止LCD
}
void showstr(uchar str[]){
        uint i;
        i=0;
    while(str[i]!='\0'){     
        writeDDR(str[i]);//顯示字符
        i++;
    }
}
///////////////////顯示子函數//////////////////////
/*void  display(){
        jisuan();
        writeIR(0x80);
        showstr(str1);
        writeIR(0xc0);
        showstr(str2);
}*/


/////////////////DS1302操作//////////////////////////
//DS1302:寫入操作(寫一個字節,上升沿操作)
void write_byte(uchar da){
        uchar i,temp;
        temp=da;//要寫的數據送入臨時變量temp
        for(i=8;i>0;i--){//將一個字節的數據分8次,一位一位送數據線         
                IO=temp&0x01;//將臨時變量temp的最低位送入IO數據線
                CLK=0; //時鐘信號拉低   
            CLK=1;//時鐘信號拉高
              temp=temp>>1;//將下次要送的那位數據送到臨時變量temp最低位
        }
        CLK=0;//寫完一字節數據后,拉低時鐘信號
}
//DS1302:讀取操作(讀一個字節,下降沿)
uchar read_byte()
{
        uchar i,a;
        a=0x00;//a清0,這步也可不做
        for(i=0;i<8;i++){//一個字節的數據分8次讀,一位一位從數據線讀
       
             a=a>>1;//空出臨時變量a的最高位
                if(IO)a=a|0x80;//從數據線上讀位數據到臨時變量a的最高位
                else a=a|0x00;
                  CLK=1;        //時鐘信號拉高
                  CLK=0;        //時鐘信號拉低  
        }
        CLK=0;//讀完一字節數據后,拉低時鐘信號
        return a;//將臨時變量a內的值返回
}
//DS1302:寫入數據(先送地址,再寫數據)
void write_1302(uchar addr,uchar da){
           RST=0;    //停止工作
           CLK=0;    //時鐘信號拉低                             
           RST=1;   //重新工作
           write_byte(addr);    //寫入地址
          write_byte(da);//寫入數據(da是十六進制數據,BCD碼)
           CLK=0;//時鐘信號拉低
           RST=0;//停止工作
}
//DS1302:讀取數據(先送地址,再讀數據),讀出的數據是BCD碼
uchar read_1302(uchar addr)
{
           uchar temp;
           RST=0;   //停止工作
           CLK=0; //時鐘信號拉低
          RST=1;//重新工作
           write_byte(addr);   //寫入地址
           temp=read_byte();//讀取數據(16進制,BCD碼)
           CLK=0;//時鐘信號拉低
           RST=0;//停止工作  
        return temp;
}
uchar toDEC(uchar da){
        uchar temp,dat1,dat2;
        temp=da;
        dat1=temp/16;     //提取BCD碼的十位和個位
          dat2=temp%16;
          temp=dat1*10+dat2;     //轉換成10進制數
           return temp;
}
uchar toBCD(uchar da){
        uchar temp;
        temp=(da/10)<<4|(da%10);//轉換成BCD碼
        return temp;
}
void setProtect(bit flag){
        if(flag)
                write_1302(0x8e,0x80);//打開寫保護
        else
                write_1302(0x8e,0x00);//關閉寫保護
}
//設置時間函數提供參數:控制字,要寫入的10進制數據
void setTime(uchar addr,uchar da){
        setProtect(0);//關閉寫保護
          write_1302(addr,toBCD(da));//寫入BCD碼到指定寄存器
}
void getTime(){//獲取時鐘芯片的時鐘數據
        second=read_1302(0x81);//讀秒(BCD碼)
        second=toDEC(second&0x7f);//BCD碼轉十進制
        minute=read_1302(0x83);//讀分(BCD碼)
        minute=toDEC(minute);//BCD碼轉十進制
        hour=read_1302(0x85);//讀時(BCD碼)
        hour=toDEC(hour);//BCD碼轉十進制
        day=read_1302(0x87);//讀日(BCD碼)]
        day=toDEC(day);//BCD碼轉十進制
        month=read_1302(0x89);//讀月(BCD碼)
        month=toDEC(month);//BCD碼轉十進制
        year=read_1302(0x8d);//讀年(BCD碼)
        year=toDEC(year);//BCD碼轉十進制
        week=read_1302(0x8b);//讀星期(BCD碼)
        week=toDEC(week);//BCD碼轉十進制       
}

void jisuan(){//計算子程序,計算時間各位的值
        uint i;
        i=week-1;
        if(i==0)i=7;         
        str1[0]=yearH/10+'0';//提取年的千位
        str1[1]=yearH%10+'0';//提取年的百位
        str1[2]=year/10+'0';//提取年的十位
        str1[3]=year%10+'0';//提取年的個位
        str1[4]='-';
        str1[5]=month/10+'0';//提取月的十位
        str1[6]=month%10+'0';//提取月的個位
        str1[7]='-';
        str1[8]=day/10+'0';//提取日的十位
        str1[9]=day%10+'0';//提取日的個位
        str1[10]=' ';
        str1[11]=' ';
        str1[12]=i+'0';//星期
        str2[0]=hour/10+'0';//提取小時的十位
        str2[1]=hour%10+'0';//提取小時的個位
        str2[2]=':';
        str2[3]=minute/10+'0';//提取分鐘的十位
        str2[4]=minute%10+'0';//提取分鐘的個位
        str2[5]=':';
        str2[6]=second/10+'0';//提取秒鐘的十位
        str2[7]=second%10+'0';//提取秒鐘的個位
        str2[8]=' ';

         
}
void initial(){//初始化函數
        uchar second=read_1302(0x81);
        if(second&0x80){//時鐘停止,則初始化
                setTime(0x80,0);
                setTime(0x82,20);
                setTime(0x84,8);
                setTime(0x86,1);
                setTime(0x88,6);
                setTime(0x8a,5);
                setTime(0x8c,12);
        }
}

//按鍵部分程序

void Upkey(){//加按鈕
        up=1;
        if(up==0){ //加按鍵按下
                delay(10);
                if(up==0){//加按鍵確實按下
                        switch(count){//根據選擇的模塊進行調整
                                case 7://調整星期
                                                temp=week+1;//秒數加1
                                                if(week==7) temp=1;//越界處理
                                                up_flag=1;//數據調整后更新標志
                                                break;
                                case 6://調整秒
                                                temp=second+1;//秒數加1
                                                if(second==59) temp=0;//越界處理
                                                up_flag=1;//數據調整后更新標志
                                                break;
                                case 5://調整分
                                                temp=minute+1;//分數加1
                                                if(minute==59) temp=0;//越界處理
                                                up_flag=1;//數據調整后更新標志
                                                break;
                                case 4://調整時
                                                temp=hour+1;//小時數加1
                                                if(hour==23) temp=0;//越界處理
                                                up_flag=1;//數據調整后更新標志
                                                break;
                                case 3://調整日
                                                temp=day+1;//日數加1
                                                if(day==31) temp=1;//越界處理
                                                up_flag=1;//數據調整后更新標志
                                                break;
                                case 2://調整月
                                                temp=month+1;//月數加1
                                                if(month==12) temp=1;//越界處理
                                                up_flag=1;//數據調整后更新標志
                                                break;
                                case 1://調整年
                                                temp=year+1;//年數加1
                                                if(year==99){ temp=0;yearH=yearH+1;}//越界處理
                                                up_flag=1;//數據調整后更新標志
                                                break;
                                default:break;
                        }
                        while(up==0)display();
                }
        }
}
void Downkey(){//減按鈕
        down=1;
        if(down==0){
                delay(10);
                if(down==0){
                        switch(count){
                                case 7://調整星期
                                        temp=week-1;
                                        if(week==0) temp=7;
                                        down_flag=1;
                                        break;
                                case 6://調整秒
                                        temp=second-1;
                                        if(second==0) temp=59;
                                        down_flag=1;
                                        break;
                                case 5://調整分
                                        temp=minute-1;
                                        if(minute==0) temp=59;
                                        down_flag=1;
                                        break;
                                case 4://調整時
                                        temp=hour-1;
                                        if(hour==0) temp=23;
                                        down_flag=1;
                                        break;
                                case 3://調整日
                                        temp=day-1;
                                        if(day==1) temp=31;
                                        down_flag=1;
                                        break;
                                case 2://調整月
                                        temp=month-1;
                                        if(month==1) temp=12;
                                        down_flag=1;
                                        break;
                                case 1://調整年
                                        temp=year-1;
                                        if(year==0){ temp=99;yearH=yearH-1;}
                                        down_flag=1;
                                        break;
                                default:break;
                        }
                        while(down==0)display();
                }
        }
}
void Selkey(){//調整部分選擇按鍵
        select=1;
        if(select==0){
                delay(10);
                if(select==0){
                        count=count+1;
                        if(count==9) count=1;//調整部分計數加1
                        done=1;//進入調整模式
                }
        }
        while(select==0)display();
}
void keydone(){//按鍵功能執行       
        if(flag==0){//關閉時鐘,停止計時
                setProtect(0);//寫入允許
                temp=read_1302(0x81);
                write_1302(0x80,temp|0x80);
                setProtect(1);//禁止寫入
                flag=1;
        }
        Selkey();//掃描調整部分選擇按鍵
        switch(count){
                case 1:do{
                                        Upkey();//掃描加按鈕
                                        Downkey();//掃描減按鈕
                                        if(up_flag==1||down_flag==1){//數據更新,重新寫入新的數據
                                                setProtect(0);//寫入允許
                                                write_1302(0x8c,toBCD(temp));//寫入新的年數
                                                setProtect(1);//禁止寫入
                                                up_flag=0;
                                                down_flag=0;
                                        }
                                        getTime();
                                        display();
                                }while(count==2);
                                break;
                case 2:do{
                                        Upkey();//掃描加按鈕
                                        Downkey();//掃描減按鈕
                                        if(up_flag==1||down_flag==1){//數據更新,重新寫入新的數據
                                                setProtect(0);//寫入允許
                                                write_1302(0x88,toBCD(temp));//寫入新的月數
                                                setProtect(1);//禁止寫入
                                                up_flag=0;
                                                down_flag=0;
                                        }
                                        getTime();
                                        display();
                                }while(count==3);
                                break;
                case 3:do{
                                        Upkey();//掃描加按鈕
                                        Downkey();//掃描減按鈕
                                        if(up_flag==1||down_flag==1){//數據更新,重新寫入新的數據
                                                setProtect(0);//寫入允許
                                                write_1302(0x86,toBCD(temp));//寫入新的日數
                                                setProtect(1);//禁止寫入
                                                up_flag=0;
                                                down_flag=0;
                                        }
                                        getTime();
                                        display();
                                }while(count==4);
                                break;
                case 4:do{//調整時
                                        Upkey();//掃描加按鈕
                                        Downkey();//掃描減按鈕
                                        if(up_flag==1||down_flag==1){//數據更新,重新寫入新的數據
                                                setProtect(0);//寫入允許
                                                write_1302(0x84,toBCD(temp));//寫入新的小時數
                                                setProtect(1);//禁止寫入
                                                up_flag=0;
                                                down_flag=0;
                                        }
                                        getTime();
                                        display();
                                }while(count==5);
                                break;
                case 5:do{//調整分
                                        Upkey();//掃描加按鈕
                                        Downkey();//掃描減按鈕
                                        if(up_flag==1||down_flag==1){//數據更新,重新寫入新的數據
                                                setProtect(0);//寫入允許
                                                write_1302(0x82,toBCD(temp));//寫入新的分數
                                                setProtect(1);//禁止寫入
                                                up_flag=0;
                                                down_flag=0;
                                        }
                                        getTime();
                                        display();
                                }while(count==6);
                                break;
                case 6:do{//調整秒
                                        Upkey();//掃描加按鈕
                                        Downkey();//掃描減按鈕
                                        if(up_flag==1||down_flag==1){//數據更新,重新寫入新的數據
                                                setProtect(0);//寫入允許
                                                write_1302(0x80,toBCD(temp)|0x80);//寫入新的秒數
                                                setProtect(1);//禁止寫入
                                                up_flag=0;
                                                down_flag=0;
                                        }
                                        getTime();
                                        display();
                                }while(count==7);
                                break;
                case 7:do{//調整星期
                                        Upkey();//掃描加按鈕
                                        Downkey();//掃描減按鈕
                                        if(up_flag==1||down_flag==1){//數據更新,重新寫入新的數據
                                                setProtect(0);//寫入允許
                                                write_1302(0x8a,toBCD(temp));//寫入新的星期數
                                                setProtect(1);//禁止寫入
                                                up_flag=0;
                                                down_flag=0;
                                        }
                                        getTime();
                                        display();
                                }while(count==8);
                                break;
                case 8:do{
                                                count=0;
                                                second=read_1302(0x81);
                                                setProtect(0);//寫入允許
                                                write_1302(0x80,second&0x7f);
                                                setProtect(1);//禁止寫入
                                                done=0;
                                                display();
                                        }while(count==9);
                                        break;
                default:break;
        }
}

////////////////////主函數////////////////////////
/*void main(){
    //1602初始化工作
    writeIR(0x01);//清屏,同時光標移到左上角  
    writeIR(0x38);//功能設置:8位接口,2行,5*7字符  
    writeIR(0x0c);//控制字符、光標及閃爍:顯示器開,光標關,光標不閃爍
    writeIR(0x06);//輸入方式設置指令:光標不動,字符自動右移一格  
    //writeIR(0x80);//送DDRAM地址設置指令80H,從第1行第1列開始顯示
    //DS1302初始化工作
        flag=1;
        initial();
        up_flag=0;
        down_flag=0;
        done=0;
        while(1){
        while(done==1)keydone();
                while(done==0){
                        getTime();
                        display();
                        flag=0;
                        Selkey();
                }
    }
}*/
/////////////////////////////////////////////////////////////////
void  display(){
        jisuan();
        writeIR(0x80);
        showstr(str1);
        writeIR(0xc0);
        showstr(str2);
        writecom(0x80);
        showstr(str1);
        writecom(0xc0);
        showstr(str2);
                jisuan1();
        writecom(0x00);
        showstr(str3);
}
void jisuan1(){//計算子程序,計算時間各位的值
        //uint i;
        if(flag_t)str3[0]='-';
        else str3[0]='+';
        str3[1]=t%1000/100+'0';
        str3[2]=t%100/10+'0';
        str3[3]='.';
        str3[4]=t%10+'0';
        str3[5]=223;
        str3[6]='C';
}

///////////////////DS18B20操作//////////////////////
//延時us級
void delay_us(uchar us){
        while(us--);
}

//初始化DS18B20
bit reset(){
        bit flag;//初始化標志位
        DQ=1;//dq復位,也可以不要
        delay_us(1);//稍做延時
        DQ=0;//單片機將dq拉低
        delay_us(80);//精確延時大于480us
        DQ=1;//拉高總線
        delay_us(8);//延時
        flag=DQ;//flag=0初始化成功,flag=1則初始化失敗
        delay_us(20);
        return flag;
}
//DS18B20寫一個字節
void write_tbyte(uchar dat){
        uchar i;
        bit onebit;
        for(i=0;i<8;i++){//一位一位寫數據
                onebit=dat&0x01;//提取要寫數據的最低位
                dat=dat>>1;//數據右移,準備下一次數據的提取
                if(onebit){//要寫位為1時
                        DQ=0;//dq拉低時,空操作
                        _nop_();
                        _nop_();
                        DQ=1;//dq拉高時,延時
                        delay_us(5);
                }
                else{//要寫位為0時
                        DQ=0;//dq拉低時,延時
                        delay_us(8);
                        DQ=1;//dq拉高時,空操作
                        _nop_();
                        _nop_();
                }
        }
}
//DS18B20讀一個位
bit read_tbit(){
        bit dat;
        DQ=0;//dq拉低,1us之后釋放總線(即拉高dq)
        _nop_();
        DQ=1;//dq拉高
        _nop_();
        _nop_();
        dat=DQ;//從總線dq上讀位數據
        delay_us(10);//延時,確保讀時序的長度60us
        return dat;
}
//DS18B20讀一個字節
uchar read_tbyte(){
        uchar value,i,j;
        value=0;//value初始化清0,用于保存每次讀取
           //1位后的字節數據
        for(i=0;i<8;i++){//一位一位讀數據(從最低位開始)
                j=read_tbit();//讀位數據到j的最低位
                value=(j<<7)|(value>>1);//構造讀取的數據
//構造原理:第一步,將剛讀到的位數據移到j的最高位
//第二步,將前一次讀取的數據值右移一位
//第三步,將新的j與新的value進行或操作,
//得到當前新的讀取數據
        }
        return value;
}
uint getTemp(){
        uchar a,b;
        float f_temp;//定義浮點型溫度數據
       
        if(!reset()){//如果初始化成功
                write_tbyte(0xcc);//跳過ROM
                write_tbyte(0x44);//溫度轉換
        }
        if(!reset()){//如果初始化成功
                write_tbyte(0xcc);//跳過ROM
                write_tbyte(0xbe);//讀暫存器
                a=read_tbyte();//讀取溫度低8位
                b=read_tbyte();//讀取溫度高8位
        }
        flag_t=0;
        t=b;//把溫度數據的高8位賦給整型溫度數據temp的低8位
        t<<=8;//把以上8位數據從temp的低8位移到高8位
        t=t|a;//兩字節合并得到整型變量
        if(t>0x0fff){
                flag_t=1;       
                t=~t+1;
        }
        f_temp=t*0.0625;//得到真實的浮點型溫度數據
        t=f_temp*10+0.5;//將浮點型溫度數據放大十倍,并加0.5(加0.5是用于四舍五入)
                                                        //然后將處理后的浮點型溫度數據強制取整,賦給整型溫度數據
                                                        //這個賦值語句的目的將小數點后第一位也轉換為可顯示數字
        return t;
}
void main(){

    //1602初始化工作
    writeIR(0x01);//清屏,同時光標移到左上角  
    writeIR(0x38);//功能設置:8位接口,2行,5*7字符  
    writeIR(0x0c);//控制字符、光標及閃爍:顯示器開,光標關,光標不閃爍
    writeIR(0x06);//輸入方式設置指令:光標不動,字符自動右移一格  
    //writeIR(0x80);//送DDRAM地址設置指令80H,從第1行第1列開始顯示
    //DS1302初始化工作
        flag=1;

        initial();
        up_flag=0;
        down_flag=0;
        done=0;
        while(1){
        while(done==1)keydone();
                while(done==0){
                        getTime();
                        gettemp();
                        display();
                        flag=0;
                        Selkey();
                }
    }
}
這是我的程序   但是最高的溫度就是16°  超過16的部分都重新來

回復

使用道具 舉報

ID:260964 發表于 2017-12-13 09:44 | 顯示全部樓層
666666.做的可以 太長了吧
回復

使用道具 舉報

ID:260584 發表于 2017-12-13 11:09 | 顯示全部樓層
看了看,還可以
回復

使用道具 舉報

ID:255579 發表于 2017-12-14 09:15 | 顯示全部樓層
自我感覺你缺少的是溫度檢測那一部分的代碼設計和實體部件的設置
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 亚洲精品久久久久久宅男 | 超碰成人av| 91麻豆精品国产91久久久久久久久 | 国产精品特级片 | 91精品国产一区二区三区 | 亚洲精品免费视频 | 中文字幕一区二区三区精彩视频 | 久久午夜精品福利一区二区 | 草久久| 国产精品免费一区二区三区四区 | 午夜欧美 | 日本在线视频不卡 | 亚洲精品电影 | 99re在线免费视频 | 特黄特色大片免费视频观看 | 欧洲一级视频 | 欧美精品久久 | h视频在线播放 | 91麻豆产精品久久久久久 | 在线播放中文字幕 | 国产欧美一级二级三级在线视频 | 中文字幕国产精品 | 国产精久久久久久久妇剪断 | 日韩精品在线观看网站 | 精品一区二区三区在线观看国产 | 激情a| 免费成人在线网站 | 色天天综合 | 国产成人久久精品一区二区三区 | 欧美二区在线 | 一区二区三区高清在线观看 | v亚洲 | 亚洲色图综合 | 国产精品久久久久久婷婷天堂 | 欧美亚洲综合久久 | 午夜精品一区二区三区免费视频 | 人人精品 | 日韩电影免费在线观看中文字幕 | 精品欧美一区二区三区久久久 | 国产精品美女久久久 | 欧美日韩福利视频 |