微机原理(单片机)课程设计 总结报告-步进电机控制A_第1页
微机原理(单片机)课程设计 总结报告-步进电机控制A_第2页
微机原理(单片机)课程设计 总结报告-步进电机控制A_第3页
微机原理(单片机)课程设计 总结报告-步进电机控制A_第4页
微机原理(单片机)课程设计 总结报告-步进电机控制A_第5页
已阅读5页,还剩25页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

微机原理(单片机)课程设计报告项目编号:微机原理(单片机)课程设计总结报告项目名称:步进电机控制A

微机原理(单片机)课程设计任务书项目名称:步进电机控制A内容与要求:上位机:完成界面设计与通讯程序能够设置步进电机的启动、停止、正转、反转能够设置步进电机转速(快中慢)圈数能够保存或读取电机的工作状态可以对串口进行设置下位机:完成电路设计与控制程序完成步进电机的控制按键1可控制电机的启动和停止,按键2可控制电机的转动方向,按键3可控制电机的转速,按键4可控制转动圈数(按一次加一圈)由串行LCD显示当前转动方向,转速,圈数通过串口与上位机通讯项目组任务分担评价表姓名分担任务组内评价张浩完成LCD显示模块设计与编程、上位机串口通讯界面设计、下位机串口通讯程序、上位机串口通讯程序5李福俊查阅资料,焊接外部电路,外部电路连线,完成下位机除串口通讯以外的程序编写。5课程设计报告评分表内容总体方案硬件设计软件设计结果分析明细清单问题分析心得体会参考文献程序代码格式规范总分学生1得分学生2得分

目录总体方案4硬件设计41.单片机最小系统42.驱动电路53.步进电机电路54.LED显示电路55.总接线图5软件设计61.键盘控制模块62.串行LCD显示模块73.上位机通信模块8结果分析9明细清单10设计调试中的问题10心得体会建议11参考文献12附录113附录229

