一年多沒碰51單片機(jī)了,當(dāng)時(shí)還是為STM32過(guò)渡學(xué)習(xí)的。
這期開了單片機(jī)專業(yè)課,不得不重拾起來(lái)。想吐槽的就是,課上還用的proteus而不是實(shí)物,去年自學(xué)我好歹還五十來(lái)塊,買了個(gè)普中的。
大前天上午開了節(jié)實(shí)驗(yàn)課,一共五個(gè)實(shí)驗(yàn)。
- 流水燈
- 外部中斷
- 數(shù)碼管,定時(shí)器
- 矩陣鍵盤,串口
- 空調(diào)模擬。。。。。。。
前天晚上都做完了,算是初步掌握了proteus簡(jiǎn)單操作吧。本想用DS18B20測(cè)溫,百度搜了加熱元器件無(wú)果,就用燈泡指望燈絲加熱,降溫用一個(gè)風(fēng)扇轉(zhuǎn)轉(zhuǎn),做一個(gè)仿真真正能閉環(huán)控制的,但是proteus好像無(wú)法仿真出環(huán)境溫度的變化。模擬不出來(lái)就模擬不出來(lái)吧,做出來(lái)的意思到了就行。
DS18B20有點(diǎn)玄乎,初始化時(shí)序那邊在proteus上面需要改改,不然失敗了,就只顯示000.60還是什么數(shù)字來(lái)著。按理說(shuō)當(dāng)時(shí)實(shí)物也用的普中例程里面的能運(yùn)行才對(duì)。時(shí)序數(shù)值稍改了一下,能正常讀值測(cè)溫了。顯示部分用的數(shù)碼管,懶得在仿真上面費(fèi)工夫再去弄LCD1602了,有得有失吧,弊端就是讀DS18B20溫度時(shí),讀取函數(shù)放在數(shù)碼管顯示測(cè)得溫度和按鈕設(shè)定溫度之間,時(shí)間超出了視覺停留,會(huì)帶點(diǎn)閃動(dòng)。用1602就沒這問題了,但玩過(guò)實(shí)物了,仿真沒興趣。矩陣鍵盤仿真圖里面放了,但沒有使用到,用了兩個(gè)帶外部中斷的按鈕,實(shí)現(xiàn)增溫減溫的功能,代替了矩陣鍵盤,仿真原理圖里面沒有刪去,沒啥大礙。大燈泡和風(fēng)扇都用了個(gè)繼電器。風(fēng)扇沒用PWM波去驅(qū)動(dòng),圖省事,接電就轉(zhuǎn)。想想了,好像也沒啥了。
總的來(lái)說(shuō),難度一般,沒有隊(duì)里去年51任務(wù)最后一個(gè)難度大,要求做個(gè)萬(wàn)年歷帶溫度,密碼鎖,串口上位機(jī)能修改時(shí)間,設(shè)定鬧鈴時(shí)間,鬧鈴關(guān)還是開等等。
TIM圖片20200611110112.png (31.75 KB, 下載次數(shù): 34)
下載附件
2020-6-11 11:01 上傳
批注 2020-06-11 111340.png (42.14 KB, 下載次數(shù): 47)
下載附件
2020-6-11 11:14 上傳
對(duì)了,上面忘了提及了,左邊是檢測(cè)溫度,右邊是設(shè)定溫度。
用的多文件,proteus7版本的,keil4寫的。都是老版本莫得問題的話,應(yīng)該都能打開吧。用慣了keil5,再看看4真的簡(jiǎn)陋,喵的,而且結(jié)合32的CubeMX,更香。習(xí)慣了32的變量類型方式,uint8_t就是uchar,依此類推,或者詳見typedef.h文件。
代碼里面有些部分可能沒用到,但問題不大,工程是幾個(gè)實(shí)驗(yàn)慢慢添補(bǔ)的。沒記錯(cuò)的話,定時(shí)器那邊計(jì)數(shù)還是給交通燈實(shí)驗(yàn)三開著的沒關(guān)。
如果是我同學(xué)看到了這個(gè),起碼把原理圖位置改改,代碼函數(shù)變量改改,別照搬。我還要寫實(shí)驗(yàn)報(bào)告呢,課上我這實(shí)驗(yàn)也演示過(guò)了,雷同可不好哦。
做完算是分享吧,如果該文件有什么問題,可以私信我
單片機(jī)源程序如下:
- #include "reg52.h"
- #include "tydefine.h"
- #include "led.h"
- #include "timer.h"
- #include "exit.h"
- #include "ds18b20.h"
- #define GPIO_KEY P1
- sbit LSA = P2^2;
- sbit LSB = P2^3;
- sbit LSC = P2^4;
- sbit FAN = P2^6;
- sbit LAMP = P2^7;
- extern uint16_t SetTemNum;
- uint16_t CurrentTemNum = 0;
- uint8_t code DigitalTubeSegment[] ={
- 0x3f,0x06,0x5b,0x4f,0x66,
- 0x6d,0x7d,0x07,0x7f,0x6f
- };
- uint8_t KeyValue = 0;
- uint8_t DisplayData[8];
- void delay_ms(uint32_t n);
- void KeyDown();
- void UsartInit();
- void DigitalTubeDisplay(uint8_t ShowNumber,uint8_t DigitNumber);
- void DisplayCurrentNumber(uint16_t CurrentNumber);
- void datapros(int32_t temp);
- void TemJudgement();
- void main()
- {
- Exit0Init();
- Exit1Init();
- while(1)
- {
- datapros(Ds18b20ReadTemp());
- DigitalTubeDisplay(DisplayData[2],6);
- DigitalTubeDisplay(DisplayData[3],5);
- TemJudgement();
- datapros(Ds18b20ReadTemp());
- DisplayCurrentNumber(SetTemNum);
- TemJudgement();
- }
- }
- void delay_ms(uint32_t n)
- {
- uint32_t i=0,j=0;
- for(i=0;i<n;i++)
- for(j=0;j<123;j++);
- }
- void KeyDown()
- {
- uint8_t KeyWaitcount = 0;
- GPIO_KEY = 0x0F;
- if(GPIO_KEY != 0x0F)
- {
- delay_ms(10);
- if(GPIO_KEY != 0x0F)
- {
- switch(GPIO_KEY)
- {
- case 0x07:
- KeyValue = 1;
- break;
- case 0x0B:
- KeyValue = 2;
- break;
- case 0x0D:
- KeyValue = 3;
- break;
- case 0x0E:
- KeyValue = 4;
- break;
- }
- GPIO_KEY = 0xF0;
- switch(GPIO_KEY)
- {
- case 0xE0:
- KeyValue = KeyValue;
- break;
- case 0xD0:
- KeyValue = KeyValue + 4;
- break;
- case 0xB0:
- KeyValue = KeyValue + 8;
- break;
- case 0x70:
- KeyValue = KeyValue + 12;
- break;
- }
- while((KeyWaitcount<50)&&(GPIO_KEY != 0xF0))
- {
- delay_ms(10);
- KeyWaitcount++;
- }
- // SBUF = KeyValue;
- // while(!TI);
- // TI = 0;
- }
- }
- }
- void DigitalTubeDisplay(uint8_t ShowNumber,uint8_t DigitNumber)
- {
- switch(DigitNumber)
- {
- case 1:
- LSC = 0;LSB = 0;LSA = 0;
- break;
- case 2:
- LSC = 0;LSB = 0;LSA = 1;
- break;
- case 3:
- LSC = 0;LSB = 1;LSA = 0;
- break;
- case 4:
- LSC = 0;LSB = 1;LSA = 1;
- break;
- case 5:
- LSC = 1;LSB = 0;LSA = 0;
- break;
- case 6:
- LSC = 1;LSB = 0;LSA = 1;
- break;
- }
- P0 = DigitalTubeSegment[ShowNumber];
- delay_ms(1);
- P0 = 0x00;
- }
- void DisplayCurrentNumber(uint16_t CurrentNumber)
- {
- uint8_t UnitsDigit = 0;
- uint8_t TensDigit = 0;
- TensDigit = CurrentNumber/10;
- UnitsDigit = CurrentNumber%10;
- switch(3)
- {
- case 1:
- DigitalTubeDisplay(TensDigit,6);
- DigitalTubeDisplay(UnitsDigit,5);
- break;
- case 2:
- DigitalTubeDisplay(TensDigit,4);
- DigitalTubeDisplay(UnitsDigit,3);
- break;
- case 3:
- DigitalTubeDisplay(TensDigit,2);
- DigitalTubeDisplay(UnitsDigit,1);
- break;
- }
- }
- void datapros(int32_t temp)
- {
- float tp;
- if(temp< 0) //當(dāng)溫度值為負(fù)數(shù)
- {
- DisplayData[0] = 0x40; // -
- //因?yàn)樽x取的溫度是實(shí)際溫度的補(bǔ)碼,所以減1,再取反求出原碼
- temp=temp-1;
- temp=~temp;
- tp=temp;
- temp=tp*0.0625*100+0.5;
- //留兩個(gè)小數(shù)點(diǎn)就*100,+0.5是四舍五入,因?yàn)镃語(yǔ)言浮點(diǎn)數(shù)轉(zhuǎn)換為整型的時(shí)候把小數(shù)點(diǎn)
- //后面的數(shù)自動(dòng)去掉,不管是否大于0.5,而+0.5之后大于0.5的就是進(jìn)1了,小于0.5的就
- //算加上0.5,還是在小數(shù)點(diǎn)后面。
-
- }
- else
- {
- DisplayData[0] = 0x00;
- tp=temp;//因?yàn)閿?shù)據(jù)處理有小數(shù)點(diǎn)所以將溫度賦給一個(gè)浮點(diǎn)型變量
- //如果溫度是正的那么,那么正數(shù)的原碼就是補(bǔ)碼它本身
- temp=tp*0.0625*100+0.5;
- //留兩個(gè)小數(shù)點(diǎn)就*100,+0.5是四舍五入,因?yàn)镃語(yǔ)言浮點(diǎn)數(shù)轉(zhuǎn)換為整型的時(shí)候把小數(shù)點(diǎn)
- //后面的數(shù)自動(dòng)去掉,不管是否大于0.5,而+0.5之后大于0.5的就是進(jìn)1了,小于0.5的就
- //算加上0.5,還是在小數(shù)點(diǎn)后面。
- }
- // DisplayData[1] = temp / 10000;
- DisplayData[2] = temp % 10000 / 1000;
- DisplayData[3] = temp % 1000 / 100;
- CurrentTemNum = DisplayData[2]*10 + DisplayData[3];
- // DisplayData[4] = temp % 100 / 10;
- // DisplayData[5] = temp % 10;
- }
- void TemJudgement()
- {
- // CurrentTemNum SetTemNum
- if(CurrentTemNum > SetTemNum)
- {
- FAN = 0;
- LAMP = 1;
- }
- else if(CurrentTemNum < SetTemNum)
- {
- FAN = 1;
- LAMP = 0;
- }
- }
復(fù)制代碼
所有資料51hei提供下載:
06085.zip
(117.08 KB, 下載次數(shù): 55)
2020-6-11 11:10 上傳
點(diǎn)擊文件名下載附件
仿真及代碼 下載積分: 黑幣 -5
|