采用PWM的控制原理来完成对直流电机的正转、反转以及其加速、减速过程的控制,在此过程中是通过 单片机的定时器加上中断的方式产生不同时长的高低电压脉冲信号来完成。并通过红外对管测速仪对直流电机的转速进行测定,最后将实时测定的转速数值显示在四位共阴极的数码管上。
直流电机驱动设计 L298N可接受标准TTL逻辑电平信号VSS,VSS可接4.5~7 V电压。4脚VS接 电源电压,VS电压范围VIH为+2.5~46 V。输出电流可达2.5 A,可驱动电感性负载。1脚和15脚下管的发射极分别单独引出以便接入电流采样电阻,形成电流传感信号。L298可驱动2个电动机,OUT1,OUT2和OUT3,OUT4之间可分别接电动机,本实验装置我们选用驱动一台电动机。5,7,10,12脚接输入控制电平,控制电机的正反转。EnA,EnB接控制使能端,控制电机的停转。表1是L298N功能逻辑图。In3,In4的逻辑图与表1相同。由表1可知EnA为低电平时,输入电平对电机控制起作用,当EnA为高电平,输入电平为一高一低,电机正或反转。同为低电平电机停止,同为高电平电机刹停。 单片机最小系统与独立按键、数码管显示电路图 L298N的驱动电路和单片机的连接线路图
5.2、设计说明: 按键说明: K1——正反转切换键 K2——转速加按键 K3——转速减按键 显示说明: 四位一体数码管显示转速,最高位为转速方向显示,电机顺时针转时为灭零显示,电机逆时针转时显示负号。其他三位显示转速,转速单位r/min。 调速范围:-900r/min~900r/min。 5.3、程序流程图: 主程序流程图:
程序: #include ***it Dck=P1^0; ***it Led1=P1^1; ***it Led2=P1^2; ***it Seg1=P1^3; ***it Seg2=P1^4; ***it Seg3=P1^5; ***it Seg4=P1^6; ***it Mink=P1^7; ***it Led3=P3^1; ***it Add=P3^2; ***it Dec=P3^3; #define Disdata P0 #define Dac P2 #define uchar unsigned char #define uint unsigned int #define MARK 4 //用于输出任意分频的pwm波 uchar code dis_7[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};// 共阳极段选码 vola tile uchar data display[4]={0x00,0x00,0x00,0x00}; // 用于暂存数码管的输出数据流int Tnum=0, //定时器0定时次数的记录 Pnum=2; //用于和Tnum比较产生需要的pwm波 snum=0; uint full=0; //用于记录定时器1的溢出次数 /*************延时程序************************/ void delay(uint t) { for(;t>0;t--); } /**************数码管显示*********************/ /***********pwm波定时发生*********************/ void Time0_srv() interrupt 1 { snum++; if(snum>40) snum=0; if(snum>0&&snum<=10) { Seg4=1; Disdata=~dis_7[display[0]]; delay(30); Seg1=0; } if(snum>10&&snum<=20) { Seg1=1; Disdata=(~dis_7[display[1]])|0x80; delay(30); Seg2=0; } if(snum>20&&snum<=30) { Seg2=1; Disdata=~dis_7[display[2]]; delay(30); Seg3=0; } if(snum>30&&snum<=40) { Seg3=1; Disdata=~dis_7[display[3]]; delay(30); Seg4=0; } { TH0=(65536-425)/256; TL0=(65536-425)%256; if(Tnum { Dck=1; } else { Dck=0; } Tnum=Tnum+1; Tnum=Tnum%MARK; } } /*****************按键程序1*****************/ void key1() interrupt 0 { delay(4000); if(Add==0 ) { Pnum++; if(Pnum>=MARK+1) Pnum=MARK; } switch(Pnum) { case 0: Dac=0x00;break; //-- case 1: Dac=0x3f;break; //- case 2: Dac=0x7f;break; //0 case 3: Dac=0xbf;break; //+ case 4: Dac=0xff;break;//++ } } /****************按键程序2******************/ void key2() interrupt 2 { delay(4000); if(Dec==0) { Pnum--; Tnum=0; if(Pnum<0) Pnum=0; } switch(Pnum) { case 0: Dac=0x00;break; //-- case 1: Dac=0x3f;break; //- case 2: Dac=0x7f;break; //0 case 3: Dac=0xbf;break; //+ case 4: Dac=0xff;break;//++ } } /**************测速程序1*******************/ void Time1_srv() interrupt 3 { full++; if(full==10000) { TR0=0; full=0; TH1=0; TL1=0; Led3=1; } } /*************测速程序2*****************/ void Freeback() { static uchar dj=0; float time=0.0; uint rad=0; if(Mink==0) { TR1=1; dj++; Led3=0; } while(!Mink); if(dj==2) { TR1=0; time=full*65.536+TH1*0.256+TL1*0.001; full=0; TH1=0; TL1=0; rad=(2*3.14/(time*0.001)+0.5)*10; display[3]=rad/1000; display[2]=rad%1000/100; display[1]=rad%100/10; display[0]=rad%10; dj=0; } } /***************模块初始化****************/ void initi() { TMOD=0X11; EA=1; ET0=1; ET1=1; PT0=1; TR0=1; Dck=1; TH0=(65536-425)/256; TL0=(65536-425)%256; TH1=0; TL1=0; EX0=1; IT0=1; PX0=1; EX1=1; IT1=1; PX1=1; Mink=1; Dac=0x7f; } /****************主函数*******************/ void main() { initi(); while(1) { Freeback(); } }
|