一款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 上传)
下载积分: 黑币 -5