基于單片機AT89C52的數(shù)字電壓表設計
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
0.png (19.96 KB, 下載次數(shù): 84)
下載附件
2018-12-29 17:04 上傳
單片機源程序如下:
- #include <reg52.h> //包含頭文件,一般情況不需要改動,頭文件包含特殊功能寄存器的定義
- #include "intrins.h"
- #define uchar unsigned char
- #define uint unsigned int
-
- #define SMG_NUM 4
- uchar code DisplayNum[16]={
- 0xc0, //0
- 0xf9, //1
- 0xa4, //2
- 0xb0, //3
- 0x99, //4
- 0x92, //5
- 0x82, //6
- 0xf8, //7
- 0x80, //8
- 0x90, //9
- 0x88, //A
- 0x83, //b
- 0xc6, //C
- 0xa1, //d
- 0x86, //E
- 0x8e //F
- };
- //對應關系取字: dp g f e d c b a
- //例如 U 1 1 0 0 0 0 0 1
- uchar code DisplayOther[]={
- 0xff, //0 空
- 0x7f, //1 "."
- 0xbf, //2 "-"
- 0xa7, //3 c
- 0xC1 //3 U 1100 0001
- };
- /***********************************************************************************************************
- 數(shù)碼管顯示相關函數(shù)
- ***********************************************************************************************************/
- //數(shù)碼管位選定義
- sbit smg_we1 = P2^0; //數(shù)碼管1
- sbit smg_we2 = P2^1; //數(shù)碼管2
- sbit smg_we3 = P2^2; //數(shù)碼管3
- sbit smg_we4 = P2^3; //數(shù)碼管4
- /***********************數(shù)碼位選函數(shù)*****************************/
- void smg_we_switch(uchar i)
- {
- smg_we1 = 1;
- smg_we2 = 1;
- smg_we3 = 1;
- smg_we4 = 1;
- switch(i)
- {
- case 0: smg_we1 = 0; break;
- case 1: smg_we2 = 0; break;
- case 2: smg_we3 = 0; break;
- case 3: smg_we4 = 0; break;
- }
- }
- /********************************************************************
- * 名稱 : uchar ChangeFor(uchar dat)
- * 功能 : 交換一個字節(jié)位的位置,用于數(shù)碼管顯示
- * 輸入 : 需要改變的數(shù)
- * 輸出 : 改變后的數(shù)
- ***********************************************************************/
- #define LED_a 0 //數(shù)碼管段選的a段接在段選IO口的第0位
- #define LED_b 2
- #define LED_c 6
- #define LED_d 4
- #define LED_e 3
- #define LED_f 1
- #define LED_g 7
- #define LED_dp 5
- uchar ChangeFor(uchar dat)
- {
- uchar temp=0;
- if(dat&0x01) //判斷數(shù)據(jù)的第一位是否為1
- temp|=0x01<<LED_a;//如果為1,放到控制數(shù)碼管a段的位置
- if(dat&0x02)
- temp|=0x01<<LED_b;
- if(dat&0x04)
- temp|=0x01<<LED_c;
- if(dat&0x08)
- temp|=0x01<<LED_d;
- if(dat&0x10)
- temp|=0x01<<LED_e;
- if(dat&0x20)
- temp|=0x01<<LED_f;
- if(dat&0x40)
- temp|=0x01<<LED_g;
- if(dat&0x80)
- temp|=0x01<<LED_dp;
- return temp;
- }
- uchar dis_smg[SMG_NUM]; //顯示緩存數(shù)組
- /********************************************************************
- * 名稱 : display()
- * 功能 : 數(shù)碼管顯示
- * 輸入 : 無
- * 輸出 : 無
- ***********************************************************************/
- void DisplayScan()
- {
- static uchar i;
- P0 = 0xff; //消隱
- smg_we_switch(i); //位選
- P0 = ChangeFor(dis_smg[i]); //段選
- i++;
- if(i>=SMG_NUM)
- i=0;
- }
- /***********************************************************************************************************
- ADC0832相關函數(shù)
- ***********************************************************************************************************/
- sbit AD0832_CS = P1^2 ; //片選信號
- sbit AD0832_CLK = P1^0; //時鐘接口
- sbit AD0832_DI = P1^1; //數(shù)據(jù)接口 /*因為單片機的管腳是雙向的,且ADC0832的數(shù)據(jù)輸入輸出不同時進行,為節(jié)省單片機引腳,簡化電路所以輸入輸出連接在同一個引腳上*/
- uchar GetAD0832(bit Channel)
- {
- uchar i=0 , Data1 =0 , Data2 = 0 ;
- AD0832_CLK = 0 ; //時鐘置低平//時鐘12Mhz, 整個轉換時間為224us
- //使用芯片準備(參考PDF時序圖)
- AD0832_DI = 1 ; //開始信號為高電平
- AD0832_CS = 0 ; //片選信號置低,啟動AD轉換芯片
- AD0832_CLK = 1 ; //輸入開始信號(構成一個正脈沖),時鐘上升沿,輸入開始信號
- AD0832_CLK = 0 ; //時鐘下降沿
- //模擬信號輸入模式選擇(1:單模信號,0:雙模差分信號)
- AD0832_DI = 1 ;
- AD0832_CLK = 1 ; //時鐘上升沿,輸入開始信號
- AD0832_CLK = 0 ; //時鐘下降沿
- //模擬信號輸入通道選擇(1:通道CH1,0:通道CH0)
- AD0832_DI = Channel ; //選擇通道0
- AD0832_CLK = 1; //時鐘上升沿,輸入開始信號
- AD0832_CLK = 0; //時鐘下降沿
- AD0832_DI = 1; //數(shù)據(jù)線置高,準備接收數(shù)據(jù)
- for(i=0;i<8;i++) //從高位移入數(shù)據(jù)
- {
- AD0832_CLK = 1 ;
- AD0832_CLK = 0 ; //時鐘下降沿,AD0832輸出數(shù)據(jù),高位(MSB)先
- Data1 = Data1<<1; //數(shù)據(jù)左移位,補0
- if(AD0832_DI ==1)
- {
- Data1 = Data1 | 0x01;
- } //如果數(shù)據(jù)為“1”,移入1,
- } //如果數(shù)據(jù)為“0”,移入0,
- for(i=0;i<8;i++) //從低位移入數(shù)據(jù)
- {
- Data2 = Data2>>1; //數(shù)據(jù)左移位,補0
- if(AD0832_DI ==1)
- {
- Data2 = Data2 | 0x80;
- } //如果數(shù)據(jù)為“1”,移入1如果數(shù)據(jù)為“0”,移入0,
- AD0832_CLK = 1;
- AD0832_CLK = 0; //時鐘下降沿,AD0832輸出數(shù)據(jù),高位(MSB)先
- }
- //數(shù)據(jù)線置高,釋放總線,完成一次轉換
- AD0832_CLK = 1 ;
- AD0832_DI = 1;
- AD0832_CS = 1;
- if(Data1==Data2) //輸出
- {
- return Data2;
- }
- return 0;
- }
- /***********************************************************************************************************
- 主函數(shù)
- ***********************************************************************************************************/
- void main (void)
- {
- uchar Read_AD; //用于讀取ADC數(shù)據(jù)
- uint VIN; //電壓值變量
- while (1) //主循環(huán)
- {
- Read_AD=GetAD0832(0); //讀取AD值
- //電壓模式
- VIN=Read_AD*7.84; //換算出電壓值
- dis_smg[0]=DisplayNum[VIN/1000%10]; //顯示電壓標志
- dis_smg[1]=DisplayNum[VIN/100%10]&0x7f; //電壓十位
- dis_smg[2]=DisplayNum[VIN/10%10]; //電壓個位
- dis_smg[3]=DisplayNum[VIN%10]; //電壓十分位
- DisplayScan(); //數(shù)碼管動態(tài)掃描
- }
- }
復制代碼
0.png (42.25 KB, 下載次數(shù): 75)
下載附件
2018-12-29 17:05 上傳
所有資料51hei提供下載:
數(shù)字電壓表設計.zip
(24.34 KB, 下載次數(shù): 122)
2018-12-26 18:18 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|