使用單片機AT89C52和ADC0832芯片設計數字電壓表,通過測量0-5V之間的直流電壓值,并將測得的電壓數值信息顯示在LED數碼管(SH3461BS),從而達到測量電壓的目的。
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
51hei.png (16.66 KB, 下載次數: 95)
下載附件
2021-1-25 18:30 上傳
51hei.png (16.2 KB, 下載次數: 86)
下載附件
2021-1-25 18:30 上傳
單片機源程序如下:
- #include <reg52.h>
- #define uchar unsigned char
- #define uint unsigned int
- #include <intrins.h>
- //數碼管段選定義 0 1 2 3 4 5 6 7 8 9
- uchar code smg_du[]={0x28,0xee,0x32,0xa2,0xe4,0xa1,0x21,0xea,0x20,0xa0,
- 0x60,0x25,0x39,0x26,0x31,0x71,0xff}; //段碼
- //數碼管位選定義
- uchar code smg_we[]={0xef,0xdf,0xbf,0x7f};
- uchar dis_smg[8] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8};
- uchar smg_i = 3; //顯示數碼管的個位數
- sbit SCL=P2^2; //SCL定義為P1口的第3位腳,連接ADC0832SCL腳
- sbit DO=P2^3; //DO定義為P1口的第4位腳,連接ADC0832DO腳
- sbit CS=P2^0; //CS定義為P1口的第4位腳,連接ADC0832CS腳
- uint p1[9];
- /***********************1ms延時函數*****************************/
- void delay_1ms(uint q)
- {
- uint i,j;
- for(i=0;i<q;i++)
- for(j=0;j<120;j++);
- }
- /***********讀數模轉換數據********************************************************/
- //請先了解ADC0832模數轉換的串行協議,再來讀本函數,主要是對應時序圖來理解,本函數是模擬0832的串行協議進行的
- // 1 1 0 通道
- // 1 1 1 通道
- unsigned char ad0832read(bit SGL,bit ODD)
- {
- unsigned char i=0,value=0,value1=0;
- SCL=0;
- DO=1;
- CS=0; //開始
- SCL=1; //第一個上升沿
- SCL=0;
- DO=SGL;
- SCL=1; //第二個上升沿
- SCL=0;
- DO=ODD;
- SCL=1; //第三個上升沿
- SCL=0; //第三個下降沿
- DO=1;
- for(i=0;i<8;i++)
- {
- SCL=1;
- SCL=0; //開始從第四個下降沿接收數據
- value<<=1;
- if(DO)
- value++;
- }
- for(i=0;i<8;i++)
- { //接收校驗數據
- value1>>=1;
- if(DO)
- value1+=0x80;
- SCL=1;
- SCL=0;
- }
- CS=1;
- SCL=1;
- if(value==value1) //與校驗數據比較,正確就返回數據,否則返回0
- return value;
- return 0;
- }
- /***********************數碼顯示函數*****************************/
- void display()
- {
- uchar i;
- for(i=0;i<smg_i;i++)
- {
- P1 = 0xff; //消隱
- P3 = smg_we[i]; //位選
- P1 = dis_smg[i]; //段選
- delay_1ms(1);
- }
- }
-
- /************ 排序***************/
- void pingjun_zhi(uint *p)
- {
- static uint value;
- static uchar i,j;
- for(j=1;j<9;j++) //先對整個數組的9個值進行從小到大的排列
- for(i=0;i<9 - j;i++)
- {
- if(p[i] > p[i+1])
- {
- value = p[i];
- p[i] = p[i+1];
- p[i+1] = value;
- }
- }
- }
- /*****************主函數********************/
- void main()
- {
- static uchar i,j;
- uint temp;
- while(1)
- {
- display(); //數碼管顯示函數
- if(i % 3 == 0) //循環10次
- {
- pingjun_zhi(p1); //把數從小到大排序
-
- p1[j++] = ad0832read(1,0); //循環255個周期讀取一次0832,因CPU運行比較快,沒必要每次循環都去讀取,選擇通過CH0輸入
- if(j >= 9)
- {
- j = 0;
- temp = p1[3] ; //取個中間值
- temp = temp * 100 / 255 * 4.5 * 2;
- dis_smg[2]=smg_du[temp/100%10] & 0xdf; //得到百位
- dis_smg[1]=smg_du[temp/10%10]; //十位
- dis_smg[0]=smg_du[temp%10]; //個位 ADC0832為8位ADC,數值為0~255,我們將其分開放入l_tmpdate數組中顯示
- }
- }
- i++;
- }
- }
復制代碼
所有資料51hei提供下載:
ADC0832數字電壓表仿真圖+C程序.rar
(43.6 KB, 下載次數: 63)
2021-1-25 10:49 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|