先用ISP下載線把boot.hex寫入M8.
FUSE設定為外部晶振(4.096MHz),啟動硬件"看門狗",和BOOT區(qū)啟動
附上M8用RS232接口在線升級的BOOT軟件
使用:按下RESET鍵后按下S12鍵,就可以用AvrProg了。
電路原理圖如下:
M8控制部分2.jpg (100.23 KB, 下載次數(shù): 124)
下載附件
2020-10-9 10:15 上傳
單片機源程序如下:
- /********************************************
- **Designed by GandF
- ********************************************/
- #include <iom8v.h>
- #include <macros.h>
- #include <MATH.H>
- #include <STRING.H>
- #include <stdlib.h>
- #include <eeprom.h>
- #include "lcd.h"
- #include "delay.h"
- #include "datatran.h"
- #define Fosc 4096000 //系統(tǒng)晶振頻率 4.096MHz
- #define Fosc_TIME2 (64*10) //TIME2 比較中斷頻率=采樣率*AD通道數(shù)*工頻50Hz的倍數(shù)
- #define ATX_CTL_PORT PORTC //ATX電源控制端
- #define ATX_CTL_PIN PINC //ATX電源控制端
- #define ATX_CTL_DDR DDRC //ATX電源控制端
- #define ATX_CTL PC4 //ATX電源控制端
- #pragma data:eeprom
- unsigned char EEPROM_temp[]={'D','e','s','i','g','n',' ','b','y',' ','C','H','Q'};
- unsigned int Dead_count=10000;
- unsigned int uiEEPROM_Vref_preset=2665; // 參考電壓=2665mV
- unsigned int uiEEPROM_VtoPWM_preset[42]= // PWM控制輸出電壓與TIME1 比較寄存器OCR的關系值
- {
- 0,100,200,300,400,500,600,700,800,900,// 添加校正數(shù)據(jù)
- 1000,1100,1200,1300,1400,1500,1600,1700,1800,1900,
- 2000,2100,2200,2300,2400,2500,2600,2700,2800,2900,
- 3000,3100,3200,3300,3400,3500,3600,3700,3800,3900,
- 4000,4100
- };
- unsigned int uiEEPROM_ItoPWM_preset[42]= // PWM控制輸出電流與TIME1 比較寄存器OCR的關系值
- {
- 0,100,200,300,400,500,600,700,800,900,// 添加校正數(shù)據(jù)
- 1000,1100,1200,1300,1400,1500,1600,1700,1800,1900,
- 2000,2100,2200,2300,2400,2500,2600,2700,2800,2900,
- 3000,3100,3200,3300,3400,3500,3600,3700,3800,3900,
- 4000,4100
- };
-
- #pragma data:data
- unsigned char config=0x10,config_temp=0x10; // 功能選擇設定
- unsigned char num1,num2; // 臨時寄存器
- unsigned int uitemp1,uitemp2; // 臨時寄存器
- unsigned char time2_cmp_i=64; // TIME2 比較中斷i=采樣率*AD通道數(shù)
- unsigned char display_control=0x40; // LCD顯示的定時控制字節(jié)
- unsigned char *s1="123456789012345678901",*s2; // LCD顯示的字符串
- unsigned int uiVout_set=0,uiIout_set=0; // PWM A/B 通道(A通道控制電壓,B通道控制電流)的電壓設定輸出值
- unsigned int uiadc_value_temp; // ADC中斷的 采樣值
- unsigned int uitime2_adc0_value_sum,uiadc0_value; // TIME2 ADC0 16個采樣值的加和值,電壓輸出值=Vref*uitime2_adc0_value_sum/16/1024
- unsigned int uitime2_adc1_value_sum,uiadc1_value; // TIME2 ADC1 16個采樣值的加和值,電壓輸出值
- unsigned int uitime2_adc2_value_sum,uiadc2_value; // TIME2 ADC2 16個采樣值的加和值,電壓輸出值
- unsigned int uitime2_adc3_value_sum,uiadc3_value; // TIME2 ADC3 16個采樣值的加和值,電壓輸出值
- unsigned long uladc_data,uladc_data2,time2_count; // ADC的轉換數(shù)據(jù), TIME2 中斷計數(shù)N,0.1S計數(shù)(可作長時間定時器136年)
- unsigned char ucADC_select; // 四通道AD選擇
- unsigned int uiADC_value_sum[4]; // 四通道AD,64個數(shù)據(jù)加和值
- unsigned int uiVref_preset; // 參考電壓=2665mV
- unsigned int uiVtoPWM_preset[42]; // PWM控制輸出電壓與TIME1 比較寄存器OCR的關系值
- unsigned int uiItoPWM_preset[42];
-
- void main(void)
- {
- WDR();
- watchdog_init();
- init_devices();
- CLI(); // disable all interrupts
- timer1_init(); // 使能PWM
- adc_init(); // 使能ADC
- timer2_init(); // 使能AD轉換
- delay_ms(1000);
- WDR();
- EEPROM_READ((int) &Dead_count,uitemp1); // 開機次數(shù)計數(shù)
- uint_to_ascii(uitemp1,s1);
- uitemp1 --;
- //uitemp1 = 10000;
- EEPROM_WRITE((int) &Dead_count,uitemp1);
- lcd_init();
- lcd_write_string(0,0,"hello!");
- SEI(); // re-enable interrupts
- lcd_write_string(0,1,s1);
- delay_ms(500);
- lcd_init(); // LCD 初始化
- lcd_write_string(0,0,"Good Luck!");
- lcd_write_string(0,1,"V1.00 2005.11.13.ADC4");
- delay_ms(500);
- SRAM_data_init(); // 從EEPROM的數(shù)據(jù)設置SRAM
- lcd_init(); // LCD 初始化
- lcd_write_string(0,0,"Please");
- lcd_write_string(0,1,"Select Program!");
- delay_ms(500);
- lcd_init(); // LCD 初始化
- lcd_write_string(0,0,"Default Program= 0");
- lcd_write_string(0,1,"Program = DCpower");
- delay_ms(500);
- lcd_clear();
- uart_init();
- while(1)
- {
- if(config != config_temp) program_set(); // config != config_temp 當前功能已退出,重新選擇功能
- program_select();
- if((display_control & 0x40) == 0x40) // 如果display_control 第8位為1,就顯示
- {
- display_control = display_control & 0x07; // display_control 第8位清零
- DCpower_display();
- }
- }
- } // *** main() end ***
- /********由定時器T2中斷啟動 連續(xù)轉換四個ADC通道的值 **********/
- #pragma interrupt_handler adc_isr:15
- void adc_isr(void)
- {
- uiadc_value_temp = ADCL;
- uiadc_value_temp |= (unsigned int)ADCH << 8;
- SEI();
- switch(ucADC_select)
- {
- case 0 : // ADC0通道 數(shù)據(jù)處理
- {
- ADMUX = 0xc1; // 切換到ADC1通道,內(nèi)部Vref
- //ADMUX = 0x01; // 外部Vref,ADC1通道
- uiADC_value_sum[ucADC_select] += uiadc_value_temp; //加和值
- ADCSRA |= (1<<ADSC); // enable adc
- ucADC_select ++ ; // 切換到ADC1通道
- break;
- }
- case 1 : // ADC1通道 數(shù)據(jù)處理
- {
- ADMUX = 0xc2; // 切換到ADC2通道,內(nèi)部Vref
- //ADMUX = 0x02; // 外部Vref,ADC2通道
- uiADC_value_sum[ucADC_select] += uiadc_value_temp; //加和值
- ADCSRA |= (1<<ADSC); // enable adc
- ucADC_select ++ ; // 切換到ADC2通道
- break;
- }
- case 2 : // ADC2通道 數(shù)據(jù)處理
- {
- ADMUX = 0xc3; // 切換到ADC3通道,內(nèi)部Vref
- //ADMUX = 0x03; // 外部Vref,ADC3通道
- uiADC_value_sum[ucADC_select] += uiadc_value_temp; //加和值
- ADCSRA |= (1<<ADSC); // enable adc
- ucADC_select ++ ; // 切換到ADC3通道
- break;
- }
- case 3 : // ADC3通道 數(shù)據(jù)處理
- {
- ADMUX = 0xc0; // 切換到ADC0通道,內(nèi)部Vref,但不啟動,等待定時器T2啟動
- //ADMUX = 0x00; // 外部Vref,ADC0通道
- uiADC_value_sum[ucADC_select] += uiadc_value_temp; //加和值
- ucADC_select = 0 ; // 切換到ADC0通道,但不啟動,等待定時器T2啟動
- break;
- }
- default :
- {
- ADMUX = 0xc0; // 切換到ADC0通道,內(nèi)部Vref,但不啟動,等待定時器T2啟動
- ucADC_select = 0 ; // 切換到ADC0通道,但不啟動,等待定時器T2啟動
- break;
- }
- } // switch end
- } // AD中斷處理 end
- /********由定時器T2中斷啟動 連續(xù)轉換四個ADC通道的值 ****** end */
- /******定時器T2中斷*****************************
- *1、喂狗;2、啟動ADC;
- *3、將ADC的加和值平均,計算電壓值
- ************************************************/
- #pragma interrupt_handler timer2_comp_isr:4
- void timer2_comp_isr(void) // TIME2做四通道ADC0、ADC1、ADC2、ADC3的積分濾波 10Hz,16采樣率
- {
- WDR(); //喂狗
- if((time2_cmp_i & 0x03) == 0x00) ADCSRA |= (1<<ADSC); // 啟動ADC,16次采樣率
- time2_cmp_i --;
- if(time2_cmp_i == 0)
- {
- uitime2_adc0_value_sum = uiADC_value_sum[0]; // 16個數(shù)據(jù)加和值
- uiADC_value_sum[0] = 0; // 清零
- uitime2_adc1_value_sum = uiADC_value_sum[1]; // 16個數(shù)據(jù)加和值
- uiADC_value_sum[1] = 0; // 清零
- uitime2_adc2_value_sum = uiADC_value_sum[2]; // 16個數(shù)據(jù)加和值
- uiADC_value_sum[2] = 0; // 清零
- uitime2_adc3_value_sum = uiADC_value_sum[3]; // 16個數(shù)據(jù)加和值
- uiADC_value_sum[3] = 0; // 清零
- time2_cmp_i = 64;
- SEI();
- time2_count ++; // 0.1S計數(shù)
- display_control ++;
- if((display_control & 0x07) == 5) display_control = 0x40; // display_control 計數(shù)為5時,第7位置1
- }
- }
- //******定時器T2中斷************************* end */
- void SRAM_data_init(void) /*從EEPROM讀入SRAM區(qū)*/
- {
- unsigned char i;
- EEPROM_READ((int) &uiEEPROM_Vref_preset,uiVref_preset); // 參考電壓值
-
- for(i=0;i<42;i++) // PWM控制輸出電壓與TIME1 比較寄存器OCR的校正值
- {
- EEPROM_READ((int) &uiEEPROM_VtoPWM_preset[i],uiVtoPWM_preset[i]);
- }
- for(i=0;i<42;i++) // PWM控制輸出電流與TIME1 比較寄存器OCR的校正值
- {
- EEPROM_READ((int) &uiEEPROM_ItoPWM_preset[i],uiItoPWM_preset[i]);
- }
- }
-
- void EEPROM_Vout_preset_write(void) /*PWM控制輸出電壓與TIME1 比較寄存器OCR的校正值寫入EEPROM區(qū)*/
- {
- unsigned char i;
- for(i=0;i<42;i++) // PWM控制輸出電壓與TIME1 比較寄存器OCR的校正值
- {
- EEPROM_WRITE((int) &uiEEPROM_VtoPWM_preset[i],uiVtoPWM_preset[i]);
- }
- }
- void EEPROM_Iout_preset_write(void) /*PWM控制輸出電流與TIME1 比較寄存器OCR的校正值寫入EEPROM區(qū)*/
- {
- unsigned char i;
- for(i=0;i<42;i++) // PWM控制輸出電流與TIME1 比較寄存器OCR的校正值
- {
- EEPROM_WRITE((int) &uiEEPROM_ItoPWM_preset[i],uiItoPWM_preset[i]);
- }
- }
-
- unsigned int PWM_Vout_to_count(unsigned int uiVout_set) // 將設定的電壓值修正轉換成PWM(TIME1)的比較寄存器OCR的值,uiVout_set=0-4094
- {
- unsigned char i;
- unsigned int PWM_count;
- i = uiVout_set/100;
- PWM_count = uiVtoPWM_preset[i]+(uiVtoPWM_preset[i+1]-uiVtoPWM_preset[i])*(uiVout_set%100)/100; // 插值法
- if(PWM_count < 1) PWM_count = 1; // PWM返回值范圍為1-4094
- if(PWM_count > 4094) PWM_count = 4094;
- return PWM_count;
- }
- unsigned int PWM_Iout_to_count(unsigned int uiIout_set) // 將設定的電壓值修正轉換成PWM(TIME1)的比較寄存器OCR的值,uiVout_set=0-4094
- {
- unsigned char i;
- unsigned int PWM_count;
- i = uiIout_set/100;
- PWM_count = uiItoPWM_preset[i]+(uiItoPWM_preset[i+1]-uiItoPWM_preset[i])*(uiIout_set%100)/100; // 插值法
- if(PWM_count < 1) PWM_count = 1; // PWM返回值范圍為1-4094
- if(PWM_count > 4094) PWM_count = 4094;
- return PWM_count;
- }
- void port_init(void)
- {
- DDRB = 0x00;
- PORTB = 0x00;
- DDRC = 0x00;
- PORTC = 0x00; //m103 output only
- DDRD = 0x00;
- PORTD = 0x00;
- }
- // *********** ADC的設定及函數(shù)****************
- //ADC initialize
- // Conversion time: 128KHz(系統(tǒng)位4.096MHz,32分頻)
- void adc_init(void)
- {
- ADCSRA= 0x00; //disable adc
- ACSR = (1<<ACD); //disable comparator
- ADMUX = 0xc0; //內(nèi)部Vref,ADC0通道
- //ADMUX = 0x00; //外部Vref,ADC0通道
- ADCSRA= (1<<ADEN)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS0); // enable adc,中斷允許,32分頻|(1<<ADSC)
- //ADCSRA= (1<<ADEN)|(1<<ADSC)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1); //enable adc,64分頻
- //ADCSRA= (1<<ADEN)|(1<<ADSC)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);//enable adc,128分頻
- }
- // *********** ADC的設定及函數(shù)**************end**
-
- //TIMER2 initialize - prescale:1024
- // WGM: CTC
- // actual value: 32*2*10Hz (0.0%)=采樣率*AD通道數(shù)*工頻50Hz的倍數(shù)
- void timer2_init(void)
- {
- TCCR2 = 0x00; //stop
- ASSR = 0x00; //關閉異步方式
- TCNT2 = 0x00; //setup
- OCR2 = Fosc/Fosc_TIME2/256-1; //設置TIME2 比較中斷頻率
- TCCR2 = (1<<WGM21)|(1<<CS22)|(1<<CS21); //CTC模式,內(nèi)部時鐘256分頻
- TIMSK |= (1<<OCIE2); //timer2 中斷允許
- }
- //TIMER1 initialize - prescale:1
- // WGM: 14) PWM fast, TOP=ICRn
- // desired value: 2000Hz
- // actual value: 2000.000Hz (0.0%)
- void timer1_init(void)
- {
- DDRB |= (1<<PB1); //設置OC1A-PB1為輸出
- DDRB |= (1<<PB2); //設置OC1B-PB2為輸出
- TCCR1B = 0x00; //stop
- TCNT1H = 0x00; //setup
- TCNT1L = 0x00;
- OCR1A = PWM_Vout_to_count(uiVout_set);
- OCR1B = PWM_Iout_to_count(uiIout_set);
- ICR1H = 0x0F; // 12位PWM
- ICR1L = 0xFF;
- TCCR1A = (1<<COM1A1)|(1<<COM1A0)|(1<<COM1B1)|(1<<COM1B0)|(1<<WGM11); //0xF2;比較匹配置位OC1A/B
- TCCR1B = (1<<WGM13)|(1<<WGM12)|(1<<CS10); //0x19; WGM: 14) PWM fast, TOP=ICRn;內(nèi)部時鐘1分頻//start Timer
- }
- unsigned int cal_VD(unsigned int uiAD_16sum_data)
- {
- uladc_data = uiAD_16sum_data;
- return ((unsigned int)((uladc_data*uiVref_preset)>>14)); // 輸出ADC0的電壓值VD0=Vref*uitime2_adc0_value_sum/16/1024
- }
-
- //Watchdog initialize
- // prescale: 2048K
- void watchdog_init(void)
- {
- WDR(); //this prevents a timout on enabling
- WDTCR = 0x1F; //WATCHDOG ENABLED - dont forget to issue WDRs
- WDTCR = 0x0F; //WATCHDOG ENABLED - 看門狗定時器預分頻設為2048K,2.1S
- WDR();
- }
- void init_devices(void)
- {
- //stop errant interrupts until set up
- port_init();
- MCUCR = 0x00;
- GICR = 0x00;
- TIMSK = 0x00; //timer interrupt sources
- //all peripherals are now initialized
- }
-
- //********** ADC顯示 *************
- void DCpower_display(void)
- {
- lcd_write_string(0,0,"D0= mV D1= mV"); // LCD顯示格式
- lcd_write_string(0,1,"D2= mV D3= mV");
- //uart輸出ADC0的電壓值
- uiadc0_value=cal_VD(uitime2_adc0_value_sum); // 輸出ADC0的電壓值VD0=Vref*uitime2_adc0_value_sum/16/1024
- uint_to_ascii(uiadc0_value,s1);
- putstring("D0="); // uart輸出ADC0
- putstring(s1);
- putstring("mV ");
- lcd_write_string(3,0,s1); // LCD顯示
-
- //uart輸出ADC1的電壓值
- uiadc1_value=cal_VD(uitime2_adc1_value_sum); // 輸出ADC1的電壓值VD1=Vref*uitime2_adc1_value_sum/16/1024
- uint_to_ascii(uiadc1_value,s1);
- putstring("D1="); // uart輸出ADC1
- putstring(s1);
- putstring("mV ");
- lcd_write_string(14,0,s1); // LCD顯示
-
- //uart輸出ADC2的電壓值
- uiadc2_value=cal_VD(uitime2_adc2_value_sum); // 輸出ADC2的電壓值VD2=Vref*uitime2_adc2_value_sum/16/1024
- uint_to_ascii(uiadc2_value,s1);
- putstring("D2="); // uart輸出ADC2
- putstring(s1);
- putstring("mV ");
- lcd_write_string(3,1,s1); // LCD顯示
-
- //uart輸出ADC3的電壓值
- uiadc3_value=cal_VD(uitime2_adc3_value_sum); // 輸出ADC3的電壓值VD3=Vref*uitime2_adc3_value_sum/16/1024
- uint_to_ascii(uiadc3_value,s1);
- putstring("D3="); // uart輸出ADC3
- putstring(s1);
- putstring("mV ");
- lcd_write_string(14,1,s1); // LCD顯示
- uint_to_ascii(OCR1A,s1); // uart輸出TIME1 比較寄存器A 的值
- putstring(" 1A="); // uart輸出
- putstring(s1);
- uint_to_ascii(OCR1B,s1); // uart輸出TIME1 比較寄存器B 的值
- putstring(" 1B="); // uart輸出
- putstring(s1);
- ulong_to_ascii(time2_count/10,s1); // uart輸出TIME2秒計數(shù)值
- putstring(" tn="); // uart輸出
- putstring(s1);
- putchar('s');
-
- putchar_ENTER(); // uart輸出回車換行
- } // *********ADC顯示 end*********
- /************** 數(shù)控電源相關子程序 *********************/
- void DCpower(void) // 數(shù)控電源功能模塊
- {
- //3*4鍵盤掃描
- /*掃描1*/
- DDRD &=~((1<<PD3)|(1<<PD4)|(1<<PD5)); // SET1、2、3(PD3、4、5)(S12,S11,S10)三鍵輸入
- PORTD |= ((1<<PD3)|(1<<PD4)|(1<<PD5)); // 置上拉電阻
- PORTD &=~(1<<PD2); // 使SET0(PD2)腳輸出0,掃描SET1、2、3(PD3、4、5)腳
- DDRD |= (1<<PD2);
- while((PIND & 0x38) != 0x38)
- {
- delay_ms(1);
- if((PIND & 0x38) == 0x30) // SET1(PD3=0) S12鍵按下 PWMA電壓快速遞增
- {
- if(uiVout_set<2451) // 限定電壓不超過25.00V
- {
- uiVout_set +=50;
- OCR1A = PWM_Vout_to_count(uiVout_set); // 電壓值轉換成PWMA值
- }
- }
- if((PIND & 0x38) == 0x28) //SET2(PD4=0) S11鍵按下 PWMA電壓快速遞減
- {
- if(uiVout_set>49)
- {
- uiVout_set -=50;
- OCR1A = PWM_Vout_to_count(uiVout_set); // 電壓值轉換成PWMA值
- }
- }
- if((PIND & 0x38) == 0x18) //SET3(PD5=0) S10鍵按下 ATX電源打開
- {
- power_ON();
- }
- delay_ms(1);
- DCpower_display();
- for(num1=0;num1<30;num1++)
- {
- if((PIND & 0x38) == 0x38) return;
- delay_ms(10);
- }
- }
-
- /*掃描2*/
- DDRD &=~((1<<PD2)|(1<<PD4)|(1<<PD5)); // SET0、2、3(PD2、4、5)(S22,S21,S20)三鍵輸入
- PORTD |= ((1<<PD2)|(1<<PD4)|(1<<PD5)); // 置上拉電阻
- PORTD &=~(1<<PD3); // 使SET1(PD3)腳輸出0,掃描SET0、2、3(PD2、4、5)腳
- DDRD |= (1<<PD3);
- while((PIND & 0x34) != 0x34)
- {
- delay_ms(1);
- if((PIND & 0x34) == 0x30) // SET0(PD2=0) S22鍵按下 PWMA電壓慢速遞增
- {
- if(uiVout_set<2500) // 限定電壓不超過25.00V
- {
- uiVout_set +=1;
- OCR1A = PWM_Vout_to_count(uiVout_set); // 電壓值轉換成PWMA值
- }
- }
- if((PIND & 0x34) == 0x24) //SET2(PD4=0) S21鍵按下 PWMA電壓慢速遞減
- {
- if(uiVout_set>0)
- {
- uiVout_set -=1;
- OCR1A = PWM_Vout_to_count(uiVout_set); // 電壓值轉換成PWM值
- }
- }
- if((PIND & 0x34) == 0x14) //SET3(PD5=0) S20鍵按下 ATX電源關閉
- {
- power_OFF();
- }
- delay_ms(1);
- DCpower_display();
- for(num1=0;num1<30;num1++)
- {
- if((PIND & 0x34) == 0x34) return;
- delay_ms(10);
- }
- }
-
- /*掃描3*/
- DDRD &=~((1<<PD2)|(1<<PD3)|(1<<PD5)); // SET0、1、3(PD2、3、5)(S32,S31,S30)三鍵輸入
- PORTD |= ((1<<PD2)|(1<<PD3)|(1<<PD5)); // 置上拉電阻
- PORTD &=~(1<<PD4); // 使SET2(PD4)腳輸出0,掃描SET0、1、3(PD2、3、5)腳
- DDRD |= (1<<PD4);
- while((PIND & 0x2c) != 0x2c)
- {
- delay_ms(1);
- if((PIND & 0x2c) == 0x28) //SET0(PD2=0) S32鍵按下 PWMB電壓快速遞增
- {
- if(uiIout_set<3901) // 限定電流不超過4.000A
- {
- uiIout_set +=100;
- OCR1B = PWM_Iout_to_count(uiIout_set); // 電流值轉換成PWMB值
- }
- }
- if((PIND & 0x2c) == 0x24) //SET1(PD3=0) S31鍵按下 PWMB電壓快速遞減
- {
- if(uiIout_set>99)
- {
- uiIout_set -=100;
- OCR1B = PWM_Iout_to_count(uiIout_set); // 電流值轉換成PWMB值
- }
- }
- if((PIND & 0x2c) == 0x0c) // SET3(PD5=0) S30鍵按下 "CANCEL"鍵 當前功能退出
- {
- config_temp++; // 改變config_temp值,令config_temp!=config
- }
- delay_ms(1);
- DCpower_display();
- for(num1=0;num1<30;num1++)
- {
- if((PIND & 0x2c) == 0x2c) return;
- delay_ms(10);
- }
- }
- /*掃描4*/
- DDRD &=~((1<<PD2)|(1<<PD3)|(1<<PD4)); // SET0、1、2(PD2、3、4)(S42,S41,S40)三鍵輸入
- PORTD |= ((1<<PD2)|(1<<PD3)|(1<<PD4)); // 置上拉電阻
- PORTD &=~(1<<PD5); // 使SET3(PD5)腳輸出0,掃描SET0、1、2(PD2、3、4)腳
- DDRD |= (1<<PD5);
- while((PIND & 0x1c) != 0x1c)
- {
- delay_ms(1);
- if((PIND & 0x1c) == 0x18) // SET0(PD2=0) S42鍵按下 PWMB電壓慢速遞增
- {
- if(uiIout_set<4000) // 限定電流不超過4.000A
- {
- uiIout_set +=1;
- OCR1B = PWM_Iout_to_count(uiIout_set); // 電流值轉換成PWMB值
- }
- }
- if((PIND & 0x1c) == 0x14) // SET1(PD3=0) S41鍵按下 PWMB電壓慢速遞減
- {
- if(uiIout_set>0)
- {
- uiIout_set -=1;
- OCR1B = PWM_Iout_to_count(uiIout_set); // 電流值轉換成PWMB值
- }
- }
- if((PIND & 0x1c) == 0x0c) // SET2(PD4=0) S40鍵按下
- {
-
- }
- delay_ms(1);
- DCpower_display();
- for(num1=0;num1<30;num1++)
- {
- if((PIND & 0x1c) == 0x1c) return;
- delay_ms(10);
- }
- }
- }
-
- void power_ON(void) // 開關電源打開
- {
- ATX_CTL_DDR |= (1<<ATX_CTL); //
- ATX_CTL_PORT |= (1<<ATX_CTL); // 置1
- }
- void power_OFF(void) // 開關電源關閉
- {
- ATX_CTL_DDR |= (1<<ATX_CTL); //
- ATX_CTL_PORT &=~ (1<<ATX_CTL); // 置0
- }
- /************** 數(shù)控電源相關子程序 *************** END */
-
- void program_set(void) // 功能模塊選擇設定
- {
- //循環(huán)3*4鍵盤掃描
- while(1)
- {
- /*掃描1*/
- DDRD &=~((1<<PD3)|(1<<PD4)|(1<<PD5)); // SET1、2、3(PD3、4、5)(S12,S11,S10)三鍵輸入
- PORTD |= ((1<<PD3)|(1<<PD4)|(1<<PD5)); // 置上拉電阻
- PORTD &=~(1<<PD2); // 使SET0(PD2)腳輸出0,掃描SET1、2、3(PD3、4、5)腳
- DDRD |= (1<<PD2);
- while((PIND & 0x38) != 0x38)
- {
- delay_ms(1);
- if((PIND & 0x38) == 0x30) //SET1(PD3=0) S12 "1"鍵按下 選擇數(shù)控電源
- {
- config_temp = 0x10;
- }
- if((PIND & 0x38) == 0x28) //SET2(PD4=0) S11 "5"鍵按下
- {
- }
- if((PIND & 0x38) == 0x18) //SET3(PD5=0) S10鍵按下
- {
- }
- delay_ms(50);
- }
-
- /*掃描2*/
- DDRD &=~((1<<PD2)|(1<<PD4)|(1<<PD5)); // SET0、2、3(PD2、4、5)(S22,S21,S20)三鍵輸入
- PORTD |= ((1<<PD2)|(1<<PD4)|(1<<PD5)); // 置上拉電阻
- PORTD &=~(1<<PD3); // 使SET1(PD3)腳輸出0,掃描SET0、2、3(PD2、4、5)腳
- DDRD |= (1<<PD3);
- while((PIND & 0x34) != 0x34)
- {
- delay_ms(1);
- if((PIND & 0x34) == 0x30) //SET0(PD2=0) S22鍵按下
- {
- }
- if((PIND & 0x34) == 0x24) //SET2(PD4=0) S21鍵按下
- {
- }
- if((PIND & 0x34) == 0x14) //SET3(PD5=0) S20鍵按下
- {
- }
- delay_ms(50);
- }
-
- /*掃描3*/
- DDRD &=~((1<<PD2)|(1<<PD3)|(1<<PD5)); // SET0、1、3(PD2、3、5)(S32,S31,S30)三鍵輸入
- PORTD |= ((1<<PD2)|(1<<PD3)|(1<<PD5)); // 置上拉電阻
- PORTD &=~(1<<PD4); // 使SET2(PD4)腳輸出0,掃描SET0、1、3(PD2、3、5)腳
- DDRD |= (1<<PD4);
- while((PIND & 0x2c) != 0x2c)
- {
- delay_ms(1);
- if((PIND & 0x2c) == 0x28) //SET0(PD2=0) S32鍵按下
- {
- }
- if((PIND & 0x2c) == 0x24) //SET1(PD3=0) S31鍵按下
- {
- }
- if((PIND & 0x2c) == 0x0c) // SET3(PD5=0) S30鍵按下 "CANCEL"鍵 當前功能退出
- {
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
見2樓
|