給大家分享一個用ADC0832模數轉換芯片設計的電壓表設計,內含protues電路圖和帶有注釋的keil工程文件
ADC0832電壓表仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
單片機電壓表源程序如下:
- #include <reg52.h>
- #include <intrins.h>
- #define uint unsigned int
- #define uchar unsigned char
-
- sbit CS =P3^4; //片選使能端
- sbit DI =P1^1; //數據信號輸入端,選擇通道控制(SIG/DIF和ODD/EVEN)
- sbit DO =P1^1; //數據輸出端
- sbit CLK =P1^0; //時鐘脈沖
- sbit S_1 = P2^3;
- sbit S_2 = P2^4;
- sbit S_3 = P2^5;
- sbit S_4 = P2^6;
- unsigned char wd[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //不帶小數點的段選碼
- unsigned char yd[]={0x40,0x79,0x024,0x30,0x19,0x12,0x02,0x78,0x00,0x10};//帶小數點的段選碼
- // ===========延時子程序=================
- void delay_ms(unsigned int x)
- {
- unsigned int i,j;
- for(i=0;i<x;i++)
- for(j=0;j<123;j++); //延時1ms
- }
- /*=============讀ADC0832函數=============*/
- /*=============采集并返回=================*/
- unsigned int Adc0832(unsigned char channel) //AD轉換,返回結果
- {
- uchar i=0;
- uchar j;
- uint dat=0; //正向輸入數據
- uchar ndat=0; //反向輸入數據
- //****************初始化操作**************
- if(channel==0)channel=2; //10B對應SGL/DIF=1,ODD/EVEN=0
- if(channel==1)channel=3; //11B對應SGL/DIF=1,ODD/EVEN=1
- //****************寫操作,將通道數據寫入ADC0832**************
- DI=1; _nop_();_nop_(); //發起始位,固定為1(1位)
- CS=0;_nop_();_nop_(); //拉低CS端,讓ADC0832使能
- CLK=1;_nop_();_nop_(); //拉高CLK端,DI端的數據移入ADC0832內部的多路移位寄存器
- CLK=0;_nop_();_nop_(); //拉低CLK端,形成下降沿1,第一個周期開始
- CLK=1; //拉高CLK端,在第一個時鐘周期內,DI為高電平,表示啟動位
- //緊接著輸入兩位配置位進行通道選擇
- DI=channel&0x1;_nop_();_nop_(); //假設選取通道0,則10&01=0,即SGL/DIF=0,為差分輸入(2位)
- CLK=0;_nop_();_nop_(); //拉低CLK端,形成下降沿2,第二個周期開始
- CLK=1; //拉高CLK端
- DI=(channel>>1)&0x1;_nop_();_nop_(); //假設選取通道0,則01&01=1,ODD/EVEN=1,表示通道0
- CLK=0; //拉低CLK端,形成下降沿3
- DI=1;_nop_();_nop_(); //控制命令結束
- dat=0;
- //*************讀操作,將AD轉換的數從DO口輸出****************
- for(i=0;i<8;i++) //每一個CLK下降沿輸出一位數,先輸出高位
- {
- dat|=DO; //收數據,“|”位或,如果2位中有一位為1,則結果為1,否則為0
- CLK=1;_nop_();_nop_();
- CLK=0;_nop_();_nop_(); //形成一次時鐘脈沖
- dat<<=1;
- if(i==7)dat|=DO;
- }
-
- for(i=0;i<8;i++) //每一個CLK下降沿輸出一位數,先輸出低位
- {
- j=0;
- j=j|DO; //收數據
- CLK=1;_nop_();_nop_();
- CLK=0;_nop_();_nop_(); //形成一次時鐘脈沖
- j=j<<7;
- ndat=ndat|j;
- if(i<7)ndat>>=1;
- }
- //*********************結束AD轉換,并返回轉換的數***********************
- CS=1; //拉低CS端
- CLK=0; //拉低CLK端
- DO=1; //拉高數據端,回到初始狀態
- dat<<=8;
- dat|=ndat;
- return(dat); //返回數據
- }
- //============數碼管顯示函數==========================
- void display(uchar p) //數碼管顯示函數
- {
- uchar S1,S2,S3;
-
- S1=p/51; //個位
- S2=(p*10/51)%10; //十分位
- S3=(p*100/51)%10; //百分位
-
- //個位
- S_1 = 1; //第一個數碼管
- S_2 = 0;
- S_3 = 0;
- S_4= 0;
- P0=yd[S1]; //選取帶有小數點的段選碼
- delay_ms(5); //延時
- S_1 = 0; //消隱
-
- //十分位
- S_1 = 0;
- S_2 = 1; //取第二個數碼管
- S_3= 0;
- S_4= 0;
- P0=wd[S2]; //選取不帶有小數點的段選碼
- delay_ms(5);
- S_2 = 0; //消隱
-
- //百分位
- S_1 = 0;
- S_2 = 0;
- S_3= 1; //取第三個數碼管
- S_4= 0;
- P0=wd[S3]; //選取不帶有小數點的段選碼
- delay_ms(5);
- S_3= 0; //消隱
- }
- //===========主函數================
- int main(void)
- {
- while(1) //無限循環
- display(Adc0832(0));//數碼管顯示
- //Adc0832(0):選擇通道0,單端模式
- //調用Adc0832(0),SIG/DIF=0,ODD/EVEN=1,表示工作在差分輸入方式,且CH0為-,CH1為+
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼 Keil代碼與Proteus8.8仿真下載:
基于ADC0832簡易數字電壓表.zip
(64.85 KB, 下載次數: 1077)
2018-6-9 23:23 上傳
點擊文件名下載附件
|