找回密码
 立即注册

QQ登录

只需一步,快速开始

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

我想通过单片机定时器中断来实现led的流水灯,可是程序出了点问题

[复制链接]
跳转到指定楼层
楼主
ID:474631 发表于 2019-2-3 23:06 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
目的是使led从左到右然后再从右到左 可是我的代码只能实现一次从左到右然后就没有led亮(灯8个)
我的思路是通过余数判断是否移位到边界然后转向 我在草稿纸上也算过了发现没什么问题啊 可是就是实现不了 求大神帮忙修改一下

单片机源程序:
#include "reg51.h"
typedef unsigned char u8;
typedef unsigned int u16;
#define led P0
u16 j=0;
void time()
{
        TMOD=0x01;
        TH0=0xfc;TL0=0x12;ET0=1;
        TR0=1;EA=1;
}
void main()
{
        u8 dat=0x01,k=0,i=0;
        time();
        while(1)
        { led=dat;
                if(j==500)
                {
                        j=0;
                        if(i/2==1)
                        {
                                dat=dat>>1;
                        }
                        if(i/2==0)
                        {
                                dat=dat<<1;
                        }
                        k++;
                        if(k%7==0&&k!=0)
                        i++;
          }
        }
}
void time0() interrupt 1
{
        TH0=0xfc;TL0=0x12;
        j++;
}

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

使用道具 举报

沙发
ID:474631 发表于 2019-2-3 23:17 | 只看该作者
找到问题根源了。。。我把取余号写成除号了。。还有应该是k=7的时候才转向。。。
回复

使用道具 举报

板凳
ID:474631 发表于 2019-2-3 23:22 | 只看该作者
额 不过我还有一个问题 我这个i和k都是有上限的 如何让他无限的流水?我这个程序当i k其中一个大于65535的时候应该就gg了
回复

使用道具 举报

地板
ID:472242 发表于 2019-2-4 04:37 | 只看该作者
日本人孙笑川 发表于 2019-2-3 23:22
额 不过我还有一个问题 我这个i和k都是有上限的 如何让他无限的流水?我这个程序当i k其中一个大于65535的 ...

定时器的值是TH0=0xfc;T L0=0x12;同你i,k没关系,而却上限是255(typedef unsigned char u8),就算你最终到255,也会现重新从0开始运行

评分

参与人数 2黑币 +27 收起 理由
#include51.h + 15
站着说话不腰疼 + 12

查看全部评分

回复

使用道具 举报

5#
ID:474677 发表于 2019-2-4 10:04 | 只看该作者
shuisheng60 发表于 2019-2-4 04:37
定时器的值是TH0=0xfc;T L0=0x12;同你i,k没关系,而却上限是255(typedef unsigned char u8),就算你最终到2 ...

楼主的定时中断是用于控制流水灯的跑动间隔时间,跟循环次数没有关系,楼主的意思应该是实现无限循环
回复

使用道具 举报

6#
ID:474677 发表于 2019-2-4 10:08 | 只看该作者
日本人孙笑川 发表于 2019-2-3 23:22
额 不过我还有一个问题 我这个i和k都是有上限的 如何让他无限的流水?我这个程序当i k其中一个大于65535的 ...

要实现无限循环就只不需要编写这么复杂,while(1)主循环体就是一个无限循环,你只需要包括一个从左到右再从右到左的单循环体就能实现了。
回复

使用道具 举报

7#
ID:474677 发表于 2019-2-4 10:16 | 只看该作者
本帖最后由 iofree 于 2019-2-4 11:37 编辑

回帖审核时间太长了,主体循环这样写应该就可以了,还要增加一个延时函数:void delay()
这个延时函数不细写了,自己定制吧
while(1)
{
  for(i=0;i<8;i++){
    led=dat;
    dat<<=1;    delay();
  }
  for(i=0;i<8;i++){
    led=dat;
    dat>>=1;
    delay();
  }
}
希望能实现你的要求,祝你成功

回复

使用道具 举报

8#
ID:474631 发表于 2019-2-5 22:58 | 只看该作者
iofree 发表于 2019-2-4 10:16
回帖审核时间太长了,主体循环这样写应该就可以了,还要增加一个延时函数:void delay()
这个延时函数不细 ...

牛b 谢谢老哥
回复

使用道具 举报

9#
ID:401113 发表于 2019-2-9 00:34 | 只看该作者
iofree 发表于 2019-2-4 10:16
回帖审核时间太长了,主体循环这样写应该就可以了,还要增加一个延时函数:void delay()
这个延时函数不细 ...

我觉得的这样写不行,<<会把前面的数据挤掉,后面的补0(>>同理),循环8次dat的值就成了0x00,这样灯就不亮了。
回复

使用道具 举报

10#
ID:401113 发表于 2019-2-9 00:48 | 只看该作者
iofree 发表于 2019-2-4 10:16
回帖审核时间太长了,主体循环这样写应该就可以了,还要增加一个延时函数:void delay()
这个延时函数不细 ...

这个可以,我试过很多遍了
        while(1)
        {
                    led=dat;
                  while(j!=500);
                  j=0;       
                  for(i=0;i<7;i++)
                  {
                       
                    dat<<=1;
                    led=dat;
                        while(j!=500);
                        j=0;
                  }
                  for(i=0;i<7;i++)
                  {
                    
                    dat>>=1;
                        led=dat;
                        while(j!=500);
                        j=0;
              }
        }
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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