一、总体方案:总体方案:步进电机控制系统框图如图1所示。图1步进电机控制系统总体功能模块示意图图中,控制器为单片机STC89C52,通过串口与上位机相连,与上位机实现通讯。通过IO口输出到驱动电路,通过驱动电路控制步进电机的工作。同时将步进电机的工作状态通过串行LCD模块显示出来。二、硬件设计:1.单片机最小系统单片机的最小系统是指单片机能正常工作所必须的基本电路,主要有单片机,电源电路,复位电路,晶振电路构成。其原理图如下所示:2.驱动电路步进电机的驱动芯片我们采用的ULN2003实现。实验中1脚到4脚接单片机输出信号,13到16脚接步进电机。8脚接地,9脚接电源。电路图如下:3.步进电机电路连接图:步进电机用万用表测试后,将其与ULN2003和电源连接。4.LED显示电路连接图:5.总接线图三、软件设计:结合STC89C52的各个引脚,分配它的各个端口给各个模块。在本次设计中用到了串行LCD显示模块,键盘控制模块,模块。键盘控制模块本次课程设计中,设定了四个按键来控制电机启动、停止、转向、圈数(按一次加一圈)。先检测每个键是否被按下,再根据设定的键位判断要让电机实现什么功能。按键控制转速流程图如下:图中,Dir代表电机的工作状态,0代表正转,1代表反转,2代表停止;Speed代表电机的转速,100代表慢速,30代表中速,5代表快速;N代表电机转动脉冲数,50代表实际转一圈。串行LCD显示模块本次课程设计使用了串行LCD诺基亚5110,该模块具有以下特点:1)性价比高,LCD1602可以显示32个字符,而Nokia5110可以显示15个汉字,30个字符。Nokia5110裸屏仅8.8元,LCD1602一般15元左右,LCD12864一般50~70元。2)接口简单,仅四根I/O线即可驱动,LCD1602需11根I/O线,LCD12864需12根。3)速度快,是LCD12864的20倍,是LCD1602的40倍。4)Nokia5110工作电压3.3V,正常显示时工作电流200uA以下,具有掉电模式,适合电池供电的便携式移动设备。将串行LCD与单片机IO口相连,可以通过编写程序使其实现数字、英文字符、汉字及图形的显示,显示程序见附录。5110的管脚配置如下:上位机通信模块通过串口与上位机实现通讯,在VS2010中使用MSCOMM控件编写一个串口应用程序。使用组合框实现串口号、波特率、校验类型的选择,添加命令按钮打开串口及发送数据。(1)打开串口:在打开串口按钮的代码中,首先判断各个组合框的值,然后打开相应的串口端口。代码如下:UpdateData();m_mscomm1.put_CommPort(m_comnum+1);//端口号m_mscomm1.put_InBufferSize(1024);//设置输入缓冲区的大小,Bytesm_mscomm1.put_OutBufferSize(512);//设置输出缓冲区的大小,Bytesif(!m_mscomm1.get_PortOpen())//打开串口{m_mscomm1.put_PortOpen(true);}m_mscomm1.put_InputMode(1);//设置输入方式为二进制方式//m_mscomm1.put_Settings(L"9600,n,8,1");//设置波特率等参数CStringstr,str0,str1,str2,str3,strr;intboderate;strr=",";str2="8";str3="1";boderate=pow(2.0,m_boderate)*4800;str0.Format(_T("%d"),boderate);if(m_check==0)str1="n";elseif(m_check==1)str1="O";else str1="P";str=str0+strr+str1+strr+str2+strr+str3;m_mscomm1.put_Settings(str);m_mscomm1.put_RThreshold(1);//为表示有一个字符即引发事件m_mscomm1.put_InputLen(0);(2)接收数据:接收事件中的代码如下:VARIANTvariant_inp;COleSafeArraysafearray_inp;longi=0;intlen;charrxdata[1000];switch(m_mscomm1.get_CommEvent()){case2://表示接缓冲区内有字符variant_inp=m_mscomm1.get_Input();//接收数据safearray_inp=variant_inp;len=safearray_inp.GetOneDimSize();for(i=0;i<len;i++){safearray_inp.GetElement(&i,&rxdata[i]);}rxdata[i]='\0';m_rev+=rxdata;UpdateData(false);break;default:break;}(3)发送数据:发送数据按钮的代码为:UpdateData();m_mscomm1.put_Output(COleVariant(m_send));(4)利用CStdioFile类读写文件MFC中使用CStdioFile类封装了C++运行时刻文件流的操作,流文件采用缓冲方式,支持文件模式和二进制模式文件操作,默认方式为文本模式。CStdioFile类从CFile类继承,具有如下三个构造函数:1、CStdioFile():建立一个CStdioFile类的对象,但不打开文件;2、CStdioFile(FILE*pOpenStream):建立一个CStdioFile类的对象,并将该对象同一个已经打开的文件相联系;3、CStdioFile(LPCTSTRlpszFileName,UINTnOpenFlags):建立一个CStdioFile类的对象,同时打开一个文件,nOpenFlags是打开文件的方式。四、结果分析或项目所实现的功能、指标等最终实验装置如下图(上位机略):工作状态:上位机保存并打开文件:五、明细清单:步进电机X1ULN2003x1ATC89C51集成系统x1NOKIA5110显示屏x1六、设计调试中遇到的疑难问题及解决方法李福俊: 1.开始不清楚步进电机的接线,在网上对应型号的步进电机接线也不对,后面用万用表测量,分清了对应的线。2.在下位机编程时候,开始编的程序按键不灵敏,会有误操作,解决办法是加入了一段按键去抖的程序。3.开始编下位机程序时候,对按一下按键3增加一圈不清楚怎么实现,以及在转了一段时间后按下反向键后怎么算圈数不清楚。后面和组员讨论后决定先给点机设定一个初始圈数,每当检测到一次按键3按下后,在初始圈数自加一。而在中途按下反向键后,前面已经转过的圈数清零,重新开始记圈数。张浩:用串行LCD实现显示汉字功能一开始不会做,之后经过网上查找资料,下载了LCD显示屏的汉字提取程序,将汉字转换成编码来显示。串口界面设计时虚拟串口实验无法正确连接,经检查是波特率设计时显示有问题,界面中显示的顺序与实际波特率不同导致串口无法连接,发现问题之后修改界面设计程序的语句解决。在上位机和下位机通讯时,发现一下只能接收一位数据,而我们要传输转速,方向,圈数3个量。感觉没法实现。解决办法是一次传输一个字符,根据其ASCALL码的不同来对应不同的状态,然后建立一个真值表,可以很方便的看出每个字符所对应的状态。七、心得体会与建议:李福俊:在通过这次的课程设计,真正的将理论知识用到实际中来,在发现问题,分析问题和解决问题的过程中,积累了很多经验。在遇到困难时候和队友讨论,查阅资料,以及寻求老师的帮助,一步一步解决问题,更加明白了团结合作的重要性。同时,通过这次的课程设计,明白了课程设计的步骤,或者说是大体了解了去完成一个工程的步骤。也明白了综合运用各种知识的重要性。在自学上位机编程的过程中,遇到了很大的困难,但我们小组没有退缩,而是迎难而上,最终完成了任务,也就是说在这次课程设计中,我们的自信心得到了提高。张浩:本次课程设计我们小组抽到的题难度并不大,不过在做的过程中还是遇到很多问题,下位机的按键控制电机运动的实现还是比较顺利的,问题在于我们上位机的设计,尤其是对串行通讯了解不够,包括通信原理方法及控制等,一度出现编程毫无思路的状况,幸亏在向其他同学询问以及自己花了一定时间理解之后,做出了一个可以基本实现要求的上位机通讯程序,虽然程序并不完美,但是对我们小组来说已经有了很大的进步,我们也从中学到了很多知识和处理问题的方法。最后,课程设计的完成离不开老师的指导和小组的共同努力,也感谢在设计过程中给我们帮助的所有同学。八、参考文献【1】李全利,《单片机原理及应用》,北京,高等教育出版社,2009年【2】杨素行,《微型计算机系统原理及应用》,北京,清华大学出版社,2004年

