求一款单片机芯片,控制基于单片机的步进电机控制系统设计的。A2210


麦克阿瑟曾经说过,如果你到暑假了才找到这份步进电机实习报告,那么你的单片机八成是要等着挂科了。摘要:步进电机是一种将电脉冲信号变换成相应的角位移的机电执行元件,每输入一个脉冲信号, 转子就转动一个角度或前进一步,其输出的角位移或线位移与输入的脉冲数成正比,转速与脉冲频 率成正比。。通过控制脉冲个数来控制角位移量,可以达到准确定位的目的,调节脉冲频率来控制 电机转动的速度,从而达到调速的目的。 本设计采用 AT89C51 系列单片机对步进电机进行控制,对步进电机系统的控制方式和软件设计 进行了研究,在此次实习中我们采用串口通信与利用定时器功能相结合的方式来操纵电机,通过精 简的命令来控制电机的转向和速度,并将电机的运行速度和运行时间显示在 LCD 上。 关键词:AT89C51 系列单片机;步进电机;LCD;一、 总体设计方案 1.1 设计任务与要求 (1) 通过单片机控制步进电机单步或连续运行。 (2) 使用按键控制步进电机运行和正反转。 (3) 通过按键设置步进电机运行速度、运行时间、转动角度等,并将有关参数显 示在LCD显示器上。 1.2.设计步骤 (1) 使用Proteus按设计要求绘制电路图。 (2) 按要求编写相应程序。 (3) 使用Proteus仿真程序,对程序进行调试。 (5) 撰写课程设计报告。 1.3 硬件设计 (1)中心电路:中心电路采用 AT89C51 单片机芯片。 (2)输入电路:由开关进行控制,分别控制正转、反转、加速、减速、连续运行。 (3)输出电路:输出分为两个部分,一部分是由 ULN2003 芯片连接到步进电机作 为驱动控制输出,另一部分是接一个 LCD 液晶显示屏作为当前转速的输出显示。 具体仿真如图:(图一 仿真效果图) 1.3.1 硬件各模块概要 根据设计需求,我们将硬件分为四个模块,分别为信息处理模块、控制输入模块、 驱动输出模块、显示模块。 (1) 信息处理模块 (图二 信息处理) 此处采用与实际硬件相同的AT89C51 型单片机,AT89C52内置8位中央处理单元、 512 字节内部数据存储器 RAM、8k 片内程序存储器(ROM)32 个双向输入/输出(I/O) 口、3 个 16 位定时/计数器和 5 个两级中断结构,一个全双工串行通信口,片内时钟实习报告 6 振荡电路。此外,89C52 还可工作于低功耗模式,可通过两种软件选择空闲和掉电模 式。在空闲模式下冻结 CPU 而 RAM 定时器、串行口和中断系统维持其功能。掉电模 式下,保存 RAM 数据,时钟振荡停止,同时停止芯片内其它功能。89C51 有 PDIP(40pin) 和 PLCC(44pin)两种封装形式。它基于标准的 MCS-51 单片机体系结构和指令系统, 属于 89C51 增强型单片机版本,集成了时钟输出和向上或向下计数器等更多的功能, 适合于类似马达控制等应用场合。 (2)驱动输出模块 步进电机模块中使用的驱动芯片为ULN2003A [2],该模块最主要的是利用ULN2003芯片 将我们的单片机和要控制的步进电机连接起来。ULN2003内部还集成了一个消线圈反电 动势的二极管,可用来驱动继电器。它是双列16脚封装,NPN晶体管矩阵,最大驱动电压 =50V,电流=500mA,输入电压=5V,适用于TTL COMS,由达林顿管组成驱动电路。 ULN是集 成达林顿管IC,内部还集成了一个消线圈反电动势的二极管,它的输出端允许通过电流 为200mA,饱和压降VCE 约1V左右,耐压BVCEO 约为36V。用户输出口的外接负载可根据 以上参数估算。采用集电极开路输出,输出电流大,故可直接驱动继电器或固体继电器, 也可直接驱动低压灯泡。通常单片机驱动ULN2003时,上拉2K的电阻较为合适,同时, COM引脚应该悬空或接电源。 步进电动机是一种将电脉冲信号转换成角位移或线位移的机电元件。步进电动机的 输入量是脉冲序列,输出量则为相应的增量位移或步进运动。正常运动情况下,它每转 一周具有固定的步数;做连续步进运动时,其旋转转速与输入脉冲的频率保持严格的对 应关系,不受电压波动和负载变化的影响。由于步进电动机能直接接受数字量的控制, 所以特别适宜采用微机进行控制。(图三 四相八拍步进电机)(4)显示模块 显示模块主要是通过将 LCD 液晶显示屏接到 P0 口与单片机相连,将步进电机当前 的转速情况,通过的单片机的中心信息处理,输出到液晶显示屏,这样显示屏就可以显 示电机当前的转速,正反转状态,角度,运行时间及转过的圈数。使得使用者对目前电 机的参数有了更加数字化的了解。 LCD 显示器的原文是 Liquid Crystal Display,取每字的第一个字母组成,中文多 称「液晶平面显示器」或「液晶显示器」。其工作原理就是利用液晶的物理特性:通电 时排列变得有序,使光线容易通过;不通电时排列混乱,阻止光线通过,说简单点就是 让液晶如闸门般地阻隔或让光线穿透。 LCD 的好处有: 与 CRT 显示器相比,LCD 的优 点主要包括零辐射、低功耗、散热小、体积小、图像还原精确、字符显示锐利等。(图四 液晶显示模块) 1.4 软件设计 软件编码的实现,主要分为三个部分:初始化及自定义部分、驱动控制主函数部 分、各部分控制的子函数部分。其中自定义及初始化部分的代码将后边要用的变量进行 定义,对于显示和应用的数组进行初始化。其次是各个模块的控制的子程序的编写,由 于函数过多而且大多并没有多次的调用,故并没有写很多,而是只写了少数会经常被使 用的比如显示屏初始化函数,写/读函数等显示屏会经常用到的函数。最后是我们的主 函数,和其他不一样,我们的主函数通过扫描矩阵键盘所生成的 value 值,然后通过 value 值的不同情况来运行不同的指令,进而达到通过按键控制步进电机驱动来实现对 步进电机的转动控制。 二、结论 2.1 仿真成果部分展示
(图六 反转) 2.2 实物效果图 三实验代码及注释 #include<reg51.h> #include<stdio.h> #include<intrins.h>//输入头文件
#define uchar unsigned char #define uint unsigned int sbit E=P2^6; sbit RS=P2^4; sbit RW=P2^5;//定义 lcd1602 模块输入口 uchar code ZZDM[8]={0x09,0x08,0x0c,0x04,0x06,0x02,0x03,0x01}; uchar code FZDM[8]={0x01,0x03,0x02,0x06,0x04,0x0c,0x08,0x09};//定义四相八拍单片机正反 转代码 uchar DYH[]="State: V: 002"; uchar DEH[]="Time:000 Ang:000";//定义屏幕开始时显示代码 uchar m; uchar value,flag=5; speed=2; zflag,znum,fflag,fnum,select,pp,qq,pt,sjj=0; float zz,fz,sj; void delay(uint z)//当 z 取 1 时,约 0.11us { uint x,y; for(x=z;x>0;x--) for(y=100;y>0;y--); } void delay1ms() //由烧录软件生成的函数,延迟 1 毫秒,晶振频率为 11.0592MHz { uchar i, j; _nop_(); _nop_(); _nop_(); i = 11; j = 190; do { while (--j); } while (--i); } void LcdWriteCmd(uchar cmd)//定义 Lcd 写指令函数 { delay(5);//消除抖动 RS=0;//定义指令模式实习报告 RW=0;//定义写模式 P0=cmd; E=1;//数据有效 delay(2); E=0;//执行命令 } void LcdWriteData(uchar dat)//定义写数据函数 { delay(5); RS=1;//数据模式 RW=0; P0=dat; E=1; delay(2); E=0; } void Lcdinit()//液晶模块初始化函数 { delay(15); LcdWriteCmd(0X38);//显示设置,设置为两行显示,每一小格为 5*7 矩阵 LcdWriteCmd(0X0c);//显示开,光标关,闪烁关 LcdWriteCmd(0X06);//读写操作后,光标自动加一,画面不动 LcdWriteCmd(0X01);//光标复位,清屏 LcdWriteCmd(0x80);//定位到第 1 个矩阵写数据 } void LcdGotoXY(uchar line,uchar column)//定义坐标函数 { if(line==0) LcdWriteCmd(0x80+column);//设置坐标,同时将其最高位 D7 位置为高电平 if(line==1) LcdWriteCmd(0x80+0x40+column); } void Display()//定义初始化显示函数 { delay(15); LcdWriteCmd(0x38); LcdWriteCmd(0x06); LcdWriteCmd(0x0c); LcdWriteCmd(0x01); LcdGotoXY(0,0); for(m=0;m<16;m++)//16 个格子 { LcdWriteData(DYH[m]);//屏幕显示第一行内容 delay(15); } LcdGotoXY(1,0); for(m=0;m<16;m++) { LcdWriteData(DEH[m]); delay(15); } } void keyscan()//定义键盘扫描函数 { P3 = 0x3c;//P3 口初始化,将四个按键全部置为高电平,表示未按下 if(P3!=0x3c) { delay(10); switch(P3) { case 0x1c: value= 0; break; case 0x2c: value= 1; break; case 0x34: value= 2; break; case 0x38: value= 3; break; } while(P3!=0x3c);//检测是否松开按键 if(value==1) { delay(5); if(value==1) { flag=5; } } } }
void write_sfm(uchar add,uchar date)//Lcd 屏显示三位数 { uchar bai,shi,ge; bai=date/100; shi=date%100/10; ge=date%10; LcdWriteCmd(0x80+add); LcdWriteData(0x30+bai); LcdWriteData(0x30+shi); LcdWriteData(0x30+ge); LcdWriteData(0x20); } void handle_flag() { uchar select1; if(flag==5) { select1++; select1%=2; if(select==0) { TR0=0; TR1=0;//关闭定时计数器 if(select==0) write_sfm(0x40+0x0D,zz); else write_sfm(0x40+0x0D,fz); } else { P1=0xff; if(select1==0) { TR0=1; TR1=0;//启动定时器 1(方式 1) } else { TR1=1; TR0=0;//启动定时器 2(方式 1) } znum=0; fnum=0; pp=0; qq=0; zflag=0; fflag=0; write_sfm(0x40+0x05,0); write_sfm(0x40+0x0D,0); } } flag=0; } void pdzfz()//判断并显示正反转函数 { if(value==0) { delay(5); if(value==0) { pt++; if(pt>=2) { pt=0; TR0=0; TR1=1; LcdWriteCmd(0x80+0x07); LcdWriteData('-'); delay(20); select=1; } else { TR0=1; TR1=0; LcdWriteCmd(0x80+0x07); LcdWriteData('+'); delay(20); select=0; } } }
} void jjsxs()//定义加减速运算以及显示函数 { if(value==2) { speed++; if(speed>=3) speed=3; write_sfm(0x0D,speed); delay(20); } if(value==3) { speed--; if(speed<=1) speed=1; write_sfm(0x0D,speed); delay(20); } } void zfzyx() { if(TR0==1) { jjsxs();//调用加减速运算及显示代码 if(zflag==4096)//若中断达到 4096 次则进入新的累加 { zflag=0; } if(zflag%64==0)//若正转外部转动 5.625 度 { pp++; zz=(uint)(pp*5.625);//计算累计转动角度 if(zz==360)//若转动一圈 pp=0; write_sfm(0x40+0x0D,zz); switch(speed)//根据不同速度档位计算 1 秒所需剩余时间 { case 1: sj=sj+0.234368; break; case 3: sj=sj+0.937472; break; case 2: sj=sj+0.117184; break; } write_sfm(0x40+0x05,sj); } } if(TR1==1)//反转代码参考正转代码 { jjsxs(); if(fflag==4096) { fflag=0; } if(fflag%64==0) { sj++; qq++; fz=(uint)(qq*5.625); if(fz==360) qq=0; write_sfm(0x40+0x0D,fz); if(zz==360) pp=0; write_sfm(0x40+0x0D,zz); switch(speed) { case 1: sj=sj+0.234368; break; case 3: sj=sj+0.937472; break; case 2: sj=sj+0.117184; break; } write_sfm(0x40+0x05,sj); 19 } } } void main()//主函数 { pp=0; qq=0; TMOD=0x11;//定时器方式 1 EA=1;//开启总中断 ET0=1;//允许 T0 口中断 ET1=1;//允许 T1 口中断 TH0=(65536-(14648/speed))/256; TL0=(65536-(14648/speed))%256;//由于减速比为 64,转一圈为 360 度,其中内部一次步进 为 5.625 度,故一次步进外部为 5.625/64 度,一圈需要 360/(5.625/64)等于 4096 次步进,若外部 转一圈为 60s,则一次步进需要 60/4096 约 14648 微秒。 TH1=(65536-(14648/speed))/256; TL1=(65536-(14648/speed))%256; TR0=0; TR1=0;//初始化定时器 Display(); while(1) { value=1; keyscan();//检测是否键按下 handle_flag(); pdzfz(); zfzyx(); } } void time0() interrupt 1 { uint zzz; TH0=(65536-(14648/(13-(speed*4))))/256; TL0=(65536-(14648/(13-(speed*4))))%256; zzz%=8; P1=FZDM[zzz]; zzz++; zflag++; } void time1() interrupt 3实习报告 { uint ffz; TH1=(65536-(14648/(13-(speed*4))))/256; TL1=(65536-(14648/(13-(speed*4))))%256; ffz%=8; P1=ZZDM[ffz]; ffz++; fflag++; } 到这里就结束了。如果需要具体的完整文件包(含实验报告,仿真图,视频讲解),可以私我。
一、背景(1)L298N简介
L298N 是一种双H桥电机驱动芯片,其中每个H桥可以提供2A的电流,功率部分的供电电压范围是2.5-48v,逻辑部分5v供电,接受5vTTL电平。一般情况下,功率部分的电压应大于6V否则芯片可能不能正常工作。它可以用来控制直流电机,也可以控制步进电机。(2)步进电机简介
步进电机又称为脉冲电机,基于最基本的电磁铁原理,它是一种可以自由回转的电磁铁,其动作原理是依靠气隙磁导的变化来产生电磁转矩。由于步进电机是一个可以把电脉冲转换成机械运动的装置,具有很好的数据控制特性,因此,计算机成为步进电机的理想驱动源, 随着微电子和计算机技术的发展,软硬件结合的控制方式成为了主流,即通过程序产生控制脉冲,驱动硬件电路。单片机通过软件来控制步进电机, 更好地挖掘出了电机的潜力。在不超载的情况下电机的转速和停止位置只取决于脉冲信号的频率和数量;并且步进电机的脉冲与步进旋转的角度成正比,脉冲的频率与步进的转速成正比,所以可以很好的从源头控制信号的输出;且步进电机只有周期性的误差,使得在速度、位置等控制领域用步进电机来控制变的非常的简单。下面是步进电机的拆解图:本设计就是使用proteus仿真软件对步进电机的控制进行简单的仿真,帮助大家了解和入门步进电机。当然如果想要更好的控制电机还是需要别的控制算法,这里先不做介绍。(3) LCD1602液晶显示器
LCD1602液晶显示器曾经是广泛使用的一种字符型液晶显示模块。它是由字符型液晶显示屏(LCD)、控制驱动主电路HD44780及其扩展驱动电路HD44100,以及少量电阻、电容元件和结构件等装配在PCB板上而组成。不同厂家生产的LCD1602芯片可能有所不同,但使用方法都是一样的。为了降低成本,绝大多数制造商都直接将裸片做到板子上。不多目前这种液晶性价比并不好,使用的越来越少了。二、设计目标
使用51单片机控制步进电机的正反转,加减速。设置有三个按键,通过按键控制步进电机的正反转和加减速等。同时设计有LCD1602液晶显示器,通过LCD1602可以显示步进电机的状态,包括方向、启停,档位等。三、设计过程首先我们使用proteus软件绘制好仿真图,如图所示然后使用keil建立工程并编写相应的程序,如图最后加载HEX文件就可以通过proteus进行仿真了,如下视频所示对仿真感兴趣的话可以关注我,通过下面的方式获取点我获取仿真和程序发布于 2021-03-04 15:04

我要回帖

更多关于 基于单片机的步进电机控制系统设计 的文章