电动车控制器C语言源代码
电动车控制器C语言源代码讲解
******************************************************************************/
void main(void)
{
Init(); //初始化
Init_IO(); //初始化端口
H_Sample(); //霍尔信号采样
{
Speed_Buffer[i]=0;
}
for (i=0;i<16;i++)
{
Voltage_Buffer[i]=0;
}
Current_P=0;
Speed_P=0;
Voltage_P=0;;
Speed_SUM=0;
// PWM_MAX=0;
Current_SUM=0;
Voltage_SUM=0;
H_State=0;
KS_Finish();
}
}
//***Function Set***//
if(AH_Count >= 100)
{
AutoHelp(); //自助力
AH_Count = 0;
}
if(KS_CNT >= 3000)
{
KS_CNT = 0;
Keep_Speed(); //巡航定速
}
Volt_Low(); //欠压保护
*/
while(1)
{
_nop_();
//AutoHelpEN(0,0x1AA,100);
//Keep_SpeedEN(1,0x20,6);
//Current_Lim(0xB50);
//LowVoltage_Lim(0x9B0);
//EABS_Set(0,0);
单片机控制步进电机系统(C语言源代码)
题目:单片机控制步进电机系统摘要很多工业控制设备对位移和角度的控制精度要求较高, 一般电机很难实现, 而步进电机可精确实现所设定的角度和转数。
本设计主要是运用51 单片机控制六线4相步进电机系统, 由单片机产生驱动脉冲信号, 控制步进电机以一定的转速向某一方向产生一定的转动角度。
同时能够利用单片机实现电机的正、反转及速度控制,并能在数码管上显示出相应的速度。
本文中给出了该系统设计的硬件电路,软件设计,人机交互等。
并对各个功能模块进行了详细的说明。
主要内容包括以下几个方面:单片机控制步进电机的一般原理。
电机驱动及控制的实现。
控制系统整体设计以及模块划分说明。
原理图。
代码。
关键词:单片机;步进电机;系统;驱动AbstractMany Industrial control equipment have a highly requirement in displacement and angle with control accuracy, the most motor can't carry out .but the step motor can carry out the displacement and angle that you enactmented in accuracy. This design mainly used SCM to control step motor system.The step motor is formed six lines and four phasic.Through SCM generate the drive pulse signal.Control stepper motor through a certain speed in a direction to get a certain degree of rotation angle.At the same time, It can use SCM to realization of the motor is , reverse and speed control. and showed the speed in the digital tube.In this paper, given the design of the system hardware circuit,software design, human-computer interaction and so on.and it given the details description of each functional module.the main contents include the following:(1) The general principles of signal_chip controlling step motor.(2) The realization of motor driving and controlling(3) Control system overall design and description module division(4) Schematic Diagram(5) CodeKey Words:SCM; stepper motor; system; drive目录引言41 单片机控制步进电机的一般原理41.1 步进电机41.1.1 步进电机介绍41.1.2 步进电机分类51.1.3 技术指标51.1.4 步进电机工作原理51.2 单片机72 步进电机驱动实现82.1简介82.2驱动选择83 系统硬件设计93. 1 单片机控制电机93.2 键盘93.3 显示部分10程序流程图11总结12致谢13参考文献13附录13C代码13引言目前,在工业控制生产以及仪器上应用十分广泛。
C语言实现控制电机加减速正反转(飞思卡尔C代码)
C语言实现控制电机加减速正反转(飞思卡尔C代码)用单片机控制直流电动机的正反转、加减速的程序如何用C语言写参考一下这个例子吧。
#include#defineucharunignedchar#defineuintunignedintbitPW1=P2^0;bitPW2=P2^1;//控制电机的两个输入bitaccelerate=P2^2;//调速按键bittop=P2^3;//停止按键bitleft=P2^4;//左转按键bitright=P2^5;//右转按键#defineright_turnPW1=0;PW2=1//顺时针转动#defineleft_turnPW1=1;PW2=0//逆向转动#defineend_turnPW1=1;PW2=1//停转uintt0=25000,t1=25000;//初始时占空比为50%uinta=25000;//设置定时器装载初值25m设定频率为20Hzucharflag=1;//此标志用于选择不同的装载初值uchardflag;//左右转标志ucharcount;//用来标志速度档位voidkeycan();//键盘扫描voiddelay(ucharz);voidadjut_peed();//通过调整占空比来调整速度//某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某//voidmain(){keycan();//不断扫描键盘程序,以便及时作出相应的响应}}if(flag){flag=0;end_turn;a=t0;//t0的大小决定着低电平延续时间TH0=(65536-a)/256;TL0=(65536-a)%6;//重装载初值}ele{flag=1;//这个标志起到交替输出高低电平的作用if(dflag==0){right_turn;//右转}ele{left_turn;//左转}a=t1;//t1的大小决定着高电平延续时间TH0=(65536-a)/256;TL0=(65536-a)%6;//重装载初值}}TMOD=0某01;//工作方式寄存器软件起动定时器定时器功能方式1定时器0TH0=(65536-a)/256;TL0=(65536-a)%6;//装载初值ET0=1;//开启定时器中断使能EA=1;//开启总中断TR0=0;}//某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某//voiddelay(ucharz)//在12M下延时z毫秒{ uint某,y;for(某=z;某>0;某--)for(y=110;y>0;y--);}//某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某//voidkeycan(){if(top==0){TR0=0;//关闭定时器0即可停止转动end_turn;} if(left==0){TR0=1;dflag=1;//转向标志置位则左转}if(right==0){TR0=1;dflag=0;//转向标志复位则右转}if(accelerate==0){delay(5);//延时消抖if(accelerate==0){ while(accelerate==0);//等待松手count++;if(count==1){t0=20000;t1=30000;//占空比为百分之60}if(count==2){t0=15000;t1=35000;//占空比为百分之70}if(count==3){t0=10000;t1=40000;//占空比为百分之80}if(count==4){t0=5000;t1=45000;//占空比为百分之90}if(count==5){count=0;}}}}功能特点:1)总线速度高达40MHz,CAN总线:3个1Mbp的CAN总线,兼容CAN2.0A/B;2)128KB程序Flah和8KBDataFlah,用于实现程序和数据存储,均带有错误校正码(ECC);3)可配置A/D:16通道模数转换器;可选8位10位和12位精度,3μ的转换时间4)内嵌MSCAN模块用于CAN节点应用,内嵌支持LIN协议的增强型SIC模块和SPI模块;5)4通道16位计数器,CRG时钟和复位发生器:锁相环、看门狗、实时中断;增强型捕捉定时器;6)出色的低功耗特性,带有中断唤醒功能的10,实现唤醒休眠系统的功能;7)通道PWM:8位8通道或16位4通道PWM,易于实现电机控制。
无刷直流电机调速--C语言源程序
无刷直流电机调速--C语言源程序附录1. C语言源程序:#include"stdio.h"#include"myapp.h"#include"ICETEK-VC5502-EDU.h"#include"scancode.h"#include"lcd.h"#define CTRSTATUS (*(unsigned int * )0x608000) //port8000 #define CTRLED (*(unsigned int * )0x608004) //port8004#define MCTRKEY (*(unsigned int * )0x608005) //port8005 #define CTRCLKEY (*(unsigned int * )0x608006) //port8006 #define CTRMOTORBSPEED (*(unsigned int * )0x608003)void InitMcBSP();void INTR_init( void );void InitForMotorB( void );void showparameters();void LCDPutString(unsigned int * pData,int x,int y,unsigned int nCharNumber,unsigned color);void PIDControl(int rk,int yk);void PrintParameters();//定时器分频参数#define T100 99 // 100个时钟周期中断一次#define T2Hz 20000 // 20000个时钟周期读取速度一次//工作变量usigned int uWork,uN,nCount,nCount1,nCount2,nCount3,nCount4;int nSSS,nJSSpeed,pwm1;int md,wc;unsigned int nScreenBuffer[30*128];float a=0.6f,b=0.2f,c=0.1f,duk;int ek,ek1,ek2,tz;int nInput;unsigned int *www=(unsigned int *)0x608003;Int m_nSpeed,m_bPCSet;// 主函数main(){unsigned char ccc;int speed[100],sp,lj;float ljh;int i,w1,w2,w3;unsigned int uWork1;unsigned int bWork1,*pWork;int breakflage;// 初始化工作变量for ( sp=0;sp<100;sp++ )speed[sp]=0;for ( sp=0;sp<1024;sp++ ) nScreenBuffer[sp]=0;sp=nSSS=nCount=nCount1=nCount2=nCount3=nCount4= nJSSpeed=0;nInput=tz=wc =0;ek=ek1=ek2=0;uN=40;md=70;pwm1=60;m_nSpeed=70;m_bPCSet=0;inputspeed=0;uWork1=0;breakflage=0;initemif();CLK_init();*(int*)0x400001=1;CREG=1; //使能外部总线接口InitCTR();CTRGR=0x80;CTRGR=0;CTRGR=0x80;LCDTurnoff();// 设置显示参数和内容LCDSetDelay(1); //设置延时等待参数LCDSetScreenBuffer(nScreenBuffer); // 显示缓冲区for (bWork=0,pWork=nScreenBuffer;bWork<30*128;bWork++,pWork++) (*pWork=0)LCDTurnOn();//打开显示LCDCLS();//清除显示内存LCDPutCString(str1,0,127,8,0);LCDPutCString(str2,0,111,2,1);LCDPutCString(str3,68,111,2,1);LCDPutCString(str4,68,79,2,1);LCDPutCString(str5,68,95,2,1);LCDPutCString(str6,0,95,2,1);LCDPutCString(str7,0,79,3,1);ShowParamctors();//参数显示InitMcBSP();INTR-init();InitForMotorB();While(!breakflage){if(nCount==0) //读取键盘标志{uWork=MCTRKEY;CTRCLKEY=0;Switch(uWork1){Casc 128;if(inputspecd!=0){Md=inputspecd;Inputspecd=0;LCDPutCString(numbers+104,104,79,1,1); LCDPutCString(numbers+104,112,79,1,1); LCDPutCString(numbers+104,120,79,1,1); LCDRefreshScreen();}break;case 64;breakflage=1;case 1;inputspeed=inputspeed+1break;case 2;inputspeed=inputspeed-1;break;case 4;inputspeed=inputspeed+10;break;case 8;inputspeed=inputspeed-10;break;}if(inputspeed>90){inputspeed=90;}if(inputspeed<0){inputspeed=0;}w1=inputspeed%1000/100;w2=inputspeed%100/10;w3=in putspeed%10; LCDPutString(numbers+w1*8,104,79,1,1);LCDPutString(numbers+w2*8,112,79,1,1);LCDPutString(numbers+w3*8,120,79,1,1);LCDRefreshScreen();}if(m-bPCSet){m-bPCSst=0;if (m-nSpeed>=0&&m-nSpeed<256){md=m-nSpeed;LCDPutCString(numbers+104,104,79,1,1); LCDPutCString(numbers+104,112,79,1,1);LCDPutCString(numbers+104,120,79,1,1); LCDRefreshScreen();printparameters();}}if(nJSSpeed==0) //读取速度标志{LED=1;nJSSpeed=0;ccc=CTRMOTORBSPEED; //读取端口速度计数ccc=ccc&0xff;nSSS=ccc;if(nSSS>=0 && nSSS<400) //合法性检测{speed(sp)=Nssssp++;sp%=33;}if(sp==0) //读取实际速度{lj=0;ljh=0;for(i=0;i<33;i++){if(speed(i)>=0&&speed(i)<400){ljh+=speed(i);lj++;}}nCount3++;nCount3%=3;if(nCount3==2){PIDControl(md,wc); //调用PID算法控制程序uN=100-pwml; //利用占空比调整控制Showparameters(); //显示各参数到LCD }CloseCTR();exit(0);}//PID算法控制子程序void PIDControl(int rk,int yk){ek=rk-yk;duk=a*ek+b*ek1+c*ek2; //计算控制输出ek2=ek1; ek1=ek;tz=(int)duk;pwm1+=tz; //计算当前占空比if(pwml<0) pwml=0;else if(pwml>99) pwml=99;}void interrupt Timer(){uWork=PCR1; //pwml输出if(nCont1>u N){uWork=4; //根据占空比设置FSR状态}else{uWork&=0x0fffb;}PCR1=uWork;//设置中断控制寄存器void INTR-init(void){asm(“BSET INTM”);IVPD=0x01;IVPH=0x01;IERO=0x10;DBIERO=0x10;IFRO=0xffff;asm(“BCLR INTM”);}void InitForMotorB(void)ioport unsigned int *GPTCTL1-0;ioport unsigned int *GPTPRD1-0;ioport unsigned int *GPTGCTL1-0;*GPTCTL1-0=0;*GPTPRD1-0=0x1d8;*GPTGCTL1-0=0x3;}//显示参数到LCDvoid ShowParameters(){int w1,w2,w3;w1=md%1000/100;w2=md%100/10,w3=md%10; LCDPutString(numbers+w1*8,36,111,1,1); LCDPutString(numbers+w2*8,44,111,1,1); LCDPutString(numbers+w3*8,52,111,1,1);if (ek>=0){LCDPutString(numbers+88,36,95,1,1);w3=((int)ek)%100;}else{LCDPutString(numbers+96,36,95,1,1);w3=((int)(-ek))%100;}for (j=0;j<16;j++,k<<=1){if (color==2) mcolor=2;elsemcolor=(pData(1*8+i)&k)(1):(0);if(color==0) mcolor=1-mcolor;}LCDPutPixel(x+1*8+I,y-j,mcolor);}int wwss;void PrintParameters(){wwcc=wc-md;printf(“测速(%3d) 设置(%3d) 误差(%+4d) PID调整量(%+3d) 占空比(%3d%%)\n”,wc,md,wwcc,tz,pwm1);}。
C语言程序单片机控制的电动自行车驱动系统
第14章单片机控制的电动自行车驱动系统14.4.4 C语言程序#include <pic.h>//电动车双闭环程序,采用双闭环方式控制电机,以得到最好的zh转速性能,并且可以//限制电机的最大电流。
本应用程序用到两个CCP部件,其中CCP1用于PWM输出,以控//制电机电压;CCP2用于触发AD,定时器TMR2、TMR1,INT中断,RB口电平变化中断,//看门狗以及6个通用I/O口#define AND 0xe0 //状态采集5,6,7位#define CURA 0X0a //电流环比例和积分系数之和#define CURB 0X09 //电流环比例系数#define THL 0X6400 //电流环最大输出#define FULLDUTY 0X0FF //占空比为1时的高电平时间#define SPEA 0X1d //转速环比例和积分系数之和#define SPEB 0X1c //转速环比例系数#define GCURHILO 0X0330 //转速环最大输出#define GCURH 0X33 //最大给定电流#define GSPEH 0X67 //最大转速给定#define TSON 0X38 //手柄开启电压1.1 V,TSON*2为刹车后手柄开启电压,即 //2.2 V#define VOLON 0X4c //低电压保护重开电压3.0 V即33 V#define VOLOFF 0X49 //低电压保护关断电压2.86 V即31.5 Vvolatile unsigned char DELAYH,DELAYL,oldstate,speed,speedcount,tsh,count_ts,count_vol,gcur,currenth,voltage; //寄存器定义static bit sp1,spe,ts,volflag,spepid,lowpower,off,shutdown,curpid; //标志位定义static volatile unsigned char new[10]={0xaf,0xbe,0xff,0x7e,0xcf, 0xff,0xd7,0x77,0xff,0xff}; //状态寄存器表//------------PIC16F877初始化子程序------------void INIT877(){PORTC=0X0FF; //关断所有MOSFETTRISC=0X02; //设置C口输出PIE1=0X00; //中断寄存器初始化,关断所有中断TRISA=0XCF; //设置RA4,RA5 输出TRISB=0XEF; //RB 口高三位输入,采集电机三相的霍尔信号PORTC=new[(PORTB&AND)>>5]; //采集第一次霍尔信号,并输出相应的信号,导通//两个MOS管T2CON=0X01; //TMR2 4分频CCPR1L=0X0FF; //初始时PWM输出全高CCP1CON=0X0FF; //CCP1设置为PWM方式CCP2CON=0X0B; //CCP2设置为特殊方式,以触发ADADCON0=0X81; //AD时钟为32分频,且AD使能,选择AN0通道采集手//柄电压TMR2=0X00; //TMR2寄存器初始化TMR1H=0X00; //TMR1寄存器初始化TMR1L=0X00;T1CON=0X00; //TMR1为1分频CCPR2H=0X08;CCPR2L=0X00; //电流采样周期设置为T AD=512 μsPR2=0XC7; //PWM频率设置为5 kHzADCON1=0X02; //AD结果左移OPTION=0XFB; //INT上升沿触发TMR2ON=1; //PWM开始工作INTCON=0XD8; //中断设置GIE=1,PEIE=1,RBIE=1ADIE=1; //AD中断使能speedcount=0x00; //转速计数寄存器speed=0x7f; //转速保持寄存器spe=1; //低速标志位sp1=1; //低速标志位oldstate=0x0ff; //初始状态设置,区别于其他状态count_ts=0x08; //电流采样8次,采集1次手柄count_vol=0x00; //采样256次手柄,采集1次电池电压ts=1; //可以采集手柄值的标志位ADGO=1; //AD采样使能TMR1ON=1; //CCP2部件开始工作}//------------延时子程序---------------#pragma interrupt_level 1void DELAY1(x)char x;{DELAYH=x; //延时参数设置#asmDELAY2 MOVLW 0X06MOVWF _DELAYLDELAY1 DECFSZ _DELAYLGOTO DELAY1DECFSZ _DELAYHGOTO DELAY2#endasm}//-----------状态采集子程序----------------------void sample(){char state1,state2,state3,x;do {x=1;state1=(PORTB&AND); //霍尔信号采集DELAY1(x);state2=(PORTB&AND);}while(state1-state2); //当三次采样结果不相同时继续采集状态if(state1-oldstate!=0) //看本次采样结果是否与上次相同,不同//则执行{oldstate=state1; //将本次状态设置为旧状态state1=(oldstate>>5);PORTC=new[state1]; //C口输出相应的信号触发两个MOS管 if(sp1==1){spe=1;sp1=0;}else { //如果转速很低,则spe置1spe=0;sp1=0;speedcount<<=1;state3=(TMR1H>>2); //否则,spe=0,计转速speed=speedcount+state3; //speed寄存器为每256 μs加1}speedcount=0;}}//-----------------AD采样子程序----------------------void AD(){char x;ADIF=0; //清AD中断标志位if(ts==1){ //如果为手柄采样,则采样手柄值CHS0=1; //选择电流采样通道count_vol=count_vol+1; //电池采样计数寄存器spepid=1; //置转速闭环运算标志ts=0;tsh=ADRESH; //存手柄值if(count_vol==0) { //如果电池采样时间到,则选择AN2通道,采集电池电压CHS0=0;CHS1=1;volflag=1;x=1;DELAY1(x);ADGO=1;}}else if(volflag==1) { //电池采样完毕,进行相应的处理CHS1=0;CHS0=1;volflag=0;voltage=ADRESH;lowpower=1;}else { //否则,中断为采样电流中断speedcount=speedcount+1; //speedcount寄存器加1,作为测量转速用if(speedcount>0x3d) sp1=1; //如果转速低于1 000 000 μs/(512 μs*3eh*3) // 则认为为低速状态currenth=ADRESH;curpid=1;count_ts=count_ts-1;if(count_ts==0) { //如果手柄时间到,则转入手柄采样通道CHS0=0;count_ts=0x08;ts=1;x=1;DELAY1(x);ADGO=1;}}}//-------------刹车处理子程序------------------void BREAKON(){char x;off=0; //off清零,如果是干扰则不复位shutdown=0;if(RB0==1) { //如果刹车信号为真,则停止输出电压ADIE=0; //关AD中断INTE=0; //关刹车中断CCPR1L=FULLDUTY; //输出电压0TMR1ON=0; //关CCP2,不再触发ADfor(;ADGO==1;) continue;//如正在采样,则等待采样结束ADIF=0; //ADIF位清零CHS0=0; //选择通道0采样手柄CHS1=0;x=1;DELAY1(x);do {ADGO=1;for(;ADIF==0;)continue;ADIF=0;CCPR1L=FULLDUTY;asm("CLRWDT");tsh=(ADRESH>>1);}while(tsh>TSON||RB0==1); //当手柄值大于2.2 V或刹车仍旧继续时,执行以 //上语句off=1; //置复位标志}}//---------欠保护子程序-------------------void POWER(){char x;lowpower=0;voltage>>=1; //电压值换为7位,以利于单字节运算if(voltage<VOLOFF) { //电池电压小于3*k(V)时保护ADIE=0;INTE=0;TMR1ON=0;CCPR1L=FULLDUTY;for(;ADGO==1;)continue;ADIF=0;CHS0=0;CHS1=1;x=1;DELAY1(x);do{ADGO=1;for(;ADIF==0;)continue;ADIF=0;voltage=(ADRESH>>1);CCPR1L=FULLDUTY;asm("CLRWDT");}while(voltage<VOLON); //电池电压小于35 V时继续保护off=1; //置复位标志}}//------------电流环运算子程序-----------------void CURPI(){ static int curep=0x00,curek=0x00,curuk=0x00;union data{int pwm;char a[2];}b; //定义电流环运算寄存器curpid=0; //清电流运算标志curep=curek*CURB; //计算上一次偏差与比例系数的积if(currenth<2)currenth=2; //如果采样电流为零,则认为有一个小电流以利于//使转速下降currenth>>=1;curek=gcur-currenth; //计算本次偏差curuk=curuk+curek*CURA-curep; //按闭环PI运算方式得到本次输出结果,下//面对结果进行处理if(curuk<0x00) { //如果输出小于零,则认为输出为零curuk=0;CCPR1L=FULLDUTY;CCP1X=0;CCP1Y=0;}else if(curuk-THL>=0) {//如果输出大于限幅值,则输出最大电压curuk=THL;CCPR1L=0;CCP1X=0;CCP1Y=0;}else { //否则,按比例输出相应的高电平时间到CCPR1寄存器b.pwm=THL-curuk;b.pwm<<=1;CCPR1L=b.a[1]; //CCPR1L=(b.pwm>>8)&0x0ff;将PWM寄存器的高半字节if(b.pwm&0x80!=0) CCP1X=1;else CCP1X=0;if(b.pwm&0x40!=0) CCP1Y=1;else CCP1Y=0;}}//---------------转速环运算子程序-----------------------void SPEPI(){ static int speep=0x00,speek=0x00,speuk=0x00;int tsh1,speed1; //转速寄存器定义spepid=0; //清转速运算标志if(spe==1) speed1=0x00; //若转速太低,则认为转速为零else speed1=0x7f-speed; //否则计算实际转速if(speed1<0) speed1=0;speep=speek*SPEB;tsh1=tsh-0x38; //得到计算用的手柄值speek=tsh1-speed1;if(tsh1<0) {speuk=0;gcur=0;} //当手柄值低于1.1 V时,则认为手柄给定为零else { //否则,计算相应的转速环输出if(tsh1>=GSPEH) //限制最大转速tsh1=GSPEH;speuk=speuk+speek*SPEA-speep; //计算得转速环输出if(speuk<=0X00) {speuk=0x00;gcur=0x00;}//转速环输出处理else if(speuk>GCURHILO) { //转速环输出限制,即限制最大电流约12 A speuk=GCURHILO;gcur=GCURH;}else { //调速状态时的输出gcur=(speuk>>4)&0x0ff;}}}//-----------主程序-------------------------main(){for(;;){INIT877(); //单片机复位后,先对其进行初始化off=0; //清复位标志for(;off==0;) { //复位标志为零,则执行下面程序,否则复位if(curpid==1) CURPI(); //电流PI运算else if(spepid==1) SPEPI(); //转速PI运算else if(lowpower==1) POWER();else if(shutdown==1) BREAKON();asm("CLRWDT");}}}//---------中断服务子程序---------------------#pragma interrupt_level 1void interrupt INTS(void){if(RBIF==1) {RBIF=0;sample();}else if(ADIF==1) AD();else if(INTF==1) {shutdown=1;INTF=0;} //刹车中断来,置刹车标志}。
C51万能学习型遥控器源程序
#define SEND5P22
#define SEND6P21
#define SEND7P20
#define SEND8P11
#define SEND9P12
#define SEND10P13
#define SEND11P14
#define SEND12P15
#define SEND13P16
temp=SBUF;
if((temp>=0xe0)&&(temp<=0xef))
{
device=temp%16;
r_device=1;
}
else
order=temp;
RI=0;
}
}
void open_scon()
{
SCON=0x40;
REN=1;
void write8(unsigned char d);
unsigned char read(unsigned int addr);
unsigned char read0(unsigned char addr);
void write0(unsigned char addr,unsigned char x);
void send_sharp();
void send_rec();
void rec(unsigned char key);
intcode y=10700;
unsigned char code mask[8]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
void delay(unsigned int x);
电动车C语言讲解
第14章单片机控制的电动自行车驱动系统14.4.4 C语言程序#include <pic.h>//电动车双闭环程序,采用双闭环方式控制电机,以得到最好的zh转速性能,并且可以//限制电机的最大电流。
本应用程序用到两个CCP部件,其中CCP1用于PWM输出,以控//制电机电压;CCP2用于触发AD,定时器TMR2、TMR1,INT中断,RB口电平变化中断,//看门狗以及6个通用I/O口#define AND 0xe0 //状态采集5,6,7位#define CURA 0X0a //电流环比例和积分系数之和#define CURB 0X09 //电流环比例系数#define THL 0X6400 //电流环最大输出#define FULLDUTY 0X0FF //占空比为1时的高电平时间#define SPEA 0X1d //转速环比例和积分系数之和#define SPEB 0X1c //转速环比例系数#define GCURHILO 0X0330 //转速环最大输出#define GCURH 0X33 //最大给定电流#define GSPEH 0X67 //最大转速给定#define TSON 0X38 //手柄开启电压1.1 V,TSON*2为刹车后手柄开启电压,即 //2.2 V#define VOLON 0X4c //低电压保护重开电压3.0 V即33 V#define VOLOFF 0X49 //低电压保护关断电压2.86 V即31.5 Vvolatile unsigned char DELAYH,DELAYL,oldstate,speed,speedcount,tsh,count_ts,count_vol,gcur,currenth,voltage; //寄存器定义static bit sp1,spe,ts,volflag,spepid,lowpower,off,shutdown,curpid; //标志位定义static volatile unsigned char new[10]={0xaf,0xbe,0xff,0x7e,0xcf, 0xff,0xd7,0x77,0xff,0xff}; //状态寄存器表//------------PIC16F877初始化子程序------------void INIT877(){PORTC=0X0FF; //关断所有MOSFETTRISC=0X02; //设置C口输出PIE1=0X00; //中断寄存器初始化,关断所有中断TRISA=0XCF; //设置RA4,RA5 输出TRISB=0XEF; //RB 口高三位输入,采集电机三相的霍尔信号PORTC=new[(PORTB&AND)>>5]; //采集第一次霍尔信号,并输出相应的信号,导通//两个MOS管T2CON=0X01; //TMR2 4分频CCPR1L=0X0FF; //初始时PWM输出全高CCP1CON=0X0FF; //CCP1设置为PWM方式CCP2CON=0X0B; //CCP2设置为特殊方式,以触发ADADCON0=0X81; //AD时钟为32分频,且AD使能,选择AN0通道采集手//柄电压TMR2=0X00; //TMR2寄存器初始化TMR1H=0X00; //TMR1寄存器初始化TMR1L=0X00;T1CON=0X00; //TMR1为1分频CCPR2H=0X08;CCPR2L=0X00; //电流采样周期设置为T AD=512 μsPR2=0XC7; //PWM频率设置为5 kHzADCON1=0X02; //AD结果左移OPTION=0XFB; //INT上升沿触发TMR2ON=1; //PWM开始工作INTCON=0XD8; //中断设置GIE=1,PEIE=1,RBIE=1ADIE=1; //AD中断使能speedcount=0x00; //转速计数寄存器speed=0x7f; //转速保持寄存器spe=1; //低速标志位sp1=1; //低速标志位oldstate=0x0ff; //初始状态设置,区别于其他状态count_ts=0x08; //电流采样8次,采集1次手柄count_vol=0x00; //采样256次手柄,采集1次电池电压ts=1; //可以采集手柄值的标志位ADGO=1; //AD采样使能TMR1ON=1; //CCP2部件开始工作}//------------延时子程序---------------#pragma interrupt_level 1void DELAY1(x)char x;{DELAYH=x; //延时参数设置#asmDELAY2 MOVLW 0X06MOVWF _DELAYLDELAY1 DECFSZ _DELAYLGOTO DELAY1DECFSZ _DELAYHGOTO DELAY2#endasm}//-----------状态采集子程序----------------------void sample(){char state1,state2,state3,x;do {x=1;state1=(PORTB&AND); //霍尔信号采集DELAY1(x);state2=(PORTB&AND);}while(state1-state2); //当三次采样结果不相同时继续采集状态if(state1-oldstate!=0) //看本次采样结果是否与上次相同,不同//则执行{oldstate=state1; //将本次状态设置为旧状态state1=(oldstate>>5);PORTC=new[state1]; //C口输出相应的信号触发两个MOS管 if(sp1==1){spe=1;sp1=0;}else { //如果转速很低,则spe置1spe=0;sp1=0;speedcount<<=1;state3=(TMR1H>>2); //否则,spe=0,计转速speed=speedcount+state3; //speed寄存器为每256 μs加1}speedcount=0;}}//-----------------AD采样子程序----------------------void AD(){char x;ADIF=0; //清AD中断标志位if(ts==1){ //如果为手柄采样,则采样手柄值CHS0=1; //选择电流采样通道count_vol=count_vol+1; //电池采样计数寄存器spepid=1; //置转速闭环运算标志ts=0;tsh=ADRESH; //存手柄值if(count_vol==0) { //如果电池采样时间到,则选择AN2通道,采集电池电压CHS0=0;CHS1=1;volflag=1;x=1;DELAY1(x);ADGO=1;}}else if(volflag==1) { //电池采样完毕,进行相应的处理CHS1=0;CHS0=1;volflag=0;voltage=ADRESH;lowpower=1;}else { //否则,中断为采样电流中断speedcount=speedcount+1; //speedcount寄存器加1,作为测量转速用if(speedcount>0x3d) sp1=1; //如果转速低于1 000 000 μs/(512 μs*3eh*3) // 则认为为低速状态currenth=ADRESH;curpid=1;count_ts=count_ts-1;if(count_ts==0) { //如果手柄时间到,则转入手柄采样通道CHS0=0;count_ts=0x08;ts=1;x=1;DELAY1(x);ADGO=1;}}}//-------------刹车处理子程序------------------void BREAKON(){char x;off=0; //off清零,如果是干扰则不复位shutdown=0;if(RB0==1) { //如果刹车信号为真,则停止输出电压ADIE=0; //关AD中断INTE=0; //关刹车中断CCPR1L=FULLDUTY; //输出电压0TMR1ON=0; //关CCP2,不再触发ADfor(;ADGO==1;) continue;//如正在采样,则等待采样结束ADIF=0; //ADIF位清零CHS0=0; //选择通道0采样手柄CHS1=0;x=1;DELAY1(x);do {ADGO=1;for(;ADIF==0;)continue;ADIF=0;CCPR1L=FULLDUTY;asm("CLRWDT");tsh=(ADRESH>>1);}while(tsh>TSON||RB0==1); //当手柄值大于2.2 V或刹车仍旧继续时,执行以 //上语句off=1; //置复位标志}}//---------欠保护子程序-------------------void POWER(){char x;lowpower=0;voltage>>=1; //电压值换为7位,以利于单字节运算if(voltage<VOLOFF) { //电池电压小于3*k(V)时保护ADIE=0;INTE=0;TMR1ON=0;CCPR1L=FULLDUTY;for(;ADGO==1;)continue;ADIF=0;CHS0=0;CHS1=1;x=1;DELAY1(x);do{ADGO=1;for(;ADIF==0;)continue;ADIF=0;voltage=(ADRESH>>1);CCPR1L=FULLDUTY;asm("CLRWDT");}while(voltage<VOLON); //电池电压小于35 V时继续保护off=1; //置复位标志}}//------------电流环运算子程序-----------------void CURPI(){ static int curep=0x00,curek=0x00,curuk=0x00;union data{int pwm;char a[2];}b; //定义电流环运算寄存器curpid=0; //清电流运算标志curep=curek*CURB; //计算上一次偏差与比例系数的积if(currenth<2)currenth=2; //如果采样电流为零,则认为有一个小电流以利于//使转速下降currenth>>=1;curek=gcur-currenth; //计算本次偏差curuk=curuk+curek*CURA-curep; //按闭环PI运算方式得到本次输出结果,下//面对结果进行处理if(curuk<0x00) { //如果输出小于零,则认为输出为零curuk=0;CCPR1L=FULLDUTY;CCP1X=0;CCP1Y=0;}else if(curuk-THL>=0) {//如果输出大于限幅值,则输出最大电压curuk=THL;CCPR1L=0;CCP1X=0;CCP1Y=0;}else { //否则,按比例输出相应的高电平时间到CCPR1寄存器b.pwm=THL-curuk;b.pwm<<=1;CCPR1L=b.a[1]; //CCPR1L=(b.pwm>>8)&0x0ff;将PWM寄存器的高半字节if(b.pwm&0x80!=0) CCP1X=1;else CCP1X=0;if(b.pwm&0x40!=0) CCP1Y=1;else CCP1Y=0;}}//---------------转速环运算子程序-----------------------void SPEPI(){ static int speep=0x00,speek=0x00,speuk=0x00;int tsh1,speed1; //转速寄存器定义spepid=0; //清转速运算标志if(spe==1) speed1=0x00; //若转速太低,则认为转速为零else speed1=0x7f-speed; //否则计算实际转速if(speed1<0) speed1=0;speep=speek*SPEB;tsh1=tsh-0x38; //得到计算用的手柄值speek=tsh1-speed1;if(tsh1<0) {speuk=0;gcur=0;} //当手柄值低于1.1 V时,则认为手柄给定为零else { //否则,计算相应的转速环输出if(tsh1>=GSPEH) //限制最大转速tsh1=GSPEH;speuk=speuk+speek*SPEA-speep; //计算得转速环输出if(speuk<=0X00) {speuk=0x00;gcur=0x00;}//转速环输出处理else if(speuk>GCURHILO) { //转速环输出限制,即限制最大电流约12 A speuk=GCURHILO;gcur=GCURH;}else { //调速状态时的输出gcur=(speuk>>4)&0x0ff;}}}//-----------主程序-------------------------main(){for(;;){INIT877(); //单片机复位后,先对其进行初始化off=0; //清复位标志for(;off==0;) { //复位标志为零,则执行下面程序,否则复位if(curpid==1) CURPI(); //电流PI运算else if(spepid==1) SPEPI(); //转速PI运算else if(lowpower==1) POWER();else if(shutdown==1) BREAKON();asm("CLRWDT");}}}//---------中断服务子程序---------------------#pragma interrupt_level 1void interrupt INTS(void){if(RBIF==1) {RBIF=0;sample();}else if(ADIF==1) AD();else if(INTF==1) {shutdown=1;INTF=0;} //刹车中断来,置刹车标志}。
车身控制器代码源码
车身控制器代码源码#include <stdio.h>//定义常量#define MAX_STEERING_ANGLE 90#define MAX_SPEED_VALUE 5//声明函数void initialize_car_controllers(; // 初始化车身控制器void move_car_forward(int speed); // 前进void move_car_backwards(int speed); // 后退void steer_car(int steering_angle); // 方向调节//定义枚举变量enumSTEER_LEFT=-1,STEER_CENTER=0,STEER_RIGHT=1};//全局变量int steering_angle; // 方向角度int speed_value; // 速度值/************************************************ *功能:车身控制器的初始化*说明:将控制器的方向和速度设置为初始值*参数:无*返回值:无************************************************/ void initialize_car_controllersspeed_value = 0;steering_angle = STEER_CENTER;/************************************************ *功能:车辆前进操作* 说明:按<speed>的速度前进* 参数:speed From 0 to MAX_SPEED_VALUE*返回值:无************************************************/ void move_car_forward(int speed)if (speed < 0 , speed > MAX_SPEED_VALUE)printf("invalid speed value\n");return;}speed_value = speed;printf("moving car forward at speed %d\n", speed_value); /*************************************************功能:车辆后退操作* 说明:按<speed>的速度后退* 参数:speed From 0 to MAX_SPEED_VALUE*返回值:无************************************************/void move_car_backwards(int speed)if (speed < 0 , speed > MAX_SPEED_VALUE)printf("invalid speed value\n");return;}speed_value = -speed;printf("moving car backwards at speed %d\n", speed_value); /*************************************************功能:车辆调节操作*说明:调整方向角度* 参数:steering_angle From -MAX_STEERING_ANGLE toMAX_STEERING_ANGLE*返回值:无************************************************/void steer_car(int steering_angle)if (steering_angle < -MAX_STEERING_ANGLE , steering_angle > MAX_STEERING_ANGLE)printf("invalid steering angle\n");return;}steering_angle = steering_angle;printf("steering car to angle %d\n", steering_angle);。
电动车控制器C语言源代码讲解
#define _E_BIKE_W79E83X_C_#include intrins.h#include E_BIKE_W79E83X.H#includeW79E834.h/*************************************************************************** *** 主函数**************************************************************************** **/void main(void){Init(); // 初始化Init_IO(); // 初始化端口H_Sample(); // 霍尔信号采样Phase_Change(); // 相位变换AutoHelpEN(1,0x1AA,200);/*第一个参数设定助力功能允许与否,1为允许,0为禁止第二个参数设定助力力量(PWM占空比),数值范围:0~0x355,数值越大,力量越大第三个参数设定助力时间,数值越大,时间越长*/Keep_SpeedEN(1,0x20,6);/*第一个参数设定定速巡航功能允许与否,1为允许,0为禁止第二个参数设定定速巡航最低速设置第三个参数设定在巡航点保持多长时间后才进入巡航*/Current_Lim(0xB48);/*过流保护上限值设定0xB00对应限电流最大大约为2.6A0xB80对应限流值最大大约为3.8A*/LowVoltage_Lim(0x9B0);/*欠压保护下限值设定电池电压为47.9V时ADC采样值为0xB6 ==> 0xB60推算电池电压为41V时的采样值为0x9B ==> 0x9B0推算电池电压为40V时的采样值为0x98 ==> 0x980*/EABS_Set(1,1);/*第一个参数为滑行充电功能使能,1为允许,0为禁止第二个参数为电刹车功能使能,1为允许,0为禁止*/Speed_LimHW(0,0,0,1);/*硬件控制最大速度参数只能有一个为1。
电动车控制器C语言源代码
Speed_LimHW(0,0,0,1);
/*
硬件控制最大速度
参数只能有一个为1。
第一个参数对应15km/h
第二个参数对应20km/h
第三个参数对应30km/h
第四个参数对应40km/h
*/
Speed_LimSW(0x01);
/*
软件控制最大速度
参数数值由0x00~0x20,数值越小速度越大,反之则越小
Cou nt_Curre nt=O;
Coun t_Speed=O;
Cou nt_Voltage=0;.
Speed_REQ=O;
Curre nt_REQ=0;
Voltage_REQ=O;
ADC_Ready=O;
〃PWM_Duty=0;
*********/
void In it_IO(void)
{
//——P0端口设置——//
P0M仁0xBE;
P0M2=0x01;
/*
P0M1.Y P0M2.Y=00设置I/O端口为普通双向模式
P0M1.Y P0M2.Y=01设置I/O端口为推拉模式
P0M1.Y P0M2.Y=10设置I/O端口为输入,高阻,模式
*********
*主函数
*********************************************************************
*********/
void ma in (void)
{
Init(); //初始化
In it_IO(); //初始化端口
H_Sample(); //霍尔信号采样
/*
欠压保护下限值设定
电池电压为47.9V时ADC采样值为0xB6==>0xB60
电动车控制器stm32源码
电动车控制器stm32源码1. 介绍电动车控制器是电动车的核心部件之一,负责控制电动机的启停、转速、扭矩等参数,实现对电动车的驱动控制。
本文将介绍电动车控制器的stm32源码开发。
2. STM32开发环境搭建2.1 安装Keil MDKKeil MDK是一款常用的嵌入式开发工具,支持多种芯片平台,包括STM32系列。
通过Keil MDK,我们可以方便地进行stm32源码的开发和调试。
2.2 编写stm32源码在Keil MDK中,我们可以使用C语言编写stm32的源码。
源码主要包括以下几个部分:2.2.1 引入头文件在源码的开头,我们需要引入一些头文件,以便使用相关的函数和宏定义。
例如:#include "stm32f10x.h"#include "stm32f10x_gpio.h"#include "stm32f10x_rcc.h"2.2.2 定义全局变量在源码中,我们可以定义一些全局变量,用于保存各种状态和参数。
例如:uint8_t speed = 0; // 电动车的速度uint8_t torque = 0; // 电动车的扭矩2.2.3 初始化函数在源码中,我们需要编写初始化函数,用于初始化STM32的各个模块和外设。
例如:void GPIO_Configuration(void){GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(GPIOA, &GPIO_InitStructure);}2.2.4 主函数在源码中,我们需要编写主函数,用于实现电动车控制器的逻辑功能。
电动车控制器C语言源代码
电动车控制器C语言源代码#define _E_BIKE_W79E83X_C_#include "intrins.h"#include "E_BIKE_W79E83X.H"#include"W79E834.h"/************************************************************** ****** ********** 主函数*************************************************************** ****** *********/void main(void){Init(); // 初始化Init_IO(); // 初始化端口H_Sample(); // 霍尔信号采样Phase_Change(); // 相位变换AutoHelpEN(1,0x1AA,200);/*第一个参数设定助力功能允许与否,1为允许,0为禁止第二个参数设定助力力量(PWM占空比),数值范围:0~0x355,数值越大,力量越大第三个参数设定助力时间,数值越大,时间越长*/Keep_SpeedEN(1,0x20,6);/*第一个参数设定定速巡航功能允许与否,1为允许,0为禁止第二个参数设定定速巡航最低速设置第三个参数设定在巡航点保持多长时间后才进入巡航 */Current_Lim(0xB48);过流保护上限值设定0xB00对应限电流最大大约为2.6A0xB80对应限流值最大大约为3.8A*/LowVoltage_Lim(0x9B0);/*欠压保护下限值设定电池电压为47.9V时ADC采样值为0xB6 ==> 0xB60 推算电池电压为41V时的采样值为0x9B ==> 0x9B0推算电池电压为40V时的采样值为0x98 ==> 0x980 */EABS_Set(1,1);/*第一个参数为滑行充电功能使能,1为允许,0为禁止第二个参数为电刹车功能使能,1为允许,0为禁止 */Speed_LimHW(0,0,0,1);/*硬件控制最大速度参数只能有一个为1。
c语言电机控制中enablecloseflag
C语言电机控制中的enablecloseflag随着科技的不断进步,电机控制技术在各个领域得到了广泛应用。
其中,C语言作为一种高效的编程语言,在电机控制中也扮演着重要的角色。
enablecloseflag作为C语言中电机控制的关键参数之一,对电机控制的实现起着至关重要的作用。
本文将从enablecloseflag在电机控制中的作用、其实现原理、应用场景等方面展开介绍,以帮助读者更好地理解和应用C语言电机控制中的enablecloseflag。
一、enablecloseflag在电机控制中的作用1.1 控制电机启停enablecloseflag作为一个标志位参数,用于控制电机的启停。
当enablecloseflag为1时,表示电机处于启动状态;当enablecloseflag为0时,表示电机处于停止状态。
通过控制enablecloseflag的数值,可以实现对电机的灵活控制,满足不同场景下对电机启停的需求。
1.2 调节电机转速除了控制电机的启停外,enablecloseflag还可以用于调节电机的转速。
通过对enablecloseflag的动态变化,可以实现对电机转速的精准调节,使其适应不同的工作要求。
1.3 控制电机运行模式在一些特定的应用场景中,电机需要根据实际需求切换运行模式。
enablecloseflag可以作为一个开关来控制电机的运行模式,使其在不同的工作状态下具有不同的运行特性。
二、enablecloseflag的实现原理2.1 与硬件的配合在C语言电机控制中,enablecloseflag的实现需要与硬件配合。
通过与相应的电机控制电路连接,可以实现对电机启停、转速调节、运行模式切换等功能。
2.2 通过开关控制enablecloseflag可以通过物理开关或传感器来控制。
在实际的应用中,通过对开关状态或传感器信号的获取,可以实现对enablecloseflag的实时控制,从而实现对电机的实时控制。
基于 STM32 的电动车控制器软件-源代码
__HAL_RCC_AFIO_CLK_ENABLE();
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_2);
/* System interrupt init*/
/* MemoryManagement_IRQn interrupt configuration */
#include "usart/bsp_usartx.h"
#include "led/bsp_led.h"
/* USER CODE BEGIN 0 */
#include "spiflash/bsp_spiflash.h"
/* USER CODE END 0 */
/* External variables --------------------------------------------------------*/
}
else
{
while(1)
{
printf("获取不到W25Q32 ID!\n");
LED1_TOGGLE;
HAL_Delay(1000);
}
}
while(KEY1_StateRead()==KEY_UP);
while(KEY1_StateRead()==KEY_DOWN);
printf("开始擦除FLASH\n");
{
uint8_t j;
/*复位所有外设,初始化Flash接口和系统滴答定时器*/
HAL_Init();
/*配置系统时钟*/
SystemClock_Config();
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
电动车控制器C语言源代码.#define _E_BIKE_W79E83X_C_ #include "intrins.h"#include "E_BIKE_W79E83X.H" #include"W79E834.h"/******************************************************************* *********** 主函数******************************************************************** **********/void main(void){Init(); // 初始化Init_IO(); // 初始化端口H_Sample(); // 霍尔信号采样Phase_Change(); // 相位变换AutoHelpEN(1,0x1AA,200);/*第一个参数设定助力功能允许不否,1为允许,0为禁止第二个参数设定助力力量(PWM占空比),数值范围:0~0x355,数值越大,力量越大第三个参数设定助力时间,数值越大,时间越长*/Keep_SpeedEN(1,0x20,6);/*第一个参数设定定速巡航功能允许不否,1为允许,0为禁止第二个参数设定定速巡航最低速设置..第三个参数设定在巡航点保持多长时间后才进入巡航*/Current_Lim(0xB48);/*过流保护上限值设定0xB00对应限电流最大大约为2.6A0xB80对应限流值最大大约为3.8A*/LowVoltage_Lim(0x9B0);/*欠压保护下限值设定电池电压为47.9V时ADC采样值为0xB6 ==> 0xB60推算电池电压为41V时的采样值为0x9B ==> 0x9B0推算电池电压为40V时的采样值为0x98 ==> 0x980*/EABS_Set(1,1);/*第一个参数为滑行充电功能使能,1为允许,0为禁止第二个参数为电刹车功能使能,1为允许,0为禁止*/Speed_LimHW(0,0,0,1);/*硬件控制最大速度参数只能有一个为1。
第一个参数对应15km/h第二个参数对应20km/h..第三个参数对应30km/h第四个参数对应40km/h*/Speed_LimSW(0x01);/*软件控制最大速度参数数值由0x00~0x20,数值越小速度越大,反之则越小*/while(1){_nop_();//AutoHelpEN(0,0x1AA,100);//Keep_SpeedEN(1,0x20,6);//Current_Lim(0xB50);//LowVoltage_Lim(0x9B0);//EABS_Set(0,0);//Speed_LimHW(0,0,0,1);}}/******************************************************************* ************ I/O端口初始化******************************************************************** **********/void Init_IO(void){//------P0端口设置------//P0M1=0xBE;..P0M2=0x01;/*P0M1.Y P0M2.Y=00 设置I/O端口为普通双向模式P0M1.Y P0M2.Y=01 设置I/O端口为推拉模式P0M1.Y P0M2.Y=10 设置I/O端口为输入,高阻,模式P0M1.Y P0M2.Y=11 设置I/O端口为开漏模式*///P0ID=0x78; // 设置四个AD端口0数字输入禁止P0=0xFF;//------P1端口设置------//P1M1=0x1C;P1M2=0xC0;P1=0xFF;//------P2端口设置------//P2M1=0x01;P2M2=0x1E;P2=0xFF;}/******************************************************************* ************ 初始化程序******************************************************************** **********/void Init(void){unsigned char i;//------PWM设置------//..// PWMP > PWMn 高电平,反之低电平PWMPH=0X03;PWMPL=0X55;PWM0H=0X00;PWM0L=0X00;PWM1H=0X00;PWM1L=0X00;PWM2H=0X00;PWM2L=0X00;PWMCON1=0XC7; // 打开PWM电路,三个PWM口反相输出PWMCON3=0xF0;//------飞车保护--------//EA=1;/*do {ADCCON=1;ADCCON&=0xef;ADCCON|=0x08;ADC_Ready=0;while(ADC_Ready);}while (ADCH>0x60);*///-----相位检测-------//while(P02==0){H_Sample();Phase_Detect(); ..}//------变量初始化------// for (i=0;i<32;i++){Current_Buffer[i]=0;}for (i=0;i<20;i++){Speed_Buffer[i]=0;}for (i=0;i<16;i++){Voltage_Buffer[i]=0;}Current_P=0;Speed_P=0;Voltage_P=0;;Speed_SUM=0;// PWM_MAX=0;Current_SUM=0;Voltage_SUM=0;H_State=0;Old_State=0;PWM_Duty=0;// PWM_MAX=0;Count_Current=0;Count_Speed=0;Count_Voltage=0; ..Speed_REQ=0;Current_REQ=0;Voltage_REQ=0;ADC_Ready=0;//PWM_Duty=0;PWM_Duty_min=0;//********************* KeepSpeed_Flag = 0;KS_Z1 = 0;KS_Z2 = 0;Motor_Speed = 0x50;//********************* AutoHelp_Flag = 0; Current_Max=0xcffe;Speed_Low=0x0500;//Speed_High=0x1c37;//Speed_MAX=0x1c00; //-----定时器的设置-----//TH0=0x50;TL0=0x50; // 设定定时器的初值TH1=0xE0;TL1=0xE0; // 设定定时器的初值TMOD=0x22; // T0选为定时器,八位,模式2,TL0自动加载TH0中的初值CKCON&=0X00; // 定时器选择为1/12系统时钟ET0=1; // 允许定时器中断TR0=1; // 启动定时器ET1=1;TR1=1;..//-----外部中断设定-----//EX1 = 1; // 允许外部中断1IT1 = 0; // 电平触収中断1AUXR1|=0x04; // 打开ADC电路EADC=1; // 允许ADC中断ADCCON &= 0xE7;// Settings of Timer2 capture modeCKCON=0x60;CAPCON0=0xA8;CAPCON1=0x00;T2MOD=0xF0;IE1 |= 0x80; // enable capture mode interruptRCAP2L = 0x00; //自动重装载低位RCAP2H = 0x00; //自动重装载高位IE1 |= 0x40;//EA=1; // enable interruptT2CON |= 0x04;//enable timer2//***************************//KS_EN = 1;KS_Time = 8;//***************************// }/******************************************************************* ***********..* ADC中断处理程序******************************************************************** **********/void ADC_ISR(void) interrupt 11{//UB=~UB;UB=~UB;//EADC=0;ADC_Ready=1;ADCCON &= 0xE7;if(Current_REQ) // 电流采样{Current_REQ=0;if(Current_SUM>Current_Buffer[Current_P]) Current_SUM -= Current_Buffer[Current_P]; Current_Buffer[Current_P]=ADCH;Current_SUM += ADCH;Current_P++;if(Current_P>31)Current_P=0;}if(Speed_REQ) // 转把电压采样{Speed_REQ=0;if(Speed_SUM>Speed_Buffer[Speed_P]) Speed_SUM-=Speed_Buffer[Speed_P];Speed_Buffer[Speed_P]=ADCH;Speed_SUM+=ADCH;Speed_P++;..if(Speed_P == 14)Speed_P=0;}if(Voltage_REQ) // 电源电压采样{Voltage_REQ=0;if(Voltage_SUM>Voltage_Buffer[Voltage_P])Voltage_SUM -= Voltage_Buffer[Voltage_P];Voltage_Buffer[Voltage_P]=ADCH;Voltage_SUM += ADCH;Voltage_P++;if(Voltage_P>15)Voltage_P=0;}//PWM_ADJ();//UB=~UB;}/******************************************************************* ************ 定时器0中断处理函数******************************************************************** **********/// ========== Interrupt Cycle: 100uS ===================void T0M1_ISR(void) interrupt 1{//UB=~UB;//UB=~UB;ADC_Ready=0;Current_REQ=1;..Speed_REQ=0;Voltage_REQ=0;ADCCON=2;Count_Speed++;KS_CNT++;AH_Count++;if(Count_Speed>5)//17 {ADCCON=4;Current_REQ=0;Speed_REQ=1;Count_Speed=0;Count_Voltage++;if( Count_Voltage>5)//50 {ADCCON=3;Speed_REQ=0;Voltage_REQ=1;Count_Voltage=0;//******** Keep Speed Setting ******// KS_Finish();}}//***Function Set***//if(AH_Count >= 100){AutoHelp(); // 自助力AH_Count = 0;}..if(KS_CNT >= 3000){KS_CNT = 0;Keep_Speed(); // 巡航定速}Volt_Low(); // 欠压保护if(P02==0)Brake_Setting(); // 刹车ADCCON&=0xef;ADCCON|=0x08;EADC=1;PWM_ADJ();}/******************************************************************* ************ 定时器1中断处理函数******************************************************************** **********/void T1M1_ISR(void) interrupt 3 {_nop_();}/******************************************************************* ************ 定时器2捕获模式中断处理函数******************************************************************** **********/void Timer2_ISR() interrupt 13 using 2 ..{//*******Motor Speed*******//Motor_Speed = TH2;TH2 = 0;TL2 = 0;H_Sample(); // 霍尔信号采集Phase_Change(); // 相位变换}/******************************************************************* ************ 定时器2溢出中断处理函数******************************************************************** **********/void T2_ISR() interrupt 8 {TF2 = 0;Motor_Speed = 0x50;Block_Detect(); // 堵转保护}/******************************************************************* ************ 外部中断处理函数,过流中断******************************************************************** **********/void INT1_ISR() interrupt 2 {CurrentOver_Count++;if(CurrentOver_Count >= 5) // 防抖处理..{PWM_Duty_min = 1;CurrentOver_Count = 0;}}/******************************************************************* ************ 定时器3中断处理函数,采叏捕获模式********************************************************************* *********/void H_Sample(void) {CAPCON1 &= 0xF8;H1=P12;H2=P07;H3=P20;do{State1=H1<<2;State1+=H2<<1;State1+=H3;_nop_();_nop_();State2=H1<<2;State2+=H2<<1;State2+=H3;}while(State1!=State2); // 状态去抖H_State=State1; .. }/******************************************************************* ************ 根据电机霍尔换向信号给出相应控制信号 * 上桥臂:VT,UT,WT* 下桥臂:VB,UB,WB******************************************************************** **********/void Phase_Change(void) {if(EABS_Flag){if(!AutoHelp_Flag){UB = 1;VB = 1;WB = 1;_nop_();UT = 1;VT = 1;WT = 1;}}else if(PWM_Duty_min) {UT=0;VT=0;WT=0;UB=1;VB=1;WB=1; // 电机停转}else..{switch(H_State){case 6: // 110,V3,V4VT=0;UT=0;VB=1;WB=1;_nop_();WT=1;UB=0;break;case 2: // 010,V4,V5 case 7:UT=0;WB=0;VB=1;WB=1; _nop_();VT=1;UB=0;break;case 3: // 011,V5,V6 UT=0;WT=0;UB=1;VB=1; _nop_();VT=1;WB=0;break;case 1: // 001,V6,V1 WT=0;VT=0;UB=1;VB=1; _nop_();UT=1;WB=0;break;case 5: // 101,V1,V2 case 0:WT=0;VT=0;UB=1;WB=1; _nop_();VB=0;UT=1;break;..case 4: // 100,V2,V3UT=0;VT=0;UB=1;WB=1;_nop_();WT=1;VB=0;break;case 9:UT=0;VT=0;WT=0;UB=1;VB=1;WB=1;break;default:break;}}/*if(PWM_Duty_min){UT=0;VT=0;WT=0;UB=1;VB=1;WB=1; // 电机停转}*/}/******************************************************************* ************ 相位检测程序* 上桥臂:VT,UT,WT* 下桥臂:VB,UB,WB******************************************************************** **********/void Phase_Detect(void){WT=0;UT=0;VT=0;switch(H_State)..{case 6: // 110,V3,V4UB=0;VB=1;WB=1;break;case 2: // 010,V4,V5case 7:UB=0;VB=1;WB=1;break;case 3: // 011,V5,V6UB=1;VB=1;WB=0;break;case 1: // 001,V6,V1UB=1;VB=1;WB=0;break;case 5: // 101,V1,V2case 0:UB=1;VB=0;WB=1;break;case 4: // 100,V2,V3UB=1;VB=0;WB=1;break;default:break;}}/******************************************************************* ************ PWM值转换程序* 在限流允许下,将转把电压ADC值转换为PWMn的值 * 电流超过限流值时,做限流处理..******************************************************************** **********/void PWM_ADJ(void){//=====没有超过限流最大值的情冴====//if(Current_SUM < Current_Max){if(Speed_SUM < Speed_Low){ //---没有转把电压,由Speed_Low的值决定转把电压最小值---// if(!KeepSpeed_Flag){if(!AutoHelp_Flag){ // 定速,助力功能下电机正常转动,否则电机停转//PWM_Duty=0;//PWM_Duty_min=1; // 停转标志//PWM_Duty_Max = 0;if(Motor_Speed < 0x010){if(P02==1){if(EABS_SlipEN){EABS_Flag = 1;if(PWM_Duty_Max<0x55)PWM_Duty_Max = 0x055; // 滑行充电}else{PWM_Duty_Max = 0; ..PWM_Duty_min=1; // 停转标志PWM_Duty=0;}}else{PWM_Duty_Max = 0;PWM_Duty_min=1; // 停转标志PWM_Duty=0;}}else{PWM_Duty_Max = 0;PWM_Duty_min=1; // 停转标志PWM_Duty=0;}}}Block_Flag = 0;}else if(P02 == 1){ //---转把电压有效---//PWM_Duty_Max=Speed_SUM-Speed_Low; // 对应转把电压的最大计算值EABS_Flag = 0;if(PWM_Duty_min){if(!Block_Flag){..PWM_Duty_min = 0; // 退出无有效转把电压状冴Phase_Change(); // 相序对应}}/*if(LowNoise_Flag){PWM_Duty_Max += 0x200;}*/if(PWM_Duty_Max>0x06F0)PWM_Duty_Max = 0x06E8; // 最大值限制PWM_Duty_Max=PWM_Duty_Max>>1; // 由转把电压转换为PWMn的值}if(AutoHelp_Flag){PWM_Duty_Max=AH_Duty; // 助力下为PWMn赋值EABS_Flag = 0;}if(KeepSpeed_Flag){PWM_Duty_Max=KS_PWM_Duty; // 定速模式下为PWMn赋值AutoHelp_Flag = 0; // 定速巡航状态时无助力}if(PWM_Duty < PWM_Duty_Max){if(Motor_Speed > SP_Lim)PWM_Duty++; // 转把电压相对应的PWMn值缓慢增加 . .}else{if(PWM_Duty > 3)PWM_Duty--; // 转把电压相对应的PWMn值缓慢减小elsePWM_Duty = 0;}}//======超过限流最大值的情冴======//else{if(PWM_Duty > 0x02){PWM_Duty--; // PWMn值减小}else{PWM_Duty=0;}}PWM_Duty_H = PWM_Duty>>8;PWM_Duty_L = (PWM_Duty & 0x0FF); // 对应PWMn的值,高、低位,if (Power_Off)PWM_Duty_min = 1; // 欠压保护//PWM_Duty_H = 0x01; ..//PWM_Duty_L = 0x20; //测试之用PWM_Setting();}/******************************************************************* ************ 过流保护上限值设定* 0x1600对应限电流最大大约为2.6A* 0x1700对应限流值最大大约为3.8A******************************************************************** **********/void Current_Lim(unsigned int CM) {Current_Max = CM;}/******************************************************************* ************ 欠压保护程序******************************************************************** **********/void Volt_Low(void){if(Voltage_SUM < Voltage_Min){ // 欠压状态Voltage_Count++;if(Voltage_Count > 200)Power_Off=1;}else..{Power_Off=0;Voltage_Count = 0;}}/******************************************************************* ************ 欠压保护下限值设定* 电池电压为47.9V时ADC采样值为0xB6 ==> 0xB60 * 推算电池电压为41V 时的采样值为0x9B ==> 0x9B0 * 推算电池电压为40V时的采样值为0x98 ==>0x980********************************************************************* *********/void LowVoltage_Lim(unsigned int CM) {Voltage_Min = CM;}/******************************************************************* ************ 软件控制最大速度* 分为四个档位1,2,3,4分别对应15km/h,20km/h,30km/h,40km/h********************************************************************* *********/void Speed_LimSW(unsigned char SG) {SP_Lim = SG;}../******************************************************************* ************ 硬件控制最大速度* 分为四个档位SG1,SG2,SG3,SG4分别对应15km/h,20km/h,30km/h,40km/h ******************************************************************** **********/void Speed_LimHW(bit SG1,bit SG2,bit SG3,bit SG4){SP_Lim = 0x01;if(SG4)SP_Lim = 0x01;else if(SG3)SP_Lim = 0x03;else if(SG2)SP_Lim = 0x05;else if(SG1)SP_Lim = 0x08;}/******************************************************************* ************ 堵转保护程序******************************************************************** **********/void Block_Detect(void){if(Current_SUM > Current_Max - 0x80){Block_CNT++;}..elseBlock_CNT = 0;if(Block_CNT >= 20){PWM_Duty_min = 1;Block_Flag = 1;AutoHelp_Flag = 0;KeepSpeed_Flag = 0;UT=0;VT=0;WT=0;UB=1;VB=1;WB=1; // 电机停转}}/******************************************************************* ************ 刹车功能******************************************************************** **********/void Brake_Setting(void) {unsigned char i;KeepSpeed_Flag = 0;AutoHelp_Flag = 0;PWM_Duty_min = 1;Block_Flag = 0;UB = 1;VB = 1;WB = 1;Speed_SUM = 0;for(i=0;i<20;i++){..Speed_Buffer[i] = 0;}if(EABS_BrakeEN) // 电子刹车{if(Speed_SUM < Speed_Low) {PWM_Duty_H = 0x01;PWM_Duty_L = 0x00;EABS_Flag = 1;UT = 1;VT = 1;WT = 1;}else{UT = 0;VT = 0;WT = 0;}PWM_Setting();}}/******************************************************************* ************ 滑行充电功能******************************************************************** **********//*void Slip_Setting(void) {..if(EABS_SlipEN){UB = 1;VB = 1;WB = 1;_nop_();EABS_Flag = 1;UT = 1;VT = 1;WT = 1;}}/******************************************************************* ************ 电刹车功能使能* EBS_EN:滑行充电功能使能* EBB_EN:电刹车功能使能******************************************************************** **********/void EABS_Set(bit EBS_EN,bit EBB_EN) {EABS_SlipEN = EBS_EN;EABS_BrakeEN = EBB_EN;}/******************************************************************* ************ 1:1自动程序助力* 电动车中轴速度传感器(单开关霍尔信号),当转动中轴时产生高低电平信号。