找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2499|回复: 0
打印 上一主题 下一主题
收起左侧

PIC30F4011 SPWM波 光伏逆变代码 2009年电赛资料

[复制链接]
跳转到指定楼层
楼主
ID:367747 发表于 2018-7-9 10:45 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
2009年电赛代码

单片机源程序如下:
  1. #include<p30f4011.h>
  2. #include "oled.h"
  3. //配置位
  4. _FOSC(CSW_FSCM_OFF&XT_PLL4);
  5. _FWDT(0X0000);//关狗
  6. _FBORPOR(PBOR_OFF&MCLR_EN);
  7. _FGS(CODE_PROT_OFF);

  8. #define FCY 8000000
  9. #define FPWM 17050
  10. #define FLAG  PORTDbits.RD3
  11. #define AN0 ADCBUF1
  12. #define AN1 ADCBUF2
  13. #define AN2 ADCBUF3
  14. #define AN3 ADCBUF0
  15. unsigned long get_hz_1=0,get_hz_2=0,get_hz_3=0,get_hz_4=0,sum_int = 0;
  16. unsigned int hz_flag=0,hz_count=0,change_flag = 0,change_hz_flag = 0;
  17. unsigned int HZ_count = 0;//用来记录0.25步进hz在数组中的位置
  18. float hz = 0,sum_float = 0;
  19. unsigned long int M = 850;
  20. unsigned int z0=0;//z1=99;z2 = 199;
  21. unsigned long sum0 = 0,sum1 = 0,sum2 = 0,sum3 = 0;//AN0-3
  22. unsigned long ave0 = 0,ave1 = 0,ave2 = 0,ave3 = 0;//AN0-3
  23. unsigned long true0 = 0,true1 = 0,true2 = 0,true3 = 0;
  24. unsigned int  ADC_count = 0,ADC_display = 0,ADC_flag = 0;
  25. unsigned int timer1[201] = {
  26. 593,592,591,591,590,589,589,588,587,587,
  27. 586,585,585,584,584,583,582,582,581,580,
  28. 580,579,578,578,577,577,576,575,575,574,
  29. 573,573,572,572,571,570,570,569,569,568,
  30. 567,567,566,566,565,564,564,563,563,562,
  31. 561,561,560,560,559,558,558,557,557,556,
  32. 556,555,554,554,553,553,552,552,551,550,
  33. 550,549,549,548,548,547,546,546,545,545,
  34. 544,544,543,543,542,541,541,540,540,539,
  35. 539,538,538,537,537,536,535,535,534,534,
  36. 533,533,532,532,531,531,530,530,529,529,
  37. 528,528,527,526,526,525,525,524,524,523,
  38. 523,522,522,521,521,520,520,519,519,518,
  39. 518,517,517,516,516,515,515,514,514,513,
  40. 513,512,512,511,511,510,510,509,509,508,
  41. 508,507,507,506,506,506,505,505,504,504,
  42. 503,503,502,502,501,501,500,500,499,499,
  43. 498,498,498,497,497,496,496,495,495,494,
  44. 494,493,493,492,492,492,491,491,490,490,
  45. 489,489,488,488,488,487,487,486,486,485,
  46. 485,
  47. }; //步进0.05hz   45-55hz 201个点
  48. unsigned long int sin[300]={
  49. 0,17,35,53,71,89,106,124,142,159,
  50. 177,194,212,229,246,263,280,297,313,330,
  51. 346,363,379,395,410,426,441,457,472,487,
  52. 501,516,530,544,558,572,585,598,611,624,
  53. 637,649,661,673,685,696,708,719,729,740,
  54. 750,760,770,779,789,798,806,815,823,831,
  55. 839,846,854,860,867,873,880,885,891,896,
  56. 901,906,910,914,917,921,924,926,929,931,
  57. 932,934,934,935,935,935,934,933,932,930,
  58. 928,925,922,918,914,910,905,899,894,887,
  59. 881,873,866,857,849,840,830,820,809,798,
  60. 787,775,762,749,736,722,707,692,677,661,
  61. 645,628,611,593,575,556,538,518,499,479,
  62. 458,438,417,395,374,352,329,307,284,261,
  63. 238,215,191,168,144,120,96,72,48,24,
  64. 0,17,35,53,71,89,106,124,142,159,
  65. 177,194,212,229,246,263,280,297,313,330,
  66. 346,363,379,395,410,426,441,457,472,487,
  67. 501,516,530,544,558,572,585,598,611,624,
  68. 637,649,661,673,685,696,708,719,729,740,
  69. 750,760,770,779,789,798,806,815,823,831,
  70. 839,846,854,860,867,873,880,885,891,896,
  71. 901,906,910,914,917,921,924,926,929,931,
  72. 932,934,934,935,935,935,934,933,932,930,
  73. 928,925,922,918,914,910,905,899,894,887,
  74. 881,873,866,857,849,840,830,820,809,798,
  75. 787,775,762,749,736,722,707,692,677,661,
  76. 645,628,611,593,575,556,538,518,499,479,
  77. 458,438,417,395,374,352,329,307,284,261,
  78. 238,215,191,168,144,120,96,72,48,24,

  79. };

  80. void System_Init(void)
  81. {
  82.         TRISD = 0x0000;
  83.         TRISDbits.TRISD0 = 1;
  84.         TRISDbits.TRISD1 = 1; //RD0,RD1输入捕捉
  85.         TRISDbits.TRISD3 = 0;//flag out
  86.         TRISB = 0x00FF;//0为输出,1为输入
  87.         TRISBbits.TRISB4 = 0;
  88.         TRISBbits.TRISB5 = 0;
  89.         TRISBbits.TRISB6 = 0;
  90.         TRISBbits.TRISB7 = 0;
  91.         TRISBbits.TRISB8 = 0;
  92.         //PORTB = 0x0000;
  93.         //PWMCON1 = 0x0000;//通用IO
  94.         TRISE = 0x0000;//设置输出
  95. }

  96. void delay_ams(int ms)//????
  97. {
  98.     while(ms--)
  99.         {
  100.             unsigned int i;
  101.             for(i=0;i<8000;i++);
  102.         }
  103. }


  104. void Timer3_init()
  105. {
  106.     TMR3 = 0;//定时器3计数寄存器TMR3=0
  107.     T3CON = 0x0000;//使用内部时钟
  108.     T3CONbits.TCKPS = 1; //预分频比为1:8
  109.     T3CONbits.TON = 1;//打开定时器TMR3
  110.     IEC0bits.T1IE = 0;
  111. }

  112. void init_hz() //IC1(RD0)  IC2(RD1) 启用
  113. {
  114.    IC1CON = 0x0043;//每1次捕捉事件中断一次,每一个上升沿捕捉一次
  115.    IC2CON = 0x0023;
  116.    IC1CONbits.ICTMR = 0;//选用Timer3
  117.    IC2CONbits.ICTMR = 0;
  118.    IFS0bits.IC1IF = 0;//清IC6中断标志
  119.    IEC0bits.IC1IE = 1;//使能中断
  120.    IC1CONbits.ICM = 3;
  121.    //IPC0bits.IC1IP = 6;//设置中断优先级6
  122. }

  123. void InitPWM()                     //PWM
  124. {
  125.   
  126.      LATE = 0X0000 ;
  127.        TRISE = 0X0000 ;                 //??RE0-RE5??????PWM1-PWM3
  128.        PTPER = FCY / FPWM   ;            //20KHzPWM??  不减1会有毛刺
  129.        PWMCON1 = 0x0077;                   //PWM I/O ???????????
  130.        //??1H ?1L ???I/0?
  131.        SEVTCMP = PTPER ;                   //368*4  PWM ??????  101110000
  132.        PWMCON2 = 0x0F00;                   //????????????1?16
  133.        OVDCON = 0XFF00;                    //bit 15-8 POVD4H-POVD1L? PWM ?????1 = PWMxx I/O ??????? PWM ?????
  134.        PDC1 = 100*4 ;                           //PWM1 ??? 0.136(PDC1/PTPER/2)
  135.        PDC2 = 100*4 ;                           //PWM2 ??? 0.136
  136.        PDC3 = 400;
  137.        PTCON = 0x8000 ;                         //??PWM????1?1????1:1???????
  138.                                             //PTCON? PWM ???????    bit 7-4 PTOPS<3:0>? PWM ???????????     bit 3-2 PTCKPS<1:0>? PWM ?????????????
  139.                                             //bit 1-0 PTMOD<1:0>? PWM ???????
  140.        DTCON1bits.DTA = 0x01;            //????
  141.       // DTCON1bits.DTB =1;
  142. }   

  143. void Timer1()//??????
  144. {
  145.         T1CONbits.TON = 0;//?????
  146.         T1CON = 0x0000;//???? ???1:1 ?????? FOSC/4
  147.         T1CONbits.TSYNC = 1;//????
  148.         IEC0bits.T1IE = 1;//??Timer1????
  149.         INTCON1 |= 0X8000;//??????  NSTDIS?1
  150.         IPC0bits.T1IP = 0x07;//?????7
  151.         T1CONbits.TON = 1;//?????
  152.         PR1 = 533;//8000000/(300*HZ);//0 7.5K   8000000/(150*hz) 150个点   
  153.         //533.33 是300点50hz的值 800是200点50hz
  154. }//FCY/HZ

  155. void ADC_Init()//
  156. {
  157.         TRISBbits.TRISB0 = 1;//输入
  158.         TRISBbits.TRISB1 = 1;//输入
  159.         TRISBbits.TRISB2 = 1;//输入
  160.         TRISBbits.TRISB3 = 1;//输入
  161.         ADCON1 = 0x0000;//无符号整数格式
  162.         ADCON1bits.SSRC = 7;//内部计数器结束采样并开始转换(自动转换)
  163.         ADCON1bits.ASAM = 1;//采样自动 上次转换结束后开始
  164.         ADCON2 = 0x020C;//参考电压配置AVDD,AVSS;4个采样/转换完成后产生中断
  165.         ADCON3 = 0x1f1f; //使用系统时钟,相邻两次采样之间的时间间隔为31Tad,Tad=32Tcy
  166.         ADCHS = 0x0003;////通道0负输入是Vref-,通道0正输入是AN3
  167.         ADPCFGbits.PCFG3 = 0;//AN2模拟模式,禁止端口读取输入,A/D采样引脚电压
  168.         ADPCFGbits.PCFG2 = 0;//AN2模拟模式,禁止端口读取输入,A/D采样引脚电压
  169.         ADPCFGbits.PCFG1 = 0;//AN1模拟模式,禁止端口读取输入,A/D采样引脚电压
  170.         ADPCFGbits.PCFG0 = 0;//AN1模拟模式,禁止端口读取输入,A/D采样引脚电压
  171.         ADCSSL = 0x0000;//不对输入引脚扫描
  172.         IPC2bits.ADIP = 6; //设置AD转换中断优先级为7
  173.         IEC0bits.ADIE = 1; //使能AD转换完成中断
  174.         ADCON1bits.ADON = 1; //启动ADC  0未启动
  175. }

  176. void delete_hz()
  177. {
  178.      /****消除溢出标志****/
  179.    if(IC1CONbits.ICOV == 1)
  180.    {
  181.      IC1CONbits.ICM = 0;
  182.      while(IC1CONbits.ICBNE!=0);
  183.      IC1CONbits.ICM = 3;
  184.    }
  185. }
  186. void PWM_adjust(unsigned int want,unsigned int min)
  187. {

  188.              if((ave0 > want+5) && (M < 1020))//普通稳压调节
  189.              {
  190.                M++;
  191.              }
  192.        
  193.              if((ave0 < want-5) && (M > 20))
  194.                M--;
  195.    
  196. }


  197. int main()
  198. {
  199.     System_Init();
  200.     OLED_Init();                        //初始化OLED
  201.     OLED_Clear();
  202.     disn(4,0,2);disn(5,0,0);disn(6,0,1);disn(7,0,8);disn(8,0,16);disn(9,0,17);disn(10,0,18);disn(11,0,19);//2018电赛(汉字需要左右俩个格子)
  203.     disn(1,1,11);disn(2,1,12);disn(3,1,0);disn(4,1,20);disn(5,1,0);disn(6,1,0);disn(7,1,0);disn(8,1,13);//U=0.000V
  204.     disn(1,2,14);disn(2,2,12);disn(3,2,0);disn(4,2,20);disn(5,2,0);disn(6,2,0);disn(7,2,0);disn(8,2,15);//I=0.000A
  205.     disn(1,3,21);disn(2,3,12);disn(8,3,22);disn(9,3,23);//f=00.00Hz
  206.     ADC_Init();
  207.     init_hz();
  208.     Timer3_init();
  209.       InitPWM();
  210.     Timer1();
  211.     while(1)
  212.     {
  213.         /**********计算hz的大小**********/
  214.        if(hz_flag == 0)
  215.        {
  216.          
  217.             hz = 1000000.0/(get_hz_2 -get_hz_1);
  218.             sum_float = sum_float + hz;
  219.             hz_count++;
  220.            }

  221.        if(hz_count==8)
  222.        {
  223.           hz_count = 0;
  224.           sum_float = sum_float/8;
  225.           sum_int = (int)(sum_float*100);//显示测量频率小数点后俩位
  226.           disn(3,3,sum_int/1000);
  227.           disn(4,3,sum_int/100%10);
  228.           disn(5,3,20);
  229.           disn(6,3,sum_int/10%10);
  230.           disn(7,3,sum_int%10);
  231.           HZ_count = (sum_float*100 -4500) /5 +0.5;  //计算在数组中的位置,加0.5为了四舍五入
  232.           if(HZ_count <0)
  233.            HZ_count = 0;
  234.           if(HZ_count >200)
  235.            HZ_count = 200;
  236.          change_hz_flag =1;
  237.           sum_float = 0;
  238.           sum_int = 0;
  239.                 }
  240.        /********根据hz改变定时器1的值改变spwm的频率********/
  241.        if(change_hz_flag ==1)
  242.        {

  243.           PR1 = timer1[HZ_count];
  244.          change_hz_flag ==0;
  245.        }

  246.        /***************ADC采样的值计算*****************/
  247.             if(ADC_flag == 0)
  248.            {
  249.                     sum0 = sum0 + AN0;
  250.                     sum1 = sum1 + AN1;
  251.                   //  sum2 = sum2 + AN2;
  252.                   //  sum3 = sum3 + AN3;
  253.                     ADC_count++;                                                               
  254.             }
  255.             if(ADC_count==16)
  256.             {
  257.                  ave0 = sum0>>4;  //512 2.5V
  258.                           ave1 = sum1>>4;

  259.                  if((ave1 >= 135) || (M<=20 && ave0<515))   //过流保护
  260.              {      
  261.                      M = 0;
  262.                      delay_ams(1000);
  263.                       M = 100;
  264.                      //PWMCON1 = 0x0077;
  265.              }      
  266.               

  267.                          //ave2 = sum2>>5;
  268.                         // ave3 = sum3>>5;
  269.                  ADC_count=0;
  270.                  ADC_flag=1;
  271.             }

  272.            if(ADC_display == 200)
  273.            {
  274.               ADC_display = 0;
  275.             true0 = ave0*4.8828;
  276.                         disn(3,1,true0/1000);disn(5,1,true0/100%10);
  277.             disn(6,1,true0/10%10);disn(7,1,true0%10);
  278.             disn(11,3,M/100); disn(12,3,M/10%10); disn(13,3,M%10);
  279.             
  280.                   }

  281.          ADC_display++;

  282.        delete_hz();
  283.     }

  284. }


  285. void __attribute__((__interrupt__, auto_psv))_IC1Interrupt(void)
  286. {
  287.   IFS0bits.IC1IF = 0;
  288.     z0 = 5;
  289.    if(hz_flag==0)
  290.    {
  291.      
  292.      get_hz_1 = IC1BUF;
  293.      hz_flag = 1;
  294.     }
  295.    else if (hz_flag == 1)
  296.     {
  297.        get_hz_2 = IC1BUF;
  298.        hz_flag =0;
  299.         TMR3= 0;
  300.     }
  301.    // IFS0bits.IC1IF = 0;
  302. }

  303. void __attribute__((__interrupt__, auto_psv)) _T1Interrupt(void)//功能:key调节rate和pi控制
  304. {
  305.         IFS0bits.T1IF = 0;
  306.     if(z0<150)
  307.         {
  308.        PDC1 =  0;  
  309.        PDC2 =  ((M*sin[z0])>>10);
  310.        z0++;
  311.         }
  312.         else
  313.         {
  314.            PDC1 =  ((M*sin[z0])>>10);
  315.        PDC2 =  0;   
  316.        z0++;
  317.        if(z0==300) {z0=0;}
  318.         }
  319.    
  320. }

  321. void __attribute__((__interrupt__,no_auto_psv))_ADCInterrupt(void)//ADC  6.3Khz 4.2us PDC 调节 10.48us(加计算)   6.56
  322.   {
  323.           // PORTDbits.RD3 = 1;
  324.            IFS0bits.ADIF=0; //清AD转换中断标志位
  325.            if(ADC_flag == 1)
  326.            {
  327.                 PWM_adjust(640,536);//3.08 3.14(5v)-643   2.616---535.75--536
  328.                  sum0 = 0;
  329.                              sum1 = 0;
  330.                                  //sum2 = 0;
  331.                                  //sum3 = 0;
  332.                  ADC_count=0;ADC_flag = 0;
  333.            }
  334.            //PORTDbits.RD3 = 0;
  335. }
复制代码

所有资料51hei提供下载:
guangfu.zip (95.51 KB, 下载次数: 43)


评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表