附录1:源程序(含有中文注释)#include<reg52.h>#include<intrins.h>#include"stdio.h"#include<led.h>typedefunsignedcharUINT8;/*给unsignedchar重新定义一个别名UINT8,用的时候直接写UINT8就可以*/typedefunsignedintUINT16;/*给unsignedint重新定义一个别名UINT16,用的时候直接写UINT16就可以*/voiddisplay(unsignedcharDirection,unsignedcharSpeed,unsignedchark);voidLCD_Init(void);voidLCD_WriteByte(unsignedchardat,unsignedcharcommand);voidLCD_Set_XY(unsignedcharX,unsignedcharY);voidLCD_Clear(void);voidLCD_WriteChar(unsignedcharx,unsignedchary,unsignedcharc);voidLCD_WriteString(unsignedcharX,unsignedcharY,char*s);voidLCD_WriteNum(unsignedcharX,unsignedcharY,unsignedintnum);voidLCD_Write_12X16Font(unsignedcharx,unsignedchary,unsignedcharc[2]);voidLCD_DrawPicture(unsignedcharX,unsignedcharY,unsignedcharconst*map,unsignedcharPix_x,unsignedcharPix_y);#defineucharunsignedchar#defineuintunsignedint#defineGPIO_MOTORP2//选用P2口控制电机sbitK1=P3^7;//按键1sbitK2=P3^6;//按键2sbitK3=P3^5;//按键3sbitK4=P3^4;//按键4sbitq=P2^7;sbitLCD_RST=P0^0;//P0口控制显示屏sbitLCD_CE=P0^1;sbitLCD_DC=P0^2;sbitLCD_DIN=P0^3;sbitLCD_CLK=P0^4;unsignedcharcodeFFW[8]={0xf1,0xf3,0xf2,0xf6,0xf4,0xfc,0xf8,0xf9};//反转顺序unsignedcharcodeFFZ[8]={0xf9,0xf8,0xfc,0xf4,0xf6,0xf2,0xf3,0xf1};//正转顺序unsignedchara[8];voidDelay1(unsignedintt);//延时函数声明unsignedcharDirection=2,Speed=50;intN=250,s=0;voidMotor();voiddisplay();voidMotor1();//步进电机程序函数声明/*********************************************************************名称:delay()*功能:延时,延时时间大概为5US。*输入:无*输出:无***********************************************************************/voiddelay(){ _nop_(); _nop_(); _nop_(); _nop_(); _nop_();}/*********************************************************************名称:Delay_1ms()*功能:延时子程序,延时时间为1ms*x*输入:x(延时一毫秒的个数)*输出:无***********************************************************************/voidDelay(uinti){ uintx,j; for(j=0;j<i;j++) for(x=0;x<=148;x++); }sbitRS485RD=P3^5;/*P35为RS485的控制收发端,高电平发送,低电平接收*/#defineLEDP2/********************************************************************************函数名:mInitSTDIO*描述:输出初始化串口*输入:无.*返回:无.*******************************************************************************/voidmInitSTDIO(){SCON=0x50;/*1位起始位,8位数据位,1位停止位,允许接收数据*/PCON=0x80;/*波特率加倍*/TMOD=0x20;/*T1定时器工作在自动八位重装模式*/TH1=0xFA;/*11.0592MHz晶振,9600bps*/TR1=1;/*打开定时器T1*/}/********************************************************************************函数名:SendByte*描述:输出数据到串口*输入:UINT8mData:*要发送的数据.*返回:无.*******************************************************************************/voidSendByte(UINT8mData){TI=0;/*清发送标志*/SBUF=mData;/*数据送发送缓冲区*/while(TI==0);/*等待数据发送完成*/TI=0;/*清发送标志*/}/********************************************************************************函数名:RecByte*描述:接收数据*输入:无.*返回:UINT8mData:*接收到的数据.*******************************************************************************/UINT8RecByte(){UINT8mData;RI=0;/*清接收标志*/while(RI==0);/*等待数据接收完成,如果没有数据发送过来,就会一直在这等*/mData=SBUF;/*接收数据*/RI=0;/*清接收标志*/returnmData;/*返回接收的数据*/}/********************************************************************************函数名:DelayMs*描述:毫秒延时.*输入:UINT8Ms:*要延时的Ms时间.*返回:无.*******************************************************************************/voidDelayMs(UINT16Ms){UINT8i;while(Ms--){for(i=0;i<114;i++);/*大概1MS,不精确*/}}/*******************************************************************************步进电机控制程序*******************************************************************************/voidMotor(){ inti,k=0; if(Direction==2)//Direction为方向,0为停止,1为顺时针,2为逆时针 {GPIO_MOTOR=0;LCD_Clear(); } else{ for(i=0;i<8;i++) { if(Direction==1) {GPIO_MOTOR=FFW[i];} if(Direction==0) {GPIO_MOTOR=FFZ[i];} Delay(Speed); //调节转速 } s++; k=s/50; } }/*******************************************************************************延时程序*******************************************************************************/voidDelay1(unsignedintt){ unsignedintk; while(t--) { for(k=0;k<80;k++) {} }}/************************************************************函数名:LCD_Init*功能:初始化LCD*参数:无*返回值:无*备注:***********************************************************/voidLCD_Init(void){unsignedchari;LCD_RST=0; //复位for(i=0;i<150;i++);LCD_RST=1;LCD_WriteByte(0x21,0); //使用扩展命令设置LCD模式LCD_WriteByte(0xc0,0); //设置偏置电压,修改可改变5110点阵显示的亮度 /*5110接5V时偏置电压改为(0xa7,0),接3.3V时改为(0xc0,0)*/LCD_WriteByte(0x20,0); //使用基本命令。并设置V=0,水平寻址LCD_Clear(); //清屏LCD_WriteByte(0x0c,0); //设定显示模式,正常显示(普通显示)LCD_CE=0; }/************************************************************函数名:LCD_WriteByte*功能:模拟SPI接口时序写数据/命令LCD*参数:data:写入的数据;command:写数据(1)/命令选择(0);*返回值:无*备注:***********************************************************/voidLCD_WriteByte(unsignedchardat,unsignedcharcommand){unsignedchari;LCD_CE=0; //5110片选有效,允许输入数据if(command==0) //写命令LCD_DC=0; elseLCD_DC=1; //写数据for(i=0;i<8;i++) //传送8bit数据{if(dat&0x80)LCD_DIN=1;elseLCD_DIN=0;LCD_CLK=0;dat=dat<<1;LCD_CLK=1;}LCD_CE=1; //禁止5110}/************************************************************函数名:LCD_Set_XY*功能:设置LCD坐标*参数:X:0-83Y:0-5*返回值:无*备注:***********************************************************/voidLCD_Set_XY(unsignedcharX,unsignedcharY){LCD_WriteByte(0x40|Y,0);//column列LCD_WriteByte(0x80|X,0);//row 行}/************************************************************函数名:LCD_Clear*功能:LCD清屏函数*参数:无*返回值:无*备注:***********************************************************/voidLCD_Clear(void){unsignedchart;unsignedchark;LCD_Set_XY(0,0);//设置RAM起始地址for(t=0;t<6;t++){for(k=0;k<84;k++){LCD_WriteByte(0x00,1);}}}/************************************************************函数名:LCD_WriteChar*功能:LCD写一个6X8的字符*参数:c*返回值:无备注:***********************************************************/voidLCD_WriteChar(unsignedcharx,unsignedchary,unsignedcharc){unsignedchari;c-=32;//数组的行号LCD_Set_XY(x,y);for(i=0;i<12;i++){LCD_WriteByte(font6x12[c][i],1);if(i==5){y++;LCD_Set_XY(x,y);}}}/************************************************************函数名:LCD_WriteString*功能:LCD写6X8的字符串*参数:X,Y,S*返回值:无备注:***********************************************************/voidLCD_WriteString(unsignedcharX,unsignedcharY,char*s){while(*s){LCD_WriteChar(X,Y,*s);s++;X+=6;}}/*****************************************************************函数名:LCD_WriteNum(unsignedintnum)*功能:写入数字*参数:num*返回值:无*****************************************************************/voidLCD_WriteNum(unsignedcharX,unsignedcharY,unsignedintnum){unsignedcharstr[8],i=0,len=0;unsignedinttemp;temp=num;while(temp){temp/=10;len++;}if(!num){len++;str[0]=0x30;}str[len]=0;while(num){str[len-i-1]=num%10+0x30;num/=10;i++;}LCD_WriteString(X,Y,(char*)str);}/************************************************************函数名:LCD_Write_16X16Font*功能:写一个16X16的汉字*参数:x,y,c[2]x:0-83y:0-5*返回值:无*备注:***********************************************************/voidLCD_Write_12X16Font(unsignedcharx,unsignedchary,unsignedcharc[2]){unsignedchari,k;LCD_Set_XY(x,y);for(k=0;k<25;k++)//K的值表示汉字库最多存放的字的数量(可改大){if((font12x16[k].Index[0]==c[0])&&(font12x16[k].Index[1]==c[1])){for(i=0;i<24;i++){LCD_WriteByte(font12x16[k].Msk[i],1);if(i==11){y++;LCD_Set_XY(x,y);}}}}}voiddisplay(){ LCD_Write_12X16Font(0,0,"方"); //写一个16X16的汉字LCD_Write_12X16Font(12,0,"向");LCD_Write_12X16Font(0,2,"转"); LCD_Write_12X16Font(12,2,"速"); LCD_Write_12X16Font(0,4,"圈"); LCD_Write_12X16Font(12,4,"数"); if(Direction==1&&Speed==50) { LCD_Write_12X16Font(48,0,"顺"); LCD_Write_12X16Font(60,0,"时"); LCD_Write_12X16Font(72,0,"针"); LCD_Write_12X16Font(60,2,"慢"); } if(Direction==1&&Speed==20) { LCD_Write_12X16Font(48,0,"顺"); LCD_Write_12X16Font(60,0,"时"); LCD_Write_12X16Font(72,0,"针"); LCD_Write_12X16Font(60,2,"中"); } if(Direction==1&&Speed==5) { LCD_Write_12X16Font(48,0,"顺"); LCD_Write_12X16Font(60,0,"时"); LCD_Write_12X16Font(72,0,"针"); LCD_Write_12X16Font(60,2,"快"); } if(Direction==0&&Speed==50) { LCD_Write_12X16Font(48,0,"逆"); LCD_Write_12X16Font(60,0,"时"); LCD_Write_12X16Font(72,0,"针"); LCD_Write_12X16Font(60,2,"慢"); } if(Direction==0&&Speed==20) { LCD_Write_12X16Font(48,0,"逆"); LCD_Write_12X16Font(60,0,"时"); LCD_Write_12X16Font(72,0,"针"); LCD_Write_12X16Font(60,2,"中"); } if(Direction==0&&Speed==5) { LCD_Write_12X16Font(48,0,"逆"); LCD_Write_12X16Font(60,0,"时"); LCD_Write_12X16Font(72,0,"针"); LCD_Write_12X16Font(60,2,"快"); }}/*********************************************************************名称:Main()*功能:主函数*输入:无*输出:无***********************************************************************/voidMain(){ uchari,j; uchark;LCD_Init();LCD_Clear(); mInitSTDIO();/*初始化串口*/ /*控制接收数据*/ while(1) { if(s>N) {break;} if(RI==1){j=RecByte(); a[6]=j%2; a[5]=(j/2)%2; a[4]=(j/4)%2; a[3]=(j/8)%2; a[2]=(j/16)%2; a[1]=(j/32)%2; a[0]=(j/64)%2; a[7]=(j/128)%2;if(a[0]==0)Direction=2;if(a[0]==1&&a[1]==0)Direction=0;if(a[0]==1&&a[1]==1)Direction=1;if(a[2]==0&&a[3]==1)Speed=5;if(a[2]==1&&a[3]==0)Speed=20;if(a[2]==1&&a[3]==1)Speed=50;N=50*(a[6]+a[5]*2+a[4]*4); k=s/50; Motor(); display(); RI=0; } else{ if(K1==0) //检测按键K1是否按下 { Delay(1); //消除抖动 if(K1==0) { if(Direction==2){Direction=0; LCD_Write_12X16Font(0,0,"方"); //写一个16X16的汉字LCD_Write_12X16Font(12,0,"向");LCD_Write_12X16Font(0,2,"转"); LCD_Write_12X16Font(12,2,"速"); LCD_Write_12X16Font(0,4,"圈"); LCD_Write_12X16Font(12,4,"数"); LCD_Write_12X16Font(48,0,"逆"); LCD_Write_12X16Font(60,0,"时"); LCD_Write_12X16Font(72,0,"针"); LCD_Write_12X16Font(60,2,"慢"); } else {Direction=2; LCD_Clear(); } } while((i<5000)&&(K1==0)) //检测按键是否松开 { Delay(1); i++; } i=0; } if(K2==0) //检测按键K2是否按下 { Delay(1); //消除抖动 if(K2==0) { if(Direction==0) {Direction=1; LCD_Write_12X16Font(48,0,"顺"); LCD_Write_12X16Font(60,0,"时"); LCD_Write_12X16Font(72,0,"针"); } elseif(Direction==1) {Direction=0; LCD_Write_12X16Font(48,0,"逆"); LCD_Write_12X16Font(60,0,"

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论