作為一個初學者,如何學好單片機,課堂上的內容過于粗淺
單片機源程序如下:
- /*---------------------------------------------------------------
- 項目名稱:自動售水機系統
- ----------------------------------------------------------------*/
- #include"reg52.h"
- #include"pcf8591.h"
- #include"iic.h" //iic協議
- #include"ct107.h" //CT107單片機初始化
- #include"deplay.h" //延時
- #define AddWr 0x90 //寫數據地址
- #define AddRd 0x91 //讀數據地址
- sbit key6=P3^1; //定義按鍵端口
- sbit key7=P3^0;
- unsigned char code smg_du[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //數碼管段選“0~9”
- unsigned char code smg_we[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; //數碼管位選
- unsigned char tab[8]={0,0,5,0,0,0,0,0}; //顯示數組
- unsigned int water,total; //定義水量,總價
- float price; //定義單價
- unsigned char light; //定義光照強度變量
- bit flag,flag1,flag2; //定義標志位
- unsigned char ReadADC(unsigned char Ch1); //讀AD函數,Ch1為通道號,取值0~3;
- void diswork(); //數據處理函數
- main()
- {
- price=0.5; //設定單價為0.5元/L
- TMOD=0x11; //設置定時器0,1為16位定時器
- TH0=(65536-50000)/256; //設定定時器0初值50ms,用于累計水量
- TL0=(65536-50000)%256;
- TH1=(65536-2000)/256; //設定定時器0初值2ms,用于掃描數碼管和L1
- TL1=(65536-2000)%256;
- TR1=1; //開定時器1
- TR0=1; //開定時器0
- ET1=1; //開定時器1中斷允許位
- EA=1; //開總中斷
- ct107_init();
- while(1) //停止
- {
- if(!key6) //判斷按鍵是否按下
- {
- deplay_50us(200); //消抖
- if(!key6) //確認按鍵按下
- {
- ET0=0;
- P2&=0x1f;
- RELAY=0; //關繼電器
- BUZZ=0; //避免蜂鳴器的影響
- P2|=Y5C;
- P2&=0x1f;
- flag=1; //停止標志位
- flag2=0; //按下停止后把許可啟動標志位置0,方可進入下次啟動
- }
- }
- if(!flag2) //許可啟動標志位為0才可啟動
- if(!key7) //啟動
- {
- deplay_50us(200);
- if(!key7)
- {
- ET0=1;
- water=0; //水量清0
- total=0; //總價清0
- P2&=0x1f;
- RELAY=1; //開繼電器
- BUZZ=0;
- P2|=Y5C;
- P2&=0x1f;
- flag=0; //復位停止標志位
- flag2=1; //置位許可啟動標志位防止再次進入啟動程序
- }
- }
- diswork(); //顯示數據處理
- light=ReadADC(1); //讀AD數據(光敏電阻)
- if(light<64) //判斷電壓是否下于1.25V。1.25*255/5=64
- flag1=1;
- else
- flag1=0;
- }
- }
- void diswork()
- {
- if(flag) //停止時顯示總價,啟動時顯示水量
- {
- total=(unsigned int)(water*price);
- tab[4]=total/1000;
- tab[5]=total%1000/100;
- tab[6]=total%100/10;
- tab[7]=total%10;
- }
- else
- {
- tab[4]=water/1000;
- tab[5]=water%1000/100;
- tab[6]=water%100/10;
- tab[7]=water%10;
- }
- }
- unsigned char ReadADC(unsigned char Ch1) //讀通道Ch1的數據
- {
- unsigned char Data;
- init_iic();
- Start();
- Send(AddWr);
- Ack();
- Send(0x40|Ch1);
- Ack();
- Start();
- Send(AddRd);
- Ack();
- Data=Read();
- Scl=0;
- NoAck();
- Stop();
- return Data;
- }
- void timeint_0() interrupt 1 //定時器0中斷用于計算水量,其中斷優先級比定時器1中斷高,防止了中斷被打斷,使數據更準確
- {
- static unsigned char k;
- TH0=(65536-50000)/256; //每50ms進一次中斷
- TL0=(65536-50000)%256;
- if(k) //每100ms水量增加10mL
- {
- k=0;
- if(water==9999)
- {
- ET0=0;
- P2&=0x1f;
- RELAY=0;
- BUZZ=0;
- P2|=Y5C;
- P2&=0x1f;
- flag=1;
- flag2=0;
- }
- else
- water++;
- }
- else
- k++;
- }
- void timeint_1() interrupt 3
- { //數碼管和L1掃描函數
- unsigned char com[8]={0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff}; //用于控制數碼管的亮滅
- static char i;
- TH1=(65536-2500)/256; //每2ms掃描一次
- TL1=(65536-2500)%256;
- P2&=0x1f;
- P0=0xff;
- P2|=Y7C;
- P2&=0x1f;
- P0=smg_we[i]&com[i];
- P2|=Y6C;
- P2&=0x1f;
- if(i==1|i==5)
- P0=smg_du[tab[i]]&0x7f; //為第二和第六個數碼管加小數點
- else
- P0=smg_du[tab[i]];
- P2|=Y7C;
- P2&=0x1f;
- if(flag1) //開L1
- {
- P2&=0x1f;
- P0=0xfe;
- P2=Y4C;
- P2&=0x1f;
- }
- else //關L1
- {
- P2&=0x1f;
- P0=0xff;
- P2=Y4C;
- P2&=0x1f;
- }
- if(i==7) //掃描完8個數碼管就清零從新掃描
- {
- i=0;
- }
- else
- i++;
- }
復制代碼
所有資料51hei提供下載:
自動售水機.zip
(517.53 KB, 下載次數: 4)
2019-5-19 10:57 上傳
點擊文件名下載附件
售水機 下載積分: 黑幣 -5
|