數控直流電源
目錄
1、介紹 …………
2、整體方案 …………
3、硬件電路 …………
4、軟件 …………
5、心得小結 …………
6、附錄: 1、元器件 …………
2、電路圖 …………
3、代碼 …………
1、介紹:
這個數控直流電源,是基于CORTEX_M3的STM32F103ZET6芯片的一個制作。它的能實現0~9.9V的電壓變化,每次變化為0.1V。它采用了內部的12位DAC和12位的ADC,精度比普通的8位ADC高出16倍,在實際的測試中,本制作的精度達到0.01V。本制作可以實現按鍵加減電壓大小、按鍵自動調節電壓、輸入數值控制輸出電壓、輸出幅值頻率可調的三角波功能。同時,本制作采用320*240的LCD液晶顯示,并且在顯示的基礎上,制作了完整的用戶界面,大大方便了用戶的使用。
2、整體方案:
方案介紹:
本方案圍繞stm32芯片,由供電模塊、液晶顯示模塊、報警模塊、負載電流檢測模塊、電源產生模塊、按鍵模塊構成。
電源模塊:我采用的是橋式整流結合三端穩壓芯片的處理方法。由此得到單片機使用的5v電源和驅動運算放大器的12V電源。
電源發生模塊:這個系統由LM358運算放大器和stm32芯片內部12位DAC組成。
負載電流檢測模塊:這個模塊由stm32內部12位ADC和自制的1歐姆康銅電阻組成。
液晶顯示模塊:主要有320*240LCD組成,負責顯示參數和提供用戶服務界面。
過流報警模塊:這個部分由蜂鳴器和紅色的LED指示燈組成。負責當發生過流現象時,給用戶報警。
3、硬件電路
(1)、stm32f103zet6單片機最小系統:
這款ST公司生產的基于cortex_m3內核的芯片,在當今的電子產品領域占有很大的市場。這塊32位芯片,有 144個引腳、512K的rom、2路ADC支持16通道,2路DAC,14個定時器,spi通信、i2c通信、串口通信方式。對于本系統,這個芯片的已經足夠。
(2)、電源電路
在這個部分,我主要采用橋式整流,使用了四個耐壓1000v的in4007,將雙24V的變壓器得到的副邊電壓進行整流,再由1000uf電容和LM7815和LM2940穩壓得系統所需的5V和12V電源。
(3)、電源產生電路和檢測電路
在運算放大器部分,我選擇的是帶寬1M的LM358,采用1k的精密電阻,將DA得到的電源放大4倍,再經過一級的放大器 跟隨電路輸入到負載電路之中。
負載串聯了1歐姆的康銅電阻,康銅電阻的溫漂小,直接AD測量兩端的電壓便可得到負載的電流狀況。
(4)、顯示電路:
采用的是lil9320驅動的320*240方案。
(5)、報警電路和按鍵電路燈省略。
4、軟件部分:
主體程序流程圖
在程序設計部分,主要設計ADC和DAC以及定時器中斷和外部觸發中斷的使用。
5、心得小結
在本次設計中,前期我花費了大量的時間查閱論文和思考放大電路設計上,而最后經過試驗,還是選擇了簡單而實用的放大器加更隨器的方案。在設計過程中遇到過很麻煩的事,當時網購了DAC7512的12位DAC芯片,發現是很小的貼片,經過較長時間搞定之后,一次使用過程中,這塊芯片壞了。于是,不得不轉到當前采用的方案上。
這個教訓,讓我明白實踐和試驗的重要性,少走彎路,多做實用的事。
6、附錄:
1、元器件清單:stm32f103zet6單片機最小系統,320*240tft lcd,24V變壓器、按鍵模塊、LM7805、LM7815、LM2940等
2、原理圖:
3、源程序:
主函數部分:
int main(void)
{
。
。
。
while(1) //主循環
{
DAC->DHR12R1 =0;
ili9320_Chinese_str((320-16*17)/2,50,17,Chinese_Table_16x16_nan,charColor,Blue);
ili9320_Chinese_str(70,90,3,Chinese_Table_16x16_ti,charColor,Blue);
ili9320_Chinese_str(140,90,8,Chinese_Table_16x16_shu,charColor,Blue);
ili9320_Chinese_str((320-16*15)/2,200,15,Chinese_Table_16x16_zun,charColor,Blue);
if(!GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_5))
{
Delay_ARMJISHU(100);
while(!GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_5));
ili9320_Clear(Blue);
exit_2=1;
while(exit_2) //按*鍵進入 功能循環
{
DAC->DHR12R1 = 0;
ili9320_Chinese_str(0,10,6,Chinese_Table_16x16_1,charColor,Blue);
ili9320_Chinese_str(0,40,6,Chinese_Table_16x16_2g,charColor,Blue);
ili9320_Chinese_str(0,70,6,Chinese_Table_16x16_3,charColor,Blue);
ili9320_Chinese_str(0,100,3,Chinese_Table_16x16_4,charColor,Blue);
// ili9320_Chinese_str(0,130,2,Chinese_Table_16x16_5,charColor,Blue);
//功能一:手動加減電壓值
if(!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_12))
{
Delay_ARMJISHU(200);
if(!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_12))
{
while(!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_12));
ili9320_Clear(Blue);
exit=1;
while(exit)
{
ili9320_Chinese_str(110,55,4,Chinese_Table_16x16_d,charColor,Blue);
ili9320_PutStr_16x24(248, 50, c4, 1, charColor, Blue);
a1=(vol+1)%10;
a2=(vol+1-a1)/10;
ili9320_PutChar_num(176,50,a2,charColor,Blue);
ili9320_DrawPoint(200,50,charColor,Blue);//畫一個點
ili9320_PutChar_num(224,50,a1,charColor,Blue);
if(!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_8)) //+
{
Delay_ARMJISHU(300);
if(!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_8))
{
if(vol<99)
{
vol=vol+1;
}
while(!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_8));
}
}
if(!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_9)) //-
{
Delay_ARMJISHU(300);
if(!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_9))
{
if(vol>3)
{
vol=vol-1;
while(!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_9));
}
}
}
DAC->DHR12R1 = (vol*40950-230)/1304;
//檢測過流
ADCConvertedValueLocal = ADCConvertedValue;
Precent = (ADCConvertedValueLocal*100/0x1000); //算出百分比
Voltage = Precent*33;
while(Voltage>500)
{
ili9320_Clear(Blue);
while(1)
{
ili9320_Chinese_str(110,55,4,Chinese_Table_16x16_d,charColor,Blue);
DAC->DHR12R1 = 0;
a1=0;
a2=0;
ili9320_PutChar_num(176,50,a2,charColor,Blue);
ili9320_DrawPoint(200,50,charColor,Blue);//畫一個點
ili9320_PutChar_num(224,50,a1,charColor,Blue);
ili9320_PutStr_16x24(248, 50, c4, 1, charColor, Blue);
ili9320_Chinese_str((320-16*10)/2,200,10,Chinese_Table_16x16_x,charColor,Blue);
GPIO_SetBits(GPIO_DAC,DS1_PIN|DS2_PIN); //所有引腳置高電平
}
}
//退出按鍵,在所有的功能中都使用這種退出方法
if(!GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_5))
{
Delay_ARMJISHU(300);
if(!GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_5))
{
while(!GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_5));
exit=0;
vol=0;
ili9320_Clear(Blue);
}
}
}
}
}
//功能2:自動加減電壓值 (6號按鍵)
if(!GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_6))
{
Delay_ARMJISHU(200);
if(!GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_6))
{
exit=1;
while(!GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_6));
/*-----------功能2的定時器初始化------------*/
Timer_Config();
NVIC_Config();
TIM_Cmd(TIM2,DISABLE); //起初是關閉的,當進入功能2后打開
ili9320_Clear(Blue);
while(exit)
{
vol=vol_21;
ili9320_Chinese_str(110,55,4,Chinese_Table_16x16_d,charColor,Blue);
ili9320_PutStr_16x24(248, 50, c4, 1, charColor, Blue);
a1=(vol+1)%10;
a2=(vol+1-a1)/10;
ili9320_PutChar_num(176,50,a2,charColor,Blue);
ili9320_DrawPoint(200,50,charColor,Blue);//畫一個點
ili9320_PutChar_num(224,50,a1,charColor,Blue);
//自加掃描
if(!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_8)&counter21)
{
flag2=1;
Delay_ARMJISHU(200);
if(!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_8))
{
TIM_Cmd(TIM2,ENABLE);
counter21=0;
while(!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_8));
}
}
if(!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_8)&!counter21)
{
Delay_ARMJISHU(200);
if(!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_8))
{
TIM_Cmd(TIM2,DISABLE);
counter21=1;
while(!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_8));
}
}
//自減掃描
if(!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_9)&counter22)
{
flag2=0;
Delay_ARMJISHU(200);
if(!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_9))
{
TIM_Cmd(TIM2,ENABLE);
counter22=0;
while(!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_9));
}
}
if(!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_9)&!counter22)
{
Delay_ARMJISHU(200);
if(!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_9))
{
TIM_Cmd(TIM2,DISABLE);
counter22=1;
while(!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_9));
}
}
DAC->DHR12R1 = (vol*40950-230)/1304;
//檢測過流
ADCConvertedValueLocal = ADCConvertedValue;
Precent = (ADCConvertedValueLocal*100/0x1000); //算出百分比
Voltage = Precent*33;
while(Voltage>500)
{
ili9320_Clear(Blue);
while(1)
{
ili9320_Chinese_str(110,55,4,Chinese_Table_16x16_d,charColor,Blue);
DAC->DHR12R1 = 0;
a1=0;
a2=0;
ili9320_PutChar_num(176,50,a2,charColor,Blue);
ili9320_DrawPoint(200,50,charColor,Blue);//畫一個點
ili9320_PutChar_num(224,50,a1,charColor,Blue);
ili9320_PutStr_16x24(248, 50, c4, 1, charColor, Blue);
ili9320_Chinese_str((320-16*10)/2,200,10,Chinese_Table_16x16_x,charColor,Blue);
GPIO_SetBits(GPIO_DAC,DS1_PIN|DS2_PIN); //所有引腳置高電平
}
}
//退出按鍵,在所有的功能中都使用這種退出方法
if(!GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_5))
{
Delay_ARMJISHU(100);
if(!GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_5))
{
while(!GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_5));
exit=0;
TIM_Cmd(TIM2,DISABLE);
vol=0;
vol_22=0;
ili9320_Clear(Blue);
}
}
}
}
}
//功能3:輸入電壓數值 7號功能鍵
if(!GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_7))
{
Delay_ARMJISHU(100);
if(!GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_7))
{
exit=1;
while(!GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_7));
ili9320_Clear(Blue);
while(exit)
{
num31=num33;
num32=num34;
ili9320_Chinese_str(10,12,12,Chinese_Table_16x16_q,charColor,Blue);
ili9320_Chinese_str(110,55,4,Chinese_Table_16x16_d,charColor,Blue);
ili9320_DrawPoint(200,50,charColor,Blue); //畫一個點
ili9320_PutStr_16x24(248, 50, c4, 1, charColor, Blue); //顯示單位:v
ili9320_PutChar_num(176,50,num32,charColor,Blue); //顯示十位
ili9320_PutChar_num(224,50,num31,charColor,Blue); //顯示個位
DAC->DHR12R1 = (vol*40950-230)/1304;
//先輸入十位上的數鍵位,切換鍵,個位按鍵,確認鍵
if(!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_9))
{
Delay_ARMJISHU(300);
if(!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_9))
{
while(!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_9));
counter_3++;
}
}
if((!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_8)))
{
Delay_ARMJISHU(300);
if(!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_8))
{
while(!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_8));
if(!(counter_3%2))
{
if(num33<10) num33=num33+1;
if(num33>=10) num33=0;
}
if(counter_3%2)
{
if(num34<10) num34=num34+1;
if(num34>=10) num34=0;
}
}
}
if(!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_10)) //確認鍵
{
Delay_ARMJISHU(300);
if(!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_10))
{
while(!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_10));
vol=num32*10+num31;
}
}
//退出按鍵,在所有的功能中都使用這種退出方法
if(!GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_5))
{
Delay_ARMJISHU(300);
if(!GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_5))
{
while(!GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_5));
exit=0;
ili9320_Clear(Blue);
num31=0;
num32=0;
vol=0;
num33=0;
num34=0;
}
}
//檢測過流
ADCConvertedValueLocal = ADCConvertedValue;
Precent = (ADCConvertedValueLocal*100/0x1000); //算出百分比
Voltage = Precent*33;
while(Voltage>500)
{
ili9320_Clear(Blue);
while(1)
{
DAC->DHR12R1 = 0;
a1=0;
a2=0;
ili9320_Chinese_str(110,55,4,Chinese_Table_16x16_d,charColor,Blue);
ili9320_PutChar_num(176,50,a2,charColor,Blue);
ili9320_DrawPoint(200,50,charColor,Blue);//畫一個點
ili9320_PutChar_num(224,50,a1,charColor,Blue);
ili9320_PutStr_16x24(248, 50, c4, 1, charColor, Blue);
ili9320_Chinese_str((320-16*10)/2,200,10,Chinese_Table_16x16_x,charColor,Blue);
GPIO_SetBits(GPIO_DAC,DS1_PIN|DS2_PIN); //所有引腳置高電平
}
}
}
}
}
/*--------------------------------------------------功能4:三角波--------------------------------------------------------------*/
//功能4:輸出三角波 8號按鍵 :第一次使用的時候先輸入一個值,然后確認,當確認完畢后,可以隨意調節;再次按確認鍵停止工作
if(!GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_8))
{
Delay_ARMJISHU(200);
if(!GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_8))
{
while(!GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_8));
exit=1;
ili9320_Clear(Blue);
vol_ap=20;
vol_fp=10;
while(exit)
{
//畫波形的代碼
ili9320_Chinese_str(90,120,9,Chinese_Table_16x16_ru,charColor,Blue);
ili9320_Chinese_str(90,55,5,Chinese_Table_16x16_fu,charColor,Blue); //電壓幅值
ili9320_Chinese_str(90,85,3,Chinese_Table_16x16_pin,charColor,Blue); //頻率
ili9320_Chinese_str(165,85,1,Chinese_Table_16x16_dang,charColor,Blue); //檔
if((!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_8))) //設置電壓值:1號按鍵
{
Delay_ARMJISHU(200);
if(!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_8))
{
while(!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_8));
vol_ap=vol_ap+5;
if(vol_ap>95) vol_ap=20;
ili9320_PutStr_16x24(248, 50, c4, 1, charColor, Blue);
a1=(vol_ap)%10;
a2=(vol_ap-a1)/10;
ili9320_PutChar_num(176,50,a2,charColor,Blue);
ili9320_DrawPoint(200,50,charColor,Blue);//畫一個點
ili9320_PutChar_num(224,50,a1,charColor,Blue);
}
}
if((!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_9))) //設置頻率:2號按鍵
{
Delay_ARMJISHU(200);
if(!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_9))
{
while(!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_9));
vol_fp=vol_fp+1;
if(vol_fp>10) vol_fp=1;
ili9320_PutChar_num(140,80,vol_fp,charColor,Blue);
}
}
if((!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_10))) //第一次按的時候,確認開始
{
Delay_ARMJISHU(200);
if(!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_10))
{
while(!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_10));
ili9320_Clear(Blue);
ili9320_Chinese_str(20,100,16,Chinese_Table_16x16_bo,charColor,Blue); //電壓幅值
while(1)
{
while((vol_apc>vol_pre)&(vol_apc<=(vol_ap*40950/1304)))
{
vol_pre=vol_apc;
vol_apc=vol_apc+vol_fp;
DAC->DHR12R1 =vol_apc;
}
while(vol_apc>(vol_ap*40950/1304))
{
vol_apc=vol_apc-2*vol_fp;
DAC->DHR12R1 =vol_apc;
}
while((vol_apc
{
vol_pre=vol_apc;
vol_apc=vol_apc-vol_fp;
DAC->DHR12R1 =vol_apc;
}
while(vol_apc<=vol_fp)
{
vol_apc=vol_apc+2*vol_fp;
DAC->DHR12R1 =vol_apc;
}
}
}
}
//退出按鍵,在所有的功能中都使用這種退出方法
if(!GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_5))
{
Delay_ARMJISHU(300);
if(!GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_5))
{
while(!GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_5));
exit=0;
ili9320_Clear(Blue);
TIM_Cmd(TIM3,DISABLE);
}
}
//檢測過流
ADCConvertedValueLocal = ADCConvertedValue;
Precent = (ADCConvertedValueLocal*100/0x1000); //算出百分比
Voltage = Precent*33;
while(Voltage>500)
{
ili9320_Clear(Blue);
while(1)
{
DAC->DHR12R1 = 0;
a1=0;
a2=0;
ili9320_Chinese_str(110,55,4,Chinese_Table_16x16_d,charColor,Blue);
ili9320_PutChar_num(176,50,a2,charColor,Blue);
ili9320_DrawPoint(200,50,charColor,Blue);//畫一個點
ili9320_PutChar_num(224,50,a1,charColor,Blue);
ili9320_PutStr_16x24(248, 50, c4, 1, charColor, Blue);
ili9320_Chinese_str((320-16*10)/2,200,10,Chinese_Table_16x16_x,charColor,Blue);
GPIO_SetBits(GPIO_DAC,DS1_PIN|DS2_PIN); //所有引腳置高電平
}
}
}
}
}
/*-------------------------------------------------------------------------------------------------------------------------------*/
if(!GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_5))
{
Delay_ARMJISHU(100);
if(!GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_5))
{
while(!GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_5));
exit_2=0;
ili9320_Clear(Blue);
}
}
}
word文檔數控直流電源