|
電位器調節待檢測電壓值,在數碼管上顯示出來,
代碼大多從書上搬過來的,書上例5.3.1要求前3個數碼管顯示AD轉換后的8位數字量(即0~255)
我這里讓前4個數碼管顯示具體電壓值,比如1.352- #include <reg52.h>
- #include "MY51.H"
-
- void initSMG() //數碼管初始化信息
- {
- //上電時,都為高電平
- P0=0xff;
- wela=open;
- P0=0xff;
- wela=lock;
-
- P0=0;
- dula=open;
- P0=0;
- dula=lock;
- }
-
- void ADC0804_csToLow() //cs置低電平
- {
- wela=open; //打開鎖存器
- P0=0x7f; //鎖存器最高位送0,也就是CSAD置0
- wela=lock;
- }
-
- void ADC0804_startConvert() //P3.6口是wr,由高到底,再拉高后,ad開始轉換
- {
- adwr=high; //雖然原本就是高的,但我們要養成好習慣,該是什么就是什么
- _nop_();
- adwr=low; //wr置低后,過小會后AD內部開始執行轉換,轉換完成后INTR自動置低觸發中斷
- _nop_();
- adwr=high;
- //由于我們用的不是150pF電容,而是104pF,所以轉換比較慢,在調用本函數后最好延時10毫秒以上
- }
-
- uint8 ADC0804_readResult() //讀轉換結果
- {
- uint8 result=0;
- //延時一會兒,轉換就完成了,由于我們將INTR和CS都拉低了,直接操作RD后就可以讀了
- P1=0xff; //防止由于轉換未完成原因引起的誤讀
- adrd=high;
- _nop_();
- adrd=low; //rd置低電平后數據總線P1口得到數據,并由led顯示現象
- _nop_();
- result=P1;
- adrd=high;
- //讀完以后,如果ad芯片不用了,就把cs拉高,注銷片選
- return result;
- }
-
- void show(uint8 value) //基準電壓是2.5V 為了計算方便擴大到2500
- {
- uint16 temp=value*(2500/255.0); //擴大到4位整數,小數點另外附加顯示
- uint8 oneWela,twoWela,threeWela,fourWela; //oneWela是最左邊的數碼管
- oneWela=temp/1000;
- twoWela=temp%1000/100;
- threeWela=temp%100/10;
- fourWela=temp%10;
- displaySMG(oneWela,twoWela,threeWela,fourWela,dark,dark,dotTable[1]); //最左邊的數碼管顯示小數點
- }
-
- void main()
- {
-
- uchar i=0;
- uchar adTemp=0;
- initSMG(); //數碼管數據初始化
- ADC0804_csToLow(); //cs置低
- while(1)
- {
- ADC0804_startConvert(); //開始將電壓數據轉換成數字信號
- for(i=5;i>0;i--) //主要是延時一段時間,讓ad完成轉換
- {
- delayms(1);
- show(adTemp); //延時的時候,數碼管繼續動態顯示
- }
- adTemp=ADC0804_readResult(); //讀取數據
- show(adTemp);
- }
- }
復制代碼- #ifndef _MY51_H_
- #define _MY51_H_
- #include <math.h>
- #include <intrins.h>
-
- typedef int int16 ;
- typedef int INT16 ;
- typedef unsigned int uint16 ;
- typedef unsigned int UINT16 ;
- typedef unsigned short uint ;
- typedef unsigned short UINT ;
- typedef unsigned short word ;
- typedef unsigned short WORD ;
- typedef unsigned long uint32 ;
- typedef unsigned long UINT32 ;
- typedef unsigned long DWORD ;
- typedef unsigned long dword ;
- typedef signed long int32 ;
- typedef signed long INT32 ;
- typedef float float32 ;
- typedef double double64 ;
- typedef signed char int8 ;
- typedef signed char INT8 ;
- typedef unsigned char byte ;
- typedef unsigned char BYTE ; //WINDOWS的windef.h里面是這么定義的
- typedef unsigned char uchar ;
- typedef unsigned char UCHAR ;
- typedef unsigned char UINT8 ;
- typedef unsigned char uint8 ;
- typedef unsigned char BOOL ; //windows中定義BOOL為int
- typedef unsigned char bool ; //bool是c++的內置類型
-
- #define TRUE 1
- #define true 1
- #define FALSE 0
- #define false 0
-
- #define open 1 //open和close用于 標志打開和關閉狀態
- #define OPEN 1
- #define close 0
- #define CLOSE 0
- #define lock 0
- #define start 1
- #define START 1
- #define stop 0
- #define STOP 0
- #define keyDown 0
- #define keyUp 1
- #define gnd 0 //接地
- #define GND 0 //接地
- #define high 1 //高電平
- #define low 0 //低電平
- #define yes 1
- #define YES 1
- #define no 0
- #define NO 0
-
- sbit dula =P2^6; //段選鎖存器控制 控制筆段
- sbit wela =P2^7; //位選鎖存器控制 控制位置
-
- #define led P1 //燈總線控制
- sbit led0=P1^0; //8個led燈,陰極送低電平點亮
- sbit led1=P1^1;
- sbit led2=P1^2;
- sbit led3=P1^3;
- sbit led4=P1^4;
- sbit led5=P1^5;
- sbit led6=P1^6;
- sbit led7=P1^7;
-
- sbit keyS2=P3^4; //4個獨立按鍵
- sbit keyS3=P3^5;
- sbit keyS4=P3^6;
- sbit keyS5=P3^7;
-
- sbit csda=P3^2; //DAC0832模數轉換cs口
- sbit adwr=P3^6; //ADC0804這個同DAC0832
- sbit dawr=P3^6;
- sbit adrd=P3^7; //ADC0804
- sbit beep=P2^3; //蜂鳴器
- void displaySMG(uint8 one,uint8 two,uint8 three,uint8 four,uint8 five,uint8 six,uint8 dot);
- void delayms(uint16 ms);
- void T0_Work();
-
- void delayms(uint16 ms) //軟延時函數
- {
- uint16 i,j;
- for(i=ms;i>0;i--)
- {
- for(j=113;j>0;j--)
- {}
- }
- }
- ///////////////////////////////////////////////////////////////////////////
- #define dark 0x11 //在段中,0x11是第17號元素,為0是低電平,數碼管不亮
- #define dotDark 0xff //小數點全暗時
- uint8 code table[]= { //0~F外加小數點和空輸出的數碼管編碼
- 0x3f , 0x06 , 0x5b , 0x4f , // 0 1 2 3
- 0x66 , 0x6d , 0x7d , 0x07 , // 4 5 6 7
- 0x7f , 0x6f , 0x77 , 0x7c , // 8 9 A B
- 0x39 , 0x5e , 0x79 , 0x71 , // C D E F
- 0x80 , 0x00 ,0x40 // . 空 負號 空時是第0x11號也就是第17號元素
- };
-
- uint8 dotTable[]={ //小數點位置
- 0xff , //全暗
- 0xfe , 0xfd , 0xfb , //1 2 3
- 0xf7 , 0xef , 0xdf //4 5 6
- };
- /////////////////////////////////////////////////////////////////////////////
- uint8 TH0Cout=0 ; //初值
- uint8 TL0Cout=0 ;
- uint16 T0IntCout=0; //中斷計數
- uint16 T0IntCountAll=0; //(N-1)/65536+1; //總中斷次數
- bool bT0Delay=false; //使用延時函數標志,初始未用
- bool bT0Over=false; //中斷處理函數執行結果之一
-
- void startT0(uint32 ms) //開啟定時器
- {
- float32 t=ms/1000.0; //定時時間
- double64 fox =11.0592*(pow(10,6)); //晶振頻率
- uint32 N=(t*fox)/12 ; //定時器總計數值
-
- TH0Cout =(65536-N%65536)/256; //裝入計時值零頭計數初值
- TL0Cout =(65536-N%65536)%256;
- T0IntCountAll=(N-1)/65536+1; //總中斷次數
- TMOD=TMOD | 0x01; //設置定時器0的工作方式為1
-
- EA =open; //打開總中斷
- ET0=open; //打開定時器中斷
-
- TH0=TH0Cout; //定時器裝入初值
- TL0=TL0Cout;
- TR0=start; //啟動定時器
- }
-
- void delayT0(uint32 ms) //硬延時函數,自己亂寫的不好用,求指點
- {
- startT0(ms); //啟動定時器
- bT0Delay=true; //告訴T0定時器,起用延時模式
- while(bT0Over==false); //時間沒到的話繼續檢測
- bT0Over=false; //時間到了,讓標志復位
- }
-
- void T0_times() interrupt 1 //T0定時器中斷函數
- {
- T0IntCout++;
- if(T0IntCout==T0IntCountAll) //達到總中斷次數值
- {
- T0IntCout=0; //中斷次數清零,重新計時
- bT0Over=true; //時間真的到了
- if(bT0Delay) //本次中斷是用來延時的嗎
- {
- TR0=stop; //如果是由延時函數開啟T0的話,關閉T0
- return;
- }
-
- TH0=TH0Cout; //循環定時的話要重裝初值,每次定時1秒,重裝一次
- TL0=TL0Cout;
- T0_Work(); //工作函數
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- void displaySMG(uint8 oneWela,uint8 twoWela,uint8 threeWela,uint8 fourWela,uint8 fiveWela,uint8 sixWela,uint8 dot)
- {
- //控制6位數碼管顯示函數,不顯示的位用參數dark,保留ADC0804的片選信號
- uint8 csadState=0x80&P0; //提取最高位,即ADC0804的片選信號
- uint8 tempP0=((csadState==0)?0x7f:0xff); //數碼管位選初始信號,陰極全置高電平
- P0=tempP0; //0x7f表示數碼管不亮,同時ADC0804片選有效
- wela=1; //注:wela和dula上電默認為1
- P0=tempP0;
- wela=0;
-
- P0=0; //由于數碼管是共陰極的,陽極送低電平,燈不亮,防止燈誤亮
- dula=1;
- P0=0;
- dula=0; //段選數據清空并鎖定
- //////////////////////////oneWela
- { //消除疊影,數碼管陰極置高電平,并鎖存
- P0=tempP0;
- wela=1;
- P0=tempP0;
- wela=0;
- }
- P0=0; //低電平送到數碼管陽極,避免數碼管誤亮
- dula=1;
- P0=table[oneWela]|((0x01&dot)?0x00:0x80); //送段數據,疊加小數點的顯示
- dula=0;
-
-
- P0=tempP0; //送位數據前關閉所有顯示,并保持csad信號
- wela=1;
- P0=tempP0 & 0xfe; //0111 1110最高位是AD片選,低6位是數碼管位選,低電平有效
- wela=0;
- delayms(2);
-
- /////////////////////////twoWela
- { //消除疊影
- P0=tempP0;
- wela=1;
- P0=tempP0;
- wela=0;
- }
- P0=0;
- dula=1;
- P0=table[twoWela]|((0x02&dot)?0x00:0x80);
- dula=0;
-
- P0=tempP0;
- wela=1;
- P0=tempP0 & 0xfd; //0111 1101
- wela=0;
- delayms(2);
-
- /////////////////////////threeWela
- { //消除疊影
- P0=tempP0;
- wela=1;
- P0=tempP0;
- wela=0;
- }
- P0=0;
- dula=1;
- P0=table[threeWela]|((0x04&dot)?0x00:0x80);
- dula=0;
-
- P0=tempP0;
- wela=1;
- P0=tempP0 & 0xfb; //0111 1011
- wela=0;
- delayms(2);
-
- /////////////////////////fourWela
- { //消除疊影
- P0=tempP0;
- wela=1;
- P0=tempP0;
- wela=0;
- }
- P0=0;
- dula=1;
- P0=table[fourWela]|((0x08&dot)?0x00:0x80);
- dula=0;
-
- P0=tempP0;
- wela=1;
- P0=tempP0 & 0xf7; //0111 0111
- wela=0;
- delayms(2);
-
- /////////////////////////fiveWela
- { //消除疊影
- P0=tempP0;
- wela=1;
- P0=tempP0;
- wela=0;
- }
- P0=0;
- dula=1;
- P0=table[fiveWela]|((0x10&dot)?0x00:0x80);
- dula=0;
-
- P0=tempP0;
- wela=1;
- P0=tempP0 & 0xef; //0110 1111
- wela=0;
- delayms(2);
-
- /////////////////////////sixWela
- { //消除疊影
- P0=tempP0;
- wela=1;
- P0=tempP0;
- wela=0;
- }
- P0=0;
- dula=1;
- P0=table[sixWela]|((0x20&dot)?0x00:0x80);
- dula=0;
-
- P0=tempP0;
- wela=1;
- P0=tempP0 & 0xdf; //0101 1111
- wela=0;
- delayms(2);
- }
-
- #endif
復制代碼
|
|