找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 1579|回復(fù): 0
收起左側(cè)

基于STM32單片機(jī)數(shù)字電壓表自動(dòng)切換量程及源程序

[復(fù)制鏈接]
ID:190577 發(fā)表于 2023-11-19 09:55 | 顯示全部樓層 |閱讀模式
一、系統(tǒng)方案
1、本設(shè)計(jì)采用這STM32單片機(jī)作為主控器。
2、液晶1602顯示。
3、內(nèi)部ADC采集電壓0-12V,自動(dòng)切換檔位。
1.png

二、硬件設(shè)計(jì)
原理圖如下:
2.png

三、單片機(jī)軟件設(shè)計(jì)
1、首先是系統(tǒng)初始化
u8 i;
         u16 a,b,c,d;
        u16 adcx;
        float adc;
        unsigned char  datas[4];
        InitGPIO();
        LcdInit();
        Adc_Init();

        LcdWriteCom(0xc0);  //設(shè)置數(shù)據(jù)指針起點(diǎn)

        for(i=0;i<16;i++)
        {
                LcdWriteData(Disp_Vol[i ]);
        }                 

2、液晶顯示程序
/*******************************************************************************
* 函 數(shù) 名         : LcdWriteCom
* 函數(shù)功能                   : 向LCD寫入一個(gè)字節(jié)的命令
* 輸    入         : com
* 輸    出         : 無(wú)
*******************************************************************************/
void LcdWriteCom(uchar com)          //寫入命令
{
//        LCD1602_E = 0;     //使能
        GPIO_ResetBits(GPIOB,GPIO_Pin_3);
//        LCD1602_RS = 0;           //選擇發(fā)送命令
        GPIO_ResetBits(GPIOB,GPIO_Pin_1);
//        LCD1602_RW = 0;           //選擇寫入
        GPIO_ResetBits(GPIOB,GPIO_Pin_2);
//        LCD1602_DATAPINS = com;     //放入命令
        GPIO_Write(GPIOC,0X00FF&com);
        Lcd1602_Delay1ms(1);                //等待數(shù)據(jù)穩(wěn)定
//        LCD1602_E = 1;                  //寫入時(shí)序
        GPIO_SetBits(GPIOB,GPIO_Pin_3);
        Lcd1602_Delay1ms(5);          //保持時(shí)間
//        LCD1602_E = 0;
        GPIO_ResetBits(GPIOB,GPIO_Pin_3);        
}
/*******************************************************************************
* 函 數(shù) 名         : LcdWriteData
* 函數(shù)功能                   : 向LCD寫入一個(gè)字節(jié)的數(shù)據(jù)
* 輸    入         : dat
* 輸    出         : 無(wú)
*******************************************************************************/
void LcdWriteData(uchar dat)                        //寫入數(shù)據(jù)
{
//        LCD1602_E = 0;        //使能清零
        GPIO_ResetBits(GPIOB,GPIO_Pin_3);        
//        LCD1602_RS = 1;        //選擇輸入數(shù)據(jù)
        GPIO_SetBits(GPIOB,GPIO_Pin_1);        
//        LCD1602_RW = 0;        //選擇寫入
        GPIO_ResetBits(GPIOB,GPIO_Pin_2);
//        LCD1602_DATAPINS = dat; //寫入數(shù)據(jù)
        GPIO_Write(GPIOC,0X00FF&dat);        
        Lcd1602_Delay1ms(1);

//        LCD1602_E = 1;   //寫入時(shí)序
        GPIO_SetBits(GPIOB,GPIO_Pin_3);        
        Lcd1602_Delay1ms(5);   //保持時(shí)間
//        LCD1602_E = 0;
        GPIO_ResetBits(GPIOB,GPIO_Pin_3);               
}
3、ADC程序
//獲得ADC值
//ch:通道值 0~3
u16 Get_Adc(u8 ch)   
{
          //設(shè)置指定ADC的規(guī)則組通道,一個(gè)序列,采樣時(shí)間
        ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5 );        //ADC1,ADC通道,采樣時(shí)間為239.5周期                                      

        ADC_SoftwareStartConvCmd(ADC1, ENABLE);                //使能指定的ADC1的軟件轉(zhuǎn)換啟動(dòng)功能        

        while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待轉(zhuǎn)換結(jié)束

        return ADC_GetConversionValue(ADC1);        //返回最近一次ADC1規(guī)則組的轉(zhuǎn)換結(jié)果
}

u16 Get_Adc_Average(u8 ch,u8 times)
{
        u32 temp_val=0;
        u8 t;
        for(t=0;t<times;t++)
        {
                temp_val+=Get_Adc(ch);
                delay_ms(5);
        }
        return temp_val/times;
}         

4、核心算法程序
int main(void)
{        
  u8 i;
         u16 a,b,c,d;
        u16 adcx;
        float adc;
        unsigned char  datas[4];
        InitGPIO();
        LcdInit();
        Adc_Init();

        LcdWriteCom(0xc0);  //設(shè)置數(shù)據(jù)指針起點(diǎn)

        for(i=0;i<16;i++)
        {
                LcdWriteData(Disp_Vol[i ]);
        }                 
        while(1)
        {
                adcx=Get_Adc_Average(ADC_Channel_1,10);
                adc=(float)adcx*(5.0/4096);
                adcx=adc;
                a=adcx;
                adc-=adcx;
                adcx=adc*100;  //1位有效數(shù)字
                b=adcx;
                c=a*100+b;
                d=c*24/10;
                if(d<500)
                {
                        LcdWriteCom(0x80);  //設(shè)置數(shù)據(jù)指針起點(diǎn)
                        for(i=0;i<16;i++)
                        {
                                LcdWriteData(Disp_Vol1[i ]);
                        }        
                }
                else
                {
                  LcdWriteCom(0x80);  //設(shè)置數(shù)據(jù)指針起點(diǎn)
                        for(i=0;i<16;i++)
                        {
                                LcdWriteData(Disp_Vol2[i ]);
                        }        
                }        
                LcdWriteCom(0xc9);
                LcdWriteData('0'+d/1000);
                        LcdWriteData('0'+d%1000/100);
                LcdWriteCom(0xcc);
                LcdWriteData('0'+d%1000%100/10);
                LcdWriteData('0'+d%10);

        }

}

四、 proteus仿真設(shè)計(jì)
Proteus軟件是一款應(yīng)用比較廣泛的工具,它可以在沒有硬件平臺(tái)的基礎(chǔ)上通過(guò)自身的軟件仿真出硬件平臺(tái)的運(yùn)行情況,這樣就可以通過(guò)軟件仿真來(lái)驗(yàn)證我們?cè)O(shè)計(jì)的方案有沒有問(wèn)題,如果有問(wèn)題,可以重新選擇器件,連接器件,直到達(dá)到我們?cè)O(shè)定的目的,避免我們搭建實(shí)物的時(shí)候,如果當(dāng)初選擇的方案有問(wèn)題,我們器件都已經(jīng)焊接好了,再去卸載下去,再去焊接新的方案的器件,測(cè)試,這樣會(huì)浪費(fèi)人力和物力,也給開發(fā)者帶來(lái)一定困惑,Proteus仿真軟件就很好的解決這個(gè)問(wèn)題,我們?cè)谠O(shè)計(jì)之初,就使用該軟件進(jìn)行模擬仿真,測(cè)試,選擇滿足我們?cè)O(shè)計(jì)的最優(yōu)方案。最后根據(jù)測(cè)試沒問(wèn)題的仿真圖紙,焊接實(shí)物,調(diào)試,最終完成本設(shè)計(jì)的作品。

評(píng)分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表