社区导航

 

搜索
查看: 258|回复: 1

[经验] MSP430单片机制作智能数字万用表电路图+程序

[复制链接]

1280

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2019-10-8 22:15 | 显示全部楼层 |阅读模式

留给想做万用表的小伙伴们
电路原理图如下:

360截图20191008221446997.jpg

单片机源程序如下:

  1. /*
  2. * 简易低功耗万用表
  3. */
  4. #include <msp430g2553.h>
  5. #include "LCD12864P.h"
  6.  
  7. unsigned int ADC_flag,ADC_flag1,shua_xin;
  8. unsigned int ADC_data[8],ADC_result[8],mser,song,liang_cheng = 0,s,wen_pt,pt100 = 0,zu_zhi = 0;
  9.  
  10. unsigned int data0,data1,data2,data3,data4,data5,data6,data7;
  11.  
  12. //double data0,data1,data2,data3,data4,data5,data6,data7;
  13. unsigned int table[]={0x00,0x02,0x01,0x04,0x08,0xEF,0xdf,0xcf,0x80};//量程选择 【1】直流10v   【2】直流1v  【3】电阻值10k
  14.  
  15. /*
  16. *初始化
  17. */
  18. void int_t()
  19. {
  20.  
  21.     WDTCTL = WDT_MDLY_8;    //看门狗定时器的初始化设置
  22.     IE1 |= WDTIE;
  23.     Ini_Lcd();                                 //lcd初始化
  24.         BCSCTL1 = CALBC1_8MHZ;
  25.         DCOCTL  = CALDCO_8MHZ;
  26.         /*
  27.         P1DIR &= BIT3+BIT4;/////////将按键口设置为输入
  28.         P1REN |= BIT3+BIT4;////////打开上拉电阻,目的为产生触发沿高电平往低电平
  29.         P1IE  |= 0X18;//////////设置按键口中断
  30.         P1IES |= 0X18;///////////下降沿中断。只有在松手时触发中断的产生
  31.         */
  32.         P1DIR &= BIT3;/////////将按键口设置为输入
  33.         P1REN |= BIT3;////////打开上拉电阻,目的为产生触发沿高电平往低电平
  34.         P1IE  |= 0X08;//////////设置按键口中断
  35.         P1IES |= 0X08;///////////下降沿中断。只有在松手时触发中断的产生
  36.  
  37.         P2DIR &= ~(BIT2+BIT3+BIT4+BIT5);/////////将功能选择按键口设置为输入        1.直流电压   2.交流电压   3.电阻量程    4.电容测量
  38.  
  39.         P1DIR |= BIT5 + BIT6 + BIT7 ;                        //        将扩展口为输出
  40.  
  41.         _EINT();                                          //使能中断,这是一个C编译器支持的内部过程。
  42.  
  43. }
  44. /*
  45. * 按键延时程序
  46. */
  47. void delay(unsigned int n)//带参数有返回值的函数
  48. {
  49.         unsigned int i;
  50.         unsigned int j;
  51.         for(i=n;i>0;i--)
  52.                 for(j=100;j>0;j--)
  53.                         _nop();
  54. }
  55. /**************************************************************
  56. *名称:ADC()
  57. *功能:AD设置转换  中断
  58. ****************************************************************/
  59.  
  60. void  ADC()
  61. {
  62.         P1SEL |= BIT0 + BIT1 + BIT2 + BIT4;//+ BIT3;//+ BIT4 + BIT5 + BIT6 + BIT7;                  //设置为模拟输入
  63.         ADC10AE0  |= BIT0 + BIT1 + BIT2+ BIT4;// + BIT3;//+ BIT4 + BIT5 + BIT6 + BIT7;   //开启通道A1/A2/A4/A5/A6/A7
  64.         ADC10CTL0|=ADC10ON+MSC+ADC10SHT_2+ADC10IE;                        //打开ADC转换  ,ADC10使能 ,设置采用频率16个周期,允许中断
  65.         ADC10CTL0 |=SREF_1 + REFON + REF2_5V;                           //开内部参考电压为2.5V,允许中断
  66.         ADC10CTL1|=CONSEQ_3+INCH_7;                                                 //使用双(4)通道、循环采集模式
  67.         ADC10DTC1|=0x08;                                                                      //每一通道连续采样1次
  68.         _BIS_SR(GIE);
  69. }
  70. /*
  71. *功能:AD数据处理
  72. */
  73. void ADC_DATA()
  74. {
  75.         unsigned char i;
  76.         ADC10CTL0&=~ENC;
  77.         while(ADC10CTL1&ADC10BUSY);                                                //检测AD是否繁忙
  78.         ADC10CTL0|=ENC+ADC10SC;                                                  //启动ADC
  79.         ADC10SA=(unsigned int)ADC_result;                                //获取ADC_result[]的首地址。首先对A1、A0采样,放入ADC_result[0]和ADC_result[1]中,如此循环下去。
  80.         for(i=0;i<8;i++)
  81.     {
  82.                 ADC_data=0;
  83.                 ADC_data=ADC_result;
  84.         //        ADC_data=(ADC_data*25)/1023;                     //将ADC转换成实际的电压值
  85.     }
  86. }
  87. /*
  88. * 扩展芯片595写入程序
  89. */
  90. void kuo_zhan(unsigned int dat)
  91. {
  92.         unsigned int i;
  93.         for(i=0;i<8;i++)
  94.         {
  95.                 if((dat<<i)&0x80)
  96.                         P1OUT|=BIT5;
  97.                 else
  98.                 P1OUT &= ~BIT5;
  99.                 P1OUT &= ~BIT7;
  100.                 _NOP();
  101.                 P1OUT |= BIT7;
  102.                 _NOP();
  103.         }
  104.         P1OUT &= ~BIT6;
  105.         _NOP();
  106.         P1OUT |= BIT6;
  107.         _NOP();
  108. }
  109. /*
  110. * 直流电压检测
  111. */
  112. void zhi_liu()
  113. {
  114.         unsigned int song_chao;
  115.  
  116.         lcd_pos(1,0);
  117.         Disp_HZ("★低功耗万用表★",8);
  118.  
  119.         lcd_pos(2,0);
  120.         Disp_HZ("直流电压",4);
  121.  
  122.         lcd_pos(3,0);
  123.         Disp_HZ("测量量程",4);
  124.  
  125.         lcd_pos(4,0);
  126.         Disp_HZ("测量电压",4);
  127.  
  128.         if(liang_cheng == 1)                                                //量程为10v的时候数据处理
  129.         {
  130.                 kuo_zhan(table[1]);                                                //打开10v通道
  131.                 song_chao = data0*5.8585*0.002443*100;                                        //
  132.                 if(ADC_flag1 == 1)
  133.                 {
  134.                         ADC_flag1 = 0;
  135.                         lcd_pos(3,5);
  136.                         Disp_SZ(10/10);
  137.                         Disp_SZ(10%10);
  138.                         lcd_pos(3,6);
  139.                         Disp_HZ("V",1);
  140.  
  141.                         lcd_pos(4,5);
  142.                         Disp_SZ(song_chao/1000);
  143.                         Disp_SZ(song_chao%1000/100);
  144.                         Disp_SZ(song_chao%100/10);
  145.                         Disp_SZ(song_chao%10);
  146.  
  147.                         lcd_pos(4,7);
  148.                         Disp_HZ("V",1);
  149.                 }
  150.         }
  151.         else if(liang_cheng == 2)                                                //量程为10v的时候数据处理
  152.         {
  153.                 kuo_zhan(table[2]);                                                //打开10v通道
  154.                 song_chao = data0*1.9825*0.002443*1000;                                        //
  155.                 if(ADC_flag1 == 1)
  156.                 {
  157.                         ADC_flag1 = 0;
  158.                         lcd_pos(3,5);
  159.                         Disp_SZ(01/10);
  160.                         Disp_SZ(01%10);
  161.                         lcd_pos(3,6);
  162.                         Disp_HZ("V",1);
  163.  
  164.                         lcd_pos(4,5);
  165.                         Disp_SZ(song_chao/1000);
  166.                         Disp_SZ(song_chao%1000/100);
  167.                         Disp_SZ(song_chao%100/10);
  168.                         Disp_SZ(song_chao%10);
  169.  
  170.                         lcd_pos(4,7);
  171.                         Disp_HZ("V",1);
  172.                 }
  173.         }
  174.         else if(liang_cheng == 3)                                                //量程为10v的时候数据处理
  175.                 {
  176.                         kuo_zhan(table[3]);                                                //打开10v通道
  177.                         song_chao = data0*0.0891*0.002443*1000;                                        //
  178.                         if(ADC_flag1 == 1)
  179.                         {
  180.                                 ADC_flag1 = 0;
  181.                                 lcd_pos(3,4);
  182.                                 Disp_SZ(01/10);
  183.                                 Disp_HZ(".",1);
  184.                                 Disp_SZ(01%10);
  185.                                 lcd_pos(3,6);
  186.                                 Disp_HZ("V",1);
  187.  
  188.                                 lcd_pos(4,5);
  189.                                 Disp_SZ(song_chao/1000);
  190.                                 Disp_SZ(song_chao%1000/100);
  191.                                 Disp_SZ(song_chao%100/10);
  192.                                 Disp_SZ(song_chao%10);
  193.  
  194.                                 lcd_pos(4,7);
  195.                                 Disp_HZ("V",1);
  196.                         }
  197.                 }
  198. }
  199. /*
  200. * 交流电压检测
  201. */
  202. void jiao_liu()
  203. {
  204.         unsigned int chao_song;
  205.  
  206.         lcd_pos(1,0);
  207.         Disp_HZ("★低功耗万用表★",8);
  208.  
  209.         lcd_pos(2,0);
  210.         Disp_HZ("交流电压",4);
  211.  
  212.         lcd_pos(3,0);
  213.         Disp_HZ("测量量程",4);
  214.  
  215.         lcd_pos(4,0);
  216.         Disp_HZ("测量电压",4);
  217.  
  218.         if(liang_cheng == 1)                                                //量程为10v的时候数据处理
  219.         {
  220.                 chao_song = data1*3.5*0.002443*100;                //
  221.                 if(ADC_flag1 == 1)
  222.                 {
  223.                         ADC_flag1 = 0;
  224.                         lcd_pos(3,4);
  225.                         Disp_SZ(10/10);
  226.                         Disp_SZ(10%10);
  227.                         lcd_pos(3,6);
  228.                         Disp_HZ("V",1);
  229.  
  230.                         lcd_pos(4,5);
  231.                         Disp_SZ(chao_song/1000);
  232.                         Disp_SZ(chao_song%1000/100);
  233.                         Disp_SZ(chao_song%100/10);
  234.                         Disp_SZ(chao_song%10);
  235.  
  236.                         lcd_pos(4,7);
  237.                         Disp_HZ("V",1);
  238.                 }
  239.         }
  240.         else if(liang_cheng == 2)                                                //量程为10v的时候数据处理
  241.                 {
  242.                         chao_song = data1*3.5*0.002443*1000;                //
  243.                         if(ADC_flag1 == 1)
  244.                         {
  245.                                 ADC_flag1 = 0;
  246.                                 lcd_pos(3,4);
  247.                                 Disp_SZ(01/10);
  248.                                 Disp_SZ(01%10);
  249.                                 lcd_pos(3,6);
  250.                                 Disp_HZ("V",1);
  251.  
  252.                                 lcd_pos(4,5);
  253.                                 Disp_SZ(chao_song/1000);
  254.                                 Disp_SZ(chao_song%1000/100);
  255.                                 Disp_SZ(chao_song%100/10);
  256.                                 Disp_SZ(chao_song%10);
  257.  
  258.                                 lcd_pos(4,7);
  259.                                 Disp_HZ("V",1);
  260.                         }
  261.                 }
  262. }
  263. /*
  264. * 电阻电压检测
  265. */
  266. void dian_zu()
  267. {
  268.         lcd_pos(1,0);
  269.         Disp_HZ("★低功耗万用表★",8);
  270.  
  271.         lcd_pos(2,0);
  272.         Disp_HZ("电阻电压",4);
  273.  
  274.         lcd_pos(3,0);
  275.         Disp_HZ("测量量程",4);
  276.  
  277.         lcd_pos(4,0);
  278.         Disp_HZ("测量电压",4);
  279.  
  280.         if(liang_cheng == 1)                                                //量程为10v的时候数据处理
  281.         {
  282.                 kuo_zhan(table[5]);
  283.                 if(ADC_flag1 == 1)
  284.                 {
  285.                         zu_zhi = (data2*1.3125*10);                                //100 欧姆 数据处理
  286.  
  287.                         ADC_flag1 = 0;
  288.                         lcd_pos(3,5);
  289.                         Disp_SZ(10/10);
  290.                         Disp_SZ(10%10);
  291.                         lcd_pos(3,6);
  292.                         Disp_HZ("K",1);
  293.                         lcd_pos(4,5);
  294.                         Disp_SZ(zu_zhi/1000);
  295.                         Disp_SZ(zu_zhi%1000/100);
  296.                         Disp_SZ(zu_zhi%100/10);
  297.                         Disp_SZ(zu_zhi%10);
  298.  
  299.                         lcd_pos(4,7);
  300.                         Disp_HZ("V",1);
  301.                 }
  302.         }
  303.         else if(liang_cheng == 2)                                                //量程为10v的时候数据处理
  304.         {
  305.                 kuo_zhan(table[6]);
  306.                 if(ADC_flag1 == 1)
  307.                 {
  308.                         zu_zhi = ((data2*0.00125438)/(1-data2*0.00125438))*1870;;                                //100 欧姆 数据处理
  309.  
  310.                         ADC_flag1 = 0;
  311.                         lcd_pos(3,5);
  312.                         Disp_SZ(01/10);
  313.                         Disp_SZ(01%10);
  314.                         lcd_pos(3,6);
  315.                         Disp_HZ("K",1);
  316.                         lcd_pos(4,5);
  317.                         Disp_SZ(zu_zhi/1000);
  318.                         Disp_SZ(zu_zhi%1000/100);
  319.                         Disp_SZ(zu_zhi%100/10);
  320.                         Disp_SZ(zu_zhi%10);
  321.  
  322.                         lcd_pos(4,7);
  323.                         Disp_HZ("V",1);
  324.                 }
  325.         }
  326.         else if(liang_cheng == 3)                                                //量程为10v的时候数据处理
  327.                 {
  328.                         kuo_zhan(table[7]);
  329.                         if(ADC_flag1 == 1)
  330.                         {
  331.                                 zu_zhi = ((data2*0.001244895)/(1-data2*0.001244895))*4950; //10K 欧姆的数据处理
  332.  
  333.                                 ADC_flag1 = 0;
  334.                                 lcd_pos(3,5);
  335.                                 Disp_SZ(100%1000/100);
  336.                                 Disp_SZ(100%100/10);
  337.                                 Disp_SZ(100%10);
  338.                                 lcd_pos(3,7);
  339.                                 Disp_HZ("Ω",1);
  340.                                 lcd_pos(4,5);
  341.                                 Disp_SZ(zu_zhi/1000);
  342.                                 Disp_SZ(zu_zhi%1000/100);
  343.                                 Disp_SZ(zu_zhi%100/10);
  344.                                 Disp_SZ(zu_zhi%10);
  345.  
  346.                                 lcd_pos(4,7);
  347.                                 Disp_HZ("V",1);
  348.                         }
  349.                 }
  350. }
  351. /*
  352. * 温度pt100功能
  353. */
  354. void wen_du()
  355. {
  356.         wen_pt = ((32231.7975*data4+0.3150709*data4*data4)*0.000016);        //温度的数据处理
  357.  
  358.         lcd_pos(2,4);
  359.         Disp_SZ(wen_pt%1000/100);
  360.         Disp_SZ(wen_pt%100/10);
  361.         Disp_HZ(".",1);  //充电电流
  362.         Disp_SZ(wen_pt%10);
  363.  
  364.         lcd_pos(2,7);
  365.         Disp_HZ("℃",1);
  366. }
  367. /*
  368. * 主函数
  369. */
  370. void main()
  371. {
  372.         int_t();
  373.         ADC();                                                        //AD功能设置
  374. //        ADC_DATA();                                                //AD转换开始
  375.         while(1)
  376.         {
  377.                 ADC_DATA();                                                                //AD转换开始
  378.  
  379.                 if(pt100 == 1)
  380.                 {
  381.                         pt100 = 0;
  382.                         wen_du();
  383.                 }
  384.                 if(P2IN & BIT2)                                                        //直流电压检测档位
  385.                 {
  386.                         zhi_liu();                                                                               //直流电压量程选择控制
  387.                 }
  388.                 else if(P2IN & BIT3)                                        //交流电压检测档位
  389.                 {
  390.                         jiao_liu();                                                                      //直流电压量程选择控制
  391.                 }
  392.                 else if(P2IN & BIT4)                                        //电阻电压检测档位
  393.                 {
  394.                         dian_zu();                                                                      //直流电压量程选择控制
  395.                 }
  396.         }
  397. }
  398. /**
  399. *名称      看门狗 定时 中断
  400. **/
  401. #pragma vector=WDT_VECTOR
  402. __interrupt void watchdog_timer(void)
  403. {
  404.         shua_xin++;
  405.         if(shua_xin >= 1000)
  406.         {
  407.                 shua_xin = 0;
  408.                 ADC_flag1 = 1;
  409.                 s++;
  410.                 if(s >= 50)
  411.                 {
  412.                         pt100 = 1;
  413.                 }


回复

使用道具 举报

1666

TA的帖子

0

TA的资源

纯净的硅(初级)

Rank: 4

发表于 2019-10-9 09:15 | 显示全部楼层

不错的分享

 



回复

使用道具 举报

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

关闭

站长推荐上一条 /5 下一条

  • 论坛活动 E手掌握

    扫码关注
    EEWORLD 官方微信

  • EE福利  唾手可得

    扫码关注
    EE福利 唾手可得

Archiver|手机版|小黑屋|电子工程世界 ( 京ICP证 060456 )

GMT+8, 2019-11-16 08:05 , Processed in 0.115486 second(s), 18 queries , Gzip On, MemCache On.

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