[资料分享] MSP430单片机制作智能数字万用表电路图+程序

灞波儿奔   2019-4-14 19:34 楼主
360截图20190414194019291.jpg
单片机源程序如下:
/*
* 简易低功耗万用表
*/
#include
#include "LCD12864P.h"

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

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

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

/*
*初始化
*/
void int_t()
{

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

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

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

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

}
/*
* 按键延时程序
*/
void delay(unsigned int n)//带参数有返回值的函数
{
        unsigned int i;
        unsigned int j;
        for(i=n;i>0;i--)
                for(j=100;j>0;j--)
                        _nop();
}
/**************************************************************
*名称:ADC()
*功能:AD设置转换  中断
****************************************************************/

void  ADC()
{
        P1SEL |= BIT0 + BIT1 + BIT2 + BIT4;//+ BIT3;//+ BIT4 + BIT5 + BIT6 + BIT7;                  //设置为模拟输入
        ADC10AE0  |= BIT0 + BIT1 + BIT2+ BIT4;// + BIT3;//+ BIT4 + BIT5 + BIT6 + BIT7;   //开启通道A1/A2/A4/A5/A6/A7
        ADC10CTL0|=ADC10ON+MSC+ADC10SHT_2+ADC10IE;                        //打开ADC转换  ,ADC10使能 ,设置采用频率16个周期,允许中断
        ADC10CTL0 |=SREF_1 + REFON + REF2_5V;                           //开内部参考电压为2.5V,允许中断
        ADC10CTL1|=CONSEQ_3+INCH_7;                                                 //使用双(4)通道、循环采集模式
        ADC10DTC1|=0x08;                                                                      //每一通道连续采样1次
        _BIS_SR(GIE);
}
/*
*功能:AD数据处理
*/
void ADC_DATA()
{
        unsigned char i;
        ADC10CTL0&=~ENC;
        while(ADC10CTL1&ADC10BUSY);                                                //检测AD是否繁忙
        ADC10CTL0|=ENC+ADC10SC;                                                  //启动ADC
        ADC10SA=(unsigned int)ADC_result;                                //获取ADC_result[]的首地址。首先对A1、A0采样,放入ADC_result[0]和ADC_result[1]中,如此循环下去。
        for(i=0;i<8;i++)
    {
                ADC_data=0;
                ADC_data=ADC_result;
        //        ADC_data=(ADC_data*25)/1023;                     //将ADC转换成实际的电压值
    }
}
/*
* 扩展芯片595写入程序
*/
void kuo_zhan(unsigned int dat)
{
        unsigned int i;
        for(i=0;i<8;i++)
        {
                if((dat<                         P1OUT|=BIT5;
                else
                P1OUT &= ~BIT5;
                P1OUT &= ~BIT7;
                _NOP();
                P1OUT |= BIT7;
                _NOP();
        }
        P1OUT &= ~BIT6;
        _NOP();
        P1OUT |= BIT6;
        _NOP();
}
/*
* 直流电压检测
*/
void zhi_liu()
{
        unsigned int song_chao;

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

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

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

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

        if(liang_cheng == 1)                                                //量程为10v的时候数据处理
        {
                kuo_zhan(table[1]);                                                //打开10v通道
                song_chao = data0*5.8585*0.002443*100;                                        //
                if(ADC_flag1 == 1)
                {
                        ADC_flag1 = 0;
                        lcd_pos(3,5);
                        Disp_SZ(10/10);
                        Disp_SZ(10%10);
                        lcd_pos(3,6);
                        Disp_HZ("V",1);

                        lcd_pos(4,5);
                        Disp_SZ(song_chao/1000);
                        Disp_SZ(song_chao%1000/100);
                        Disp_SZ(song_chao%100/10);
                        Disp_SZ(song_chao%10);

                        lcd_pos(4,7);
                        Disp_HZ("V",1);
                }
        }
        else if(liang_cheng == 2)                                                //量程为10v的时候数据处理
        {
                kuo_zhan(table[2]);                                                //打开10v通道
                song_chao = data0*1.9825*0.002443*1000;                                        //
                if(ADC_flag1 == 1)
                {
                        ADC_flag1 = 0;
                        lcd_pos(3,5);
                        Disp_SZ(01/10);
                        Disp_SZ(01%10);
                        lcd_pos(3,6);
                        Disp_HZ("V",1);

                        lcd_pos(4,5);
                        Disp_SZ(song_chao/1000);
                        Disp_SZ(song_chao%1000/100);
                        Disp_SZ(song_chao%100/10);
                        Disp_SZ(song_chao%10);

                        lcd_pos(4,7);
                        Disp_HZ("V",1);
                }
        }
        else if(liang_cheng == 3)                                                //量程为10v的时候数据处理
                {
                        kuo_zhan(table[3]);                                                //打开10v通道
                        song_chao = data0*0.0891*0.002443*1000;                                        //
                        if(ADC_flag1 == 1)
                        {
                                ADC_flag1 = 0;
                                lcd_pos(3,4);
                                Disp_SZ(01/10);
                                Disp_HZ(".",1);
                                Disp_SZ(01%10);
                                lcd_pos(3,6);
                                Disp_HZ("V",1);

                                lcd_pos(4,5);
                                Disp_SZ(song_chao/1000);
                                Disp_SZ(song_chao%1000/100);
                                Disp_SZ(song_chao%100/10);
                                Disp_SZ(song_chao%10);

                                lcd_pos(4,7);
                                Disp_HZ("V",1);
                        }
                }
}
/*
* 交流电压检测
*/
void jiao_liu()
{
        unsigned int chao_song;

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

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

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

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

        if(liang_cheng == 1)                                                //量程为10v的时候数据处理
        {
                chao_song = data1*3.5*0.002443*100;                //
                if(ADC_flag1 == 1)
                {
                        ADC_flag1 = 0;
                        lcd_pos(3,4);
                        Disp_SZ(10/10);
                        Disp_SZ(10%10);
                        lcd_pos(3,6);
                        Disp_HZ("V",1);

                        lcd_pos(4,5);
                        Disp_SZ(chao_song/1000);
                        Disp_SZ(chao_song%1000/100);
                        Disp_SZ(chao_song%100/10);
                        Disp_SZ(chao_song%10);

                        lcd_pos(4,7);
                        Disp_HZ("V",1);
                }
        }
        else if(liang_cheng == 2)                                                //量程为10v的时候数据处理
                {
                        chao_song = data1*3.5*0.002443*1000;                //
                        if(ADC_flag1 == 1)
                        {
                                ADC_flag1 = 0;
                                lcd_pos(3,4);
                                Disp_SZ(01/10);
                                Disp_SZ(01%10);
                                lcd_pos(3,6);
                                Disp_HZ("V",1);

                                lcd_pos(4,5);
                                Disp_SZ(chao_song/1000);
                                Disp_SZ(chao_song%1000/100);
                                Disp_SZ(chao_song%100/10);
                                Disp_SZ(chao_song%10);

                                lcd_pos(4,7);
                                Disp_HZ("V",1);
                        }
                }
}
/*
* 电阻电压检测
*/
void dian_zu()
{
        lcd_pos(1,0);
        Disp_HZ("★低功耗万用表★",8);

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

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

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

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

                        ADC_flag1 = 0;
                        lcd_pos(3,5);
                        Disp_SZ(10/10);
                        Disp_SZ(10%10);
                        lcd_pos(3,6);
                        Disp_HZ("K",1);
                        lcd_pos(4,5);
                        Disp_SZ(zu_zhi/1000);
                        Disp_SZ(zu_zhi%1000/100);
                        Disp_SZ(zu_zhi%100/10);
                        Disp_SZ(zu_zhi%10);

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

                        ADC_flag1 = 0;
                        lcd_pos(3,5);
                        Disp_SZ(01/10);
                        Disp_SZ(01%10);
                        lcd_pos(3,6);
                        Disp_HZ("K",1);
                        lcd_pos(4,5);
                        Disp_SZ(zu_zhi/1000);
                        Disp_SZ(zu_zhi%1000/100);
                        Disp_SZ(zu_zhi%100/10);
                        Disp_SZ(zu_zhi%10);

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

                                ADC_flag1 = 0;
                                lcd_pos(3,5);
                                Disp_SZ(100%1000/100);
                                Disp_SZ(100%100/10);
                                Disp_SZ(100%10);
                                lcd_pos(3,7);
                                Disp_HZ("Ω",1);
                                lcd_pos(4,5);
                                Disp_SZ(zu_zhi/1000);
                                Disp_SZ(zu_zhi%1000/100);
                                Disp_SZ(zu_zhi%100/10);
                                Disp_SZ(zu_zhi%10);

                                lcd_pos(4,7);
                                Disp_HZ("V",1);
                        }
                }
}
/*
* 温度pt100功能
*/
void wen_du()
{
        wen_pt = ((32231.7975*data4+0.3150709*data4*data4)*0.000016);        //温度的数据处理

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

        lcd_pos(2,7);
        Disp_HZ("℃",1);
}
/*
* 主函数
*/
void main()
{
        int_t();
        ADC();                                                        //AD功能设置
//        ADC_DATA();                                                //AD转换开始
        while(1)
        {
                ADC_DATA();                                                                //AD转换开始

                if(pt100 == 1)
                {
                        pt100 = 0;
                        wen_du();
                }
                if(P2IN & BIT2)                                                        //直流电压检测档位
                {
                        zhi_liu();                                                                               //直流电压量程选择控制
                }
                else if(P2IN & BIT3)                                        //交流电压检测档位
                {
                        jiao_liu();                                                                      //直流电压量程选择控制
                }
                else if(P2IN & BIT4)                                        //电阻电压检测档位
                {
                        dian_zu();                                                                      //直流电压量程选择控制
                }
        }
}
/**
*名称      看门狗 定时 中断
**/
#pragma vector=WDT_VECTOR
__interrupt void watchdog_timer(void)
{
        shua_xin++;
        if(shua_xin >= 1000)
        {
                shua_xin = 0;
                ADC_flag1 = 1;
                s++;
                if(s >= 50)
                {
                        pt100 = 1;
                }

回复评论

暂无评论,赶紧抢沙发吧
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复