選用材料為藍橋杯官方提供的開發板。
因為此板選用了4塊74LS573芯片用于鎖存P0口信號,這種設計可節約很多的i/0口,與市面上很多的開發板不一樣,所以如果要換到其他開發板上使用,需要改一下顯示代碼 和LED亮滅代碼,但是大致思路不變,只要改變一下那幾個比較特殊的使用到了573鎖存來編程的函數即可。
我也是一名菜雞 如果有那個大神有更好的編程思路的話 那就拜托大神賜教了。
設計要求如下:
1、 讀取DS18B20溫度,在數碼管的最后兩位顯示。
2、讀取DS1302時間,初始化為13:30。在數碼管的高五位顯示,格式為:13-30
3、其余沒用到的數碼管滅。
4、通過串口設置DS18B20溫度上限和下限,設置格式為:30-28,其中30是高溫上限,28是低溫下限
5、采集DS18B20溫度,通過串口上傳實時數據給上位機。
6、當溫度超過上限,LED1隔1秒亮一次。超過下限,LED2隔1秒亮一次。
7、串口波特率一律用2400bps
效果圖:
1.png (36.23 KB, 下載次數: 46)
下載附件
2018-1-13 16:09 上傳
3.jpg (138.65 KB, 下載次數: 37)
下載附件
2018-1-13 16:09 上傳
代碼如下:
- #include<reg52.h>
- #include<intrins.h> //_nop_()延時函數頭文件
- #define uchar unsigned char
- #define uint unsigned int
- sfr AUXR=0x8e; //定義stc15芯片的特殊寄存器AUXR地址 因為采用的是52的頭文件 如果采用15的頭文件擇不用設置
- // 如果改為51系列芯片的話只需刪掉這行然后把定時器和中斷的初始化函數改掉 此寄存器的作用在此為設置定時器速度為1T還是12T模式
- sbit DQ=P1^4; //溫度引腳
- sbit CE=P1^3; //1302芯片引腳
- sbit SCL=P1^7;
- sbit io=P2^3;
- uchar code tab[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XBF,0XFF}; //共陽數碼管數值
- // 0, 1 , 2 , 3 , 4 ........ — ,關顯示
- uchar dspbuf[]={11,11,11,11,11,11,11,11}; //顯示緩沖區
- uchar DSP;
- uchar zi[]={"wendu:"}; //串口發送數據
- uchar jieshou[6];
- uchar zd4_add;
- uchar max,min;
- uchar cmd_ds[3]; //接收1302時間
- uchar int_ds[]={30,13,0,0,0,0}; //初始化1302
- uchar temp;
- uint sec_add;
- bit sec_flag;
- bit sz_flag;
- void int_t0(); //定時器t0初始化
- void int_chuankou(); //串口初始化
- void display();
- //*********************1302*****************************************//
- void DS1302_wuchar(uchar cmd); //寫一個字節到1302
- uchar DS1302_ruchar(); //讀取一個字節
- void write_DS1302(uchar cmd,uchar dat); //寫dat數據到cmd寄存器地址
- uchar red_DS1302(uchar cmd); //讀取cmd地址中的數據
- void red_ds(); //讀取全部時間
- void int_DS1302(); //初始化1302
- //***********************溫度函數**********************************//
- void w_18(uchar cmd); //寫cmd到1820
- uchar r_18(); //讀取一個字節
- uchar red_18(); //讀取溫度
- void int_18(); //初始化溫度
- void Delay500us(); //延時
- void Delay100us();
- void open_led1(); //開LED1
- void cls_led1(); //關LED1
- void open_led2();
- void cls_led2();
- void ckfz(); //串口發送
- void main()
- {
- max=30; //初始最大值與最小值
- min=28;
- int_t0(); //初始化定時器t0
- int_DS1302(); //初始化1302
- int_chuankou(); //串口初始化
- while(1)
- {
- temp=red_18(); //讀取溫度
- red_ds(); //讀取時間
- dspbuf[6]=temp/10; //顯示
- dspbuf[7]=temp%10; //顯示格式為 xx—xx xx
- dspbuf[0]=cmd_ds[1]/10;
- dspbuf[1]=cmd_ds[1]%10;
- dspbuf[2]=10; //顯示橫杠
- dspbuf[3]=cmd_ds[0]/10;
- dspbuf[4]=cmd_ds[0]%10;
- ckfz(); //串口發送溫度到PC
- if(sz_flag) //如果串口接收到修改最大值最小值指令 sz_flag會由0變1 最大值與最小值更新
- {
- max=jieshou[0]*10+jieshou[1];
- min=jieshou[3]*10+jieshou[4];
- sz_flag=0; //標志位清零
- }
- // dspbuf[6]=jieshou[0];
- // dspbuf[7]=jieshou[1];
- // dspbuf[2]=jieshou[2];
- // dspbuf[3]=jieshou[3];
- // dspbuf[4]=jieshou[4];
- }
- }
- void t0() interrupt 1
- {
- sec_add++;
- if(sec_add==1000) //1s
- {
- sec_add=0;
- sec_flag=~sec_flag; //1秒標志位
- }
- if(temp>max) //如果溫度大于最大值 LED1隔1秒閃爍
- {
- if(sec_flag)
- {open_led1();}
- else
- {cls_led1();}
- }
- if(temp<min) //如果溫度小于最小值 LED2隔1秒閃爍
- {
- if(sec_flag)
- {open_led2();}
- else
- {cls_led2();}
- }
- display(); //中斷刷新顯示函數
- }
- void ck() interrupt 4 //串口接收中斷
- {
- if(RI) //如果RI接收標志位為1
- {
- EA=0;
- RI=0;
- jieshou[zd4_add]=SBUF-48; //接收 xx-xx格式數據 5個字節 串口應為文本發送 因為字符0 代表十進制48 所以應減去48 才是10進制的0
- zd4_add++;
- if(zd4_add==5) //接收5次
- zd4_add=0;
- EA=1;
- }
- sz_flag=1; //單片機接收到數據時 sz_flag=1
- }
- void int_t0()
- {
- AUXR |= 0x80; //定時器時鐘1T模式
- TMOD &= 0xF0; //設置定時器模式
- TL0 = 0x9A; //設置定時初值 //1ms延時
- TH0 = 0xA9; //設置定時初值
- TF0 = 0; //清除TF0標志
- TR0 = 1; //定時器0開始計時
- EA=1;
- ET0=1;
- }
- void int_chuankou() //2400波特率
- {
- SCON = 0x50; //8位數據,可變波特率
- AUXR |= 0x40; //定時器1時鐘為Fosc,即1T
- AUXR &= 0xFE; //串口1選擇定時器1為波特率發生器
- TMOD &= 0x0F; //設定定時器1為16位自動重裝方式
- TL1 = 0x80; //設定定時初值
- TH1 = 0xFB; //設定定時初值
- ET1 = 0; //關閉定時器1中斷
- ES=1; //開啟串口中斷
- TR1 = 1; //啟動定時器1
- }
- void display() //顯示函數
- {
- P2=(P2&0x1f)|0xe0; //關顯示
- P0=0xff;
- P2&=0X1F;
- P2=(P2&0x1f)|0xc0; //位選
- P0=1<<DSP;
- P2&=0X1F;
- P2=(P2&0x1f)|0xe0; //查表顯示
- P0=tab[dspbuf[DSP]];
- P2&=0X1F;
- DSP++;
- if(DSP==8)
- DSP=0;
- }
- //******************溫度函數************************//
- void int_18() //初始化溫度傳感器
- {
- DQ = 0;
- Delay500us();// 延時大于480us
- DQ = 1;
- Delay500us();
- }
- void w_18(uchar cmd)
- {
- uchar i;
- for(i=0;i<8;i++)
- {
- DQ=0;
- DQ=cmd&0x01; //從低位寫起
- Delay100us();
- DQ=1;
- cmd>>=1;
- }
- }
- uchar r_18()
- {
- uchar num,i;
- for(i=0;i<8;i++)
- {
- DQ=0; //溫度從低位讀起
- num>>=1;
- DQ=1;
- if(DQ)
- {
- num=num|0x80;
- }
- Delay100us();
- }
- return num;
- }
- uchar red_18()
- {
- uchar low,high,num;
- int_18();
- w_18(0xcc);
- w_18(0x44);
- // Delayus(200);
-
- int_18();
- w_18(0xcc);
- w_18(0xbe);
- low=r_18(); //先讀低八位
- high=r_18();
- num=high<<4;
- num=num|(low>>4);
- return num;
- }
- void Delay500us() //@11.0592MHz
- {
- unsigned char i, j;
- _nop_();
- _nop_();
- i = 6;
- j = 93;
- do
- {
- while (--j);
- } while (--i);
- }
- void Delay100us() //@11.0592MHz
- {
- unsigned char i, j;
- _nop_();
- _nop_();
- i = 2;
- j = 15;
- do
- {
- while (--j);
- } while (--i);
- }
- //**************DS1302****************//
- void int_DS1302() //初始化DS1302,把int_ds[]數組里的數寫入相應時間寄存器地址
- {
- write_DS1302(0x8e,0x00); //寫保護關
- write_DS1302(0x80,int_ds[0]);
- write_DS1302(0x82,int_ds[1]);
- write_DS1302(0x8e,0x80); //寫保護開
- }
- void DS1302_wuchar(uchar cmd)
- {
- uchar i;
- for(i=0;i<8;i++)
- {
- SCL=0;
- io=cmd&0x01;
- SCL=1;
- cmd>>=1;
- }
- }
- uchar DS1302_ruchar()
- {
- uchar dat,i;
- for(i=0;i<8;i++)
- {
- SCL=0;
- dat>>=1;
- if(io)
- dat|=0x80;
- SCL=1;
- }
- return dat;
- }
- void write_DS1302(uchar cmd,uchar dat)
- {
- uchar x;
- CE=0;
- SCL=0;
- CE=1;
- DS1302_wuchar(cmd);
- x=(dat/10<<4)|(dat%10);//十進制轉換十六進制
- DS1302_wuchar(x);
- CE=0;
- }
- uchar red_DS1302(uchar cmd)
- {
- uchar dat;
- uchar dat1,dat2;
- CE=0;
- SCL=0;
- CE=1;
- DS1302_wuchar(cmd);
- dat=DS1302_ruchar();
- dat1=dat/16; //十六進制轉十進制
- dat2=dat%16;
- dat=dat1*10+dat2;
- io=0;
- CE=0;
- return dat;
- }
- void red_ds()
- {
- write_DS1302(0x8e,0x00);
- cmd_ds[0]=red_DS1302(0x81);
- cmd_ds[1]=red_DS1302(0x83);
- write_DS1302(0x8e,0x80);
- }
- void ckfz()
- {
- uchar i;
- if(sec_flag)
- {
- for(i=0;i<6;i++) //發送溫度數據到PC
- {
- SBUF=zi[i];
- while(TI==0);
- TI=0;
- }
- SBUF=temp/10+0x30;//(temp/10)<<4|(temp%10);
- while(TI==0);
- TI=0;
- SBUF=temp%10+0x30;//(temp/10)<<4|(temp%10);
- while(TI==0);
- TI=0;
- SBUF='\n';
- while(TI==0);
- TI=0;
- sec_flag=0;
- }
- }
- void open_led1()
- {
- P2=(P2&0x1f)|0x80;
- P0=0x7f;
- P2&=0x1f;
- }
- void cls_led1()
- {
- P2=(P2&0x1f)|0x80;
- P0=0xff;
- P2&=0x1f;
- }
- void open_led2()
- {
- P2=(P2&0x1f)|0x80;
- P0=0xbf;
- P2&=0x1f;
- }
- void cls_led2()
- {
- P2=(P2&0x1f)|0x80;
- P0=0xff;
- P2&=0x1f;
- }
復制代碼
附上代碼和原理圖
2012.rar
(312.39 KB, 下載次數: 25)
2018-1-13 16:13 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|