找回密码
 注册
关于网站域名变更的通知
查看: 185|回复: 3
打印 上一主题 下一主题

单片机步进电机调速控制 LCD1602显示圈数程序与Proteus仿真操作流

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2022-6-24 09:26 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载). L: x0 ?- o/ F. k

8 x2 Q" u* G/ X9 l1 v7 w$ P: E
9 o0 d, ]) v( v3 H- e& ZProteus仿真操作流如下:2 @6 r9 p8 k% Q+ G' N3 F: ^- w
步骤一:打开仿真.DSN文件(用Proteus7.8打开)
步骤二:左键双击U1单片机,打开加载HEX文件界面,左键单击文件夹图标
) T. v! j6 D; I; E
步骤三:选择给的1号源程序文件夹,找到HEX文件。
步骤四:左键双击打开HEX文件,跳到步骤二界面,点击OK
# F/ x( a  |( o
步骤五:左键点击左下角运行

4 E  t) k) d8 G6 i0 |
! x6 J" O  h) N  e. u单片机源程序如下:5 _! d# b5 Q; y' e! H
  • #include<reg52.h>
  • #include<stdio.h>
  • #include<intrins.h>
  • #define uchar unsigned char
  • #define uint unsigned int
  • sbit RS = P2^4;//1602数据/命令选择端(H:数据寄存器L:指令寄存器)
  • sbit RW = P2^5;//1602读/写选择端
  • sbit E  = P2^6;//1602使能信号端
  • sbit key1=P3^0;//用户按键
  • sbit key2=P3^1;
  • sbit key3=P3^2;
  • sbit key4=P3^3;
  • sbit key5=P3^4;
  • uchar code B_Rotation[8]={0x7f,0x3f,0xbf,0x9f,0xdf,0xcf,0xef,0x6f}; //反转表格
  • uchar code F_Rotation[8]={0xef,0xcf,0xdf,0x9f,0xbf,0x3f,0x7f,0x6f}; //正转表格
  • uchar table1[]="dir: +  spe:005";
  • uchar table2[]="cir:000 ang:000";
  • uchar num;
  • uint key,flag,speed=5,zflag,znum,fflag,fnum,select,pp,qq;
  • //1键值2键值标志3速度4正转标志5正转圈数6反转标志7反转圈数8正转角度9反转角度10选择
  • float zang,fang;
  • /******************************************************************/
  • /*                    延时函数 Xms                                   */
  • /******************************************************************/
  • void delay(uint z)
  • {
  •         uint x,y;
  •         for(x=z;x>0;x--)
  •                 for(y=110;y>0;y--);
  • }
  • /******************************************************************/
  • /*                   LCD1602写命令操作                            */
  • /******************************************************************/
  • void WriteCommand(uchar com)
  • {
  •         delay(5);//操作前短暂延时,保证信号稳定
  •         E=0;
  •         RS=0;
  •         RW=0;
  •         P0=com;
  •         E=1;
  •         delay(5);
  •         E=0;
  • }
  • /******************************************************************/
  • /*                   LCD1602写数据操作                            */
  • /******************************************************************/
  • void WriteData(uchar dat)
  • {
  •         delay(5);  //操作前短暂延时,保证信号稳定
  •         E=0;
  •         RS=1;
  •         RW=0;
  •         P0=dat;
  •         E=1;
  •         delay(5);
  •         E=0;
  • }
  • /******************************************************************/
  • /*                           1602初始化程序                       */
  • /******************************************************************/
  • void InitLcd()//1602初始化程序
  • {
  •         delay(15);
  •         WriteCommand(0x38); //display mode
  •         WriteCommand(0x38); //display mode
  •         WriteCommand(0x38); //display mode
  •         WriteCommand(0x06); //当读或写一个字符后地址指针加一,且光标加一
  •         WriteCommand(0x0c); //显示开及光标不显示
  •         WriteCommand(0x01); //清屏
  •         WriteCommand(0x80);
  •         for(num=0;num<15;num++)//第一行的显示
  •         {
  •                 WriteData(table1[num]);
  •                 delay(15);
  •         }
  •         WriteCommand(0x80+0x40);//第二行的显示
  •         for(num=0;num<15;num++)
  •         {
  •                 WriteData(table2[num]);
  •                 delay(15);
  •         }
  • }
  • /******************************************************************/
  • /*              独立键盘扫描函数                                  */
  • /******************************************************************/
  • void keyscan()
  • {
  •         P3=0xff;//拉高P3口,以读取P3口的值
  •         if(key1==0)//键1被按下
  •         {
  •                 delay(5);//延时消抖
  •                 if(key1==0)
  •                 {
  •                         flag=1;
  •                 }
  •                 while(!key1);
  •                 delay(5);//延时消抖
  •                 while(!key1);//松手检测
  •         }
  •         if(key2==0)
  •         {
  •                 delay(5);
  •                 if(key2==0)
  •                 {
  •                         flag=2;
  •                 }
  •                 while(!key2);
  •                 delay(5);
  •                 while(!key2);
  •         }
  •         if(key3==0)//键1被按下
  •         {
  •                 delay(5);//延时消抖
  •                 if(key3==0)
  •                 {
  •                         flag=3;
  •                 }
  •                 while(!key3);
  •                 delay(5);//延时消抖
  •                 while(!key3);//松手检测
  •         }
  •         if(key4==0)
  •         {
  •                 delay(5);
  •                 if(key4==0)
  •                 {
  •                         flag=4;
  •                 }
  •                 while(!key4);
  •                 delay(5);
  •                 while(!key4);
  •         }
  •         if(key5==0)
  •         {
  •                 delay(5);
  •                 if(key5==0)
  •                 {
  •                         flag=5;
  •                 }
  •                 while(!key5);
  •                 delay(5);
  •                 while(!key5);
  •         }
  • }
  • /******************************************************************/
  • /*                           1602显示3位数                       */
  • /******************************************************************/
  • void write_sfm(uchar add,uint date)//1602显示
  • {
  •         uchar bai,shi,ge;
  •         bai=date/100;
  •         shi=date%100/10;
  •         ge=date%10;
  •         WriteCommand(0x80+add);//设置数据地址指针
  •         WriteData(0x30+bai);
  •         WriteData(0x30+shi);
  •         WriteData(0x30+ge);
  •         WriteData(0x20);
  • }
  • /******************************************************************/
  • /*                           键值处理                             */
  • /******************************************************************/
  • void handle_flag()
  • {
  •         uchar select1;
  •         if(TR0==0&&TR1==0)
  •         {
  •                 if(flag==1) //正转
  •                 {
  •                         WriteCommand(0x80+0x05);
  •                         WriteData('+');
  •                         delay(20);
  •                         select=0;
  •                 }
  •                 if(flag==2) //反转
  •                 {
  •                         WriteCommand(0x80+0x05);
  •                         WriteData('-');
  •                         delay(20);
  •                         select=1;
  •                 }
  •                 if(flag==3)//转速加
  •                 {
  •                     speed++;
  •                         if(speed>=12)
  •                                 speed=12;
  •                         write_sfm(0x0c,speed);//显示速度
  •                         delay(20);
  •             }
  •                 if(flag==4)        //转速减
  •                 {
  •                         speed--;
  •                         if(speed<=1)
  •                                 speed=1;
  •                         write_sfm(0x0c,speed);//显示速度
  •                         delay(20);
  •                 }
  • }
  •         if(flag==5)////关闭中断,停止电机
  •         {
  •                 select1++;
  •                 select1%=2;
  •                 if( select1==0)
  •                 {
  •                         TR0=0;
  •                         TR1=0;
  •                         if(select==0)//显示转动的角度
  •                                 write_sfm(0x40+0x0c,zang);
  •                         else
  •                                 write_sfm(0x40+0x0c,fang);
  •              }
  •                 else
  •                 {if(select==0)
  •                 {
  •                         TR0=1;//开定时器0,产生正转相序
  •                         TR1=0;//关定时器1
  •                 }
  •                 else
  •                 {
  •                         TR1=1;//开定时器1,产生反转相序
  •                         TR0=0;//关定时器0
  •                 }
  •                 }
  •         }
  •         flag=0;
  • }
  • void main()
  • {
  •         pp=0;
  •         qq=0;
  •         InitLcd();
  •         TMOD=0x11;
  •     EA=1;
  •         ET0=1;
  •         ET1=1;
  •         TH0=(65536-(14648/speed))/256;
  •         TL0=(65536-(14648/speed))%256;
  •         TH1=(65536-(14648/speed))/256;
  •         TL1=(65536-(14648/speed))%256;
  •         TR0=0;
  •         TR1=0;
  •         while(1)
  •         {
  •                 keyscan();
  •                 handle_flag();
  •         }
  • }
  • void time0() interrupt 1
  • {
  •         uint zz;
  •         TH0=(65536-(14648/speed))/256; // 360/(5.625/64)=4096
  •                                    //假设60秒转一圈,即60秒中断4096次,
  •                                                                    //那么一次中断需要60000000/4096=14648个时钟
  •                                                                    //60000000/(4096*speed)   zflag=4096时一圈
  •         TL0=(65536-(14648/speed))%256;
  •         zz%=8;
  •         P1=F_Rotation[zz];  //输出对应的相
  •         zz++;
  •         zflag++;
  •         if(zflag==4096) //正转了一圈
  •         {
  •                 zflag=0;
  •                 znum++;
  •                 write_sfm(0x40+0x04,znum);
  •         }
  •         if(zflag%64==0)//计算正转动的角度
  •         {
  •                 pp++;
  •                 zang=(uint)(pp*5.625);
  •                 if(zang==360)
  •                         pp=0;
  •                 write_sfm(0x40+0x0c,zang);
  •         }
  •         //zang=0.088*zflag;
  •         //write_sfm(0x40+0x0c,zang);
  • }
  • void time1() interrupt 3
  • {
  •         uint ff;
  •         TH1=(65536-(14648/speed))/256;
  •         TL1=(65536-(14648/speed))%256;
  •     ff%=8;
  •         P1=B_Rotation[ff]; //输出对应的相
  •         ff++;
  •         fflag++;
  •         if(fflag==4096) //反转了一圈
  •         {
  •                 fflag=0;
  •                 fnum++;
  •                 write_sfm(0x40+0x04,fnum);
  •         }
  •         if(fflag%64==0)//计算反转动的角度
  •         {
  •                 qq++;
  •                 fang=(uint)(qq*5.625);
  •                 if(fang==360)
  •                 qq=0;
  •                 write_sfm(0x40+0x0c,fang);
  •         }
  • }+ N) j' @2 j% O; j$ ?+ D8 I2 g
% T1 [# U% c4 A6 n) c8 R. r

该用户从未签到

2#
发表于 2022-6-24 10:02 | 只看该作者
||ヽ(* ̄▽ ̄*)ノミ|Ю看一看,学习学习。

该用户从未签到

3#
发表于 2022-6-24 14:24 | 只看该作者
看一看学习学习。

该用户从未签到

4#
发表于 2022-6-24 15:01 | 只看该作者
看一看学习学习。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

推荐内容上一条 /1 下一条

EDA365公众号

关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

GMT+8, 2025-6-25 13:43 , Processed in 0.078125 second(s), 23 queries , Gzip On.

深圳市墨知创新科技有限公司

地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

快速回复 返回顶部 返回列表