久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 5496|回復: 3
打印 上一主題 下一主題
收起左側

ATMEGA8單片機數(shù)控電源和電壓自動校正的C語言程序

[復制鏈接]
跳轉到指定樓層
樓主
ID:696930 發(fā)表于 2020-10-9 10:16 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
先用ISP下載線把boot.hex寫入M8.
FUSE設定為外部晶振(4.096MHz),啟動硬件"看門狗",和BOOT區(qū)啟動

附上M8用RS232接口在線升級的BOOT軟件
使用:按下RESET鍵后按下S12鍵,就可以用AvrProg了。

電路原理圖如下:


單片機源程序如下:
  1. /********************************************
  2. **Designed by GandF
  3. ********************************************/
  4. #include <iom8v.h>
  5. #include <macros.h>
  6. #include <MATH.H>
  7. #include <STRING.H>
  8. #include <stdlib.h>
  9. #include <eeprom.h>
  10. #include "lcd.h"
  11. #include "delay.h"
  12. #include "datatran.h"

  13. #define   Fosc           4096000          //系統(tǒng)晶振頻率 4.096MHz
  14. #define   Fosc_TIME2      (64*10)             //TIME2 比較中斷頻率=采樣率*AD通道數(shù)*工頻50Hz的倍數(shù)

  15. #define  ATX_CTL_PORT          PORTC            //ATX電源控制端
  16. #define  ATX_CTL_PIN          PINC             //ATX電源控制端
  17. #define  ATX_CTL_DDR           DDRC             //ATX電源控制端
  18. #define  ATX_CTL                PC4              //ATX電源控制端

  19. #pragma data:eeprom
  20. unsigned char EEPROM_temp[]={'D','e','s','i','g','n',' ','b','y',' ','C','H','Q'};
  21. unsigned int  Dead_count=10000;
  22. unsigned int  uiEEPROM_Vref_preset=2665;         // 參考電壓=2665mV
  23. unsigned int  uiEEPROM_VtoPWM_preset[42]=        // PWM控制輸出電壓與TIME1 比較寄存器OCR的關系值
  24.                  {
  25.                                    0,100,200,300,400,500,600,700,800,900,// 添加校正數(shù)據(jù)
  26.                                    1000,1100,1200,1300,1400,1500,1600,1700,1800,1900,
  27.                                    2000,2100,2200,2300,2400,2500,2600,2700,2800,2900,
  28.                                    3000,3100,3200,3300,3400,3500,3600,3700,3800,3900,
  29.                                    4000,4100
  30.                                  };                       
  31. unsigned int  uiEEPROM_ItoPWM_preset[42]=        // PWM控制輸出電流與TIME1 比較寄存器OCR的關系值
  32.                  {
  33.                                    0,100,200,300,400,500,600,700,800,900,// 添加校正數(shù)據(jù)
  34.                                    1000,1100,1200,1300,1400,1500,1600,1700,1800,1900,
  35.                                    2000,2100,2200,2300,2400,2500,2600,2700,2800,2900,
  36.                                    3000,3100,3200,3300,3400,3500,3600,3700,3800,3900,
  37.                                    4000,4100
  38.                                  };                               

  39. #pragma data:data

  40. unsigned char  config=0x10,config_temp=0x10;              // 功能選擇設定
  41. unsigned char  num1,num2;                                 // 臨時寄存器
  42. unsigned int   uitemp1,uitemp2;                           // 臨時寄存器
  43. unsigned char  time2_cmp_i=64;                            // TIME2 比較中斷i=采樣率*AD通道數(shù)
  44. unsigned char  display_control=0x40;                      // LCD顯示的定時控制字節(jié)

  45. unsigned char  *s1="123456789012345678901",*s2;           // LCD顯示的字符串
  46. unsigned int   uiVout_set=0,uiIout_set=0;                           // PWM A/B 通道(A通道控制電壓,B通道控制電流)的電壓設定輸出值
  47. unsigned int   uiadc_value_temp;                          // ADC中斷的 采樣值
  48. unsigned int   uitime2_adc0_value_sum,uiadc0_value;           // TIME2  ADC0 16個采樣值的加和值,電壓輸出值=Vref*uitime2_adc0_value_sum/16/1024
  49. unsigned int   uitime2_adc1_value_sum,uiadc1_value;           // TIME2  ADC1 16個采樣值的加和值,電壓輸出值
  50. unsigned int   uitime2_adc2_value_sum,uiadc2_value;           // TIME2  ADC2 16個采樣值的加和值,電壓輸出值
  51. unsigned int   uitime2_adc3_value_sum,uiadc3_value;           // TIME2  ADC3 16個采樣值的加和值,電壓輸出值

  52. unsigned long  uladc_data,uladc_data2,time2_count;                                     // ADC的轉換數(shù)據(jù), TIME2 中斷計數(shù)N,0.1S計數(shù)(可作長時間定時器136年)

  53. unsigned char  ucADC_select;                                                             // 四通道AD選擇
  54. unsigned int   uiADC_value_sum[4];                                                   // 四通道AD,64個數(shù)據(jù)加和值

  55. unsigned int   uiVref_preset;                                               // 參考電壓=2665mV
  56. unsigned int   uiVtoPWM_preset[42];                                          // PWM控制輸出電壓與TIME1 比較寄存器OCR的關系值                       
  57. unsigned int   uiItoPWM_preset[42];
  58.                                  
  59. void main(void)
  60.   {
  61.          WDR();
  62.          watchdog_init();
  63.          init_devices();
  64.          CLI();                     // disable all interrupts
  65.          timer1_init();             // 使能PWM
  66.          adc_init();                // 使能ADC
  67.          timer2_init();             // 使能AD轉換
  68.          delay_ms(1000);
  69.          WDR();
  70.          EEPROM_READ((int) &Dead_count,uitemp1);  // 開機次數(shù)計數(shù)
  71.          uint_to_ascii(uitemp1,s1);
  72.          uitemp1 --;
  73.          //uitemp1 = 10000;
  74.          EEPROM_WRITE((int) &Dead_count,uitemp1);
  75.          lcd_init();
  76.          lcd_write_string(0,0,"hello!");
  77.          SEI();                    // re-enable interrupts
  78.          lcd_write_string(0,1,s1);
  79.          delay_ms(500);
  80.          lcd_init();                // LCD 初始化
  81.          lcd_write_string(0,0,"Good Luck!");
  82.          lcd_write_string(0,1,"V1.00 2005.11.13.ADC4");
  83.          delay_ms(500);
  84.          SRAM_data_init();          // 從EEPROM的數(shù)據(jù)設置SRAM
  85.          lcd_init();                // LCD 初始化
  86.          lcd_write_string(0,0,"Please");
  87.          lcd_write_string(0,1,"Select Program!");
  88.          delay_ms(500);
  89.          lcd_init();                // LCD 初始化
  90.          lcd_write_string(0,0,"Default Program= 0");
  91.          lcd_write_string(0,1,"Program =  DCpower");
  92.          delay_ms(500);
  93.          lcd_clear();
  94.          uart_init();
  95.          while(1)
  96.        {
  97.                  if(config != config_temp) program_set(); // config != config_temp 當前功能已退出,重新選擇功能
  98.                  program_select();
  99.                  if((display_control & 0x40) == 0x40)  // 如果display_control 第8位為1,就顯示
  100.             {
  101.                   display_control = display_control & 0x07; // display_control 第8位清零
  102.                   DCpower_display();
  103.             }
  104.            }
  105.   } // *** main() end ***

  106. /********由定時器T2中斷啟動 連續(xù)轉換四個ADC通道的值 **********/
  107. #pragma interrupt_handler adc_isr:15
  108. void adc_isr(void)
  109. {
  110. uiadc_value_temp  = ADCL;
  111. uiadc_value_temp |= (unsigned int)ADCH << 8;
  112. SEI();
  113. switch(ucADC_select)
  114.    {
  115.          case  0 :    // ADC0通道 數(shù)據(jù)處理
  116.            {
  117.                  ADMUX   = 0xc1;          // 切換到ADC1通道,內(nèi)部Vref
  118.          //ADMUX   = 0x01;        // 外部Vref,ADC1通道
  119.                  uiADC_value_sum[ucADC_select] += uiadc_value_temp; //加和值
  120.          ADCSRA |= (1<<ADSC);     // enable adc
  121.                  ucADC_select ++ ;        // 切換到ADC1通道
  122.                  break;
  123.            }
  124.      case  1 :    // ADC1通道 數(shù)據(jù)處理
  125.            {
  126.                  ADMUX   = 0xc2;          // 切換到ADC2通道,內(nèi)部Vref
  127.          //ADMUX   = 0x02;        // 外部Vref,ADC2通道
  128.                  uiADC_value_sum[ucADC_select] += uiadc_value_temp; //加和值
  129.                  ADCSRA |= (1<<ADSC);     // enable adc
  130.                  ucADC_select ++ ;        // 切換到ADC2通道
  131.                  break;
  132.            }
  133.      case  2 :    // ADC2通道 數(shù)據(jù)處理
  134.            {
  135.                  ADMUX   = 0xc3;          // 切換到ADC3通道,內(nèi)部Vref
  136.          //ADMUX   = 0x03;        // 外部Vref,ADC3通道
  137.                  uiADC_value_sum[ucADC_select] += uiadc_value_temp; //加和值
  138.          ADCSRA |= (1<<ADSC);     // enable adc
  139.                  ucADC_select ++ ;        // 切換到ADC3通道
  140.                  break;
  141.            }
  142.      case  3 :    // ADC3通道 數(shù)據(jù)處理
  143.            {
  144.                  ADMUX   = 0xc0;          // 切換到ADC0通道,內(nèi)部Vref,但不啟動,等待定時器T2啟動
  145.          //ADMUX   = 0x00;        // 外部Vref,ADC0通道
  146.                  uiADC_value_sum[ucADC_select] += uiadc_value_temp; //加和值
  147.                  ucADC_select = 0 ;       // 切換到ADC0通道,但不啟動,等待定時器T2啟動
  148.                  break;
  149.            }
  150.          default :
  151.            {
  152.             ADMUX   = 0xc0;          // 切換到ADC0通道,內(nèi)部Vref,但不啟動,等待定時器T2啟動
  153.             ucADC_select = 0 ;       // 切換到ADC0通道,但不啟動,等待定時器T2啟動
  154.             break;
  155.            }
  156.    } // switch end
  157. } // AD中斷處理 end
  158. /********由定時器T2中斷啟動 連續(xù)轉換四個ADC通道的值 ****** end */

  159. /******定時器T2中斷*****************************
  160. *1、喂狗;2、啟動ADC;
  161. *3、將ADC的加和值平均,計算電壓值
  162. ************************************************/
  163. #pragma interrupt_handler timer2_comp_isr:4
  164. void timer2_comp_isr(void)                         // TIME2做四通道ADC0、ADC1、ADC2、ADC3的積分濾波 10Hz,16采樣率
  165.   {
  166.    WDR();   //喂狗
  167.    if((time2_cmp_i & 0x03) == 0x00) ADCSRA |= (1<<ADSC);  // 啟動ADC,16次采樣率
  168.    time2_cmp_i --;
  169.    if(time2_cmp_i == 0)
  170.     {
  171.           uitime2_adc0_value_sum = uiADC_value_sum[0]; // 16個數(shù)據(jù)加和值
  172.           uiADC_value_sum[0] = 0;                      // 清零
  173.           uitime2_adc1_value_sum = uiADC_value_sum[1]; // 16個數(shù)據(jù)加和值
  174.           uiADC_value_sum[1] = 0;                      // 清零
  175.           uitime2_adc2_value_sum = uiADC_value_sum[2]; // 16個數(shù)據(jù)加和值
  176.           uiADC_value_sum[2] = 0;                      // 清零
  177.           uitime2_adc3_value_sum = uiADC_value_sum[3]; // 16個數(shù)據(jù)加和值
  178.           uiADC_value_sum[3] = 0;                      // 清零
  179.           time2_cmp_i = 64;
  180.       SEI();
  181.           time2_count ++;                              // 0.1S計數(shù)
  182.           display_control ++;                    
  183.           if((display_control & 0x07) == 5) display_control = 0x40;       // display_control 計數(shù)為5時,第7位置1
  184.         }
  185.   }
  186. //******定時器T2中斷************************* end */


  187. void SRAM_data_init(void)       /*從EEPROM讀入SRAM區(qū)*/
  188.   {
  189.    unsigned char i;
  190.    EEPROM_READ((int) &uiEEPROM_Vref_preset,uiVref_preset);   // 參考電壓值
  191.    
  192.    for(i=0;i<42;i++)             // PWM控制輸出電壓與TIME1 比較寄存器OCR的校正值
  193.      {
  194.           EEPROM_READ((int) &uiEEPROM_VtoPWM_preset[i],uiVtoPWM_preset[i]);
  195.          }
  196.    for(i=0;i<42;i++)             // PWM控制輸出電流與TIME1 比較寄存器OCR的校正值
  197.      {
  198.           EEPROM_READ((int) &uiEEPROM_ItoPWM_preset[i],uiItoPWM_preset[i]);
  199.          }
  200.   }       
  201.   
  202. void EEPROM_Vout_preset_write(void)     /*PWM控制輸出電壓與TIME1 比較寄存器OCR的校正值寫入EEPROM區(qū)*/
  203.   {
  204.     unsigned char i;
  205.         for(i=0;i<42;i++)            // PWM控制輸出電壓與TIME1 比較寄存器OCR的校正值
  206.      {
  207.           EEPROM_WRITE((int) &uiEEPROM_VtoPWM_preset[i],uiVtoPWM_preset[i]);
  208.          }
  209.   }
  210. void EEPROM_Iout_preset_write(void)     /*PWM控制輸出電流與TIME1 比較寄存器OCR的校正值寫入EEPROM區(qū)*/
  211.   {
  212.     unsigned char i;
  213.         for(i=0;i<42;i++)            // PWM控制輸出電流與TIME1 比較寄存器OCR的校正值
  214.      {
  215.           EEPROM_WRITE((int) &uiEEPROM_ItoPWM_preset[i],uiItoPWM_preset[i]);
  216.          }
  217.   }
  218.                             
  219. unsigned int  PWM_Vout_to_count(unsigned int   uiVout_set)  // 將設定的電壓值修正轉換成PWM(TIME1)的比較寄存器OCR的值,uiVout_set=0-4094
  220.   {
  221.     unsigned char i;
  222.         unsigned int  PWM_count;
  223.         i = uiVout_set/100;
  224.         PWM_count = uiVtoPWM_preset[i]+(uiVtoPWM_preset[i+1]-uiVtoPWM_preset[i])*(uiVout_set%100)/100; // 插值法
  225.         if(PWM_count < 1) PWM_count = 1;                            // PWM返回值范圍為1-4094
  226.         if(PWM_count > 4094) PWM_count = 4094;
  227.         return PWM_count;
  228.   }

  229. unsigned int  PWM_Iout_to_count(unsigned int   uiIout_set)  // 將設定的電壓值修正轉換成PWM(TIME1)的比較寄存器OCR的值,uiVout_set=0-4094
  230.   {
  231.     unsigned char i;
  232.         unsigned int  PWM_count;
  233.         i = uiIout_set/100;
  234.         PWM_count = uiItoPWM_preset[i]+(uiItoPWM_preset[i+1]-uiItoPWM_preset[i])*(uiIout_set%100)/100; // 插值法
  235.         if(PWM_count < 1) PWM_count = 1;                            // PWM返回值范圍為1-4094
  236.         if(PWM_count > 4094) PWM_count = 4094;
  237.         return PWM_count;
  238.   }


  239. void port_init(void)
  240. {
  241. DDRB  = 0x00;
  242. PORTB = 0x00;
  243. DDRC  = 0x00;
  244. PORTC = 0x00; //m103 output only
  245. DDRD  = 0x00;
  246. PORTD = 0x00;
  247. }

  248. // *********** ADC的設定及函數(shù)****************
  249. //ADC initialize
  250. // Conversion time: 128KHz(系統(tǒng)位4.096MHz,32分頻)
  251. void adc_init(void)
  252. {
  253.   ADCSRA= 0x00;       //disable adc
  254.   ACSR  = (1<<ACD);   //disable comparator
  255.   ADMUX = 0xc0;       //內(nèi)部Vref,ADC0通道
  256.   //ADMUX = 0x00;       //外部Vref,ADC0通道
  257.   ADCSRA= (1<<ADEN)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS0);   // enable adc,中斷允許,32分頻|(1<<ADSC)
  258.   //ADCSRA= (1<<ADEN)|(1<<ADSC)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1);   //enable adc,64分頻
  259.   //ADCSRA= (1<<ADEN)|(1<<ADSC)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);//enable adc,128分頻
  260. }
  261. // *********** ADC的設定及函數(shù)**************end**


  262. //TIMER2 initialize - prescale:1024
  263. // WGM: CTC
  264. // actual value: 32*2*10Hz (0.0%)=采樣率*AD通道數(shù)*工頻50Hz的倍數(shù)
  265. void timer2_init(void)
  266.   {
  267.     TCCR2  = 0x00;                                                                                                          //stop
  268.     ASSR   = 0x00;                                                                                                         //關閉異步方式
  269.     TCNT2  = 0x00;                                                                                                    //setup
  270.     OCR2   = Fosc/Fosc_TIME2/256-1;                                                                      //設置TIME2 比較中斷頻率
  271.     TCCR2  = (1<<WGM21)|(1<<CS22)|(1<<CS21);                                           //CTC模式,內(nèi)部時鐘256分頻
  272.     TIMSK |= (1<<OCIE2);                                                                                     //timer2 中斷允許
  273.   }

  274. //TIMER1 initialize - prescale:1
  275. // WGM: 14) PWM fast, TOP=ICRn
  276. // desired value: 2000Hz
  277. // actual value: 2000.000Hz (0.0%)
  278. void timer1_init(void)
  279.   {
  280.    DDRB  |= (1<<PB1);        //設置OC1A-PB1為輸出
  281.    DDRB  |= (1<<PB2);        //設置OC1B-PB2為輸出
  282.    TCCR1B = 0x00; //stop
  283.    TCNT1H = 0x00; //setup
  284.    TCNT1L = 0x00;
  285.    OCR1A  = PWM_Vout_to_count(uiVout_set);
  286.    OCR1B  = PWM_Iout_to_count(uiIout_set);
  287.    ICR1H  = 0x0F;          // 12位PWM
  288.    ICR1L  = 0xFF;
  289.    TCCR1A = (1<<COM1A1)|(1<<COM1A0)|(1<<COM1B1)|(1<<COM1B0)|(1<<WGM11);    //0xF2;比較匹配置位OC1A/B
  290.    TCCR1B = (1<<WGM13)|(1<<WGM12)|(1<<CS10);       //0x19; WGM: 14) PWM fast, TOP=ICRn;內(nèi)部時鐘1分頻//start Timer
  291.   }

  292. unsigned int cal_VD(unsigned int uiAD_16sum_data)
  293.   {
  294.         uladc_data = uiAD_16sum_data;
  295.         return ((unsigned int)((uladc_data*uiVref_preset)>>14));    // 輸出ADC0的電壓值VD0=Vref*uitime2_adc0_value_sum/16/1024
  296.   }
  297.   
  298. //Watchdog initialize
  299. // prescale: 2048K
  300. void watchdog_init(void)
  301. {
  302. WDR(); //this prevents a timout on enabling
  303. WDTCR = 0x1F; //WATCHDOG ENABLED - dont forget to issue WDRs
  304. WDTCR = 0x0F; //WATCHDOG ENABLED - 看門狗定時器預分頻設為2048K,2.1S
  305. WDR();
  306. }

  307. void init_devices(void)
  308.   {
  309.    //stop errant interrupts until set up
  310.          port_init();
  311.          MCUCR = 0x00;
  312.      GICR  = 0x00;
  313.      TIMSK = 0x00; //timer interrupt sources
  314.    //all peripherals are now initialized
  315.   }
  316.   
  317. //********** ADC顯示  *************
  318. void DCpower_display(void)  
  319.   {
  320.                  lcd_write_string(0,0,"D0=    mV  D1=    mV");  // LCD顯示格式
  321.                  lcd_write_string(0,1,"D2=    mV  D3=    mV");
  322.                  //uart輸出ADC0的電壓值
  323.              uiadc0_value=cal_VD(uitime2_adc0_value_sum);    // 輸出ADC0的電壓值VD0=Vref*uitime2_adc0_value_sum/16/1024
  324.                  uint_to_ascii(uiadc0_value,s1);
  325.                  putstring("D0=");                 // uart輸出ADC0
  326.                  putstring(s1);
  327.                  putstring("mV ");
  328.                  lcd_write_string(3,0,s1);         // LCD顯示
  329.                  
  330.                  //uart輸出ADC1的電壓值
  331.              uiadc1_value=cal_VD(uitime2_adc1_value_sum);    // 輸出ADC1的電壓值VD1=Vref*uitime2_adc1_value_sum/16/1024
  332.                  uint_to_ascii(uiadc1_value,s1);
  333.                  putstring("D1=");                 // uart輸出ADC1
  334.                  putstring(s1);
  335.                  putstring("mV ");
  336.                  lcd_write_string(14,0,s1);        // LCD顯示
  337.                  
  338.                  //uart輸出ADC2的電壓值
  339.              uiadc2_value=cal_VD(uitime2_adc2_value_sum);    // 輸出ADC2的電壓值VD2=Vref*uitime2_adc2_value_sum/16/1024
  340.                  uint_to_ascii(uiadc2_value,s1);
  341.                  putstring("D2=");                 // uart輸出ADC2
  342.                  putstring(s1);
  343.                  putstring("mV ");
  344.                  lcd_write_string(3,1,s1);         // LCD顯示
  345.                
  346.                  //uart輸出ADC3的電壓值
  347.              uiadc3_value=cal_VD(uitime2_adc3_value_sum);    // 輸出ADC3的電壓值VD3=Vref*uitime2_adc3_value_sum/16/1024
  348.                  uint_to_ascii(uiadc3_value,s1);
  349.                     putstring("D3=");                 //  uart輸出ADC3
  350.                  putstring(s1);
  351.                  putstring("mV ");
  352.                  lcd_write_string(14,1,s1);        // LCD顯示

  353.                  uint_to_ascii(OCR1A,s1);             // uart輸出TIME1 比較寄存器A 的值
  354.                  putstring(" 1A=");                 // uart輸出
  355.                  putstring(s1);

  356.                  uint_to_ascii(OCR1B,s1);             // uart輸出TIME1 比較寄存器B 的值
  357.                  putstring(" 1B=");                 // uart輸出
  358.                  putstring(s1);

  359.                  ulong_to_ascii(time2_count/10,s1);  // uart輸出TIME2秒計數(shù)值
  360.                  putstring(" tn=");            // uart輸出
  361.                  putstring(s1);
  362.                  putchar('s');
  363.                  
  364.                  putchar_ENTER();                    // uart輸出回車換行
  365.   }  // *********ADC顯示  end*********

  366. /**************  數(shù)控電源相關子程序   *********************/  
  367. void DCpower(void)                              //  數(shù)控電源功能模塊
  368.   {   
  369.         //3*4鍵盤掃描
  370.         /*掃描1*/
  371.         DDRD  &=~((1<<PD3)|(1<<PD4)|(1<<PD5));  // SET1、2、3(PD3、4、5)(S12,S11,S10)三鍵輸入
  372.         PORTD |= ((1<<PD3)|(1<<PD4)|(1<<PD5));  // 置上拉電阻
  373.         PORTD &=~(1<<PD2);                      // 使SET0(PD2)腳輸出0,掃描SET1、2、3(PD3、4、5)腳
  374.         DDRD  |= (1<<PD2);
  375.         while((PIND & 0x38) != 0x38)
  376.                 {
  377.                    delay_ms(1);
  378.                    if((PIND & 0x38) == 0x30)                                   // SET1(PD3=0) S12鍵按下  PWMA電壓快速遞增
  379.                         {
  380.                                   if(uiVout_set<2451)                         // 限定電壓不超過25.00V
  381.                                    {
  382.                                          uiVout_set +=50;
  383.                                          OCR1A = PWM_Vout_to_count(uiVout_set);  // 電壓值轉換成PWMA值
  384.                                    }
  385.                                 }   
  386.                    if((PIND & 0x38) == 0x28)                                    //SET2(PD4=0) S11鍵按下  PWMA電壓快速遞減
  387.                         {
  388.                                   if(uiVout_set>49)  
  389.                                    {
  390.                                          uiVout_set -=50;
  391.                                          OCR1A = PWM_Vout_to_count(uiVout_set);  // 電壓值轉換成PWMA值
  392.                                    }
  393.                                 }
  394.                    if((PIND & 0x38) == 0x18)                          //SET3(PD5=0) S10鍵按下  ATX電源打開
  395.                         {
  396.                    power_ON();
  397.                                 }   
  398.                    delay_ms(1);
  399.                    DCpower_display();
  400.                    for(num1=0;num1<30;num1++)
  401.                      {
  402.                            if((PIND & 0x38) == 0x38)  return;
  403.                        delay_ms(10);
  404.                      }
  405.                 }
  406.        
  407.         /*掃描2*/
  408.         DDRD  &=~((1<<PD2)|(1<<PD4)|(1<<PD5));  // SET0、2、3(PD2、4、5)(S22,S21,S20)三鍵輸入
  409.         PORTD |= ((1<<PD2)|(1<<PD4)|(1<<PD5));  // 置上拉電阻
  410.         PORTD &=~(1<<PD3);                      // 使SET1(PD3)腳輸出0,掃描SET0、2、3(PD2、4、5)腳
  411.         DDRD  |= (1<<PD3);
  412.         while((PIND & 0x34) != 0x34)
  413.                 {
  414.                    delay_ms(1);
  415.                    if((PIND & 0x34) == 0x30)                                   // SET0(PD2=0) S22鍵按下  PWMA電壓慢速遞增
  416.                         {
  417.                                   if(uiVout_set<2500)                         // 限定電壓不超過25.00V
  418.                                    {
  419.                                          uiVout_set +=1;
  420.                                          OCR1A = PWM_Vout_to_count(uiVout_set);   // 電壓值轉換成PWMA值
  421.                                    }
  422.                                 }   
  423.                    if((PIND & 0x34) == 0x24)                                    //SET2(PD4=0) S21鍵按下  PWMA電壓慢速遞減
  424.                         {
  425.                                   if(uiVout_set>0)  
  426.                                    {
  427.                                          uiVout_set -=1;
  428.                                          OCR1A = PWM_Vout_to_count(uiVout_set);  // 電壓值轉換成PWM值
  429.                                    }
  430.                                 }
  431.                    if((PIND & 0x34) == 0x14)                          //SET3(PD5=0) S20鍵按下  ATX電源關閉
  432.                         {
  433.                                   power_OFF();
  434.                                 }   
  435.                    delay_ms(1);
  436.                    DCpower_display();
  437.                    for(num1=0;num1<30;num1++)
  438.                      {
  439.                            if((PIND & 0x34) == 0x34)  return;
  440.                        delay_ms(10);
  441.                      }
  442.                 }
  443.                
  444.         /*掃描3*/
  445.         DDRD  &=~((1<<PD2)|(1<<PD3)|(1<<PD5));  // SET0、1、3(PD2、3、5)(S32,S31,S30)三鍵輸入
  446.         PORTD |= ((1<<PD2)|(1<<PD3)|(1<<PD5));  // 置上拉電阻
  447.         PORTD &=~(1<<PD4);                      // 使SET2(PD4)腳輸出0,掃描SET0、1、3(PD2、3、5)腳
  448.         DDRD  |= (1<<PD4);
  449.         while((PIND & 0x2c) != 0x2c)
  450.                 {
  451.                    delay_ms(1);
  452.                    if((PIND & 0x2c) == 0x28)                                   //SET0(PD2=0) S32鍵按下  PWMB電壓快速遞增
  453.                         {
  454.                                   if(uiIout_set<3901)                         // 限定電流不超過4.000A
  455.                                    {
  456.                                          uiIout_set +=100;
  457.                                          OCR1B = PWM_Iout_to_count(uiIout_set);  // 電流值轉換成PWMB值
  458.                                    }
  459.                                 }   
  460.                    if((PIND & 0x2c) == 0x24)                                    //SET1(PD3=0) S31鍵按下  PWMB電壓快速遞減
  461.                         {
  462.                                   if(uiIout_set>99)  
  463.                                    {
  464.                                          uiIout_set -=100;
  465.                                          OCR1B = PWM_Iout_to_count(uiIout_set);  // 電流值轉換成PWMB值
  466.                                    }
  467.                                 }
  468.                    if((PIND & 0x2c) == 0x0c)                          // SET3(PD5=0) S30鍵按下 "CANCEL"鍵 當前功能退出  
  469.                         {
  470.                                   config_temp++;                              // 改變config_temp值,令config_temp!=config
  471.                                 }   
  472.                    delay_ms(1);
  473.                    DCpower_display();
  474.                    for(num1=0;num1<30;num1++)
  475.                      {
  476.                            if((PIND & 0x2c) == 0x2c)  return;
  477.                        delay_ms(10);
  478.                      }
  479.                 }

  480.         /*掃描4*/
  481.         DDRD  &=~((1<<PD2)|(1<<PD3)|(1<<PD4));  // SET0、1、2(PD2、3、4)(S42,S41,S40)三鍵輸入
  482.         PORTD |= ((1<<PD2)|(1<<PD3)|(1<<PD4));  // 置上拉電阻
  483.         PORTD &=~(1<<PD5);                      // 使SET3(PD5)腳輸出0,掃描SET0、1、2(PD2、3、4)腳
  484.         DDRD  |= (1<<PD5);
  485.         while((PIND & 0x1c) != 0x1c)
  486.                 {
  487.                    delay_ms(1);
  488.                    if((PIND & 0x1c) == 0x18)                                   // SET0(PD2=0) S42鍵按下 PWMB電壓慢速遞增
  489.                         {
  490.                                   if(uiIout_set<4000)                         // 限定電流不超過4.000A
  491.                                    {
  492.                                          uiIout_set +=1;
  493.                                          OCR1B = PWM_Iout_to_count(uiIout_set);   // 電流值轉換成PWMB值
  494.                                    }
  495.                                 }   
  496.                    if((PIND & 0x1c) == 0x14)                                    // SET1(PD3=0) S41鍵按下 PWMB電壓慢速遞減
  497.                         {
  498.                                   if(uiIout_set>0)  
  499.                                    {
  500.                                          uiIout_set -=1;
  501.                                          OCR1B = PWM_Iout_to_count(uiIout_set);   // 電流值轉換成PWMB值
  502.                                    }
  503.                                 }
  504.                    if((PIND & 0x1c) == 0x0c)                          // SET2(PD4=0) S40鍵按下  
  505.                         {
  506.                                   
  507.                                 }   
  508.                    delay_ms(1);
  509.                    DCpower_display();
  510.                    for(num1=0;num1<30;num1++)
  511.                      {
  512.                            if((PIND & 0x1c) == 0x1c)  return;
  513.                        delay_ms(10);
  514.                      }
  515.                 }
  516.    }

  517. void power_ON(void)                         // 開關電源打開
  518.   {
  519.         ATX_CTL_DDR  |= (1<<ATX_CTL);           //
  520.         ATX_CTL_PORT |= (1<<ATX_CTL);           // 置1
  521.   }  
  522. void power_OFF(void)                        // 開關電源關閉
  523.   {
  524.     ATX_CTL_DDR  |=  (1<<ATX_CTL);          //  
  525.         ATX_CTL_PORT &=~ (1<<ATX_CTL);          // 置0
  526.   }
  527. /**************  數(shù)控電源相關子程序   *************** END */  

  528.    
  529. void program_set(void)                      // 功能模塊選擇設定
  530.   {
  531.     //循環(huán)3*4鍵盤掃描
  532.    while(1)
  533.         {
  534.         /*掃描1*/
  535.         DDRD  &=~((1<<PD3)|(1<<PD4)|(1<<PD5));  // SET1、2、3(PD3、4、5)(S12,S11,S10)三鍵輸入
  536.         PORTD |= ((1<<PD3)|(1<<PD4)|(1<<PD5));  // 置上拉電阻
  537.         PORTD &=~(1<<PD2);                      // 使SET0(PD2)腳輸出0,掃描SET1、2、3(PD3、4、5)腳
  538.         DDRD  |= (1<<PD2);
  539.         while((PIND & 0x38) != 0x38)
  540.                 {
  541.                    delay_ms(1);
  542.                    if((PIND & 0x38) == 0x30)                                   //SET1(PD3=0) S12 "1"鍵按下  選擇數(shù)控電源
  543.                         {
  544.                                          config_temp = 0x10;
  545.                                 }   
  546.                    if((PIND & 0x38) == 0x28)                                    //SET2(PD4=0) S11 "5"鍵按下  
  547.                         {
  548.                                 }
  549.                    if((PIND & 0x38) == 0x18)                          //SET3(PD5=0) S10鍵按下  
  550.                         {
  551.                                 }   
  552.                    delay_ms(50);
  553.                 }
  554.        
  555.         /*掃描2*/
  556.         DDRD  &=~((1<<PD2)|(1<<PD4)|(1<<PD5));  // SET0、2、3(PD2、4、5)(S22,S21,S20)三鍵輸入
  557.         PORTD |= ((1<<PD2)|(1<<PD4)|(1<<PD5));  // 置上拉電阻
  558.         PORTD &=~(1<<PD3);                      // 使SET1(PD3)腳輸出0,掃描SET0、2、3(PD2、4、5)腳
  559.         DDRD  |= (1<<PD3);
  560.         while((PIND & 0x34) != 0x34)
  561.                 {
  562.                    delay_ms(1);
  563.                    if((PIND & 0x34) == 0x30)                                   //SET0(PD2=0) S22鍵按下  
  564.                         {
  565.                                 }   
  566.                    if((PIND & 0x34) == 0x24)                                    //SET2(PD4=0) S21鍵按下  
  567.                         {
  568.                                 }
  569.                    if((PIND & 0x34) == 0x14)                          //SET3(PD5=0) S20鍵按下  
  570.                         {
  571.                                 }   
  572.                    delay_ms(50);
  573.                 }
  574.                
  575.         /*掃描3*/
  576.         DDRD  &=~((1<<PD2)|(1<<PD3)|(1<<PD5));  // SET0、1、3(PD2、3、5)(S32,S31,S30)三鍵輸入
  577.         PORTD |= ((1<<PD2)|(1<<PD3)|(1<<PD5));  // 置上拉電阻
  578.         PORTD &=~(1<<PD4);                      // 使SET2(PD4)腳輸出0,掃描SET0、1、3(PD2、3、5)腳
  579.         DDRD  |= (1<<PD4);
  580.         while((PIND & 0x2c) != 0x2c)
  581.                 {
  582.                    delay_ms(1);
  583.                    if((PIND & 0x2c) == 0x28)                                   //SET0(PD2=0) S32鍵按下  
  584.                         {
  585.                                 }   
  586.                    if((PIND & 0x2c) == 0x24)                                    //SET1(PD3=0) S31鍵按下  
  587.                         {
  588.                                 }
  589.                    if((PIND & 0x2c) == 0x0c)                          // SET3(PD5=0) S30鍵按下 "CANCEL"鍵 當前功能退出  
  590.                         {
  591. ……………………

  592. …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼

所有資料51hei提供下載:
見2樓

評分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏5 分享淘帖 頂 踩
回復

使用道具 舉報

沙發(fā)
ID:696930 發(fā)表于 2020-10-9 10:19 | 只看該作者
ATMEGA8數(shù)控電源和電壓自動校正的C程序

ATMEGA8數(shù)控電源和電壓自動校正的C程序.zip

114.33 KB, 下載次數(shù): 60, 下載積分: 黑幣 -5

回復

使用道具 舉報

板凳
ID:81138 發(fā)表于 2021-1-29 09:05 | 只看該作者
非此專業(yè)請圖文可以嗎
回復

使用道具 舉報

地板
ID:405183 發(fā)表于 2022-12-27 11:17 來自手機 | 只看該作者
有沒有中文說明呀
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 欧美黑人国产人伦爽爽爽 | 在线免费激情视频 | 久久99网| 天天爱天天操 | 欧美久操网 | 欧美另类视频 | 亚洲成人精选 | 男人的天堂视频网站 | 亚洲一区在线日韩在线深爱 | 久久久激情视频 | 亚洲一区二区三区在线视频 | 中文字幕在线看人 | 日本高清精品 | 欧美亚洲国产一区二区三区 | 中文字幕成人av | 91久久国产综合久久91精品网站 | 成人免费毛片片v | 欧美成人精品在线观看 | 精品一区av | 一级看片| 91免费看片 | 日韩综合在线 | 亚洲欧美日韩精品久久亚洲区 | 日本在线看片 | 国产精品免费观看 | 91精品国产综合久久久久久丝袜 | 黄色日批视频 | 久久久久久久久久久高潮一区二区 | 久久久精品久 | 久久久久一区二区 | 国产精品视频在线观看 | 日本欧美国产在线观看 | 久久1区 | 99精品久久久| 精彩视频一区二区三区 | 91麻豆产精品久久久久久夏晴子 | 国产精品久久精品 | 一区二区三区四区日韩 | 日韩免费一区 | 欧美不卡视频一区发布 | 久久久综合网 |