一、系統方案 1、本設計采用這STM32單片機作為主控器。 2、液晶1602顯示。 3、內部ADC采集電壓0-12V,自動切換檔位。
1.png (4.89 KB, 下載次數: 31)
下載附件
2023-11-19 09:55 上傳
二、硬件設計 原理圖如下:
2.png (63.32 KB, 下載次數: 38)
下載附件
2023-11-19 09:55 上傳
三、單片機軟件設計 1、首先是系統初始化
u8 i;
u16 a,b,c,d;
u16 adcx;
float adc;
unsigned char datas[4];
InitGPIO();
LcdInit();
Adc_Init();
LcdWriteCom(0xc0); //設置數據指針起點
for(i=0;i<16;i++)
{
LcdWriteData(Disp_Vol[i ]);
}
2、液晶顯示程序
/*******************************************************************************
* 函 數 名 : LcdWriteCom
* 函數功能 : 向LCD寫入一個字節的命令
* 輸 入 : com
* 輸 出 : 無
*******************************************************************************/
void LcdWriteCom(uchar com) //寫入命令
{
// LCD1602_E = 0; //使能
GPIO_ResetBits(GPIOB,GPIO_Pin_3);
// LCD1602_RS = 0; //選擇發送命令
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); //等待數據穩定
// LCD1602_E = 1; //寫入時序
GPIO_SetBits(GPIOB,GPIO_Pin_3);
Lcd1602_Delay1ms(5); //保持時間
// LCD1602_E = 0;
GPIO_ResetBits(GPIOB,GPIO_Pin_3);
}
/*******************************************************************************
* 函 數 名 : LcdWriteData
* 函數功能 : 向LCD寫入一個字節的數據
* 輸 入 : dat
* 輸 出 : 無
*******************************************************************************/
void LcdWriteData(uchar dat) //寫入數據
{
// LCD1602_E = 0; //使能清零
GPIO_ResetBits(GPIOB,GPIO_Pin_3);
// LCD1602_RS = 1; //選擇輸入數據
GPIO_SetBits(GPIOB,GPIO_Pin_1);
// LCD1602_RW = 0; //選擇寫入
GPIO_ResetBits(GPIOB,GPIO_Pin_2);
// LCD1602_DATAPINS = dat; //寫入數據
GPIO_Write(GPIOC,0X00FF&dat);
Lcd1602_Delay1ms(1);
// LCD1602_E = 1; //寫入時序
GPIO_SetBits(GPIOB,GPIO_Pin_3);
Lcd1602_Delay1ms(5); //保持時間
// LCD1602_E = 0;
GPIO_ResetBits(GPIOB,GPIO_Pin_3);
}
3、ADC程序
//獲得ADC值
//ch:通道值 0~3
u16 Get_Adc(u8 ch)
{
//設置指定ADC的規則組通道,一個序列,采樣時間
ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5 ); //ADC1,ADC通道,采樣時間為239.5周期
ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能指定的ADC1的軟件轉換啟動功能
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待轉換結束
return ADC_GetConversionValue(ADC1); //返回最近一次ADC1規則組的轉換結果
}
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); //設置數據指針起點
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位有效數字
b=adcx;
c=a*100+b;
d=c*24/10;
if(d<500)
{
LcdWriteCom(0x80); //設置數據指針起點
for(i=0;i<16;i++)
{
LcdWriteData(Disp_Vol1[i ]);
}
}
else
{
LcdWriteCom(0x80); //設置數據指針起點
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仿真設計 Proteus軟件是一款應用比較廣泛的工具,它可以在沒有硬件平臺的基礎上通過自身的軟件仿真出硬件平臺的運行情況,這樣就可以通過軟件仿真來驗證我們設計的方案有沒有問題,如果有問題,可以重新選擇器件,連接器件,直到達到我們設定的目的,避免我們搭建實物的時候,如果當初選擇的方案有問題,我們器件都已經焊接好了,再去卸載下去,再去焊接新的方案的器件,測試,這樣會浪費人力和物力,也給開發者帶來一定困惑,Proteus仿真軟件就很好的解決這個問題,我們在設計之初,就使用該軟件進行模擬仿真,測試,選擇滿足我們設計的最優方案。最后根據測試沒問題的仿真圖紙,焊接實物,調試,最終完成本設計的作品。
|