BJX 302A BLDC驱动器——4外设应用程序
TIMER0 产生几个固定时基,后续程序使用,一定不能等待的方式做延时。
1 void T0_IRQHandler(void) interrupt 1 2 { 3 TIMER0_CLR_INT_FLAG; //清除定时器0中断标志 4 5 //LED0 = ~LED0; //取反LED0 6 if(MotorState >= 2) //换相计时 7 { 8 SwStepCounter(); 9 } 10 Time10usFlg = 1; 11 Cnt10us++; 12 if(Cnt10us >= 100) 13 { 14 Cnt10us = 0; 15 Time1msFlg = 1; 16 Cnt1ms++; 17 if(Cnt1ms >=10) 18 { 19 Cnt1ms = 0; 20 Time10msFlg = 1; 21 Cnt10ms++; 22 if(Cnt10ms>= 10) 23 { 24 Cnt10ms = 0; 25 Time100msFlg = 1; 26 Cnt100ms++; 27 if(Cnt100ms>=10) 28 { 29 Cnt100ms = 0; 30 Time1sFlg = 1; 31 } 32 } 33 } 34 } 35 } 36
GPIO 用于检测换档键和启动按键,
1 void CheckSwIo(void) 2 { 3 if(!IoSpeed) //速度检测 S2 4 { 5 if(SwCkSpeedCnt < 5) 6 { 7 SwCkSpeedCnt++; 8 } 9 if(SwCkSpeedCnt == 3) 10 { 11 SwPuse |= 0x01; 12 //SwCkSpeedCnt 13 } 14 } 15 else 16 { 17 SwCkSpeedCnt = 0; 18 } 19 20 if(!IoStart) //启动检测 S1 21 { 22 if(SwCkStartCnt < 5) 23 { 24 SwCkStartCnt ++; 25 } 26 if(SwCkStartCnt == 3) 27 { 28 SwPuse |= 0x02; 29 } 30 } 31 else 32 { 33 SwCkStartCnt = 0; 34 } 35 }
ADC 用于获取目标通道的ADC值,采用手动触发的方式,后续的无极调速和反电动势过零点检测都要使用这个函数
1 /****************************************************************************** 2 * Function : ADC_HaveValuePro 3 * Description: 获取AD值: 连续采集10次,去掉最大最小值后均值 4 * Input : chn: 通道 5 * Output : ad_value 6 *******************************************************************************/ 7 sbit LED0 = P3^1; 8 9 u16 ADC_OneChnValue16Pro(u8 chn) 10 { 11 // u8 i; 12 u8 AD_H,AD_L; 13 u16 ad_value; 14 //u16 adsum=0; 15 //u16 admax=0x0000,admin=0xffff; 16 17 //6、选择相应信号的AD通道 18 ADCON0 &= ~(AINSL4 | 0x0F); 19 if (chn > 0x0F) 20 { 21 ADCON0 |= AINSL4 | (chn & 0x0F); 22 } 23 else 24 { 25 ADCON0 |= chn & 0x0F; 26 } 27 28 LED0 = ~LED0; 29 //for(i=0;i<10;i++) 30 //for(i=0;i<1;i++) 31 //{ 32 ADC_START; 33 while(!(DRDY)); //等待AD转换完成 34 AD_L = ADDOL; //读取AD数据 35 AD_H = ADDOH & 0x0F; 36 ADC_CLR_DRDY; 37 ad_value =(AD_H<<8)+ AD_L; 38 // 39 // if(admax<ad_value) 40 // { 41 // admax = ad_value; 42 // } 43 // else if(admin>ad_value) 44 // { 45 // admin = ad_value; 46 // } 47 // adsum+=ad_value; 48 //} 49 ADS=0; 50 51 //ad_value=(adsum-admax-admin)>>3; 52 //ad_value=(adsum-admax-admin)>>1; 53 LED0 = ~LED0; 54 55 return ad_value; 56 } 57
这个ADC采样方式使用低通滤波,可以提高ADC采样精度。
1 u16 ADC_HaveValue16Pro(u8 chn) 2 { 3 u8 i; 4 u8 AD_H,AD_L; 5 u16 ad_value; 6 u16 adsum=0; 7 u16 admax=0x0000,admin=0xffff; 8 9 //6、选择相应信号的AD通道 10 ADCON0 &= ~(AINSL4 | 0x0F); 11 if (chn > 0x0F) 12 { 13 ADCON0 |= AINSL4 | (chn & 0x0F); 14 } 15 else 16 { 17 ADCON0 |= chn & 0x0F; 18 } 19 20 LED0 = ~LED0; 21 for(i=0;i<10;i++) 22 //for(i=0;i<1;i++) 23 { 24 ADC_START; 25 while(!(DRDY)); //等待AD转换完成 26 AD_L = ADDOL; //读取AD数据 27 AD_H = ADDOH & 0x0F; 28 ADC_CLR_DRDY; 29 ad_value =(AD_H<<8)+ AD_L; 30 // 31 if(admax<ad_value) 32 { 33 admax = ad_value; 34 } 35 else if(admin>ad_value) 36 { 37 admin = ad_value; 38 } 39 adsum+=ad_value; 40 } 41 ADS=0; 42 43 ad_value=(adsum-admax-admin)>>3; 44 //ad_value=(adsum-admax-admin)>>1; 45 LED0 = ~LED0; 46 47 return ad_value; 48 }
UART 串口world类型打印程序主要用来做程序调试
1 void Uart_WriteWord(u16 dat) 2 { 3 if(UartCnt == 0) 4 { 5 fUartTxInt = 0; 6 S0BUF = (u8)(dat>>8); 7 UartCnt++; 8 } 9 else if(UartCnt == 1) 10 { 11 if(fUartTxInt) 12 { 13 fUartTxInt = 0; 14 S0BUF = (u8)(dat); 15 //UartCnt++; 16 UartCnt= 0; 17 } 18 } 19 // else if(UartCnt == 2) 20 // { 21 // if(fUartTxInt) 22 // { 23 // fUartTxInt = 0; 24 // S0BUF = (u8)(10); 25 // UartCnt= 0; 26 // } 27 // } 28 }
PWM 这用于给PWM通道赋值,输出对应目标占空比。
1 void PwmDuty(u16 u,u16 v,u16 w) 2 { 3 T2D1H = U16_HI_BYTE(u); 4 T2D1L = U16_LOW_BYTE(u); 5 T2D2H = U16_HI_BYTE(v); 6 T2D2L = U16_LOW_BYTE(v); 7 T2D3H = U16_HI_BYTE(w); 8 T2D3L = U16_LOW_BYTE(w); 9 }
这个函数用于给PWM驱动电机时换相使用,上桥输出占空比,下桥输出100%.
1 void SixStep(u8 StepValue) 2 { 3 switch(StepValue) 4 { 5 case 1: T2EN = 0;T2PWMCON1 = 0x04;T2PWMCON2 = 0x00;SET_SFR_PAGE0;P1 &= 0x1f;P1OE&=0x1f;P1 |= 0x40; P1OE |= 0x40; TIMER2_ENABLE;break; //UV pwm1 P16 6 case 2: T2EN = 0;T2PWMCON1 = 0x04;T2PWMCON2 = 0x00;SET_SFR_PAGE0;P1 &= 0x1f;P1OE&=0x1f;P1 |= 0x20; P1OE |= 0x20; TIMER2_ENABLE;break; //UW PWM1 P15 7 case 3: T2EN = 0;T2PWMCON1 = 0x00;T2PWMCON2 = 0x01;SET_SFR_PAGE0;P1 &= 0x1f;P1OE&=0x1f;P1 |= 0x20; P1OE |= 0x20; TIMER2_ENABLE;break; //VW PWM2 P15 8 case 4: T2EN = 0;T2PWMCON1 = 0x00;T2PWMCON2 = 0x01;SET_SFR_PAGE0;P1 &= 0x1f;P1OE&=0x1f;P1 |= 0x80; P1OE |= 0x80; TIMER2_ENABLE;break; //VU PWM2 P17 9 case 5: T2EN = 0;T2PWMCON1 = 0x00;T2PWMCON2 = 0x04;SET_SFR_PAGE0;P1 &= 0x1f;P1OE&=0x1f;P1 |= 0x80; P1OE |= 0x80; TIMER2_ENABLE;break; //WU PWM3 P17 10 case 6: T2EN = 0;T2PWMCON1 = 0x00;T2PWMCON2 = 0x04;SET_SFR_PAGE0;P1 &= 0x1f;P1OE&=0x1f;P1 |= 0x40; P1OE |= 0x40; TIMER2_ENABLE;break; //WV PWM3 P16 11 default : break; 12 } 13 } 14

浙公网安备 33010602011771号