2009年电赛代码
单片机源程序如下:
- #include<p30f4011.h>
- #include "oled.h"
- //配置位
- _FOSC(CSW_FSCM_OFF&XT_PLL4);
- _FWDT(0X0000);//关狗
- _FBORPOR(PBOR_OFF&MCLR_EN);
- _FGS(CODE_PROT_OFF);
- #define FCY 8000000
- #define FPWM 17050
- #define FLAG PORTDbits.RD3
- #define AN0 ADCBUF1
- #define AN1 ADCBUF2
- #define AN2 ADCBUF3
- #define AN3 ADCBUF0
- unsigned long get_hz_1=0,get_hz_2=0,get_hz_3=0,get_hz_4=0,sum_int = 0;
- unsigned int hz_flag=0,hz_count=0,change_flag = 0,change_hz_flag = 0;
- unsigned int HZ_count = 0;//用来记录0.25步进hz在数组中的位置
- float hz = 0,sum_float = 0;
- unsigned long int M = 850;
- unsigned int z0=0;//z1=99;z2 = 199;
- unsigned long sum0 = 0,sum1 = 0,sum2 = 0,sum3 = 0;//AN0-3
- unsigned long ave0 = 0,ave1 = 0,ave2 = 0,ave3 = 0;//AN0-3
- unsigned long true0 = 0,true1 = 0,true2 = 0,true3 = 0;
- unsigned int ADC_count = 0,ADC_display = 0,ADC_flag = 0;
- unsigned int timer1[201] = {
- 593,592,591,591,590,589,589,588,587,587,
- 586,585,585,584,584,583,582,582,581,580,
- 580,579,578,578,577,577,576,575,575,574,
- 573,573,572,572,571,570,570,569,569,568,
- 567,567,566,566,565,564,564,563,563,562,
- 561,561,560,560,559,558,558,557,557,556,
- 556,555,554,554,553,553,552,552,551,550,
- 550,549,549,548,548,547,546,546,545,545,
- 544,544,543,543,542,541,541,540,540,539,
- 539,538,538,537,537,536,535,535,534,534,
- 533,533,532,532,531,531,530,530,529,529,
- 528,528,527,526,526,525,525,524,524,523,
- 523,522,522,521,521,520,520,519,519,518,
- 518,517,517,516,516,515,515,514,514,513,
- 513,512,512,511,511,510,510,509,509,508,
- 508,507,507,506,506,506,505,505,504,504,
- 503,503,502,502,501,501,500,500,499,499,
- 498,498,498,497,497,496,496,495,495,494,
- 494,493,493,492,492,492,491,491,490,490,
- 489,489,488,488,488,487,487,486,486,485,
- 485,
- }; //步进0.05hz 45-55hz 201个点
- unsigned long int sin[300]={
- 0,17,35,53,71,89,106,124,142,159,
- 177,194,212,229,246,263,280,297,313,330,
- 346,363,379,395,410,426,441,457,472,487,
- 501,516,530,544,558,572,585,598,611,624,
- 637,649,661,673,685,696,708,719,729,740,
- 750,760,770,779,789,798,806,815,823,831,
- 839,846,854,860,867,873,880,885,891,896,
- 901,906,910,914,917,921,924,926,929,931,
- 932,934,934,935,935,935,934,933,932,930,
- 928,925,922,918,914,910,905,899,894,887,
- 881,873,866,857,849,840,830,820,809,798,
- 787,775,762,749,736,722,707,692,677,661,
- 645,628,611,593,575,556,538,518,499,479,
- 458,438,417,395,374,352,329,307,284,261,
- 238,215,191,168,144,120,96,72,48,24,
- 0,17,35,53,71,89,106,124,142,159,
- 177,194,212,229,246,263,280,297,313,330,
- 346,363,379,395,410,426,441,457,472,487,
- 501,516,530,544,558,572,585,598,611,624,
- 637,649,661,673,685,696,708,719,729,740,
- 750,760,770,779,789,798,806,815,823,831,
- 839,846,854,860,867,873,880,885,891,896,
- 901,906,910,914,917,921,924,926,929,931,
- 932,934,934,935,935,935,934,933,932,930,
- 928,925,922,918,914,910,905,899,894,887,
- 881,873,866,857,849,840,830,820,809,798,
- 787,775,762,749,736,722,707,692,677,661,
- 645,628,611,593,575,556,538,518,499,479,
- 458,438,417,395,374,352,329,307,284,261,
- 238,215,191,168,144,120,96,72,48,24,
- };
- void System_Init(void)
- {
- TRISD = 0x0000;
- TRISDbits.TRISD0 = 1;
- TRISDbits.TRISD1 = 1; //RD0,RD1输入捕捉
- TRISDbits.TRISD3 = 0;//flag out
- TRISB = 0x00FF;//0为输出,1为输入
- TRISBbits.TRISB4 = 0;
- TRISBbits.TRISB5 = 0;
- TRISBbits.TRISB6 = 0;
- TRISBbits.TRISB7 = 0;
- TRISBbits.TRISB8 = 0;
- //PORTB = 0x0000;
- //PWMCON1 = 0x0000;//通用IO
- TRISE = 0x0000;//设置输出
- }
- void delay_ams(int ms)//????
- {
- while(ms--)
- {
- unsigned int i;
- for(i=0;i<8000;i++);
- }
- }
- void Timer3_init()
- {
- TMR3 = 0;//定时器3计数寄存器TMR3=0
- T3CON = 0x0000;//使用内部时钟
- T3CONbits.TCKPS = 1; //预分频比为1:8
- T3CONbits.TON = 1;//打开定时器TMR3
- IEC0bits.T1IE = 0;
- }
- void init_hz() //IC1(RD0) IC2(RD1) 启用
- {
- IC1CON = 0x0043;//每1次捕捉事件中断一次,每一个上升沿捕捉一次
- IC2CON = 0x0023;
- IC1CONbits.ICTMR = 0;//选用Timer3
- IC2CONbits.ICTMR = 0;
- IFS0bits.IC1IF = 0;//清IC6中断标志
- IEC0bits.IC1IE = 1;//使能中断
- IC1CONbits.ICM = 3;
- //IPC0bits.IC1IP = 6;//设置中断优先级6
- }
- void InitPWM() //PWM
- {
-
- LATE = 0X0000 ;
- TRISE = 0X0000 ; //??RE0-RE5??????PWM1-PWM3
- PTPER = FCY / FPWM ; //20KHzPWM?? 不减1会有毛刺
- PWMCON1 = 0x0077; //PWM I/O ???????????
- //??1H ?1L ???I/0?
- SEVTCMP = PTPER ; //368*4 PWM ?????? 101110000
- PWMCON2 = 0x0F00; //????????????1?16
- OVDCON = 0XFF00; //bit 15-8 POVD4H-POVD1L? PWM ?????1 = PWMxx I/O ??????? PWM ?????
- PDC1 = 100*4 ; //PWM1 ??? 0.136(PDC1/PTPER/2)
- PDC2 = 100*4 ; //PWM2 ??? 0.136
- PDC3 = 400;
- PTCON = 0x8000 ; //??PWM????1?1????1:1???????
- //PTCON? PWM ??????? bit 7-4 PTOPS<3:0>? PWM ??????????? bit 3-2 PTCKPS<1:0>? PWM ?????????????
- //bit 1-0 PTMOD<1:0>? PWM ???????
- DTCON1bits.DTA = 0x01; //????
- // DTCON1bits.DTB =1;
- }
- void Timer1()//??????
- {
- T1CONbits.TON = 0;//?????
- T1CON = 0x0000;//???? ???1:1 ?????? FOSC/4
- T1CONbits.TSYNC = 1;//????
- IEC0bits.T1IE = 1;//??Timer1????
- INTCON1 |= 0X8000;//?????? NSTDIS?1
- IPC0bits.T1IP = 0x07;//?????7
- T1CONbits.TON = 1;//?????
- PR1 = 533;//8000000/(300*HZ);//0 7.5K 8000000/(150*hz) 150个点
- //533.33 是300点50hz的值 800是200点50hz
- }//FCY/HZ
- void ADC_Init()//
- {
- TRISBbits.TRISB0 = 1;//输入
- TRISBbits.TRISB1 = 1;//输入
- TRISBbits.TRISB2 = 1;//输入
- TRISBbits.TRISB3 = 1;//输入
- ADCON1 = 0x0000;//无符号整数格式
- ADCON1bits.SSRC = 7;//内部计数器结束采样并开始转换(自动转换)
- ADCON1bits.ASAM = 1;//采样自动 上次转换结束后开始
- ADCON2 = 0x020C;//参考电压配置AVDD,AVSS;4个采样/转换完成后产生中断
- ADCON3 = 0x1f1f; //使用系统时钟,相邻两次采样之间的时间间隔为31Tad,Tad=32Tcy
- ADCHS = 0x0003;////通道0负输入是Vref-,通道0正输入是AN3
- ADPCFGbits.PCFG3 = 0;//AN2模拟模式,禁止端口读取输入,A/D采样引脚电压
- ADPCFGbits.PCFG2 = 0;//AN2模拟模式,禁止端口读取输入,A/D采样引脚电压
- ADPCFGbits.PCFG1 = 0;//AN1模拟模式,禁止端口读取输入,A/D采样引脚电压
- ADPCFGbits.PCFG0 = 0;//AN1模拟模式,禁止端口读取输入,A/D采样引脚电压
- ADCSSL = 0x0000;//不对输入引脚扫描
- IPC2bits.ADIP = 6; //设置AD转换中断优先级为7
- IEC0bits.ADIE = 1; //使能AD转换完成中断
- ADCON1bits.ADON = 1; //启动ADC 0未启动
- }
- void delete_hz()
- {
- /****消除溢出标志****/
- if(IC1CONbits.ICOV == 1)
- {
- IC1CONbits.ICM = 0;
- while(IC1CONbits.ICBNE!=0);
- IC1CONbits.ICM = 3;
- }
- }
- void PWM_adjust(unsigned int want,unsigned int min)
- {
- if((ave0 > want+5) && (M < 1020))//普通稳压调节
- {
- M++;
- }
-
- if((ave0 < want-5) && (M > 20))
- M--;
-
- }
- int main()
- {
- System_Init();
- OLED_Init(); //初始化OLED
- OLED_Clear();
- 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电赛(汉字需要左右俩个格子)
- 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
- 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
- disn(1,3,21);disn(2,3,12);disn(8,3,22);disn(9,3,23);//f=00.00Hz
- ADC_Init();
- init_hz();
- Timer3_init();
- InitPWM();
- Timer1();
- while(1)
- {
- /**********计算hz的大小**********/
- if(hz_flag == 0)
- {
-
- hz = 1000000.0/(get_hz_2 -get_hz_1);
- sum_float = sum_float + hz;
- hz_count++;
- }
- if(hz_count==8)
- {
- hz_count = 0;
- sum_float = sum_float/8;
- sum_int = (int)(sum_float*100);//显示测量频率小数点后俩位
- disn(3,3,sum_int/1000);
- disn(4,3,sum_int/100%10);
- disn(5,3,20);
- disn(6,3,sum_int/10%10);
- disn(7,3,sum_int%10);
- HZ_count = (sum_float*100 -4500) /5 +0.5; //计算在数组中的位置,加0.5为了四舍五入
- if(HZ_count <0)
- HZ_count = 0;
- if(HZ_count >200)
- HZ_count = 200;
- change_hz_flag =1;
- sum_float = 0;
- sum_int = 0;
- }
- /********根据hz改变定时器1的值改变spwm的频率********/
- if(change_hz_flag ==1)
- {
- PR1 = timer1[HZ_count];
- change_hz_flag ==0;
- }
- /***************ADC采样的值计算*****************/
- if(ADC_flag == 0)
- {
- sum0 = sum0 + AN0;
- sum1 = sum1 + AN1;
- // sum2 = sum2 + AN2;
- // sum3 = sum3 + AN3;
- ADC_count++;
- }
- if(ADC_count==16)
- {
- ave0 = sum0>>4; //512 2.5V
- ave1 = sum1>>4;
- if((ave1 >= 135) || (M<=20 && ave0<515)) //过流保护
- {
- M = 0;
- delay_ams(1000);
- M = 100;
- //PWMCON1 = 0x0077;
- }
-
- //ave2 = sum2>>5;
- // ave3 = sum3>>5;
- ADC_count=0;
- ADC_flag=1;
- }
- if(ADC_display == 200)
- {
- ADC_display = 0;
- true0 = ave0*4.8828;
- disn(3,1,true0/1000);disn(5,1,true0/100%10);
- disn(6,1,true0/10%10);disn(7,1,true0%10);
- disn(11,3,M/100); disn(12,3,M/10%10); disn(13,3,M%10);
-
- }
- ADC_display++;
- delete_hz();
- }
- }
- void __attribute__((__interrupt__, auto_psv))_IC1Interrupt(void)
- {
- IFS0bits.IC1IF = 0;
- z0 = 5;
- if(hz_flag==0)
- {
-
- get_hz_1 = IC1BUF;
- hz_flag = 1;
- }
- else if (hz_flag == 1)
- {
- get_hz_2 = IC1BUF;
- hz_flag =0;
- TMR3= 0;
- }
- // IFS0bits.IC1IF = 0;
- }
- void __attribute__((__interrupt__, auto_psv)) _T1Interrupt(void)//功能:key调节rate和pi控制
- {
- IFS0bits.T1IF = 0;
- if(z0<150)
- {
- PDC1 = 0;
- PDC2 = ((M*sin[z0])>>10);
- z0++;
- }
- else
- {
- PDC1 = ((M*sin[z0])>>10);
- PDC2 = 0;
- z0++;
- if(z0==300) {z0=0;}
- }
-
- }
- void __attribute__((__interrupt__,no_auto_psv))_ADCInterrupt(void)//ADC 6.3Khz 4.2us PDC 调节 10.48us(加计算) 6.56
- {
- // PORTDbits.RD3 = 1;
- IFS0bits.ADIF=0; //清AD转换中断标志位
- if(ADC_flag == 1)
- {
- PWM_adjust(640,536);//3.08 3.14(5v)-643 2.616---535.75--536
- sum0 = 0;
- sum1 = 0;
- //sum2 = 0;
- //sum3 = 0;
- ADC_count=0;ADC_flag = 0;
- }
- //PORTDbits.RD3 = 0;
- }
复制代码
所有资料51hei提供下载:
guangfu.zip
(95.51 KB, 下载次数: 43)
|