找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 8646|回复: 37
打印 上一主题 下一主题
收起左侧

单片机自动升降旗系统仿真及程序有错误

  [复制链接]
跳转到指定楼层
楼主
lcd1602显示,正转翻转停止显示高度;

基于51单片机做的国旗自动升降系统的proteus仿真原理图:


如果没有装KEIL软件
找到  .c   .h结尾的文件即为程序。打开方式选择记事本打开
或者到开发资料里安装KEIL软件

单片机源程序如下:
  1. #include <reg52.h>                 //调用单片机头文件
  2. #define uchar unsigned char  //无符号字符型 宏定义        变量范围0~255
  3. #define uint  unsigned int         //无符号整型 宏定义        变量范围0~65535
  4. #include <intrins.h>

  5. unsigned char code zheng[4]={0xfe,0xfd,0xfb,0xf7};//正转表格
  6. unsigned char code fan[4]={0xf7,0xfb,0xfd,0xfe};//反转表格

  7. uchar flag_start ;     //启动标志位  1为起动步进电机 否则关闭电机
  8. uchar flag_z_f;        //正反标志位  0为顺时钟 1为逆时史上转
  9. uchar flag_shudu = 1;      //4种速度 0,1,2,3,
  10. bit flag_1s;   
  11. uint flag_value;      
  12. uchar time;
  13. uchar gaodu;

  14. sbit red    = P3^2;           //升期  指示灯
  15. sbit green  = P3^3;           //旗停下指示灯
  16. sbit yellow = P3^4;     //降旗  指示灯

  17. sbit rs=P1^4;         //寄存器选择信号 H:数据寄存器          L:指令寄存器
  18. sbit rw=P1^5;         //寄存器选择信号 H:数据寄存器          L:指令寄存器
  19. sbit e =P1^6;         //片选信号   下降沿触发

  20. sbit wx0 = P2^5;
  21. sbit wx1 = P2^6;
  22. sbit wx2 = P2^7;
  23. uchar key_can_wx;

  24. /***********************语音模块控制IO口的定义************************/
  25. sbit  VRST = P2^4;
  26. sbit  VBUSY= P2^0;        
  27. sbit  VSDA = P2^1;
  28. sbit  VCS  = P2^2;  
  29. sbit  VSCL = P2^3;


  30. /******************1ms 延时函数*******************/
  31. void delay_1ms(uint q)
  32. {
  33.         uint i,j;
  34.         for(i=0;i<q;i++)
  35.                 for(j=0;j<120;j++);
  36. }

  37. void  delay_us (unsigned int us)
  38. {

  39.         while(us--)
  40.         {
  41.                 _nop_();
  42.         }
  43. }

  44. /***********************三线发码子程序************************/
  45. void Send_threelines(unsigned char addr)
  46. {
  47.    unsigned char i;

  48.         if(VBUSY == 1)
  49.         {
  50.                 VRST=0;
  51.                 delay_1ms(5);
  52.                 VRST=1;
  53.                 delay_1ms(20); /* 复位拉高20ms*/
  54.                 VCS=0;
  55.                 delay_1ms(5);  /* 片选拉低5ms */
  56.             for(i=0;i<8;i++)
  57.                 {
  58.                         VSCL=0;
  59.                         if(addr&0x01)
  60.                         {
  61.                                 VSDA=1;
  62.                         }
  63.                         else
  64.                                 VSDA=0;
  65.                         addr>>=1;
  66.                         delay_us(150); /* 150us */
  67.                         VSCL=1;
  68.                         delay_us(150); /* 150us */
  69.                 }
  70.                 VCS=1;
  71.                 delay_1ms(200);
  72.         }
  73. }


  74. /********************************************************************
  75. * 名称 : delay_uint()
  76. * 功能 : 小延时。
  77. * 输入 : 无
  78. * 输出 : 无
  79. ***********************************************************************/
  80. void delay_uint(uint q)
  81. {
  82.         while(q--);
  83. }

  84. /********************************************************************
  85. * 名称 : write_com(uchar com)
  86. * 功能 : 1602命令函数
  87. * 输入 : 输入的命令值
  88. * 输出 : 无
  89. ***********************************************************************/
  90. void write_com(uchar com)
  91. {
  92.         e=0;
  93.         rs=0;
  94.         rw=0;
  95.         P0=com;
  96.         delay_uint(3);
  97.         e=1;
  98.         delay_uint(25);
  99.         e=0;
  100. }

  101. /********************************************************************
  102. * 名称 : write_data(uchar dat)
  103. * 功能 : 1602写数据函数
  104. * 输入 : 需要写入1602的数据
  105. * 输出 : 无
  106. ***********************************************************************/
  107. void write_data(uchar dat)
  108. {
  109.         e=0;
  110.         rs=1;
  111.         rw=0;
  112.         P0=dat;
  113.         delay_uint(3);
  114.         e=1;
  115.         delay_uint(25);
  116.         e=0;        
  117. }

  118. /********************************************************************
  119. * 名称 : write_string(uchar hang,uchar add,uchar *p)
  120. * 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符开始显示"ab cd ef" ,调用该函数如下
  121.                   write_string(1,5,"ab cd ef;")
  122. * 输入 : 行,列,需要输入1602的数据
  123. * 输出 : 无
  124. ***********************************************************************/
  125. void write_string(uchar hang,uchar add,uchar *p)
  126. {
  127.         if(hang==1)   
  128.                 write_com(0x80+add);
  129.         else
  130.                 write_com(0x80+0x40+add);
  131.                 while(1)
  132.                 {
  133.                         if(*p == '\0')  break;
  134.                         write_data(*p);
  135.                         p++;
  136.                 }        
  137. }


  138. /***********************lcd1602上显示两位十进制数************************/
  139. void write_sfm3_gaodu(uchar hang,uchar add,uchar date)
  140. {
  141.         if(hang==1)   
  142.                 write_com(0x80+add);
  143.         else
  144.                 write_com(0x80+0x40+add);
  145.         write_data(0x30+date/100%10);
  146.         write_data(0x30+date/10%10);
  147.         write_data('.');
  148.         write_data(0x30+date%10);        
  149. }


  150. /********************************************************************
  151. * 名称 : init_1602()
  152. * 功能 : 初始化1602液晶
  153. * 输入 : 无
  154. * 输出 : 无
  155. ***********************************************************************/
  156. void init_1602()      //1602初始化
  157. {
  158.         write_com(0x38);
  159.         write_com(0x0c);
  160.         write_com(0x06);
  161.         delay_uint(1000);
  162.         write_string(1,0,"     Guo Qi      ");
  163.         write_string(2,0,"  gaodu:00.0M     ");
  164. }


  165. /********************独立按键程序*****************/
  166. uchar key_can;         //按键值

  167. void key()         //独立按键程序
  168. {
  169.         static uchar key_new;
  170.         key_can = 20;                   //按键值还原
  171.         P3 |= 0xe0;
  172.         if((P3 & 0xe0) != 0xe0)                //按键按下
  173.         {
  174.                 delay_1ms(1);                     //按键消抖动
  175.                 if(((P3 & 0xe0) != 0xe0) && (key_new == 1))
  176.                 {                                                //确认是按键按下
  177.                         key_new = 0;
  178.                         switch(P3 & 0xe0)
  179.                         {
  180.                                 case 0xd0: key_can = 1; break;          //得到按键值
  181.                                 case 0xb0: key_can = 2; break;          //得到按键值
  182.                                 case 0x70: key_can = 3; break;          //得到按键值
  183.                         }
  184.                 }                        
  185.         }
  186.         else   //按键松开
  187.                 key_new = 1;        
  188. }

  189. /********************独立按键程序*****************/
  190. void key_wuxian()
  191. {
  192.         static uchar key_new;
  193.         key_can_wx = 20;
  194.         if(key_new == 0)
  195.         {
  196.                 key_new = 1;
  197.                 if(wx0 == 1)
  198.                 {
  199.                         key_can_wx = 1;  
  200.                 }
  201.                 if(wx1 == 1)
  202.                 {
  203.                         key_can_wx = 2;   
  204.                 }
  205.                 if(wx2 == 1)
  206.                 {
  207.                         key_can_wx = 3;           
  208.                 }
  209.         }
  210.         if((wx0 == 0) && (wx1 == 0) && (wx2 == 0))
  211.                 key_new = 0;
  212. //        write_sfm2(1,0,key_can_wx);   //按键按下显示按键值
  213. }

  214. /*****************按键升旗降旗处理*******************/
  215. void key_shenqi()
  216. {
  217.         static uchar value=0;
  218.         if((key_can == 3) || (key_can_wx == 1))   //升旗
  219.         {
  220.                 if(time < 47)
  221.                 {
  222.                         if(value == 0)
  223.                         {
  224.                                 value = 1;
  225.                                 Send_threelines(1);    //播放国歌
  226.                         }
  227.                         flag_z_f = 1;         
  228.                         red = 0;                       //红灯升旗
  229.                         green = 1;
  230.                         yellow = 1;
  231.                 }
  232.         }
  233.         if((key_can == 2) || (key_can_wx == 2))   //降旗
  234.         {
  235.                 if(time > 0)
  236.                 {
  237.                         value = 0;
  238.                         Send_threelines(2);
  239.                         flag_z_f = 2;         
  240.                         flag_start = 2;
  241.                         flag_value = 0;
  242.                         red = 1;      
  243.                         green = 1;         
  244.                         yellow = 0;          //黄灯降旗
  245.                 }
  246.         }
  247.         if((key_can == 1) || (key_can_wx == 3))  //停下
  248.         {
  249.                 Send_threelines(2);
  250.                 flag_start = 0;
  251.                 red = 1;      
  252.                 green = 0;           //绿灯停下
  253.                 yellow = 1;         
  254.                 value = 0;
  255.         }
  256. }

  257. /*********************定时器0、定时器1初始化******************/
  258. void time_init()         
  259. {
  260.         EA  = 1;                   //开总中断
  261.         TMOD = 0X11;          //定时器0、定时器1工作方式1
  262.         ET0 = 1;                  //开定时器0中断
  263.         TR0 = 1;                  //允许定时器0定时
  264. }

  265. void main()
  266. {
  267.         static uchar i;
  268.         P0 = P1 = P2 = P3 = 0XFF;
  269.         init_1602();      //1602初始化
  270.         time_init();
  271.         write_sfm3_gaodu(2,8,gaodu);          //显示速度m
  272.         while(1)
  273.         {
  274.                 key();
  275.                 key_wuxian();                        //遥控升旗降旗
  276.                 key_shenqi();           //按键升旗降旗
  277.                 for(i=0;i<4;i++)        //4相
  278.                 {
  279.                         if(flag_z_f == 1)
  280.                                 P1=zheng[i] //电机正转
  281.                         if(flag_z_f == 2)
  282.                                 P1=fan[i];   //电机反转
  283.                         delay_uint(500);        //改变这个参数可以调整电机转速
  284.                 }
  285.                 if(flag_z_f == 1)           //升旗
  286.                 {
  287.                         if(flag_1s == 1)
  288.                         {
  289.                                 flag_1s = 0;
  290.                                 time ++;     //时间在加
  291.                                 gaodu = time * 4.0191;  
  292.                                 if(time >= 46)   //停下
  293.                                 {
  294.                                         time = 47;
  295.                                         flag_z_f = 0;        
  296.                                         P1 = 0xf0;
  297.                                         red = 1;      
  298.                                         yellow = 1;         
  299.                                         green = 0;//绿灯停下
  300.                                         gaodu = 195;
  301.                                 }
  302.                                 write_sfm3_gaodu(2,8,gaodu);          //显示速度m
  303.                         }
  304. ……………………

  305. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载(仿真只能用Proteus7.5打开):
hex能仿真,但是程序编译错误,求指导如何修改.7z (38.95 KB, 下载次数: 201)

评分

参与人数 2黑币 +51 收起 理由
baibai7 + 1 赞一个!
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏6 分享淘帖 顶 踩1
回复

使用道具 举报

沙发
ID:195259 发表于 2017-6-1 18:18 | 只看该作者
电机的参数是什么啊
回复

使用道具 举报

板凳
ID:195259 发表于 2017-6-1 19:06 | 只看该作者
好资料,51黑有你更精彩!!!
回复

使用道具 举报

地板
ID:195259 发表于 2017-6-1 19:15 | 只看该作者
我用的时候电机那边没反应啊,这是怎么回事
回复

使用道具 举报

5#
ID:198958 发表于 2017-6-1 20:12 来自手机 | 只看该作者
zhaoshuai 发表于 2017-6-1 19:06
怎么不好用呢

好用啊,如果在底部就不能反转了,同样顶部不能正传
回复

使用道具 举报

6#
ID:195259 发表于 2017-6-1 21:08 | 只看该作者
什么意思、初学,不太懂,当我按下按键的时候,电机左右电平没有变化
回复

使用道具 举报

7#
ID:195259 发表于 2017-6-1 21:27 | 只看该作者
l528592564 发表于 2017-6-1 20:12
好用啊,如果在底部就不能反转了,同样顶部不能正传

初学者,不太懂,就是按键按下的时候,电机左右电平没有变化
回复

使用道具 举报

8#
ID:195259 发表于 2017-6-1 21:39 来自手机 | 只看该作者
l528592564 发表于 2017-6-1 20:12
好用啊,如果在底部就不能反转了,同样顶部不能正传

底部指的是什么啊
回复

使用道具 举报

9#
ID:198958 发表于 2017-6-2 14:42 来自手机 | 只看该作者
zhaoshuai 发表于 2017-6-1 21:27
初学者,不太懂,就是按键按下的时候,电机左右电平没有变化

步进电机是四个端口需要以次供电的,你去查查资料,我这个是旗升降,底部就是旗的高度为0
回复

使用道具 举报

10#
ID:195259 发表于 2017-6-2 17:46 | 只看该作者
l528592564 发表于 2017-6-2 14:42
步进电机是四个端口需要以次供电的,你去查查资料,我这个是国旗升降,底部就是国旗的高度为0

哥,但是现在不管怎么按,电机都不转,是电机参数的事吗?帮帮忙
回复

使用道具 举报

11#
ID:198958 发表于 2017-6-3 12:24 来自手机 | 只看该作者
zhaoshuai 发表于 2017-6-2 17:46
哥,但是现在不管怎么按,电机都不转,是电机参数的事吗?帮帮忙

你做的实物吗
回复

使用道具 举报

12#
ID:195259 发表于 2017-6-3 15:13 | 只看该作者
不是啊,也是仿真
回复

使用道具 举报

13#
ID:195259 发表于 2017-6-3 15:14 | 只看该作者

也是仿真,我什么都没动,文件下载下来,直接用的,就是电机没反应,电机参数是什么啊?
回复

使用道具 举报

14#
ID:195259 发表于 2017-6-3 15:15 | 只看该作者

加下好友可以吗
回复

使用道具 举报

15#
ID:262990 发表于 2017-12-28 11:30 | 只看该作者
老哥没有语音模块吗?
回复

使用道具 举报

16#
ID:271714 发表于 2018-1-7 21:37 来自手机 | 只看该作者
朋友,这个做实物需要什么
回复

使用道具 举报

17#
ID:254251 发表于 2018-6-8 14:33 | 只看该作者
底部和顶部什么定义,顶部想定多高都可以吗
回复

使用道具 举报

18#
ID:254251 发表于 2018-6-8 14:34 | 只看该作者
有谁做过实物
回复

使用道具 举报

19#
ID:388754 发表于 2018-8-28 07:58 | 只看该作者
请问您的升降旗速度是怎么调节的
回复

使用道具 举报

20#
ID:388870 发表于 2018-9-11 14:49 | 只看该作者
谢谢分享
回复

使用道具 举报

21#
ID:247623 发表于 2018-9-12 16:13 | 只看该作者
源程序编译有错误
if(flag_z_f == 1)

308.                                P1=zheng[i] //电机正转

309.                        if(flag_z_f == 2)

310.                                P1=fan[i];   //电机反转
显示308行有问题
回复

使用道具 举报

22#
ID:438324 发表于 2018-12-22 18:51 来自手机 | 只看该作者
楼主上面发的这份仿真图是完整的图嘛?
回复

使用道具 举报

23#
ID:603085 发表于 2019-8-23 15:36 | 只看该作者
收益匪浅,感谢!
回复

使用道具 举报

24#
ID:733247 发表于 2020-4-20 09:54 | 只看该作者
不管我怎么点 电机和lcd都没有变化  谁什么原因呢
回复

使用道具 举报

25#
ID:649321 发表于 2020-6-26 16:39 | 只看该作者
挺好的
回复

使用道具 举报

26#
ID:495287 发表于 2020-6-27 12:03 | 只看该作者
谢谢楼主分享,提供开拓思路。
回复

使用道具 举报

27#
ID:794724 发表于 2020-7-1 19:10 | 只看该作者
这个程序是完整的吗
回复

使用道具 举报

28#
ID:794724 发表于 2020-7-1 20:52 | 只看该作者

你仿真出最后的结果了吗
回复

使用道具 举报

29#
ID:794724 发表于 2020-7-1 22:03 | 只看该作者
l528592564 发表于 2017-6-2 14:42
步进电机是四个端口需要以次供电的,你去查查资料,我这个是国旗升降,底部就是国旗的高度为0

这不是一个升降系统么  不是应该可以通过调节按键去控制升或者降么 不应该电机没反应 啊
回复

使用道具 举报

30#
ID:796954 发表于 2020-7-4 22:34 来自手机 | 只看该作者
卿本佳人 发表于 2020-4-20 09:54
不管我怎么点 电机和lcd都没有变化  谁什么原因呢

我下载之后也是这样,请问你找到原因了吗
回复

使用道具 举报

31#
ID:796954 发表于 2020-7-4 22:35 来自手机 | 只看该作者
请问为什么运行之后无论怎么按键,电机都不转,灯也不变呢
回复

使用道具 举报

32#
ID:796954 发表于 2020-7-4 22:37 来自手机 | 只看该作者
zhaoshuai 发表于 2017-6-3 15:15
加下好友可以吗

请问你这个问题解决了吗,怎么解决的啊,谢谢
回复

使用道具 举报

33#
ID:922296 发表于 2021-5-17 09:10 来自手机 | 只看该作者
请问完整吗?
回复

使用道具 举报

34#
ID:922296 发表于 2021-5-17 09:11 来自手机 | 只看该作者
电机参数要自己设定吗?
回复

使用道具 举报

35#
ID:922296 发表于 2021-5-17 09:30 | 只看该作者
感谢大神,能不能讲解一下呢?
回复

使用道具 举报

36#
ID:922296 发表于 2021-5-18 10:22 来自手机 | 只看该作者
请问为什么电机不动
回复

使用道具 举报

37#
ID:922296 发表于 2021-5-18 10:23 来自手机 | 只看该作者
而且现实的距离也不变
回复

使用道具 举报

38#
ID:933336 发表于 2021-6-7 09:48 | 只看该作者
单片机噩梦 发表于 2021-5-18 10:23
而且现实的距离也不变

请问电机不动怎样解决
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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