找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2952|回复: 23
收起左侧

单片机流水灯程序左右移动卡顿问题

[复制链接]
ID:100982 发表于 2021-11-19 08:34 | 显示全部楼层 |阅读模式
代码很简单,如上,现在现象是右移到头后会卡顿一下再左移,左移到头后也会卡顿一下再右移,怀疑是延时问题,没找到解决方法,求教各位了。
单片机源程序如下:
  1. #include <reg51.h>
  2. void delay();
  3. int main()
  4. {
  5.         unsigned char cnt = 0;
  6.         bit flag = 0;

  7.         while(1)
  8.         {
  9.                 if(flag == 0)
  10.                 {
  11.                         P0 = 0x01 << cnt;
  12.                         if(P0 == 0x80)
  13.                         {
  14.                                 flag = 1;
  15.                         }
  16.                 }
  17.                 else
  18.                 {
  19.                         P0 = 0x80 >> cnt;
  20.                         if(P0 == 0x01)
  21.                         {
  22.                                 flag = 0;
  23.                         }
  24.                 }
  25.                 delay();
  26.                 cnt++;
  27.                 if(cnt >= 8)
  28.                 {
  29.                         cnt = 0;
  30.                 }
  31.         }
  32.         return 0;
  33. }

  34. void delay()
  35. {
  36.         int i = 0;
  37.         for(i = 0;i <30000;i++)
  38.         {
  39.         
  40.         }

  41. }
复制代码


回复

使用道具 举报

ID:624769 发表于 2021-11-19 08:53 来自触屏版 | 显示全部楼层
你这不是卡顿,是逻辑重复。
回复

使用道具 举报

ID:624769 发表于 2021-11-19 08:55 来自触屏版 | 显示全部楼层
你这不是卡顿,是逻辑重复。0x01会两次,0x80也会两次。
回复

使用道具 举报

ID:624769 发表于 2021-11-19 08:58 来自触屏版 | 显示全部楼层
要么,cnt到7就归0,要么cnt到8后归1。这破手机发个回复那么累。
回复

使用道具 举报

ID:624769 发表于 2021-11-19 09:03 来自触屏版 | 显示全部楼层
啊,我要抓狂了,cnt到8归1,没什么需要改,cnt到7归0要改判断逻辑,因为,p0不会
回复

使用道具 举报

ID:824490 发表于 2021-11-19 09:04 | 显示全部楼层
int main()
while(1)
{
}
return 0;//这个是要返回到哪里去?有调用才可以返回,而且是被调用的才有资格返回!
}
回复

使用道具 举报

ID:624769 发表于 2021-11-19 09:07 来自触屏版 | 显示全部楼层
我放弃了,你就到8归1吧。
回复

使用道具 举报

ID:592807 发表于 2021-11-19 09:08 | 显示全部楼层
逻辑问题,0x01 和0x08出现两次灯亮顺序是1 2 3 4 5 6 7 8 8 7 6 5 4 3 2 1 1 2 3 4 5 6..................................
你把if(cnt >= 8)改成(cnt >= 7)
灯亮顺序就是1 2 3 4 5 6 7 8 7 6 5 4 3 2 1 2 3 4 5 6 7..................................
回复

使用道具 举报

ID:887202 发表于 2021-11-19 09:10 | 显示全部楼层
异常发生在左移和右移两种状态切换的时候,那就去看两种状态切换的时候发生了什么就很容易发现问题了,切换前最后一次给P0赋值和切换后第一次给P0赋值都是同一个值,所以看起来顿了一下。
if(cnt>=8)
{
cnt = 0;//改成cnt=1;
}
这样操作一下应该就没问题了。
回复

使用道具 举报

ID:592807 发表于 2021-11-19 09:18 | 显示全部楼层

刚学C语言是main里面是有return的,用来结束代码运行的。第一个c语言代码就是int main {printf(“hellow
world!”);return 0;}
回复

使用道具 举报

