一款51單片機芯片和MCP3001 ad轉換器電路實現 8 路電壓測量系統,并可以將顯示的電壓顯示在液晶屏上。系統中 AD 測量芯片只用一片。8 電路電壓輸入采用模擬量開關進行切換。實驗
8 個 led 燈代表模擬量輸入通道狀態。
S1 鍵,按下 S1 鍵,系統工作模式為手動切換通道進行測量,并且顯示測量電壓值。
并在液晶屏的右上角顯示“M”字母,代表當前模式是手動模式。
S2 鍵,按下 S2 鍵,系統工作模式為自動切換通道進行測量,并且顯示測量電壓
值。并在液晶屏的右上角顯示“A”字母,代表當前模式是手動模式。電壓值顯
示采用輪顯方式,每個 5 秒鐘切換一次顯示。
S3 鍵,具體功能如下:
(A) 在手動模式下,沒按下一次,切換一組顯示畫面。一共四組顯示畫面。
(B) 在自動模式下,此按鍵不起作用。
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
仿真圖
MCP3001的單片機源碼:
- #include<reg52.h>
- #include <lcd.h>
- #include<intrins.h>
- int *pp;
- unsigned int Dist_temp;
- char code int2charLCD[10]="0123456789";
- sbit _4051_A = P1^5;
- sbit _4051_B = P1^6;
- sbit _4051_C = P1^7;
- sbit CLK = P1^0;
- sbit DO = P1^1;
- sbit CS = P1^2;
- sbit led1 = P3^7;
- sbit led2 = P3^6;
- sbit led3 = P3^5;
- sbit led4 = P3^4;
- sbit led5 = P3^3;
- sbit led6 = P3^2;
- sbit led7 = P3^1;
- sbit led8 = P3^0;
- sbit LED=P1^3;
- sbit KEY_S1 = P2^3;
- sbit KEY_S2 = P2^5;
- sbit KEY_S3 = P2^7;
- unsigned char sys_mode=0;//工作模式,0代表手動,1代表自動
- unsigned char hand_mode_cnt=0;//手動模式下按鍵的計數,0-7代表通道CH1-CH8
- unsigned char Time_cnt=0; //自動模式下時間計數
- unsigned int Auto_cnt=0;//自動模式狀態切換
- /**************************/
- //函數聲明
- void sysinit(); //調用程序初始化函數
- unsigned int Readad(void);
- void Voltage_cal(void);
- void disp();
- void CD4051_CH_Select(unsigned char ch);
- void key_scan(void);
- void System_Voltage_disp(void);
- void Manue_Voltage_disp(void);
- void Auto_Voltage_disp(void);
- /*****************************/
- unsigned int ad_value = 0;
- unsigned int ABC=0;
- float disp_val = 0;
- int Per;
- void delay100us()
- {
- unsigned char i,j;
- for(i=0;i<20;i++)
- for(j=0;j<=5;j++);
- }
- void delay_ms(int num)
- {
- int i,j;
- for(i=num;i>0;i--)
- for(j=1500;j>0;j--);
- }
- void write_LCD_command(unsigned command)
- {
- delay100us();
- rw=WRITE; //0
- rs=COMMAND;//0
- enable=ENABLE; //1
- P0=command;
- delay100us();
-
- //chek_busyflag();
- enable=DISABLE;//0
- rw=1;
- }
- void write_LCD_DATA1(unsigned LCDDATA1)
- {
- delay100us();
- rw=WRITE;//0
- rs=DATA1;//1
- enable=ENABLE;//1
- P0=LCDDATA1;
- delay100us();
- //chek_busyflag();
- enable=DISABLE;//0
- rw=1;
-
- }
- void init_LCD(void)
- {
- write_LCD_command(TwoLine_8bit); // 0x38 置功能:2行,5*7字符
- write_LCD_command(CURSOR_OFF); // 0x0c 置顯示開關:顯示屏開,光標不出現不閃爍
- write_LCD_command(CURSOR_RIGHT); // 0x06 置輸入模式:地址加1 光標右移,顯示屏不移動
- clear_LCD();
- }
- void init01_LCD(void)
- {
- write_LCD_command(TwoLine_8bit); // 0x38 置功能:2行,5*7字符
- write_LCD_command(CURSOR_OFF01); // 0x0c 置顯示開關:顯示屏開,光標出現閃爍
- write_LCD_command(CURSOR_RIGHT); // 0x06 置輸入模式:地址加1 光標右移,顯示屏不移動
- }
- void clear_LCD()
- {
- write_LCD_command(CLEAR); //清除顯示器
- write_LCD_command(CURSOR_HOME); //光標回到左上角
- }
- void display_LCD_string(char *p)
- {
- while(*p)
- {
- write_LCD_DATA1(*p);
- p++;
- }
- }
- void display_LCD_number(unsigned int number)
- {
- unsigned char x,y,z;
- x=number/100;
- y=(number/10)%10;
- z=number%10;
- write_LCD_DATA1(int2charLCD[x]);
- write_LCD_DATA1('.');
- write_LCD_DATA1(int2charLCD[y]);
- write_LCD_DATA1(int2charLCD[z]);
- }
- void gotoxy(unsigned x,unsigned y) //顯示行選擇
- {
- if(x==1)
- write_LCD_command(GOTO_LINE_1+y);
- else
- write_LCD_command(GOTO_LINE_2+y);
- }
- /****主函數*******/
- void main()
- {
- init_LCD();
-
- while(1)
- {
-
- key_scan();
- System_Voltage_disp();
- }
- }
- /***********AD芯片讀取函數************************/
- unsigned int Readad(void)
- {
- unsigned char i;
- unsigned int tmp;
- float Ux;
- tmp = 0;
- CLK = 0;
- CS = 0;
- _nop_();
- CLK = 1;
- _nop_();
- CLK = 0;
- _nop_();
- CLK = 1;
- _nop_();
- CLK = 0;
- _nop_();
- CLK = 1;
- _nop_();
- CLK = 0;
- for(i = 0; i < 10; i++)
- {
-
- CLK = 1;
- tmp = tmp << 1;
- if(DO == 1)
- {
- tmp = tmp + 1;
- }
- CLK = 0;
-
- }
- CS = 1;
- CLK = 1;
-
- Ux = tmp;
-
- Ux = 100*(Ux * 5.0)/1024;/**********AD測量電壓計算,計算電壓值擴大100倍******************/
-
-
- return(Ux);
-
- }
- /*******選擇模擬量通道*************/
- void CD4051_CH_Select(unsigned char ch)
- {
- switch(ch)
- {
- case 0: _4051_A = 0;
- _4051_B = 0;
- _4051_C = 0;
- //P3 = 0X80;
- led1 = 1;led2=led3=led4=led5=led6=led7=led8=0;
- break;
- case 1: _4051_A = 1;
- _4051_B = 0;
- _4051_C = 0;
- //P3 = 0X40;
- led2 = 1;led1=led3=led4=led5=led6=led7=led8=0;
- break;
- case 2: _4051_A = 0;
- _4051_B = 1;
- _4051_C = 0;
- //P3 = 0X20;
- led3 = 1;led1=led2=led4=led5=led6=led7=led8=0;
- break;
- case 3: _4051_A = 1;
- _4051_B = 1;
- _4051_C = 0;
- //P3 = 0X20;
- led4 = 1;led1=led2=led3=led5=led6=led7=led8=0;
- break;
- case 4: _4051_A = 0;
- _4051_B = 0;
- _4051_C = 1;
- //P3 = 0X20;
- led5 = 1;led1=led2=led3=led4=led6=led7=led8=0;
- break;
- case 5: _4051_A = 1;
- _4051_B = 0;
- _4051_C = 1;
- //P3 = 0X20;
- led6 = 1;led1=led2=led3=led5=led4=led7=led8=0;
- break;
- case 6: _4051_A = 0;
- _4051_B = 1;
- _4051_C = 1;
- //P3 = 0X20;
- led7 = 1;led1=led2=led3=led5=led6=led4=led8=0;
- break;
- case 7: _4051_A = 1;
- _4051_B = 1;
- _4051_C = 1;
- //P3 = 0X20;
- led7 = 1;led1=led2=led3=led4=led5=led6=led8=0;
- break;
- }
- }
- /*********按鍵掃描***************/
- void key_scan(void)
- {
- if(KEY_S1==0)
- {
- delay_ms(10);
- if(KEY_S1==0)
- {
- sys_mode = 0;
- //切換成手動模式
- }
- }
- if(KEY_S2==0)
- {
- delay_ms(10);
- if(KEY_S2==0)
- {
- sys_mode = 1; //切換成自動模式
- }
- }
- if(sys_mode==0)
- {
- if(KEY_S3==0)
- {
- delay_ms(10);
- if(KEY_S3==0)
- {
- hand_mode_cnt++;
- if(hand_mode_cnt>=8) hand_mode_cnt = 0;
-
-
- }
-
- }
- }
-
- }
- /***********電壓顯示總控制函數*******************/
- void System_Voltage_disp(void)
- {
- if(sys_mode==0)
- {
- Manue_Voltage_disp(); //手動模式下電壓顯示
- }
- else
- {
- Auto_Voltage_disp(); //自動模式下電壓顯示
- }
- }
- /***********手動模式下電壓顯示*******************/
- void Manue_Voltage_disp(void)
- { if(ad_value>250)
- {LED=~LED;}
- else
- { LED=1;}
- switch(hand_mode_cnt)
- {
-
- case 0: CD4051_CH_Select(0); //選擇通道
- ad_value = Readad();//此處調用Readad(void)函數,
-
- gotoxy(1,0);//設置顯示起始坐標
- display_LCD_string("CH1 VOL:"); //顯示字符“VOLTAGE:”
- display_LCD_number(ad_value); //顯示測量的電壓值
- display_LCD_string("V");
- gotoxy(1,14);
- display_LCD_string("M");
- gotoxy(0,0);
- display_LCD_string(" ");
- break;
- case 1: CD4051_CH_Select(1); //選擇通道
- ad_value = Readad();//此處調用Readad(void)函數,
- gotoxy(1,0);//設置顯示起始坐標
- display_LCD_string("CH2 VOL:"); //顯示字符“VOLTAGE:”
- display_LCD_number(ad_value); //顯示測量的電壓值
- display_LCD_string("V");
- gotoxy(1,14);
- display_LCD_string("M");
- gotoxy(0,0);
- display_LCD_string(" ");
-
- break;
- case 2: CD4051_CH_Select(2); //選擇通道
- ad_value = Readad();//此處調用Readad(void)函數,
- gotoxy(1,0);//設置顯示起始坐標
- display_LCD_string("CH3 VOL:"); //顯示字符“VOLTAGE:”
- display_LCD_number(ad_value); //顯示測量的電壓值
- display_LCD_string("V");
- gotoxy(1,14);
- display_LCD_string("M");
-
- gotoxy(0,0);
- display_LCD_string(" ");
-
- break;
- case 3: CD4051_CH_Select(3); //選擇通道
- ad_value = Readad();//此處調用Readad(void)函數,
- gotoxy(1,0);//設置顯示起始坐標
- display_LCD_string("CH4 VOL:"); //顯示字符“VOLTAGE:”
- display_LCD_number(ad_value); //顯示測量的電壓值
- display_LCD_string("V");
- gotoxy(1,14);
- display_LCD_string("M");
- gotoxy(0,0);
- display_LCD_string(" ");
-
- break;
- case 4: CD4051_CH_Select(4); //選擇通道
- ad_value = Readad();//此處調用Readad(void)函數,
- gotoxy(1,0);//設置顯示起始坐標
- display_LCD_string("CH5 VOL:"); //顯示字符“VOLTAGE:”
- display_LCD_number(ad_value); //顯示測量的電壓值
- display_LCD_string("V");
- gotoxy(1,14);
- display_LCD_string("M");
- gotoxy(0,0);
- display_LCD_string(" ");
-
- break;
- case 5: CD4051_CH_Select(5); //選擇通道
- ad_value = Readad();//此處調用Readad(void)函數,
- gotoxy(1,0);//設置顯示起始坐標
- display_LCD_string("CH6 VOL:"); //顯示字符“VOLTAGE:”
- display_LCD_number(ad_value); //顯示測量的電壓值
- display_LCD_string("V");
- gotoxy(1,14);
- display_LCD_string("M");
- gotoxy(0,0);
- display_LCD_string(" ");
- break;
- case 6: CD4051_CH_Select(6); //選擇通道
- ad_value = Readad();//此處調用Readad(void)函數,
- gotoxy(1,0);//設置顯示起始坐標
- display_LCD_string("CH7 VOL:"); //顯示字符“VOLTAGE:”
- display_LCD_number(ad_value); //顯示測量的電壓值
- display_LCD_string("V");
- gotoxy(1,14);
- display_LCD_string("M");
- gotoxy(0,0);
- display_LCD_string(" ");
- break;
- case 7: CD4051_CH_Select(7); //選擇通道
- ad_value = Readad();//此處調用Readad(void)函數,
- gotoxy(1,0);//設置顯示起始坐標
- display_LCD_string("CH8 VOL:"); //顯示字符“VOLTAGE:”
- display_LCD_number(ad_value); //顯示測量的電壓值
- display_LCD_string("V");
- gotoxy(1,14);
- display_LCD_string("M");
- gotoxy(0,0);
- display_LCD_string(" ");
- break;
- }
-
-
- }
- /***************自動測量模式下顯示的畫面************************/
- void Auto_Voltage_disp(void)
- {
-
- Time_cnt++;
- delay_ms(1);
- if(Time_cnt>30)//3000ms到,切換一次狀態
- {
- Time_cnt = 0;
- Auto_cnt ++;//3000ms
- if(Auto_cnt>3) Auto_cnt = 0; //變量Auto_cnt中存放自動模式下四種顯示界面的切換標志,0代表畫面1,1代表畫面2,以此類推
- }
-
- switch(Auto_cnt)
- {
- case 0:
- CD4051_CH_Select(0); //選擇通道
- ad_value = Readad();//此處調用Readad(void)函數,
- gotoxy(1,0);//設置顯示起始坐標
- display_LCD_string("CH1 VOL:"); //顯示字符“VOLTAGE:”
- display_LCD_number(ad_value); //顯示測量的電壓值
- display_LCD_string("V");
- gotoxy(1,14);
- display_LCD_string("A");
- CD4051_CH_Select(1); //選擇通道
- ad_value = Readad();//此處調用Readad(void)函數,
- gotoxy(0,0);//設置顯示起始坐標
- display_LCD_string("CH2 VOL:"); //顯示字符“VOLTAGE:”
- display_LCD_number(ad_value); //顯示測量的電壓值
- display_LCD_string("V");
-
- break;
- case 1:
- CD4051_CH_Select(2); //選擇通道
- ad_value = Readad();//此處調用Readad(void)函數,
- gotoxy(1,0);//設置顯示起始坐標
- display_LCD_string("CH3 VOL:"); //顯示字符“VOLTAGE:”
- display_LCD_number(ad_value); //顯示測量的電壓值
- display_LCD_string("V");
- gotoxy(1,14);
- display_LCD_string("A");
- CD4051_CH_Select(3); //選擇通道
- ad_value = Readad();//此處調用Readad(void)函數,
- gotoxy(0,0);//設置顯示起始坐標
- display_LCD_string("CH4 VOL:"); //顯示字符“VOLTAGE:”
- display_LCD_number(ad_value); //顯示測量的電壓值
- display_LCD_string("V");
- break;
- case 2:
- CD4051_CH_Select(5); //選擇通道
- ad_value = Readad();//此處調用Readad(void)函數,
- gotoxy(1,0);//設置顯示起始坐標
- display_LCD_string("CH5 VOL:"); //顯示字符“VOLTAGE:”
- display_LCD_number(ad_value); //顯示測量的電壓值
- display_LCD_string("V");
- gotoxy(1,14);
- display_LCD_string("A");
- CD4051_CH_Select(6); //選擇通道
- ad_value = Readad();//此處調用Readad(void)函數,
- gotoxy(0,0);//設置顯示起始坐標
- display_LCD_string("CH6 VOL:"); //顯示字符“VOLTAGE:”
- display_LCD_number(ad_value); //顯示測量的電壓值
- display_LCD_string("V");
- break;
- case 3:
- CD4051_CH_Select(7); //選擇通道
- ad_value = Readad();//此處調用Readad(void)函數,
- gotoxy(1,0);//設置顯示起始坐標
- display_LCD_string("CH7 VOL:"); //顯示字符“VOLTAGE:”
- display_LCD_number(ad_value); //顯示測量的電壓值
- display_LCD_string("V");
- gotoxy(1,14);
- display_LCD_string("A");
- CD4051_CH_Select(8); //選擇通道
- ad_value = Readad();//此處調用Readad(void)函數,
- gotoxy(0,0);//設置顯示起始坐標
- display_LCD_string("CH8 VOL:"); //顯示字符“VOLTAGE:”
- display_LCD_number(ad_value); //顯示測量的電壓值
- display_LCD_string("V");
- break;
- }
-
- }
復制代碼
全部資料51hei下載地址:
顏歡專屬.zip
(307.2 KB, 下載次數: 98)
2018-10-31 22:23 上傳
點擊文件名下載附件
|