找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5135|回复: 1
打印 上一主题 下一主题
收起左侧

单片机+MCP3001多通道电压测量的程序源码和仿真原理图

[复制链接]
跳转到指定楼层
楼主
一款51单片机芯片和MCP3001 ad转换器电路实现 8 路电压测量系统,并可以将显示的电压显示在液晶屏上。系统中 AD 测量芯片只用一片。8 电路电压输入采用模拟量开关进行切换。实验
8 个 led 灯代表模拟量输入通道状态。
S1 键,按下 S1 键,系统工作模式为手动切换通道进行测量,并且显示测量电压值。
并在液晶屏的右上角显示“M”字母,代表当前模式是手动模式。
S2 键,按下 S2 键,系统工作模式为自动切换通道进行测量,并且显示测量电压
值。并在液晶屏的右上角显示“A”字母,代表当前模式是手动模式。电压值显
示采用轮显方式,每个 5 秒钟切换一次显示。
S3 键,具体功能如下:
(A) 在手动模式下,没按下一次,切换一组显示画面。一共四组显示画面。
(B) 在自动模式下,此按键不起作用。

仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)


MCP3001的单片机源码:
  1. #include<reg52.h>
  2. #include <lcd.h>
  3. #include<intrins.h>
  4. int *pp;
  5. unsigned int Dist_temp;

  6. char code int2charLCD[10]="0123456789";

  7. sbit _4051_A = P1^5;
  8. sbit _4051_B = P1^6;
  9. sbit _4051_C = P1^7;

  10. sbit CLK = P1^0;
  11. sbit DO = P1^1;
  12. sbit CS = P1^2;

  13. sbit led1 = P3^7;
  14. sbit led2 = P3^6;
  15. sbit led3 = P3^5;
  16. sbit led4 = P3^4;
  17. sbit led5 = P3^3;
  18. sbit led6 = P3^2;
  19. sbit led7 = P3^1;
  20. sbit led8 = P3^0;
  21. sbit LED=P1^3;
  22. sbit KEY_S1 = P2^3;
  23. sbit KEY_S2 = P2^5;
  24. sbit KEY_S3 = P2^7;

  25. unsigned char sys_mode=0;//工作模式,0代表手动,1代表自动
  26. unsigned char hand_mode_cnt=0;//手动模式下按键的计数,0-7代表通道CH1-CH8
  27. unsigned char Time_cnt=0; //自动模式下时间计数
  28. unsigned int  Auto_cnt=0;//自动模式状态切换
  29. /**************************/
  30. //函数声明
  31. void sysinit();        //调用程序初始化函数
  32. unsigned int Readad(void);
  33. void Voltage_cal(void);
  34. void disp();
  35. void CD4051_CH_Select(unsigned char ch);
  36. void key_scan(void);
  37. void System_Voltage_disp(void);
  38. void Manue_Voltage_disp(void);
  39. void Auto_Voltage_disp(void);
  40. /*****************************/
  41. unsigned int ad_value = 0;
  42. unsigned int ABC=0;
  43. float disp_val = 0;

  44. int Per;

  45. void delay100us()
  46. {
  47.         unsigned char i,j;
  48.         for(i=0;i<20;i++)
  49.                 for(j=0;j<=5;j++);        
  50. }

  51. void delay_ms(int num)
  52. {
  53.         int i,j;
  54.         for(i=num;i>0;i--)
  55.          for(j=1500;j>0;j--);
  56. }

  57. void write_LCD_command(unsigned command)
  58. {
  59.         delay100us();
  60.   rw=WRITE;        //0
  61.   rs=COMMAND;//0
  62.   enable=ENABLE; //1
  63.   P0=command;
  64.   delay100us();
  65.   
  66.   //chek_busyflag();
  67.   enable=DISABLE;//0
  68.   rw=1;
  69. }

  70. void write_LCD_DATA1(unsigned LCDDATA1)
  71. {
  72.         delay100us();
  73.   rw=WRITE;//0
  74.   rs=DATA1;//1
  75.   enable=ENABLE;//1
  76.   P0=LCDDATA1;
  77.   delay100us();        
  78.   //chek_busyflag();
  79.   enable=DISABLE;//0
  80.   rw=1;
  81.   
  82. }

  83. void init_LCD(void)
  84. {
  85.     write_LCD_command(TwoLine_8bit);      // 0x38 置功能:2行,5*7字符
  86.     write_LCD_command(CURSOR_OFF);        // 0x0c 置显示开关:显示屏开,光标不出现不闪烁        
  87.     write_LCD_command(CURSOR_RIGHT);      // 0x06 置输入模式:地址加1   光标右移,显示屏不移动
  88.         clear_LCD();
  89. }

  90. void init01_LCD(void)
  91. {
  92.     write_LCD_command(TwoLine_8bit);      // 0x38 置功能:2行,5*7字符
  93.     write_LCD_command(CURSOR_OFF01);        // 0x0c 置显示开关:显示屏开,光标出现闪烁        
  94.     write_LCD_command(CURSOR_RIGHT);      // 0x06 置输入模式:地址加1   光标右移,显示屏不移动
  95. }
  96. void clear_LCD()
  97. {
  98.   write_LCD_command(CLEAR);                                //清除显示器
  99.   write_LCD_command(CURSOR_HOME);                //光标回到左上角
  100. }

  101. void display_LCD_string(char *p)
  102. {
  103.   while(*p)
  104.    {
  105.      write_LCD_DATA1(*p);
  106.          p++;
  107.    }
  108. }

  109. void display_LCD_number(unsigned int number)
  110. {
  111.   unsigned char x,y,z;
  112.   x=number/100;
  113.   y=(number/10)%10;
  114.   z=number%10;

  115.   write_LCD_DATA1(int2charLCD[x]);
  116.   write_LCD_DATA1('.');        
  117.   write_LCD_DATA1(int2charLCD[y]);
  118.   write_LCD_DATA1(int2charLCD[z]);
  119. }

  120. void gotoxy(unsigned x,unsigned y)                //显示行选择
  121. {
  122.   if(x==1)
  123.     write_LCD_command(GOTO_LINE_1+y);
  124.   else
  125.     write_LCD_command(GOTO_LINE_2+y);
  126. }


  127. /****主函数*******/
  128. void main()
  129. {
  130.         init_LCD();
  131.                
  132.         while(1)
  133.         {
  134.                

  135.                 key_scan();
  136.             System_Voltage_disp();

  137.          }
  138. }

  139. /***********AD芯片读取函数************************/
  140. unsigned int Readad(void)
  141. {
  142.         unsigned char i;
  143.         unsigned int tmp;

  144.         float Ux;
  145.    tmp  = 0;
  146.         CLK = 0;
  147.         CS = 0;

  148.    _nop_();
  149.         CLK = 1;
  150.         _nop_();
  151.         CLK = 0;

  152.     _nop_();
  153.         CLK = 1;
  154.         _nop_();
  155.         CLK = 0;

  156.         _nop_();
  157.         CLK = 1;
  158.         _nop_();
  159.         CLK = 0;

  160.         for(i = 0; i < 10; i++)
  161.         {
  162.         
  163.                 CLK = 1;
  164.                 tmp = tmp << 1;
  165.                 if(DO == 1)
  166.                 {
  167.                         tmp = tmp + 1;
  168.                 }
  169.                 CLK = 0;
  170.                
  171.         }
  172.         CS = 1;
  173.         CLK = 1;
  174.         
  175.         Ux = tmp;
  176.         
  177.         Ux = 100*(Ux * 5.0)/1024;/**********AD测量电压计算,计算电压值扩大100倍******************/
  178.         
  179.         
  180.         return(Ux);
  181.                                                                            
  182. }

  183. /*******选择模拟量通道*************/
  184. void CD4051_CH_Select(unsigned char ch)
  185. {
  186.          switch(ch)
  187.          {
  188.                  case 0: _4051_A = 0;
  189.                                 _4051_B = 0;
  190.                                 _4051_C = 0;
  191.                                 //P3 = 0X80;
  192.                                 led1 = 1;led2=led3=led4=led5=led6=led7=led8=0;
  193.                                 break;

  194.                  case 1: _4051_A = 1;
  195.                                 _4051_B = 0;
  196.                                 _4051_C = 0;
  197.                                 //P3 = 0X40;
  198.                                 led2 = 1;led1=led3=led4=led5=led6=led7=led8=0;
  199.                                 break;
  200.                 case 2: _4051_A = 0;
  201.                                 _4051_B = 1;
  202.                                 _4051_C = 0;
  203.                                 //P3 = 0X20;
  204.                                 led3 = 1;led1=led2=led4=led5=led6=led7=led8=0;
  205.                                 break;
  206.                 case 3: _4051_A = 1;
  207.                                 _4051_B = 1;
  208.                                 _4051_C = 0;
  209.                                 //P3 = 0X20;
  210.                                 led4 = 1;led1=led2=led3=led5=led6=led7=led8=0;
  211.                                 break;
  212.                 case 4: _4051_A = 0;
  213.                                 _4051_B = 0;
  214.                                 _4051_C = 1;
  215.                                 //P3 = 0X20;
  216.                                 led5 = 1;led1=led2=led3=led4=led6=led7=led8=0;
  217.                                 break;
  218.                 case 5: _4051_A = 1;
  219.                                 _4051_B = 0;
  220.                                 _4051_C = 1;
  221.                                 //P3 = 0X20;
  222.                                 led6 = 1;led1=led2=led3=led5=led4=led7=led8=0;
  223.                                 break;
  224.                 case 6: _4051_A = 0;
  225.                                 _4051_B = 1;
  226.                                 _4051_C = 1;
  227.                                 //P3 = 0X20;
  228.                                 led7 = 1;led1=led2=led3=led5=led6=led4=led8=0;
  229.                                 break;
  230.                 case 7: _4051_A = 1;
  231.                                 _4051_B = 1;
  232.                                 _4051_C = 1;
  233.                                 //P3 = 0X20;
  234.                                 led7 = 1;led1=led2=led3=led4=led5=led6=led8=0;
  235.                                 break;

  236. }
  237. }


  238. /*********按键扫描***************/
  239. void key_scan(void)
  240. {
  241.         if(KEY_S1==0)
  242.         {
  243.                 delay_ms(10);
  244.                 if(KEY_S1==0)
  245.                 {
  246.                         sys_mode = 0;
  247.                         //切换成手动模式
  248.                 }
  249.         }

  250.         if(KEY_S2==0)
  251.         {
  252.                 delay_ms(10);
  253.                 if(KEY_S2==0)
  254.                 {
  255.                         sys_mode = 1; //切换成自动模式
  256.                 }
  257.         }

  258.         if(sys_mode==0)
  259.         {
  260.            if(KEY_S3==0)
  261.                 {
  262.                         delay_ms(10);
  263.                         if(KEY_S3==0)
  264.                         {
  265.                                 hand_mode_cnt++;               
  266.                                 if(hand_mode_cnt>=8) hand_mode_cnt = 0;
  267.                                 
  268.         
  269.                         }
  270.                         
  271.                 }
  272.         }
  273.         
  274. }



  275. /***********电压显示总控制函数*******************/
  276. void System_Voltage_disp(void)
  277. {
  278.         if(sys_mode==0)
  279.         {
  280.                 Manue_Voltage_disp(); //手动模式下电压显示
  281.         }
  282.     else
  283.         {
  284.            Auto_Voltage_disp(); //自动模式下电压显示
  285.         }

  286. }

  287. /***********手动模式下电压显示*******************/
  288. void Manue_Voltage_disp(void)
  289. {        if(ad_value>250)
  290.         {LED=~LED;}
  291.         else
  292.         {        LED=1;}
  293.         switch(hand_mode_cnt)
  294.         {
  295.                
  296.                 case 0:   CD4051_CH_Select(0); //选择通道
  297.                           ad_value = Readad();//此处调用Readad(void)函数,
  298.                
  299.                 gotoxy(1,0);//设置显示起始坐标
  300.                                         display_LCD_string("CH1 VOL:"); //显示字符“VOLTAGE:”
  301.                                         display_LCD_number(ad_value); //显示测量的电压值
  302.                             display_LCD_string("V");
  303.                         gotoxy(1,14);
  304.                         display_LCD_string("M");
  305.                                         gotoxy(0,0);
  306.                                 display_LCD_string("             ");

  307.                        break;
  308.                 case 1: CD4051_CH_Select(1); //选择通道
  309.                          ad_value = Readad();//此处调用Readad(void)函数,
  310.                                         gotoxy(1,0);//设置显示起始坐标
  311.                                         display_LCD_string("CH2 VOL:"); //显示字符“VOLTAGE:”
  312.                                         display_LCD_number(ad_value); //显示测量的电压值
  313.                             display_LCD_string("V");
  314.                     gotoxy(1,14);
  315.                         display_LCD_string("M");
  316.                                     gotoxy(0,0);
  317.                         display_LCD_string("             ");               
  318.         
  319.                         break;
  320.                 case 2: CD4051_CH_Select(2); //选择通道
  321.                          ad_value = Readad();//此处调用Readad(void)函数,
  322.                                         gotoxy(1,0);//设置显示起始坐标
  323.                                         display_LCD_string("CH3 VOL:"); //显示字符“VOLTAGE:”
  324.                                         display_LCD_number(ad_value); //显示测量的电压值
  325.                             display_LCD_string("V");
  326.                                         gotoxy(1,14);
  327.                         display_LCD_string("M");
  328.         
  329.                                          gotoxy(0,0);
  330.                          display_LCD_string("             ");
  331.         
  332.                        break;
  333.                 case 3: CD4051_CH_Select(3); //选择通道
  334.                          ad_value = Readad();//此处调用Readad(void)函数,
  335.                                         gotoxy(1,0);//设置显示起始坐标
  336.                                         display_LCD_string("CH4 VOL:"); //显示字符“VOLTAGE:”
  337.                                         display_LCD_number(ad_value); //显示测量的电压值
  338.                                         display_LCD_string("V");
  339.                                         gotoxy(1,14);
  340.                         display_LCD_string("M");
  341.                                          gotoxy(0,0);
  342.                          display_LCD_string("             ");
  343.         
  344.                        break;
  345.                 case 4: CD4051_CH_Select(4); //选择通道
  346.                          ad_value = Readad();//此处调用Readad(void)函数,
  347.                                         gotoxy(1,0);//设置显示起始坐标
  348.                                         display_LCD_string("CH5 VOL:"); //显示字符“VOLTAGE:”
  349.                                         display_LCD_number(ad_value); //显示测量的电压值
  350.                                         display_LCD_string("V");
  351.                                         gotoxy(1,14);
  352.                                         display_LCD_string("M");
  353.                                          gotoxy(0,0);
  354.                                         display_LCD_string("             ");
  355.         
  356.                        break;
  357.               case 5: CD4051_CH_Select(5); //选择通道
  358.                          ad_value = Readad();//此处调用Readad(void)函数,
  359.                                         gotoxy(1,0);//设置显示起始坐标
  360.                                         display_LCD_string("CH6 VOL:"); //显示字符“VOLTAGE:”
  361.                                         display_LCD_number(ad_value); //显示测量的电压值
  362.                             display_LCD_string("V");
  363.                                         gotoxy(1,14);
  364.                         display_LCD_string("M");
  365.                                 gotoxy(0,0);
  366.                         display_LCD_string("             ");

  367.                           break;
  368.            case 6: CD4051_CH_Select(6); //选择通道
  369.                          ad_value = Readad();//此处调用Readad(void)函数,
  370.                                         gotoxy(1,0);//设置显示起始坐标
  371.                                         display_LCD_string("CH7 VOL:"); //显示字符“VOLTAGE:”
  372.                                         display_LCD_number(ad_value); //显示测量的电压值
  373.                             display_LCD_string("V");
  374.                                         gotoxy(1,14);
  375.                         display_LCD_string("M");
  376.                                         gotoxy(0,0);
  377.                          display_LCD_string("             ");

  378.                          break;                                         
  379.             case 7: CD4051_CH_Select(7); //选择通道
  380.                          ad_value = Readad();//此处调用Readad(void)函数,
  381.                                         gotoxy(1,0);//设置显示起始坐标
  382.                                         display_LCD_string("CH8 VOL:"); //显示字符“VOLTAGE:”
  383.                                         display_LCD_number(ad_value); //显示测量的电压值
  384.                             display_LCD_string("V");
  385.                                         gotoxy(1,14);
  386.                         display_LCD_string("M");
  387.                 gotoxy(0,0);
  388.                          display_LCD_string("             ");

  389.                          break;
  390. }
  391.         
  392.         
  393. }

  394. /***************自动测量模式下显示的画面************************/
  395. void Auto_Voltage_disp(void)
  396. {
  397.         
  398.         Time_cnt++;
  399.         delay_ms(1);
  400.         if(Time_cnt>30)//3000ms到,切换一次状态
  401.         {
  402.                 Time_cnt = 0;
  403.                 Auto_cnt ++;//3000ms
  404.                 if(Auto_cnt>3) Auto_cnt = 0; //变量Auto_cnt中存放自动模式下四种显示界面的切换标志,0代表画面1,1代表画面2,以此类推
  405.         }
  406.    
  407.         switch(Auto_cnt)
  408.         {
  409.                 case 0:
  410.                          CD4051_CH_Select(0); //选择通道
  411.                      ad_value = Readad();//此处调用Readad(void)函数,
  412.                          gotoxy(1,0);//设置显示起始坐标
  413.                          display_LCD_string("CH1 VOL:"); //显示字符“VOLTAGE:”
  414.                          display_LCD_number(ad_value);                //显示测量的电压值
  415.                          display_LCD_string("V");
  416.                      gotoxy(1,14);
  417.                  display_LCD_string("A");
  418.                    CD4051_CH_Select(1); //选择通道
  419.                      ad_value = Readad();//此处调用Readad(void)函数,
  420.                          gotoxy(0,0);//设置显示起始坐标
  421.                          display_LCD_string("CH2 VOL:"); //显示字符“VOLTAGE:”
  422.                          display_LCD_number(ad_value); //显示测量的电压值
  423.                      display_LCD_string("V");        
  424.                   
  425.                 break;
  426.                 case 1:
  427.                          CD4051_CH_Select(2); //选择通道
  428.                      ad_value = Readad();//此处调用Readad(void)函数,
  429.                          gotoxy(1,0);//设置显示起始坐标
  430.                          display_LCD_string("CH3 VOL:"); //显示字符“VOLTAGE:”
  431.                          display_LCD_number(ad_value); //显示测量的电压值
  432.                          display_LCD_string("V");
  433.                      gotoxy(1,14);
  434.                  display_LCD_string("A");
  435.                    CD4051_CH_Select(3); //选择通道
  436.                      ad_value = Readad();//此处调用Readad(void)函数,
  437.                          gotoxy(0,0);//设置显示起始坐标
  438.                          display_LCD_string("CH4 VOL:"); //显示字符“VOLTAGE:”
  439.                          display_LCD_number(ad_value); //显示测量的电压值
  440.                      display_LCD_string("V");
  441.                         break;
  442.                 case 2:
  443.                  CD4051_CH_Select(5); //选择通道
  444.                      ad_value = Readad();//此处调用Readad(void)函数,
  445.                          gotoxy(1,0);//设置显示起始坐标
  446.                          display_LCD_string("CH5 VOL:"); //显示字符“VOLTAGE:”
  447.                          display_LCD_number(ad_value); //显示测量的电压值
  448.                          display_LCD_string("V");
  449.                      gotoxy(1,14);
  450.                  display_LCD_string("A");
  451.                    CD4051_CH_Select(6); //选择通道
  452.                      ad_value = Readad();//此处调用Readad(void)函数,
  453.                          gotoxy(0,0);//设置显示起始坐标
  454.                          display_LCD_string("CH6 VOL:"); //显示字符“VOLTAGE:”
  455.                          display_LCD_number(ad_value); //显示测量的电压值
  456.                          display_LCD_string("V");
  457.                   break;
  458.                 case 3:
  459.                         CD4051_CH_Select(7); //选择通道
  460.                      ad_value = Readad();//此处调用Readad(void)函数,
  461.                          gotoxy(1,0);//设置显示起始坐标
  462.                          display_LCD_string("CH7 VOL:"); //显示字符“VOLTAGE:”
  463.                          display_LCD_number(ad_value); //显示测量的电压值
  464.                          display_LCD_string("V");
  465.                      gotoxy(1,14);
  466.                  display_LCD_string("A");
  467.                      CD4051_CH_Select(8); //选择通道
  468.                      ad_value = Readad();//此处调用Readad(void)函数,
  469.                          gotoxy(0,0);//设置显示起始坐标
  470.                          display_LCD_string("CH8 VOL:"); //显示字符“VOLTAGE:”
  471.                          display_LCD_number(ad_value); //显示测量的电压值
  472.                          display_LCD_string("V");
  473.                  break;

  474.         }
  475.         
  476. }
复制代码



全部资料51hei下载地址:
颜欢专属.zip (307.2 KB, 下载次数: 98)


评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:217688 发表于 2022-5-30 23:08 | 只看该作者
厉害了,正好需要,感谢楼主
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表