花了三天时间测试买了很久的L298N迷你板, 之前接了单片机的P0^0和P0^1结果没有反应, 还以为是L298N坏了
老样子, 单片机代码我尽量备注详细, 别问我要电路图啊, 引脚接线我都已注明清楚
/*******************************************************************//* 程序名称:STC89C52_PWM直流电机调速及正反转 /* 单片机型号:STC89C52系列 晶振:11.00592 MHz /* 单片机供电5V, L298N模块可共用电源, 也可以单独外接电源(具体看L298N模块说明) /* 直流电机的PWM波控制,可以直接调速从0到100共21级(每级+5) /* 所谓的占空比其实就是利用计数改变0和1的比列 /* 大家可以接LED测试, 当占空比越大, LED灯闪烁越慢, 当占空比越小, LED闪烁越快, 直到眼睛都看不出有闪烁 /* 新增功能: /* 2020.10.24 新增长按停止, 短按保留正反转 /* 2020.10.25 将调速等级和正反转状态写入EEPROM, 以便关机后再次开机能保留关机前状态 /*****************************************************************/ #include "eeprom.h" #define TH0_TL0 (65536-1000)//设定中断的间隔时长 //引脚声明 sbit Key_add=P2^0; //电机加速(轻触开关一脚接P2^0, 斜对脚接GND) sbit Key_minus=P2^1; //电机减速(轻触开关一脚接P2^1, 斜对脚接GND) sbit Key_fr=P2^2; //电机反向(轻触开关一脚接P2^2, 斜对脚接GND) //L298N模块+引脚接VCC, -引脚接GND //MOTOR-A二个引脚接电机的二个引脚, 正反自己按需求调整 sbit PWM1=P2^6; //PWM1 (接L298N模块的L298N模块的INT1) sbit PWM2=P2^7; //PWM2 (接L298N模块的L298N模块的INT2) //配合eeprom使用 uchar code set1[21]={0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12,0x13,0x14,0x15}; //用来判断调速等级 uchar code set2[2]={0x01,0x02}; //用来判断正反转 uint zsdj; //转速等级 uchar count0; //低电平的占空比 uchar count1 = 0;//高电平的占空比 bit Flag;//电机正反转标志位 -- 1正转,0反转 bit zt = 1; //记录状态(1启动, 0停止) //用于判断Key_fr的长按短按 #define key_S 500 //宏定义短按(约20ms) #define key_L 16000 //宏定义长按(约2/3s) #define key_M 8000 //宏定义长按间隔(约1/3s) /************函数声明**************/ void Write_Eeprom(void); //写eeprom void Motor_High_speed(void); //马达高速 void Motor_Low_speed(void); //马达低速 void Motor_Forward_and_Reverse(void); //马达正反转 void Timer0_init(void); //定时器0初始化 /*写eeprom*/ void Write_Eeprom(void){ IapEraseSector(0x2000); //擦除0x2000--0x21FF IapProgramByte(0x2001,set1[zsdj]); //存储count0 IapProgramByte(0x2002,set2[Flag]); //存储Flag } /*******按键+处理增加PWM,PWM越大,电机越快**********/ void Motor_High_speed(void) { if(Key_add==0) { Delay(10); if(Key_add==0) { count0 += 5; zsdj += 1; if(count0 >= 100) { count0 = 100; } if(zsdj >= 20) { zsdj = 20; } Write_Eeprom(); //eeprom操作 } while(!Key_add);//等待键松开 } } /*******按键-处理减少PWM,PWM越小,电机越慢**********/ void Motor_Low_speed(void) { if(Key_minus==0) { Delay(10); if(Key_minus==0) { count0 -= 5; zsdj -= 1; if(count0 <= 0) { count0 = 0; } if(zsdj <= 0) { zsdj = 0; } Write_Eeprom(); //eeprom操作 } while(!Key_minus); } } /************电机正反向控制**************/ void Motor_Forward_and_Reverse(void) { static uint jcs=0; //计数变量 if(!Key_fr) { jcs++; if(jcs>=key_L) //长按 { jcs=key_M; //设一个值 zt=0; //停止 } } else //按键抬起 { if(jcs>key_S && jcs<key_M)//短按 { if(zt==1){ Flag=~Flag; //当状态为1时,才会切换正反转 Write_Eeprom(); //eeprom操作 } if(zt==0){ PWM1=0; //当状态为0时,启动为正转 PWM2=1; } zt=1; //设状态为1 } jcs=0; //count清0 } } /***********定时器0初始化***********/ void Timer0_init(void) { TMOD=0x01; //定时器0工作于方式1 TH0=TH0_TL0/256; TL0=TH0_TL0%256; TR0=1; ET0=1; EA=1; } /*********主函数********************/ void main(void) { //开机初始化定时器0 Timer0_init(); //开机读取记忆数据(转速等级) switch(IapReadByte(0x2001)) { //判断 case 0x01:count0=0;zsdj=0;break; case 0x02:count0=5;zsdj=1;break; case 0x03:count0=10;zsdj=2;break; case 0x04:count0=15;zsdj=3;break; case 0x05:count0=20;zsdj=4;break; case 0x06:count0=25;zsdj=5;break; case 0x07:count0=30;zsdj=6;break; case 0x08:count0=35;zsdj=7;break; case 0x09:count0=40;zsdj=8;break; case 0x0A:count0=45;zsdj=9;break; case 0x0B:count0=50;zsdj=10;break; case 0x0C:count0=55;zsdj=11;break; case 0x0D:count0=60;zsdj=12;break; case 0x0E:count0=65;zsdj=13;break; case 0x0F:count0=70;zsdj=14;break; case 0x10:count0=75;zsdj=15;break; case 0x11:count0=80;zsdj=16;break; case 0x12:count0=85;zsdj=17;break; case 0x13:count0=90;zsdj=18;break; case 0x14:count0=95;zsdj=19;break; case 0x15:count0=100;zsdj=20;break; default:count0=50;zsdj=10; } //开机读取记忆数据(正向或反向) if(IapReadByte(0x2002)==0x01){ Flag = 0; } else if(IapReadByte(0x2002)==0x02){ Flag = 1; } while(1) { Motor_High_speed(); //加速 Motor_Low_speed(); //减速 Motor_Forward_and_Reverse(); //正反转 } }
复制代码