完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
一、设计要求
使用 PWM 电路来控制直流电机的正转、反转、加速和减速,并将转向和转速显示出来。 设置按键控制直流电机的启动/停止的开关 设置按键控制直流电机的加速、减速 设置按键控制直流电机的正转、反转 设置显示模块可以直观地了解到直流电机的转速和转向 二、设计思路 直流电机 PWM 控制系统的主要功能包括:直流电机的加速、减速以及电机的正转和反转,并且可以调整电机的转速,还可以方便地读出电机转速的大小和转向,从而实现电机的智能控制。其中还包括直流电机的直接清零、启动(置数)、暂停等功能。 该直流电机系统由以下电路模块组成:振荡器和时钟电路,这部分电路主要由 AT89C51 单片机和一些电容、晶振组成。 设计输入部分:这一模块主要是利用带中断的独立按键来实现。 设计控制部分:主要由 AT89C51 单片机的外部中断扩展电路组成。 设计显示部分:包括液晶显示部分和 LED 数码显示部分。液晶显示部分由 LCD 液晶显示模块组成;LED数码显示部分由七段数码显示管组成。 直流电机 PWM 控制实现部分:主要由一些二极管、电机和 L298 直流电机驱动模块组成。 三、仿真电路设计 AT89C51单片机、外接晶振、复位电路 P2口 P0-P7 接 LCD 的D0-D7,P0.5、P0.6、P0.7分别接 LCD 的RS、RW、E,且要接上拉电阻,P0口无上拉电阻,不然点不亮,实际应用中也要接。 独立按键通过 7 输入与门与 P3.3 口 (外部中断1) 相连 P1.0接IN1,P1.1接IN2,P1.2接 L298 使能信号ENA,初始化ENA=0;TR0=0,启动,使能ENA,TR0=~TR0,开启定时,输出PWM波。 P3.3口引起外部中断,调用按键扫描函数,进入按键处理程序。 在定时器中断服务子程序中,direc=1,为正转,IN1=1,IN2=0;direc=0,IN1=0,IN2=1,为反转,控制电机正转、反转,通过条件控制,可以改变输出 PWM 矩形波的占空比,从而实现调速效果。 四、KeilC51程序设计 1. 初始化参数 #include《reg52.h》#define uint unsigned int #define uchar unsigned char ***it k1=P3^4; //启动/停止按键***it k2=P3^5; //减速按键***it k3=P3^6; //加速按键***it k4=P3^7; //正反转按键***it k5=P3^2; //模式控制//LCD1602控制引脚,其中P2为数据口***it RS=P0^5;***it RW=P0^6;***it E=P0^7;***it ENA=P1^2; //IN1,IN2使能信号***it IN1=P1^0; //电机输入线***it IN2=P1^1;bit model=1; //手动/自动,默认启动时显示自动bit direc=1; //转向标志,默认启动时为正转 Lint rate=1; //高电平时间常数int num=0; //1ms中断记录 统计脉冲个数int count=0; //1ms中断记录,自动模式加速时间常数uchar code tab1[]=“ Welcome ”;uchar code tab2[]=“ 2020/12/9”;uchar code tab3[]=“ Motor Control ”;uchar code tab4[]=“Team:ZHL YYQ ZYY”;uchar code tab5[]=“Dire: Mode: ”;uchar code tab6[]=“Rate: T:29 ”; 2. LCD显示 /********************** LCD显示 ****************************/void w_com(uint com) //写指令{ RS=RW=E=0; P2=com; E=1; //写指令的操作时序:RS=0,RW=0,EN=高电平 delay_xus(1); E=0;}void w_data(uint dat) //写数据{ RS=1;RW=E=0; P2=dat; E=1; //写数据的操作时序:RS=0,RW=0,EN=高电平 delay_xus(1); E=0;}void w_shuzu(int addr,uchar code *p) //显示字符串{ int i; w_com(0x80+addr); delay_xus(1); for(i=0;p!=‘ ’;i++) //串口发送字符串时,可以通过‘ ’判断字符串是否结束 { w_data(p); delay_xus(1); } }void disp() //显示速度、转向、模式{ //显示数值 转成ASCII码表 if(rate《10) //小于10的时候 只有个位 { w_com(0x80+0x45); delay_xus(1); w_data(‘ ’); delay_xus(1); w_com(0x80+0x46); delay_xus(1); w_data(rate%10+0x30); //查ASCII码表 这一位的数字+0x30 数字转换成ASCII码才能显示 delay_xus(1); } else { w_com(0x80+0x45); delay_xus(1); w_data(rate/10+0x30); //十位 delay_xus(1); w_com(0x80+0x46); delay_xus(1); w_data(rate%10+0x30); //个位 delay_xus(1); } if(direc==1) //正转 { w_shuzu(0x06,“L”); } else //反转 { w_shuzu(0x06,“R”); } if(model==0) //手动按键控制 { w_shuzu(0x0f,“H”); } else //自动 { w_shuzu(0x0f,“A”); }} 3. 主程序初始化 /************* 主程序初始化 ************************/void init(){ //LCD显示初始化 w_com(0x38); //设置16*2显示 delay_xus(1); w_com(0x0c); //开显示 显示光标,光标闪烁 delay_xus(1); w_shuzu(0x00,tab1); //显示字符串 w_shuzu(0x40,tab2); delay(500); w_com(0x01); //清屏 delay_xus(1); delay(2); //忙碌 w_shuzu(0x00,tab3); w_shuzu(0x40,tab4); delay(1000); w_com(0x01); //清屏 delay_xus(1); delay(2); w_shuzu(0x00,tab5); w_shuzu(0x40,tab6); disp(); ENA=0; TMOD=0X01; //定时器0工作在方式1 TH0=0XFC; //(65536-1000)=FC18(12MHz定时的1ms) TL0=0X18; ET0=1; //定时器0中断允许 TR0=0; EX1=1; //外部中断INT1 IP=0X02; //设置定时器0为高优先级中断 T0的中断级别为高,因为PWM的脉冲宽度就是在中断程序里设定,如果此时被其他更高级别的中断打断,那么脉冲宽度将不准确,从而导致控制转速失败。 EA=1; //开总中断} 4. 主程序 /*********************** 主程序 ***************************/void main(){ init(); while(1) ;} 5. 延时子程序 /***************** 延时子程序 **************************/void delay_xus(uint x) //小延时 us{ while(x--);}void delay(uint x) //为12MHz晶振提供延时函数 ms级{ uint y; for(;x》0;x--) for(y=110;y》0;y--) ;} 6. 按键处理程序 /******************* 按键处理程序 ************************/void keyscan(){ if(k1==0) //启停 { delay(120); if(k1==0) { TR0=~TR0; //开启定时 输出PWM波 ENA=~ENA; //使能 电机转 rate=1; } } if(k2==0&&model==0) //减速 减速键按下 { delay(120); if(k2==0&&model==0) { rate-=2; //为之后改变输出PWM波的占空比 if(rate《=1) rate=1; } } if(k3==0&&model==0) //加速 加速键按下 { delay(120); //软件延时 if(k3==0&&model==0) { rate+=2; //为之后改变输出PWM波的占空比 if(rate》=29) rate=29; } } if(k4==0&&model==0) //转向 { delay(120); if(k4==0&&model==0) { direc=~direc; //取反 } } if(k5==0&&ENA==0) //模式选 { delay(120); if(k5==0&&ENA==0) { model=~model; } } disp(); //状态改变,更新显示数据} 7. 中断服务子程序 /******************* 中断服务程序 *************************/void extern1() interrupt 2 //外部中断INT1 按键扫描{ keyscan();}void timer0() interrupt 1 //定时器0中断{ num++; //计数 if(num》=29) num=0; //超过范围 num=0 if(direc==1) //通过direc判断 为正转 { if(num《=rate) //跟rate比较 高电平持续时间 { IN1=1; //正转 IN2=0; } else IN1=IN2=0; //低电平持续时间 } else //否则 反转 { if(num《=rate) { IN1=0; //反转 IN2=1; } else IN1=IN2=0; } if(model==1) //自动模式下,执行,加速时间常数 { count++; if(count==1500) //1.5s后占空常数增加,加速 { rate+=2; if(rate》=29) rate=29; count=0; disp(); } } TH0=0XFC; //重装初值 (65536-1000)=FC18(12MHz的定时1ms) TL0=0X18; } |
|
|
|
只有小组成员才能发言,加入小组>>
2493 浏览 0 评论
9481 浏览 4 评论
37292 浏览 19 评论
5123 浏览 0 评论
25343 浏览 34 评论
1803浏览 2评论
2078浏览 1评论
2565浏览 1评论
1819浏览 0评论
828浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-3-5 06:17 , Processed in 1.201945 second(s), Total 45, Slave 39 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191