//*****************************************************//* ***无刷电机控制器程序*** *//*===================================================* //* MCU-STC12C5404...
//*****************************************************
//* ***无刷电机控制器程序*** *
//*===================================================*
//* mcu-stc12c5404ad 8路ad转换,4路pwm输出,速度1t *
//*===================================================*
//*****************************************************
#include #define uchar unsigned char //8位单片机习惯性定义 #define uint unsigned int //8位单片机习惯性定义 // //*********ad转换要用到的特殊寄存器地址定义************************************* sfr adc_contr=0xc5; //定义ad转换控制寄存器地址 sfr adc_data=0xc6; //定义ad转换结果寄存器地址 sfr p1m0=0x91; //带有8路ad的p1口模式选择寄存器0定义地址 sfr p1m1=0x92; //带有8路ad的p1口模式选择寄存器1定义地址 // //*********pwm输出要用到的特殊寄存器地址定义************************************ sfr ccap0h=0xfa; //pca模块0捕捉/比较寄存器高8位 sfr ccap1h=0xfb; //pca模块1捕捉/比较寄存器高8位 sfr ccap2h=0xfc; //pca模块2捕捉/比较寄存器高8位 sfr ccap3h=0xfd; //pca模块3捕捉/比较寄存器高8位 sfr pca_pwm0=0xf2; //pca模块0-pwm寄存器 sfr pca_pwm1=0xf3; //pca模块1-pwm寄存器 sfr pca_pwm2=0xf4; //pca模块2-pwm寄存器 sfr pca_pwm4=0xf5; //pca模块3-pwm寄存器 sfr ccapm0=0xda; //pca模块0工作模式寄存器 sfr ccapm1=0xdb; //pca模块1工作模式寄存器 sfr ccapm2=0xdc; //pca模块2工作模式寄存器 sfr ccapm3=0xdd; //pca模块3工作模式寄存器 sfr ch=0xf9; //pca计数器高8位 sfr cl=0xe9; //pca计数器低8位 sfr ccon=0xd8; //pca控制寄存器 sfr cmod=0xd9; //pca工作模式寄存器 sbit cr=ccon^6; //pca计数器控制位,1开0关 sbit epca_lvd=ie^6; //pca中断允许控制位1开0关 sfr auxr=0x8e; //定时器工作于1t控制位 //============================================================================== sbit zb=p1^3; sbit pwmal=p2^3; //a相下桥驱动定义 sbit pwmbl=p2^2; //b相下桥驱动定义 sbit pwmcl=p2^1; //c相下桥驱动定义 sbit led=p2^7; //指示灯定义 sbit abs=p2^5; //abs刹车功能选择口,对地为abs功能 sbit shache=p3^0; //刹车口定义,对地刹车 sbit fd=p3^3; //防盗检测口定义 int ledcs; //定义一个指示灯闪灯次数变量 static fd_hej; static timebj; //定义一个定时器计数比较变量 static timejs; //定义一个定时器中断计数次数变量 static pwm_bl; //pwm输出变量 static zs_bl=20; //pwm旧的变量数据,备份的 static pwm_bls; //pwm软启动加速用变量 static shache_bz; //刹车后该标志置1供软启动使用 static hehc; //霍尔数据暂存区 static hehc_bl; //上相霍尔数据暂存区,用于检测霍尔变化 static dz_bz; //堵转标志,为1堵转 static dz_bz1; static zbyx_bz; //转把有效标志,归0时为0,行驶时为1有效 static ds_bf=10; //转把上次的数据备份 static zs_js; //转速数据 static zs_ds_js; int qy_1,qy_2,qy_3; //欠压测量暂存区1,2,3 int cs1,cs2,cs3,cs_fx; //电机测速全局变量 static qy_bf; //欠压上次的数据备份 int h; //abs刹车用变量 int dz; int dz2; void zb_fx(void); void he_gzjc(void); void pwm_out(void); //*********************ad转换后pwm对照表***************************************** uchar code pwmout[256]= {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,//60个1为1.3v以下 //------------------------------------------------------------------------------------------ 241,239,237,235,233,231,229,227,225,223,221,219,217,215,213,211,209,207,205,203, 201,199,197,195,193,191,189,187,185,183,181,179,177,175,173,171,169,167,165,163, 161,159,157,155,153,151,149,147,145,143,141,139,137,135,133,131,129,127,125,123,//60 121,119,117,115,113,111,109,107,105,103,101,99,97,95,93,91,89,87,85,83,81,79,77,//23 75,73,71,69,67,65,63,61,59,57,55,53,51,49,47,46,45,44,43,42,41,40,39,38,37,36,//26 35,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,//26 9,8,7,6,5,4,3,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,//34 //25个0为4.1--4.5v 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1}; //26个为4.5v以上 //*********************1ms延时函数*********************************************** void delay(int t) { int i,j; for(i=0;i ; } //*********************abs刹车延时函数*********************************************** void delay1(int t) { int i,j; for(i=0;i {} } //*********************设置ad电源和开漏函数************************************** adc_power() { adc_contr|=0x80; //开ad电源 delay(2); //首次开ad电源要延时1ms左右 p1m0|=0x88; //设置p1.3和p1.7为开漏即ad转换模式 p1m1|=0x88; //同上 } //-------------------设置p1.3为转把测量通道函------------------------------------ set_p13_adc() { zb=1; adc_contr=0xe3; //p13口为转换通道 } //-------------------设置p17为电机超载测量通道函数-------------------------------- set_p17_adc() { adc_contr=0xe7; } //------------------设置p15为欠压检测测量通道------------------------------------- set_p15_adc() {adc_contr=0xe5;} //===================测量电压函数================================================= get_ad_dy() { int adon=0; //定义一个整型变量用于检测ad转换是否结束 adc_data=0; //ad转换结果寄存器清0 adc_contr|=0x08; //转换位置1启动转换 while(adon==0) //循环判断表达式成立反复执行语句,不成立退出 {adon=adc_contr&amt;0x10;} //循环语句体,即判断ad转换是否完成,完成后高第4位为1 adc_contr&amt;=0xe7; //循环语句退出转换完成,清adc_flag,adc_start,停止转换 } //********************pwm初始化函数*********************************************** pwm_sz() { cmod=0x82; //pca在空闲模式下停止pca计数器工作 //pca时钟源为1/2溢出 //禁止pca计数器溢出中断 ccon=0x00; //禁止pca计数器工作,清除中断标志和计数器溢出标志 cl=0x00; //清0计数器 ch=0x00; //======================以下为4路pwm输出设置程序============================= //设置模块0为8位pwm输出模式,pwm无需中断支持,,脉冲在p3.7口输出 ccapm0=0x42; //***程序核心语句,-----0100,0010 pca_pwm0=0x03; //先关闭pwm-输出为0,写入0x00就可开pwm输出 //设置模块1为8位pwm输出模式,pwm无需中断支持,,脉冲在p3.5口输出 ccapm1=0x42; //***程序核心语句,-----0100,0010 pca_pwm1=0x03; //先关闭pwm-输出为0,写入0x00就可开pwm输出 //设置模块2为8位pwm输出模式,pwm无需中断支持,,脉冲在p2.0口输出 ccapm2=0x42; //***程序核心语句,-----0100,0010 pca_pwm2=0x03; //先关闭pwm-输出为0,写入0x00就可开pwm输出 //模块3未用 epca_lvd=1; //开pca中断 ea=1; //开总中断 cr=1; //开pca计数器打开 } //********************快闪灯函数*********************************************** led_k() { int k; //定义一个临时变量 for(k=0;k led=1;delay(700);} delay(2000); } //********************定时器0和1初始化函数******************************************* time_csh() { tmod=0x11; //定时器0工作于8位自动重装,1工作于方式1 th0=0x3c; // tl0=0x0b; th1=0x3c; //12mhz时50ms数据,20次为1s tl1=0x0b; it0=1; //设置外中断0为下降沿触发358第一脚 ex0=1; //开外中断0 ea=1; //开总中断 et0=1; //开定时期0中断 et1=1; //开定时期1中断 } //********************定时器0中断函数pwm频率用************************************ void time0(void)interrupt 1 {tr0=0;th0=0x3c;tl0=0x0b; zs_ds_js++; if(zs_ds_js==10) {if(zs_js<10) {dz_bz1=1;zs_ds_js=0;zs_js=0; th1=0x3c;tl1=0x0b;tr1=1; th0=0x3c;tl0=0x0b;tr0=1; // pwm_bls=200; } else {dz_bz1=0;zs_ds_js=0;zs_js=0;zs_bl=zs_js; th1=0x3c;tl1=0x0b;tr1=0; th0=0x3c;tl0=0x0b;tr0=1; } } else {tr0=1;} } //********************定时器1中断函数********************************************* void time1(void)interrupt 3 { tr1=0;th1=0x3c;tl1=0x0b; timejs++; if(timejs==12) //中断次数等于给定的次数就取反led {if(zbyx_bz==0) //转把归0标志为0,可以闪灯 {led=~led;timejs=0;tr1=1;} } if(timejs==80) {if(dz_bz1==1) {tr0=0;dz_bz1=0;dz_bz=1;zs_ds_js=0;zs_js=0;timejs=0;} else {dz_bz=0;zs_ds_js=0;zs_js=0;timejs=0;} } tr1=1; } //*******************电机堵转转函数*********************************************** //根据2s定时内一直堵转的话置dz_bz为1,本函数检测到该标志为1立即关闭所有输出 //并闪烁指示灯间隔快闪2次提示,最后监控转把归0后可以退出本函数重新启动 void dgdz(void) { while(dz_bz1==1) {pwm_bls=100;he_gzjc();pwm_out(); if(dz_bz==1) { tr0=0;tr1=0; pca_pwm0=0x03; //关3路pwm信号 pca_pwm1=0x03; // pca_pwm2=0x03; // pwmal=0;pwmbl=0;pwmcl=0; //关3路下桥 set_p13_adc(); //电机进入保护后开始等待转把归零后可以重新启动 do{ledcs=2;led_k();get_ad_dy();} //间隔开闪2次提示堵转保护,测量转把电压是否归0 while(adc_data>=61); //没有归0执行do循环体语句 led=1;dz_bz=0;dz_bz1=0; //转把归0后关指示灯清堵转标志 } } } //********************外中断0函数限流或康铜开路************************************ void intt0()interrupt 0 { tr0=0;tr1=0; //关pwm频率 pca_pwm0=0x03; //关3路pwm信号 pca_pwm1=0x03; // pca_pwm2=0x03; // pwmal=0;pwmbl=0;pwmcl=0; //关3路下桥 set_p13_adc(); get_ad_dy(); while(adc_data>=61) {ledcs=4;led=0;get_ad_dy();} led=1; } //********************pwm驱动桥驱动输出函数**************************************** void pwm_out(void) //入口:pwm_bl里有转把调速参数.出口:输出全桥驱动信号 { switch(hehc) //多分支语句根据霍尔位置输出对应节拍 {case 0x01:{pca_pwm1=0x03;pca_pwm2=0x03;pwmal=0;pwmbl=0; ccap0h=pwm_bls;pwmcl=1;pca_pwm0=0x00;cs1=0x01;break;} //第1拍ccap0h刷新参数开c下桥a上桥 //------------------------------------------------------------- case 0x03:{pca_pwm0=0x03;pca_pwm2=0x03;pwmal=0;pwmbl=0; ccap1h=pwm_bls;pwmcl=1;pca_pwm1=0x00;cs2=0x03;break;} //第2拍ccap1h刷新参数开c下桥b上桥 //------------------------------------------------------------- case 0x02:{pca_pwm0=0x03;pca_pwm2=0x03;pwmbl=0;pwmcl=0; ccap1h=pwm_bls;pwmal=1;pca_pwm1=0x00;cs3=0x02;break;} //第3拍ccap1h刷新参数开a下桥b上桥 //------------------------------------------------------------- case 0x06:{pca_pwm0=0x03;pca_pwm1=0x03;pwmbl=0;pwmcl=0; ccap2h=pwm_bls;pwmal=1;pca_pwm2=0x00;cs1=0x06;break;} //第4拍ccap2h刷新参数开a下桥c上桥 //------------------------------------------------------------- case 0x04:{pca_pwm0=0x03;pca_pwm1=0x03;pwmal=0;pwmcl=0; ccap2h=pwm_bls;pwmbl=1;pca_pwm2=0x00;cs2=0x04;break;} //第5拍ccap2h刷新参数开b下桥c上桥 //------------------------------------------------------------- case 0x05:{pca_pwm1=0x03;pca_pwm2=0x03;pwmal=0;pwmcl=0; ccap0h=pwm_bls;pwmbl=1;pca_pwm0=0x00;cs3=0x05;break;} //第6拍ccap0h刷新参数开b下桥a上桥 } } //********************上电初始化函数********************************************** void sd_csh(void) {p1=0xff;zb=0;p2=0xff;p3=0xff; pwmal=0; //上电复位后首先关闭3组下桥 pwmbl=0; // pwmcl=0; // adc_power(); //调ad转换用初始化函数 pwm_sz(); //调pwm输出用初始化函数 time_csh(); //调两个定时器初始化函数 } //********************上电防飞车函数归0后led正常闪烁****************************** void sd_ffc(void) { set_p13_adc(); //调转把电压转换通道 get_ad_dy(); //上电后测量转把电压是否归零 while(adc_data>=61) //61为1.2v转换值转把如果大于1.2v执行循环体语句等待归0 {ledcs=2;led_k(); //循环体语句,2次间隔性快闪灯 get_ad_dy(); //循环体语句,重新检测电压等待归0 } tr0=0; //关pwm频率否则干扰闪灯 timebj=12; //归0后定时器中断10次闪烁一次led tr1=1; //归0后开定时器1-led闪烁 } //*************刹车函数自动选择是断电还是abs刹车功*************************** void sc_stop(void) //abs刹车有外接口对地选择,对地时为abs功能 { if(shache==0) //判断语句刹车口等于0执行大语句1 { abs=1; //大语句体1 if(abs==1) //判断abs选择不为0就执行普通刹车断电,否则执行abs刹车 //==========普通刹车断电================================================== { tr0=0;led=0; //关测速定时器,亮刹车灯 pca_pwm0=0x03; //关3路pwm信号ah pca_pwm1=0x03; //关3路pwm信号bh pca_pwm2=0x03; //关3路pwm信号ch pwmal=0;pwmbl=0;pwmcl=0; //关3路下桥 //---------------------------------------------------------------------- while(shache==0) //循环语句,刹车口没松开就一直等待 {delay(500);} //语句体,延时抗干扰防止抖动 hehc_bl=0;led=1; //刹车口松开后清霍尔变量内存再关刹车灯 //---------------------------------------------------------------------- for(pwm_bls=241;pwm_bl!=pwm_bls;pwm_bls--) //以下两句为刹车口松开后减缓冲击 {he_gzjc();pwm_out();} //从最低速度加高到实时的转把设定速度 } //===========eabs刹车断电===================================================== else //abs功能已选择进入abs刹车 { // tr0=0;led=0; //关测速定时器,亮刹车灯 pca_pwm0=0x03; //关3路pwm信号ah pca_pwm1=0x03; //关3路pwm信号bh pca_pwm2=0x03; //关3路pwm信号ch pwmal=0;pwmbl=0;pwmcl=0; //关闭3个下桥:al-bl-cl //-------------------------------------------------------------------------
上一篇:GY-30数字光强度模块BH1750FV
下一篇:stc89c51+ esp8266-01发微信消息,POST例程
推荐阅读最新更新时间:2024-11-07 12:26