/*笙泉82G516內建10 bit ADC轉換程式,請調整精密可變電阻,或有加裝其它感測器(如光敏電阻,濕度感測器,等等),看看會如何變化*/ #include //for MPC82G516 SFR definition #include sbit LCD_RS=P1^0; //LCM接腳定義 sbit LCD_RW=P1^1; sbit LCD_E=P1^2; #define LCD_Data P2 void WriteDataLCD(char WDLCD); void WriteCommandLCD(char WCLCD); void LCDInit(void); void ChangeCursor(char X,char Y); void delay_us(int t) { while(t--); } void delay_ms(int t) { int i; while(t--) { i=1000; while(i--); } } void main(void) //程式開始 { unsigned int tmp; unsigned long int tmp1; //tmp1因需做計算,宣告為4byte整數比較不會有捨去誤差 delay_us(20000); //若LCM反應較慢,建議電源啟動後需先等一段時間再規劃LCM,LCM才可正常動作 LCDInit(); //LCM初始化 P1M0 |= 0x40; //設定P1.6為1(輸入,高阻抗模式) // ADCTL:ADCON SPEED1 SPEED0 ADCI ADCS CHS2 CHS1 CHS0 ADCTL = 0x86; //啟動內建之ADC,以P1.7為輸入腳 while(1) { ADCTL |= 0x08; //ADC開始轉換 while((ADCTL&0x10) == 0); //判斷是否轉換完畢 ADCTL = ADCTL & 0xE7; // tmp = ADCH * 4 + ADCL; ChangeCursor(0,0); tmp1=tmp; WriteDataLCD(tmp/1000+0x30); //取出千位數,並改成ASCII碼 tmp=tmp%1000; WriteDataLCD(tmp/100+0x30); //取出百位數,並改成ASCII碼 tmp=tmp%100; WriteDataLCD(tmp/10+0x30); WriteDataLCD(tmp%10+0x30); ChangeCursor(1,0); //游標移到第二行開頭 tmp1=tmp1*4340/1023; //因CPU之參考電壓為電源電壓,故量到的值要轉換顯示於LCM,需適當調整轉換成對應之電壓0~1023數值轉換成0~4.34V, //假設參考電壓量量到的值為4.34V,0~1023數值轉換成0~4.34V,故需乘4340/1023倍,所得值比原來大1000倍,故小數點放在倒數第三位 WriteDataLCD(tmp1/1000+0x30); //取出千位數,並改成ASCII碼 tmp1=tmp1%1000; WriteDataLCD('.'); WriteDataLCD(tmp1/100+0x30); tmp1=tmp1%100; WriteDataLCD(tmp1/10+0x30); WriteDataLCD(tmp1%10+0x30); WriteDataLCD('V'); delay_ms(500); //這裡為延遲讀取0831,因CPU比較快,沒必要每次循環都馬上去讀取 } } //寫資料到LCD副程式 void WriteDataLCD(char WDLCD) { LCD_Data = WDLCD; LCD_RS = 1; LCD_RW = 0; LCD_E = 1; //產生負緣 delay_us(100); //延遲等訊號穩定 LCD_E = 0; delay_us(100); //延遲等訊號處裡完畢 } //寫指令到LCD副程式 void WriteCommandLCD(char WCLCD) //BuysC為0時忽略忙檢測 { LCD_Data = WCLCD; LCD_RS = 0; LCD_RW = 0; LCD_E = 1; delay_us(100); //延遲等訊號穩定 LCD_E = 0; delay_us(100); //延遲等訊號處裡完畢 } void LCDInit(void) //LCM初始化 { WriteCommandLCD(0x38); //設定LCD介面8位元,2行,5*7字型 WriteCommandLCD(0x06); // 顯示游標移動設置 WriteCommandLCD(0x0C); // 顯示開及游標設置 WriteCommandLCD(0x01); //顯示清除 delay_us(5000); } //控制游標位址副程式 void ChangeCursor(char X,char Y) //X=(0/1)代表第一行,第二行, Y=0~15 代表第幾個字 { X &= 0x1; Y &= 0xF; //限制X不能大於15,Y不能大於1 if (X) Y |= 0x40; //當要顯示第二行時位址碼+0x40; Y |= 0x80; // 算出指令碼 WriteCommandLCD(Y); //將位址寫入LCD }