初学51单片机流水灯实现及C语言实践相关

  笔者的单片机开发板子和教学视频是來自金沙滩工作室宋老师的。

   在点亮流水灯的课后习题,要求流水灯从左到右依次亮,到底后接着从右到左点亮,来回循环。为了加深印像,笔者又在这个基础上提出了新的变化。之前是一个LED灯来回跑,这次课题是两个LED一个从左另一个从右互相来回跑。

进入正题;调试版的单片机的IO口控制着LED的通断并且低电平的时候LED点亮。并且控制端口P0.0~P0.7 8个端口刚好能被一个字符表示。 如图 (图中的值到时都要求反

预先的设想是LED1从端口1-8依次点亮然后再从8-1依次点亮往复循环,LED2从端口8-1依次点亮然后从1-8依次点亮往复循环。以下是实现的初版程序代码

第一个语句P0 = ~(shift1+shift2) 最后P0的值是0111 1110 即最左边和最右边端口的灯点亮了

程序功能实现了但是在实际观看的时候确发现好像和预期不一样,从视觉的观感上好像是这样子的

在视觉上两个LED在端口4和端口5相碰停了一下然后返回了 结果链接视频

流水灯初版_哔哩哔哩_bilibili

实际上LED确实按照之前的设想工作的为什么会发生这种情况呢,如图

当LED1运动到端口4的时候LED2运动刚好到5,接着LED1运动到端口5此时LED2运动到端口4,因为是1条流水灯,实际上LED在端口4,5延时了两次。因此会在视频上显示好像停了一段时间然后回头走了。

为了避免这种情况发生,工作到端口4和5的时候确保只亮一次灯,因此有如下

如此就不会这么明显的停留感了,看程序

while(1)
  {     
     
        P0 = ~(shift1+shift2); //P0等于循环变量取反     
        for(i=0;i<30000;i++);   //软件延时
        if(shift1 == 0x08 && dir1 == 0)    //判断是否 shit1运动到端口4并且是向左移动
        {
          shift1 = shift1<<1;    //shift1在端口4 0x08的位置往左移一位
          shift2 = shift2>>1;    //shift2在端口5    0x10的位置往右移一位,
        }                        // 因为是相对运动的因此判断了shift1的方向shift2 的方向就确认了
        if(shift1 == 0x10 && dir1 == 1)    //判断是否 shift1运动到端口5并且是向右运动
        {
          shift1 = shift1>>1;  // shift1在端口5 0x10的位置并且向右移动一位
          shift2 = shift2<<1;  // shift2在端口4 0x08的位置往左移一位
        }    
       if(dir1 == 0 ) //判断是否 shift1往左移动
            {
              {shift1 = shift1<<1; //循环变量1左移1位
               shift2 = shift2>>1;
              }    //循环变量2右移1位
               if(shift1 ==0x80 && shift2 == 0x01)    //循环变量都移到最左端和最右端
                {
                   dir1 = 1;         //换向
                 (最终的版本这里会加一行return (0);)//这里用 continue 结果也是一样的
                }
              } 

        if(dir1 == 1)  // 判断是否 shift1往右移动
          {
            {
               shift1 = shift1>>1 ;    //换向后循环变量1右移
             shift2 = shift2<<1 ;    //换向后循环变量2左移
            }
             if(shift1 == 0x01 && shift2 == 0x80)  //判断循环变量1到最右端且循环变量2到最 左端
            {
              dir1 = 0;       //又开始换向换回到原先的方向
             
            
            }
             
           }
   }

此时的现象是流水灯瑕疵版_哔哩哔哩_bilibili

发现突然流水灯来回跑的时候会有一次端口8和端口1不点亮,分析程序的工作逻辑发现

这个程序是一条线的形式执行的,程序执行到换向后就马上执行了下一个if程序,这个时候端口8和端口0并没有执行就直接先移位然后回到while()函数开头执行,显然这不是希望的结果,我们需要执行换向后直接回到while循环的第一句重新开始执行

因此加了一个return(0);由于笔者刚学单片机和C语言所以这个return(0)具体干了什么不太清楚,只知道哔哩哔哩大学的C语言老师写main()函数的时都会加一句这个。而且恰哈解决这个问题

最后的结果

流水灯改进版_哔哩哔哩_bilibili

              结语:实现这个程序笔者花了大概3天左右,一开始跟着老师抄程序,事实上C语言的语法还是理 解个懵懵懂懂,主要C语言的教程只学到printf这里,一开始照着老师原先的C语言结构改程序结果搞了好久无法下手,最后在bilibili大学直接跳到C语言else if的部分突击学习一下,就算知道逻辑也无法表达出来。不过笔者并没有气馁(一度放弃主要很多时候发现写语句的时候没注意这里少一点那里那个搞错了,逻辑也不是很明朗,最后在debug的时候发现第二版程序P0口变成变量值了而且运行二十几次就超出INt的范围,然后对比老师的程序之前的程序发现P0不是变量不会出现local里面,考虑到可能是输入法造成的果断删掉重写,这次就没这个问题了),这个过程中还学会了初步使用debug功能,对比老师的程序看P0口地址的值。

  • 29
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值