|
這塊簡單易制作的0-30VSTC單片機數字電壓表,被測電壓經限流電阻接到AD檢測端并由分流電阻分流,讀出8位(256)的AD數據,由AD值計算出AD端電壓,即分流點電壓,由此電壓計算出分流電流,再由此電流計算出輸入電壓。使用STC12C5204AD單片機,P0.0-P0.3 共陰數碼管位、P2 為共陰數碼管段a-g dp,P0、P2 設置為推挽輸出,段輸出加限流電阻,AD為8位,計算方法:5/256=0.0195312V,分流電阻為實測阻值。AD值*0.0195312v/對地分流電阻,算出分流電流,然后用分流電流*分流電阻與限流電阻之和即為要顯示的輸入電壓值,業余使用,精度已經夠用了。STC12C5204AD頭文件 網上多的是,大家搜一下就會找到的,其中涉及到端口設置的地方大家對照芯片手冊更正。
 簡單易制作的0-30VSTC單片機數字電壓表源程序:
- #include <STC12C52.H> //STC12C5204AD頭文件
- #include <intrins.h> //_nop_();
- #define uchar unsigned char
- #define uint unsigned int
- //sfr ADC_CONTR=0XBC;//adc使能位.ADC電源控制位
- sfr ADC_RES=0XBD;// adc數據高八位,即ADC值
- sfr P1ASF=0X9D;//P1各端口ADC使能端
- uchar led_bcd[]={0x3F,/*0*/ //共陰數碼管
- 0x06,/*1*/
- 0x5B,/*2*/
- 0x4F,/*3*/
- 0x66,/*4*/
- 0x6D,/*5*/
- 0x7D,/*6*/
- 0x07,/*7*/
- 0x7F,/*8*/
- 0x6F,/*9*/
- 0x00,/* */
- 0x7c /*b*/
- }
- ,ad_data
- ;
- uint data dis[5]={0x00,0x00,0x00,0x00,0x00},ZZ; //定義四個顯示數據單元和一個數據存儲單元
- //dis[4,3,2,1,5] 顯示:12.34 5為存儲單元
- /*******************************************************************/
- /* 延時子程序 */
- /* */
- /* */
- /*******************************************************************/
- void delay(uint z) //延時子函數
- {
- uchar de1,de2;
- for(de1=z;de1>0;de1--)
- for(de2=100;de2>0;de2--);
- }
- /*******************************************************/
- //顯示子函數 display(h1,h2,h3,h4)
- //h1,h2,h3,h4 為四位LED數碼管顯示變量
- //
- //
- //
- /*******************************************************/
- void display(uchar h1,uchar h2,uchar s1,uchar s2) ////LED顯示函數(參數:LED1,LED2,LED3,LED4)
- {
- // 第一個數碼管顯示數據
- if(h1==0x3f) h1=0x00; //0消隱語句
- P2=h1;
- //delay(2);
- P00=0;
- delay(2); //參數2-10 數值大LED亮度高但閃爍感強,數值小LED亮度低,但閃爍感小.
- P2=0X00;
- P00=1;
- /*******************************************************/
- // 第二個數碼管顯示數據
- P2=h2|0x80;
- //delay(2);
- P01=0;
- delay(2); //參數2-10 數值大LED亮度高但閃爍感強,數值小LED亮度低,但閃爍感小.
- P2=0X00;
- P01=1;
- //delay(5);
- /*******************************************************/
- // 第三個數碼管顯示數據
- P2=s1;
- //delay(2);
- P02=0;
- delay(2); //參數2-10 數值大LED亮度高但閃爍感強,數值小LED亮度低,但閃爍感小.
- P2=0X00;
- P02=1;
- // delay(5);
- /*******************************************************/
- // 第四個數碼管顯示數據
- P2=s2;
- //delay(2);
- P03=0;
- delay(2); //參數2-10 數值大LED亮度高但閃爍感強,數值小LED亮度低,但閃爍感小.
- P2=0X00;
- P03=1;
- //delay(5);
- }
- void init()//系統初始化函數
- {
- P2M1=0Xff; //強推挽 推動a-g dp
- P2M0=0X00; //強推挽 推動a-g dp
- P0M1=0X0f; //強推挽 推動位
- P0M0=0X00; //強推挽 推動位
- P0=0XFF; //初始化
- P2=0; //初始化
- /***定時器0初始化設置*****/
- TMOD = 0x01;
- TH0 = 0xFC; //初值1ms
- TL0 = 0x18; //初值1ms
- EA = 1; //開總中斷
- ET0 = 1; //定時器0中斷打開
- TR0 = 1; //打開定時器 開始計時
- /*************************/
- ZZ=0;
- }
- void initADC() //AD初始化
- {
- P1ASF=0x01;//只使用P1.0端口做為ADC輸入端.
- ADC_RES=0;//ADC數據寄存器清零
- ADC_CONTR=ADC_POWER|ADC_SPEEDLL; //打開ADC開關并設置 轉換速率詳見STC12C52.H
- delay(2); //打開ADC并延時.
- }
- uchar readADC() //讀AD
- {
- ADC_CONTR=ADC_POWER|ADC_SPEEDLL|0|ADC_START;
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- while(!(ADC_CONTR&ADC_FLAG));//等待轉換完成標志
- ADC_CONTR&=~ADC_FLAG;//close ADC
- return ADC_RES;//返回ADC值.
- }
- void main()
- {
- init();
- initADC();//初始化ADC
- ad_data=readADC();//開機轉換
- while(1)
- {
- float j;
- uchar ad_data;
- while(ZZ>=500) //500毫秒讀一次ADC
- {
- ad_data=readADC();//讀入ADC數據
- ZZ=0;
- }
- j=ad_data*19.5312;//由AD數據*19.5312(放大1000倍)=分流后的電壓
- j=j/9890; //j(電壓)/接地電阻(實測)9890歐
- j=j*60190;//j(電流)*(輸入限流電阻(實測)60190歐+接地電阻(實測)9890歐) 計算出實際輸入電壓 如果使用高精度電阻,則直接輸入電阻值
- dis[4]=j/1000;
- dis[3]=dis[4]/10;
- dis[2]=dis[4]%10;
- //h=(h-(dis[3]*10+dis[2]))*100;
- dis[4]=j/10-dis[4]*100;
- //dis[4]=j%100;//小數位第一位
- dis[1]=dis[4]/10;
- dis[0]=dis[4]%10;//小數位第二位
- //delay(10000);
- }
- }
- void Timer0Interrupt(void) interrupt 1
- {
- ZZ++; //AD讀取間隔時間控制
- TH0 = 0xFC;
- TL0 = 0x18;
- display(led_bcd[dis[3]],led_bcd[dis[2]],led_bcd[dis[1]],led_bcd[dis[0]]);
- }
復制代碼
|
|