/*******************************************************************************<br />华邦W79E833电动自行车方案程序<br /> 作者:邹工 13761016264 <a href="mailto:zou_zhi_chao@hotmail.com">zou_zhi_chao@hotmail.com</a><br />注:程序在不同的电机上表现有一些差异,有任何问题可以与我联系;<br />若需要头文件,原理图、PCB也可以和我联系。 <br />******************************************************************************/<br />#include "intrins.h"<br />#include "E_BIKE_83.H"<br />#include"W79E834.h"<br />#define Current_Max 0x700<br />/*****************************************************************************<br />* 主函数<br />******************************************************************************/<br />void main(void)<br />{<br /> Init_IO(); // 初始化端口<br /> Init(); // 初始化<br /> H_Sample(); // 霍尔信号采样<br /> EA=1;<br /> while(1)<br /> { <br /> PWM_Setting(); <br /> if(Speed_REQ)<br /> {PWM_ADJ();}<br /> EA=0;<br /> if(MotorStop_CNT > 5)<br /> { H_Sample();<br /> Phase_Change();<br /> MotorStop_CNT = 0;<br /> }<br /> EA=1; <br /> }<br />}<br />/******************************************************************************<br />* I/O端口初始化<br />******************************************************************************/<br />void Init_IO(void)<br />{<br /> P0M1=0xFC;//------P0端口设置------//<br /> P0M2=0x03;<br /> P0=0xFF;<br /> P1M1=0x1C;//------P1端口设置------//<br /> P1M2=0xC3;<br /> P1=0xFF;<br /> P2M1=0x01; //------P2端口设置------//<br /> P2M2=0x5E;<br /> P2=0xFF;<br />}<br />/******************************************************************************<br />* 初始化程序<br />******************************************************************************/<br />void Init(void)<br />{<br /> unsigned char i; <br /> PWMPH=0X03;//------PWM设置------//<br /> PWMPL=0X55;<br /> PWM0H=0X00;<br /> PWM0L=0X00;<br /> PWM1H=0X00;<br /> PWM1L=0X00; <br /> PWM2H=0X00;<br /> PWM2L=0X00; <br /> PWMCON1=0XC7; // 打开PWM电路,三个PWM口反相输出<br /> PWMCON3=0xF0;<br /> P21 = 0;<br /> UT=0;VT=0;WT=0;<br /> UB=1;VB=1;WB=1; // 电机停转<br /> while(P14==0)//-----相位检测-------//<br /> {<br /> H_Sample(); <br /> Phase_Detect(); <br /> }<br /> for (i=0;i<16;i++)//------变量初始化------//<br /> {Current_Buffer=0;}<br /> for (i=0;i<20;i++)<br /> {Speed_Buffer=0;}<br /> for (i=0;i<16;i++)<br /> {Voltage_Buffer=0;}<br /> Current_P=0;<br /> Speed_P=0;<br /> Voltage_P=0;;<br /> Speed_SUM=0;<br /> Current_SUM=0;<br /> Voltage_SUM=0;<br /> H_State=0;<br /> Old_State=0;<br /> PWM_Duty=0;<br /> Count_Current=0;<br /> Count_Speed=0;<br /> Count_Voltage=0;<br /> Speed_REQ=0;<br /> Current_REQ=0;<br /> Voltage_REQ=0;<br /> ADC_Ready=0; <br /> PWM_Duty_min=1; <br /> Motor_Speed = 0x50;<br /> Speed_Low=0x0500;<br /> TH0=0x7A;TL0=0x7A; // 设定定时器的初值 <br /> TMOD=0x22; // T0选为定时器(八位)模式2,TL0自动加载TH0中的初值<br /> CKCON&=0X00; // 定时器选择为1/12系统时钟<br /> ET0=1; // 允许定时器中断<br /> TR0=1; // 启动定时器<br /> AUXR1|=0x04; // 打开ADC电路<br /> EADC=1; // 允许ADC中断<br /> ADCCON &= 0xE7;<br /> CKCON=0x60; // Settings of Timer2 capture mode <br /> CAPCON0=0xA8;<br /> CAPCON1=0x00;<br /> T2MOD=0xF0;<br /> IE1 |= 0x80; // enable capture mode interrupt <br /> IP1H = 0x80;<br /> RCAP2L = 0x00; //自动重装载低位<br /> RCAP2H = 0x00; //自动重装载高位<br /> IE1 |= 0x40;<br /> T2CON |= 0x04;//enable timer2<br />}<br />/******************************************************************************<br />* ADC中断处理程序<br />******************************************************************************/<br />void ADC_ISR(void) interrupt 11<br />{<br /> ADC_Ready=1;<br /> ADCCON &= 0xE7;<br /> if(Current_REQ) // 电流采样<br /> { <br /> Current_REQ=0;<br /> if(Current_SUM>Current_Buffer[Current_P])<br /> Current_SUM -= Current_Buffer[Current_P];<br /> Current_Buffer[Current_P]=ADCH;<br /> Current_SUM += ADCH;<br /> Current_P++;<br /> if(Current_P>15)<br /> Current_P=0;<br /> }<br /> if(Speed_REQ) // 转把电压采样<br /> {<br /> Speed_REQ=0;<br /> if(Speed_SUM>Speed_Buffer[Speed_P])<br /> Speed_SUM-=Speed_Buffer[Speed_P];<br /> Speed_Buffer[Speed_P]=ADCH;<br /> Speed_SUM+=ADCH;<br /> Speed_P++;<br /> if(Speed_P == 14)<br /> Speed_P=0;<br /> }<br /> if(Voltage_REQ) // 电源电压采样<br /> { <br /> Voltage_REQ=0;<br /> if(Voltage_SUM>Voltage_Buffer[Voltage_P])<br /> Voltage_SUM -= Voltage_Buffer[Voltage_P];<br /> Voltage_Buffer[Voltage_P]=ADCH;<br /> Voltage_SUM += ADCH;<br /> Voltage_P++;<br /> if(Voltage_P>15)<br /> Voltage_P=0;<br /> }<br />}<br />/******************************************************************************<br />* 定时器0中断处理函数<br />******************************************************************************/<br />// ========== Interrupt Cycle: 100uS ===================<br />void T0M1_ISR(void) interrupt 1<br />{<br /> ADC_Ready=0;<br /> Current_REQ=1;<br /> Speed_REQ=0;<br /> Voltage_REQ=0;<br /> ADCCON=3;<br /> Count_Speed++;<br />if(Count_Speed>5)//17<br /> {<br /> ADCCON=1;<br /> Current_REQ=0;<br /> Speed_REQ=1;<br /> Count_Speed=0;<br /> Count_Voltage++;<br /> Current_Protect();<br /> if( Count_Voltage>20)//50<br /> {<br /> ADCCON=2;<br /> Speed_REQ=0;Voltage_REQ=1;<br /> Count_Voltage=0; <br /> } <br /> }<br /> ADCCON&=0xef;ADCCON|=0x08;<br /> EADC=1;<br /> MotorStop_CNT++;<br />}<br />/******************************************************************************<br />* 定时器2捕获模式中断处理函数<br />******************************************************************************/<br />void Timer2_ISR() interrupt 13 using 2<br />{<br /> EA = 0;<br /> Motor_Speed = TH2;<br /> TH2 = 0;<br /> TL2 = 0;<br /> MotorStop_CNT = 0;<br /> H_Sample(); // 霍尔信号采集<br /> Phase_Change(); // 相位变换<br /> EA = 1;<br />}<br />/******************************************************************************<br />* 定时器2溢出中断处理函数<br />******************************************************************************/<br />void T2_ISR() interrupt 8<br />{<br /> TF2 = 0;<br /> Motor_Speed = 0x50;<br /> Block_Detect(); // 堵转保护<br />}<br />/******************************************************************************<br />* 定时器3中断处理函数,采取捕获模式<br />******************************************************************************/<br />void H_Sample(void)<br />{<br /> CAPCON1 &= 0xF8;<br /> H1=P12;<br /> H2=P20;<br /> H3=P07;<br /> H_State=H1<<2;<br /> H_State+=H2<<1;<br /> H_State+=H3;<br />}<br />/******************************************************************************<br />* 根据电机霍尔换向信号给出相应控制信号<br />* 上桥臂:VT,UT,WT<br />* 下桥臂:VB,UB,WB<br />******************************************************************************/<br />void Phase_Change(void)<br />{<br /> if(PWM_Duty_min)<br /> { <br /> UT=0;VT=0;WT=0;<br /> UB=1;VB=1;WB=1; // 电机停转<br /> PWM_Duty_Max = 0;<br /> } <br /> else//========//<br /> {<br /> switch(H_State)<br /> {<br /> case 6: // 110,V3,V4<br /> VT=0;UT=0;VB=1;WB=1; <br /> WT=1;UB=0;<br /> break;<br /> case 2: // 010,V4,V5<br /> case 7:<br /> UT=0;WT=0;VB=1;WB=1;<br /> VT=1;UB=0;<br /> break;<br /> case 3: // 011,V5,V6 <br /> UT=0;WT=0;UB=1;VB=1;<br /> VT=1;WB=0;<br /> break;<br /> case 1: // 001,V6,V1<br /> WT=0;VT=0;UB=1;VB=1;<br /> UT=1;WB=0; <br /> break;<br /> case 5: // 101,V1,V2<br /> case 0:<br /> WT=0;VT=0;UB=1;WB=1; <br /> VB=0;UT=1;<br /> break;<br /> case 4: // 100,V2,V3<br /> UT=0;VT=0;UB=1;WB=1; <br /> WT=1;VB=0;<br /> break;<br /> case 9:<br /> UT=0;VT=0;WT=0;<br /> UB=1;VB=1;WB=1;<br /> break;<br /> default:break;<br /> }<br /> }<br />} <br />//-------检测--------//<br />void Phase_Detect(void)<br />{ <br /> WT=0;UT=0;VT=0;<br /> switch(H_State)<br /> {<br /> case 6: // 110,V3,V4<br /> UB=0;VB=1;WB=1;<br /> break;<br /> case 2: // 010,V4,V5<br /> case 7:<br /> UB=0;VB=1;WB=1;<br /> break;<br /> case 3: // 011,V5,V6<br /> UB=1;VB=1;WB=0;<br /> break;<br /> case 1: // 001,V6,V1<br /> UB=1;VB=1;WB=0;<br /> break;<br /> case 5: // 101,V1,V2<br /> case 0:<br /> UB=1;VB=0;WB=1;<br /> break;<br /> case 4: // 100,V2,V3<br /> UB=1;VB=0;WB=1;<br /> break;<br /> default:break;<br /> }<br />}<br />/******************************************************************************<br />* PWM值转换程序<br />* 将转把电压ADC值转换为PWMn的值<br />******************************************************************************/<br />void PWM_ADJ(void)<br />{<br /> if(Speed_SUM < Speed_Low)<br /> { //---没有转把电压,由Speed_Low的值决定转把电压最小值---// <br /> PWM_Duty_Max = 0;<br /> PWM_Duty_min=1; // 停转标志<br /> Block_Flag = 0; <br /> Block_CNT = 0; <br /> }<br /> else if(P14 == 1)<br /> { //---转把电压有效---// <br /> PWM_Duty_Max=Speed_SUM-Speed_Low; // 对应转把电压的最大计算值<br /> if(PWM_Duty_min)<br /> {<br /> if(!Block_Flag) PWM_Duty_min = 0; // 退出无有效转把电压状况<br /> }<br /> if(PWM_Duty_Max>0x06F0)PWM_Duty_Max = 0x06E8; // 最大值限制<br /> if(Block_Flag)PWM_Duty_Max = 0;<br /> PWM_Duty_Max=PWM_Duty_Max>>1; // 由转把电压转换为PWMn的值<br /> } <br />}<br />/******************************************************************************<br />* 电流闭环控制器<br />******************************************************************************/<br />void Current_Protect(void)<br />{<br /> if(Current_SUM < Current_Max) // 过流保护<br /> {<br /> if(PWM_Duty < PWM_Duty_Max)<br /> PWM_Duty ++; // 转把电压相对应的PWMn值缓慢增加<br /> else<br /> {<br /> if(PWM_Duty > 3)<br /> PWM_Duty --; // 转把电压相对应的PWMn值缓慢减小<br /> else<br /> PWM_Duty = 0;<br /> } <br /> }<br /> else if(Current_SUM > Current_Max+5)<br /> {<br /> if(PWM_Duty > 2)<br /> PWM_Duty -= 2;<br /> else<br /> PWM_Duty=0;<br /> }<br /> PWM_Duty_H = PWM_Duty>>8;<br /> PWM_Duty_L = (PWM_Duty & 0x0FF); // 对应PWMn的值(高、低位)<br />}<br />/******************************************************************************<br />* 堵转保护程序<br />******************************************************************************/<br />void Block_Detect(void)<br />{<br /> if(Current_SUM > Current_Max-0x1A0)<br /> { <br /> Block_CNT++; <br /> }<br /> if(Current_SUM<0x300)<br /> Block_CNT = 0;<br /> if(Block_CNT >= 10)<br /> {<br /> EA = 0;<br /> UT=0;VT=0;WT=0;<br /> UB=1;VB=1;WB=1; // 电机停转<br /> PWM_Duty_min = 1;<br /> Block_Flag = 1;<br /> PWM_Duty = 0;<br /> PWM_Duty_Max = 0;<br /> PWM_Duty_H = 0;<br /> PWM_Duty_L = 0; <br /> EA = 1;<br /> }<br />}<br />/******************************************************************************<br />* PWM设定<br />******************************************************************************/<br />void PWM_Setting(void)<br />{ <br /> PWM0H=PWM_Duty_H;<br /> PWM0L=PWM_Duty_L;<br /> PWM1H=PWM_Duty_H;<br /> PWM1L=PWM_Duty_L; <br /> PWM2H=PWM_Duty_H;<br /> PWM2L=PWM_Duty_L;<br /> PWMCON1 |= 0x40;<br />}<br />/******************************************************************************<br />******************************************************************************/
|