ID:824490 发表于 2021-11-19 09:28 | 显示全部楼层
黄youhui 发表于 2021-11-19 09:18
刚学C语言是main里面是有return的,用来结束代码运行的。第一个c语言代码就是int main {printf(“hellow ...

都已经while1()大循环了。。。
回复

使用道具 举报

ID:908826 发表于 2021-11-19 09:29 | 显示全部楼层
黄youhui 发表于 2021-11-19 09:18
刚学C语言是main里面是有return的,用来结束代码运行的。第一个c语言代码就是int main {printf(“hellow ...

没事,main函数就算不是空返回类型,你不写return也没事
回复

使用道具 举报

ID:624769 发表于 2021-11-19 09:31 来自触屏版 | 显示全部楼层
你们都有编译器,都有现成的程序,加return,不加return,编译一下,看看code大小,就明白了。
回复

使用道具 举报

ID:824490 发表于 2021-11-19 09:40 | 显示全部楼层
188610329 发表于 2021-11-19 09:31
你们都有编译器,都有现成的程序,加return,不加return,编译一下,看看code大小,就明白了。

test.c(30): warning C294: unreachable code

回复

使用道具 举报

ID:744809 发表于 2021-11-19 09:41 | 显示全部楼层

这种写法是支持的,main也是被启动文件调用的,而且电脑上的c程序这样写才是对的
回复

使用道具 举报

ID:824490 发表于 2021-11-19 09:42 | 显示全部楼层
我用的 uVision V4.72.9.0
警告了。
代码没变。
回复

使用道具 举报

ID:100982 发表于 2021-11-19 09:52 | 显示全部楼层
谢谢各位,菜鸟一个,太菜了,这样改了下                if(cnt >= 8)
                {
                        cnt = 1;
                }解决问题了其实是逻辑上重复了
回复

使用道具 举报

ID:100982 发表于 2021-11-19 09:53 | 显示全部楼层
return 0 这个问题是因为看linux里面gcc 代码规范都得写
回复

使用道具 举报

ID:824490 发表于 2021-11-19 09:55 | 显示全部楼层
是的,我百度了一下相关,又涨姿势了。。
/////
1、        C51中mian()并不是被调用的,而是跳转进去的;
2、        在main()中调用return语句,将会从栈中弹出SP大小的数据到SP中,进而程序会运行到弹出数据指向的地址,C51中可能就是SP指针返回0x0000。
/////


回复

使用道具 举报

ID:100982 发表于 2021-11-19 09:56 | 显示全部楼层
黄youhui 发表于 2021-11-19 09:08
逻辑问题,0x01 和0x08出现两次灯亮顺序是1 2 3 4 5 6 7 8 8 7 6 5 4 3 2 1 1 2 3 4 5 6.................. ...

这样改是不行的,运行后会变成  1  2  3  4  5  6   7      1  2  3  4  5  6  7  
回复

使用道具 举报

ID:100982 发表于 2021-11-19 09:58 | 显示全部楼层
黄youhui 发表于 2021-11-19 09:08
逻辑问题,0x01 和0x08出现两次灯亮顺序是1 2 3 4 5 6 7 8 8 7 6 5 4 3 2 1 1 2 3 4 5 6.................. ...

因为到不了 0x80  flag永远为0
回复

使用道具 举报

ID:624769 发表于 2021-11-19 12:06 | 显示全部楼层
188610329 发表于 2021-11-19 09:03
啊,我要抓狂了,cnt到8归1,没什么需要改,cnt到7归0要改判断逻辑,因为,p0不会

终于上电脑了。刚才手机发消息,差点被气死, 总是打一半就发, 终于能好好打字了。

cnt 到7归0 要改判断逻辑, 不能判断 P0 来改Flag, 而是要把 Flag = !Flag 放到 cnt判断里。

                if(flag)
                {
                        P0 = 0x01 << cnt;
                }
                else
                {
                        P0 = 0x80 >> cnt;
                }
                 delay();
                if(++cnt >= 7)
                {
                        cnt = 0;
                        flag = !flag;
                }

这是比较正统的写法。
回复

使用道具 举报

ID:624769 发表于 2021-11-19 12:13 | 显示全部楼层
名字不是重点 发表于 2021-11-19 09:40
test.c(30): warning C294: unreachable code

刚才手机上的 黑51, return 后面的  0 没有出来,所以,回复里我也说得加不加return 。

在Keil 环境里 return 是可以通过编译的, return 0 是不能通过编译的。
但是,逻辑上,return 0; 就是无返回的意思。在有些编译器里是可以通过的。但是实际上是没有意义的。所以,只要他能通过编译,你就当作是  注释  就行了,不用去考虑逻辑关系问题。
回复

使用道具 举报

ID:100982 发表于 2021-11-19 15:07 | 显示全部楼层
188610329 发表于 2021-11-19 12:13
刚才手机上的 黑51, return 后面的  0 没有出来,所以,回复里我也说得加不加return 。

在Keil 环境 ...

我在keil4里面用return0没有问题啊
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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