單位的項目,要求變頻、變壓。用來驅(qū)動高壓變壓器,做絕緣測試使用。上位機軟件通過串口控制升壓過程。
廢話不多說!先上原理圖!不知道如何轉(zhuǎn)圖片,只能傳文件了。
再來兩張印版的照片吧!
正面
背面
焊接完畢的
接下來是源碼,采用的MCU是C8051F120相中的是控制簡單(PCA模塊),速度夠快(100Mhz主頻,SPWM分辨率可以達到12位)。
/* 使用外部晶振22.1184MHz 方便串口通訊 用PLL 4.5倍頻于99.5328MHz PCA0十六位PWM方式 中斷中將計算好的初值加0xF000賦予捕捉模塊 計數(shù)器賦初值0xF000 作為十二位PWM使用 載頻24.3kHz M_min = 0.? M_max = 0.9514 */ #include#include #include #include #include #define PI 3.1415926 // π #define Carrier 24300 // 載波載頻 #define SYSCLK 99532800L // 晶振頻率 #define BAUDRATE 115200 // 波特率 #define value 4096 // 載波周期計數(shù)器值 unsigned int *point_sin; // 數(shù)組指針 unsigned int frequency = 50; // 調(diào)制波頻率 unsigned int j; // 用于操作數(shù)組 unsigned int reload; // PCA0重載值 unsigned int ISR_time; // 中斷計數(shù) unsigned int finish; // 調(diào)制波半周期載波個數(shù) float M = 0.9; // 調(diào)制比(輸出電壓) unsigned char data *s,receive[15],volt[6],freq[6]; // 接收電壓、頻率字符串 unsigned int xdata sin_list[4095]; // 用于存放計算好的計數(shù)器初值 bit Isr_flag; // 發(fā)生重載標志 bit Fun_flag; // 調(diào)制波半周期到標志 bit String_flag; // 串口接收到新參數(shù)標志 sbit funwave = P0^3; // 基波 sbit btlamp = P0^5; // 呼吸燈 void OSCILLATOR_Init (void); void PORT_Init (void); void PCA0_Init (void); void CALCULATE (void); void UART1_Init (void); void Timer2_Init(void); void main() { WDTCN = 0xde; WDTCN = 0xad; OSCILLATOR_Init (); PORT_Init (); CALCULATE (); reload = sin_list[0]; PCA0_Init (); UART1_Init (); Timer2_Init(); EA = 1; CR = 1; while(1) { if(String_flag) { String_flag = 0; s = strtok(receive,"@"); strcpy(volt,s); s = strtok(NULL,"@"); strcpy(freq,s); memset(receive,0,15); M = atof(volt); frequency = atoi(freq); CALCULATE (); } if(Isr_flag) { Isr_flag = 0; j++; if(j < finish) reload = sin_list[j]; else { j = 0; reload = sin_list[j]; } } if(Fun_flag) { Fun_flag = 0; funwave = ~funwave; } } } void CALCULATE (void) // 實時計算各交點sin值 裝入數(shù)組 { unsigned int i; static unsigned int median,surplus; finish = (Carrier/frequency) >> 1; point_sin = &sin_list[0]; median = value * sin(PI * (finish * 2 - 1)/(finish * 2)) * M; surplus = (value - median) >> 1; for(i=1; i<2 * finish; i+=2) { median = value * sin(PI * i / finish / 2) * M; if(median > 4066) median = 4066; *point_sin = surplus + 0xF000 + (value - median) / 2; surplus = (value - median) >> 1; point_sin++; } } void OSCILLATOR_Init (void) // 使用外部晶振22.1184MHz 4.5倍頻 鎖定在99.5328MHz { unsigned int i; char SFRPAGE_SAVE = SFRPAGE; SFRPAGE = CONFIG_PAGE; OSCICN = 0x80; CLKSEL = 0x00; OSCXCN = 0x67; for (i=0; i < 256; i++); while (!(OSCXCN & 0x80)); SFRPAGE = LEGACY_PAGE; FLSCL |= 0x30; if(SYSCLK <= 25000000) FLSCL &= ~0x30; else if(SYSCLK <= 50000000) FLSCL &= ~0x20; else if(SYSCLK <= 75000000) FLSCL &= ~0x10; else FLSCL &= ~0x00; SFRPAGE = PLL0_PAGE; PLL0CN = 0x04; PLL0CN |= 0x01; PLL0DIV = 0x02; PLL0FLT &= ~0x0f; PLL0FLT |= 0x07; PLL0FLT &= ~0x30; PLL0FLT |= 0x00; PLL0MUL = 0x09; for (i = 0; i < 256; i++) ; PLL0CN |= 0x02; while (PLL0CN & 0x10 == 0x00); SFRPAGE = CONFIG_PAGE; CLKSEL = 0x02; SFRPAGE = SFRPAGE_SAVE; } void PORT_Init (void) { char SFRPAGE_save = SFRPAGE; SFRPAGE = CONFIG_PAGE; XBR0 = 0x08; XBR1 = 0x00; XBR2 = 0x44; P0MDOUT |= 0xFF; SFRPAGE = SFRPAGE_save; } void PCA0_Init (void) { char SFRPAGE_save = SFRPAGE; SFRPAGE = PCA0_PAGE; PCA0CN = 0x00; PCA0MD = 0x09; PCA0CPM0 = 0xC2; PCA0H = 0xF0; PCA0CPL0 = (reload & 0x00FF); PCA0CPH0 = (reload & 0xFF00)>>8; SFRPAGE = CONFIG_PAGE; EIE1 |= 0x08; EIP1 |= 0x08; SFRPAGE = SFRPAGE_save; } void UART1_Init (void) { char SFRPAGE_SAVE = SFRPAGE; SFRPAGE = UART1_PAGE; SCON1 = 0x10; SFRPAGE = TIMER01_PAGE; TMOD &= ~0xF0; TMOD |= 0x20; if(SYSCLK/BAUDRATE/2/256 < 1) { TH1 = -(SYSCLK/BAUDRATE/2); CKCON |= 0x10; } else if (SYSCLK/BAUDRATE/2/256 < 4) { TH1 = -(SYSCLK/BAUDRATE/2/4); CKCON &= ~0x13; CKCON |= 0x01; } else if (SYSCLK/BAUDRATE/2/256 < 12) { TH1 = -(SYSCLK/BAUDRATE/2/12); CKCON &= ~0x13; } else { TH1 = -(SYSCLK/BAUDRATE/2/48); CKCON &= ~0x13; CKCON |= 0x02; } TL1 = TH1; TR1 = 1; EIE2 = 0x40; // 允許中斷 SFRPAGE = SFRPAGE_SAVE; } void Timer2_Init(void) { char SFRPAGE_SAVE = SFRPAGE; SFRPAGE = TMR2_PAGE; TMR2CN = 0x04; // 自動重裝模式并啟動 ET2 = 1; // 中斷使能 SFRPAGE = SFRPAGE_SAVE; } void Timer2_ISR (void) interrupt 5 { static unsigned char i; TF2 = 0; if(i < 63) i++; else { btlamp = ~btlamp; i = 0; } } void PCA0_ISR (void) interrupt 9 { CF = 0; PCA0H = 0xF0; PCA0CPL0 = (reload & 0x00FF); PCA0CPH0 = (reload & 0xFF00)>>8; if(!j) Fun_flag = 1; Isr_flag = 1; } void UART1_Interrupt (void) interrupt 20 { static char i; if(RI0) { RI0 = 0; if(SBUF0 == '!') { i = 0; String_flag = 1; } else { receive[i] = SBUF0; i++; } } if(TI0) TI0 = 0; }
通訊格式為A(浮點數(shù))+@(固定)+B(整數(shù))+?。ü潭ǎ?
例如:0.9@50! 表示輸出調(diào)制比為0.9(如果母線電壓為310V輸出大概為200V)輸出頻率為50Hz
波形待續(xù)……(主要還是想看看熱度)
繼續(xù)中……
這是串口助手,大家應(yīng)該不陌生。
0.1@50!
0.3@50!
0.5@50!
0.9@50!
0.9@10!
0.9@20!
0.9@300!
以上波形測得條件為:其中一路SPWM輸出,串接5.1K電阻、104電容到地
下面是PCB文件,及簡圖。
待橋電路搭建完成后,再繼續(xù)上完整的正弦波形圖。
(未完待續(xù)…………)