找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6973|回复: 6
收起左侧

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

  [复制链接]
ID:475083 发表于 2019-3-17 19:55 | 显示全部楼层 |阅读模式
留给想做万用表的小伙伴们
电路原理图如下:

DC转换电路

DC转换电路

全套MSP430万用表资料

全套MSP430万用表资料


单片机源程序如下:
  1. /*
  2. * 简易低功耗万用表
  3. */
  4. #include <msp430g2553.h>
  5. #include "LCD12864P.h"

  6. unsigned int ADC_flag,ADC_flag1,shua_xin;
  7. unsigned int ADC_data[8],ADC_result[8],mser,song,liang_cheng = 0,s,wen_pt,pt100 = 0,zu_zhi = 0;

  8. unsigned int data0,data1,data2,data3,data4,data5,data6,data7;

  9. //double data0,data1,data2,data3,data4,data5,data6,data7;
  10. unsigned int table[]={0x00,0x02,0x01,0x04,0x08,0xEF,0xdf,0xcf,0x80};//量程选择 【1】直流10v   【2】直流1v  【3】电阻值10k

  11. /*
  12. *初始化
  13. */
  14. void int_t()
  15. {

  16.     WDTCTL = WDT_MDLY_8;    //看门狗定时器的初始化设置
  17.     IE1 |= WDTIE;
  18.     Ini_Lcd();                                 //lcd初始化
  19.         BCSCTL1 = CALBC1_8MHZ;
  20.         DCOCTL  = CALDCO_8MHZ;
  21.         /*
  22.         P1DIR &= BIT3+BIT4;/////////将按键口设置为输入
  23.         P1REN |= BIT3+BIT4;////////打开上拉电阻,目的为产生触发沿高电平往低电平
  24.         P1IE  |= 0X18;//////////设置按键口中断
  25.         P1IES |= 0X18;///////////下降沿中断。只有在松手时触发中断的产生
  26.         */
  27.         P1DIR &= BIT3;/////////将按键口设置为输入
  28.         P1REN |= BIT3;////////打开上拉电阻,目的为产生触发沿高电平往低电平
  29.         P1IE  |= 0X08;//////////设置按键口中断
  30.         P1IES |= 0X08;///////////下降沿中断。只有在松手时触发中断的产生

  31.         P2DIR &= ~(BIT2+BIT3+BIT4+BIT5);/////////将功能选择按键口设置为输入        1.直流电压   2.交流电压   3.电阻量程    4.电容测量

  32.         P1DIR |= BIT5 + BIT6 + BIT7 ;                        //        将扩展口为输出

  33.         _EINT();                                          //使能中断,这是一个C编译器支持的内部过程。

  34. }
  35. /*
  36. * 按键延时程序
  37. */
  38. void delay(unsigned int n)//带参数有返回值的函数
  39. {
  40.         unsigned int i;
  41.         unsigned int j;
  42.         for(i=n;i>0;i--)
  43.                 for(j=100;j>0;j--)
  44.                         _nop();
  45. }
  46. /**************************************************************
  47. *名称:ADC()
  48. *功能:AD设置转换  中断
  49. ****************************************************************/

  50. void  ADC()
  51. {
  52.         P1SEL |= BIT0 + BIT1 + BIT2 + BIT4;//+ BIT3;//+ BIT4 + BIT5 + BIT6 + BIT7;                  //设置为模拟输入
  53.         ADC10AE0  |= BIT0 + BIT1 + BIT2+ BIT4;// + BIT3;//+ BIT4 + BIT5 + BIT6 + BIT7;   //开启通道A1/A2/A4/A5/A6/A7
  54.         ADC10CTL0|=ADC10ON+MSC+ADC10SHT_2+ADC10IE;                        //打开ADC转换  ,ADC10使能 ,设置采用频率16个周期,允许中断
  55.         ADC10CTL0 |=SREF_1 + REFON + REF2_5V;                           //开内部参考电压为2.5V,允许中断
  56.         ADC10CTL1|=CONSEQ_3+INCH_7;                                                 //使用双(4)通道、循环采集模式
  57.         ADC10DTC1|=0x08;                                                                      //每一通道连续采样1次
  58.         _BIS_SR(GIE);
  59. }
  60. /*
  61. *功能:AD数据处理
  62. */
  63. void ADC_DATA()
  64. {
  65.         unsigned char i;
  66.         ADC10CTL0&=~ENC;
  67.         while(ADC10CTL1&ADC10BUSY);                                                //检测AD是否繁忙
  68.         ADC10CTL0|=ENC+ADC10SC;                                                  //启动ADC
  69.         ADC10SA=(unsigned int)ADC_result;                                //获取ADC_result[]的首地址。首先对A1、A0采样,放入ADC_result[0]和ADC_result[1]中,如此循环下去。
  70.         for(i=0;i<8;i++)
  71.     {
  72.                 ADC_data[i]=0;
  73.                 ADC_data[i]=ADC_result[i];
  74.         //        ADC_data[i]=(ADC_data[i]*25)/1023;                     //将ADC转换成实际的电压值
  75.     }
  76. }
  77. /*
  78. * 扩展芯片595写入程序
  79. */
  80. void kuo_zhan(unsigned int dat)
  81. {
  82.         unsigned int i;
  83.         for(i=0;i<8;i++)
  84.         {
  85.                 if((dat<<i)&0x80)
  86.                         P1OUT|=BIT5;
  87.                 else
  88.                 P1OUT &= ~BIT5;
  89.                 P1OUT &= ~BIT7;
  90.                 _NOP();
  91.                 P1OUT |= BIT7;
  92.                 _NOP();
  93.         }
  94.         P1OUT &= ~BIT6;
  95.         _NOP();
  96.         P1OUT |= BIT6;
  97.         _NOP();
  98. }
  99. /*
  100. * 直流电压检测
  101. */
  102. void zhi_liu()
  103. {
  104.         unsigned int song_chao;

  105.         lcd_pos(1,0);
  106.         Disp_HZ("★低功耗万用表★",8);

  107.         lcd_pos(2,0);
  108.         Disp_HZ("直流电压",4);

  109.         lcd_pos(3,0);
  110.         Disp_HZ("测量量程",4);

  111.         lcd_pos(4,0);
  112.         Disp_HZ("测量电压",4);

  113.         if(liang_cheng == 1)                                                //量程为10v的时候数据处理
  114.         {
  115.                 kuo_zhan(table[1]);                                                //打开10v通道
  116.                 song_chao = data0*5.8585*0.002443*100;                                        //
  117.                 if(ADC_flag1 == 1)
  118.                 {
  119.                         ADC_flag1 = 0;
  120.                         lcd_pos(3,5);
  121.                         Disp_SZ(10/10);
  122.                         Disp_SZ(10%10);
  123.                         lcd_pos(3,6);
  124.                         Disp_HZ("V",1);

  125.                         lcd_pos(4,5);
  126.                         Disp_SZ(song_chao/1000);
  127.                         Disp_SZ(song_chao%1000/100);
  128.                         Disp_SZ(song_chao%100/10);
  129.                         Disp_SZ(song_chao%10);

  130.                         lcd_pos(4,7);
  131.                         Disp_HZ("V",1);
  132.                 }
  133.         }
  134.         else if(liang_cheng == 2)                                                //量程为10v的时候数据处理
  135.         {
  136.                 kuo_zhan(table[2]);                                                //打开10v通道
  137.                 song_chao = data0*1.9825*0.002443*1000;                                        //
  138.                 if(ADC_flag1 == 1)
  139.                 {
  140.                         ADC_flag1 = 0;
  141.                         lcd_pos(3,5);
  142.                         Disp_SZ(01/10);
  143.                         Disp_SZ(01%10);
  144.                         lcd_pos(3,6);
  145.                         Disp_HZ("V",1);

  146.                         lcd_pos(4,5);
  147.                         Disp_SZ(song_chao/1000);
  148.                         Disp_SZ(song_chao%1000/100);
  149.                         Disp_SZ(song_chao%100/10);
  150.                         Disp_SZ(song_chao%10);

  151.                         lcd_pos(4,7);
  152.                         Disp_HZ("V",1);
  153.                 }
  154.         }
  155.         else if(liang_cheng == 3)                                                //量程为10v的时候数据处理
  156.                 {
  157.                         kuo_zhan(table[3]);                                                //打开10v通道
  158.                         song_chao = data0*0.0891*0.002443*1000;                                        //
  159.                         if(ADC_flag1 == 1)
  160.                         {
  161.                                 ADC_flag1 = 0;
  162.                                 lcd_pos(3,4);
  163.                                 Disp_SZ(01/10);
  164.                                 Disp_HZ(".",1);
  165.                                 Disp_SZ(01%10);
  166.                                 lcd_pos(3,6);
  167.                                 Disp_HZ("V",1);

  168.                                 lcd_pos(4,5);
  169.                                 Disp_SZ(song_chao/1000);
  170.                                 Disp_SZ(song_chao%1000/100);
  171.                                 Disp_SZ(song_chao%100/10);
  172.                                 Disp_SZ(song_chao%10);

  173.                                 lcd_pos(4,7);
  174.                                 Disp_HZ("V",1);
  175.                         }
  176.                 }
  177. }
  178. /*
  179. * 交流电压检测
  180. */
  181. void jiao_liu()
  182. {
  183.         unsigned int chao_song;

  184.         lcd_pos(1,0);
  185.         Disp_HZ("★低功耗万用表★",8);

  186.         lcd_pos(2,0);
  187.         Disp_HZ("交流电压",4);

  188.         lcd_pos(3,0);
  189.         Disp_HZ("测量量程",4);

  190.         lcd_pos(4,0);
  191.         Disp_HZ("测量电压",4);

  192.         if(liang_cheng == 1)                                                //量程为10v的时候数据处理
  193.         {
  194.                 chao_song = data1*3.5*0.002443*100;                //
  195.                 if(ADC_flag1 == 1)
  196.                 {
  197.                         ADC_flag1 = 0;
  198.                         lcd_pos(3,4);
  199.                         Disp_SZ(10/10);
  200.                         Disp_SZ(10%10);
  201.                         lcd_pos(3,6);
  202.                         Disp_HZ("V",1);

  203.                         lcd_pos(4,5);
  204.                         Disp_SZ(chao_song/1000);
  205.                         Disp_SZ(chao_song%1000/100);
  206.                         Disp_SZ(chao_song%100/10);
  207.                         Disp_SZ(chao_song%10);

  208.                         lcd_pos(4,7);
  209.                         Disp_HZ("V",1);
  210.                 }
  211.         }
  212.         else if(liang_cheng == 2)                                                //量程为10v的时候数据处理
  213.                 {
  214.                         chao_song = data1*3.5*0.002443*1000;                //
  215.                         if(ADC_flag1 == 1)
  216.                         {
  217.                                 ADC_flag1 = 0;
  218.                                 lcd_pos(3,4);
  219.                                 Disp_SZ(01/10);
  220.                                 Disp_SZ(01%10);
  221.                                 lcd_pos(3,6);
  222.                                 Disp_HZ("V",1);

  223.                                 lcd_pos(4,5);
  224.                                 Disp_SZ(chao_song/1000);
  225.                                 Disp_SZ(chao_song%1000/100);
  226.                                 Disp_SZ(chao_song%100/10);
  227.                                 Disp_SZ(chao_song%10);

  228.                                 lcd_pos(4,7);
  229.                                 Disp_HZ("V",1);
  230.                         }
  231.                 }
  232. }
  233. /*
  234. * 电阻电压检测
  235. */
  236. void dian_zu()
  237. {
  238.         lcd_pos(1,0);
  239.         Disp_HZ("★低功耗万用表★",8);

  240.         lcd_pos(2,0);
  241.         Disp_HZ("电阻电压",4);

  242.         lcd_pos(3,0);
  243.         Disp_HZ("测量量程",4);

  244.         lcd_pos(4,0);
  245.         Disp_HZ("测量电压",4);

  246.         if(liang_cheng == 1)                                                //量程为10v的时候数据处理
  247.         {
  248.                 kuo_zhan(table[5]);
  249.                 if(ADC_flag1 == 1)
  250.                 {
  251.                         zu_zhi = (data2*1.3125*10);                                //100 欧姆 数据处理

  252.                         ADC_flag1 = 0;
  253.                         lcd_pos(3,5);
  254.                         Disp_SZ(10/10);
  255.                         Disp_SZ(10%10);
  256.                         lcd_pos(3,6);
  257.                         Disp_HZ("K",1);
  258.                         lcd_pos(4,5);
  259.                         Disp_SZ(zu_zhi/1000);
  260.                         Disp_SZ(zu_zhi%1000/100);
  261.                         Disp_SZ(zu_zhi%100/10);
  262.                         Disp_SZ(zu_zhi%10);

  263.                         lcd_pos(4,7);
  264.                         Disp_HZ("V",1);
  265.                 }
  266.         }
  267.         else if(liang_cheng == 2)                                                //量程为10v的时候数据处理
  268.         {
  269.                 kuo_zhan(table[6]);
  270.                 if(ADC_flag1 == 1)
  271.                 {
  272.                         zu_zhi = ((data2*0.00125438)/(1-data2*0.00125438))*1870;;                                //100 欧姆 数据处理

  273.                         ADC_flag1 = 0;
  274.                         lcd_pos(3,5);
  275.                         Disp_SZ(01/10);
  276.                         Disp_SZ(01%10);
  277.                         lcd_pos(3,6);
  278.                         Disp_HZ("K",1);
  279.                         lcd_pos(4,5);
  280.                         Disp_SZ(zu_zhi/1000);
  281.                         Disp_SZ(zu_zhi%1000/100);
  282.                         Disp_SZ(zu_zhi%100/10);
  283.                         Disp_SZ(zu_zhi%10);

  284.                         lcd_pos(4,7);
  285.                         Disp_HZ("V",1);
  286.                 }
  287.         }
  288.         else if(liang_cheng == 3)                                                //量程为10v的时候数据处理
  289.                 {
  290.                         kuo_zhan(table[7]);
  291.                         if(ADC_flag1 == 1)
  292.                         {
  293.                                 zu_zhi = ((data2*0.001244895)/(1-data2*0.001244895))*4950; //10K 欧姆的数据处理

  294.                                 ADC_flag1 = 0;
  295.                                 lcd_pos(3,5);
  296.                                 Disp_SZ(100%1000/100);
  297.                                 Disp_SZ(100%100/10);
  298.                                 Disp_SZ(100%10);
  299.                                 lcd_pos(3,7);
  300.                                 Disp_HZ("Ω",1);
  301.                                 lcd_pos(4,5);
  302.                                 Disp_SZ(zu_zhi/1000);
  303.                                 Disp_SZ(zu_zhi%1000/100);
  304.                                 Disp_SZ(zu_zhi%100/10);
  305.                                 Disp_SZ(zu_zhi%10);

  306.                                 lcd_pos(4,7);
  307.                                 Disp_HZ("V",1);
  308.                         }
  309.                 }
  310. }
  311. /*
  312. * 温度pt100功能
  313. */
  314. void wen_du()
  315. {
  316.         wen_pt = ((32231.7975*data4+0.3150709*data4*data4)*0.000016);        //温度的数据处理

  317.         lcd_pos(2,4);
  318.         Disp_SZ(wen_pt%1000/100);
  319.         Disp_SZ(wen_pt%100/10);
  320.         Disp_HZ(".",1);  //充电电流
  321.         Disp_SZ(wen_pt%10);

  322.         lcd_pos(2,7);
  323.         Disp_HZ("℃",1);
  324. }
  325. /*
  326. * 主函数
  327. */
  328. void main()
  329. {
  330.         int_t();
  331.         ADC();                                                        //AD功能设置
  332. //        ADC_DATA();                                                //AD转换开始
  333.         while(1)
  334.         {
  335.                 ADC_DATA();                                                                //AD转换开始

  336.                 if(pt100 == 1)
  337.                 {
  338.                         pt100 = 0;
  339.                         wen_du();
  340.                 }
  341.                 if(P2IN & BIT2)                                                        //直流电压检测档位
  342.                 {
  343.                         zhi_liu();                                                                               //直流电压量程选择控制
  344.                 }
  345.                 else if(P2IN & BIT3)                                        //交流电压检测档位
  346.                 {
  347.                         jiao_liu();                                                                      //直流电压量程选择控制
  348.                 }
  349.                 else if(P2IN & BIT4)                                        //电阻电压检测档位
  350.                 {
  351.                         dian_zu();                                                                      //直流电压量程选择控制
  352.                 }
  353.         }
  354. }
  355. /**
  356. *名称      看门狗 定时 中断
  357. **/
  358. #pragma vector=WDT_VECTOR
  359. __interrupt void watchdog_timer(void)
  360. {
  361.         shua_xin++;
  362.         if(shua_xin >= 1000)
  363.         {
  364.                 shua_xin = 0;
  365.                 ADC_flag1 = 1;
  366.                 s++;
  367.                 if(s >= 50)
  368.                 {
  369.                         pt100 = 1;
  370.                 }
  371. ……………………

  372. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
数字万用表内部资料.rar (4.99 MB, 下载次数: 137)

评分

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

查看全部评分

回复

使用道具 举报

ID:497832 发表于 2019-3-25 13:16 来自手机 | 显示全部楼层
下载试
回复

使用道具 举报

ID:78180 发表于 2019-3-26 09:24 | 显示全部楼层
下载试
回复

使用道具 举报

ID:15305 发表于 2019-9-18 23:17 | 显示全部楼层
不错的资料,感谢楼主的分享。谢谢!
回复

使用道具 举报

ID:1013588 发表于 2022-9-15 20:28 | 显示全部楼层
下载了,有时间试试谢谢楼主
回复

使用道具 举报

ID:567636 发表于 2022-9-28 10:30 | 显示全部楼层
我也下来看看,感谢楼主的分享。谢谢!
回复

使用道具 举报

ID:1064915 发表于 2023-4-28 14:42 | 显示全部楼层
英文较多,希望有硬件的介绍
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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