一、系統(tǒng)方案 1、本設(shè)計(jì)采用這STM32單片機(jī)作為主控器。 2、液晶1602顯示。 3、內(nèi)部ADC采集電壓0-12V,自動(dòng)切換檔位。
二、硬件設(shè)計(jì) 原理圖如下:
三、單片機(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ì)的作品。
|