基于51单片机的交通灯设计(三)-编写c51程序 / 单片机设计

2年前 阅读 / 256 来源 / 原创 文 / zhangbao

前面我们用两篇文章分别介绍了设计要求和原理图内容,我们已经对交通灯设计有了初步了解,这里,我们继续学习程序的编写。这一篇我们用到的...

前面我们用两篇文章分别介绍了设计要求和原理图内容,我们已经对交通灯设计有了初步了解,这里,我们继续学习程序的编写。

这一篇我们用到的工具软件有:

思维导图制作软件

流程图制作软件

Keil4 c51编译软件

Proteus7 仿真软件

按照我们之前在第一篇文章里绘制的“基本功能和设计思路的图表”内容,在“设计思路”里面列出了两个方法,我们选择第一种,先制作仿真后制作实物。

01.分析程序中用到的内容

可能一开始让人觉得无从下手,这个程序到底怎么写,写什么内容?

不着急,我们回顾最开始的内容,那时候我们画了一个“基本功能和设计思路的图表”,现在就根据这个图表,给它添砖加瓦,增加程序的内容,有了内容,就能做出控制流程,有了控制流程,就会有程序……

看下图:


基于51单片机的交通灯设计(三)-编写c51程序

程序设计思路整理--思维导图

交通灯设计——从功能产生程序内容

从图中可以看出,有两大部分:

一是“功能”,这是我们第一篇文章里面的内容;

二是“程序内容”,这是根据“功能”的需求,制定出的程序要编写的内容。

后面,我们就根据程序内容来完成每个小定义、小函数的编写,直到给程序准备好所有的“材料”,那么搭建一个完整的程序结构也就水到渠成了。

02.确定程序控制流程

有了内容,把它们合理安排,就可以做出我们原先设计的功能。

程序的流程用图来表达会比语言描述更加形象和直观,虽然在实际程序编写过程中不一定会完全按照这个结构完成任务,但是,事先有一个清晰的思想脉络,是非常必要的。

下面是一个简单的主程序流程图:


基于51单片机的交通灯设计(三)-编写c51程序

交通灯控制主程序流程图

03. 绘制proteus仿真图

这里贴一张程序完成后的正常运行截图:

 

基于51单片机的交通灯设计(三)-编写c51程序

04. 选择编写和编译程序的工具

对于51单片机,编译器不二的选择当然是Keil C51,但是编写程序的编辑器可以有很多选择。

常见的代码编辑工具软件有:Sublime Text3、Atom、Visual Studio Code 等等。


基于51单片机的交通灯设计(三)-编写c51程序


要注意的一点是,用编辑软件编写源码时,编译软件Keil不要点保存文件(当然工程可以保存),只编译,这样就不容易出现乱码。

git也是必要的工具,对于单片机新手来说暂时不用也不影响。

05. 编写完整程序

函数较多,首先是编写头文件,定义端口;其次编写单个程序,逐一测试。最后整合起来,用主函数来控制执行顺序。

为了思路清晰,这里采用了状态切换的方式,也加入了模式切换。实际简单程序可以只用状态来切换,调理会更清晰。

主要的子函数有:定时中断、按键检测、数码管显示、倒计时计算、信号灯控制等。

下面是主函数:

// 主函数
void main(void) {
  Delay_ms(200);
  PortInit();      // 初始化IO端口
  Timer0Init();    // 初始化定时器0
  TimeValueInit(); // 初始化倒计时时间值
  StatusInit();    // 初始化状态

  while (1) {
    //判断模式
    switch (uc_Mode) {             
      // 如果为正常模式      
      case kMode_Normal: {   
        if (g_flag1s == isYes) {    // 如果中断计数1S时间到
          testTimeChangeState();    // 检测倒计时时间,时间到则改变状态
          g_flag1s = isNo;          // 重置1S标记
          if (uc_State == i_EWY) {
            ioLed_EW_Yellow = isLedON;
          } else if (uc_State == i_SNY) {
            ioLed_SN_Yellow = isLedON;
          }        
        } else if (g_flag05s == isYes) {  // 如果中断计数0.5S时间到
          g_flag05s = isNo;               // 重置1S标记
          if (uc_State == i_EWY) {
            ioLed_EW_Yellow = isLedOFF;
          } else if (uc_State == i_SNY) {
            ioLed_SN_Yellow = isLedOFF;
          }
        }
        mainDisplay();        // 主显示子程序(包含按键检测和执行子程序)
      } break;
      // 如果为设置时间模式
      case kMode_SetTime: {  
        mainDisplay();        // 主显示子程序(包含按键检测和执行子程序)
        g_flag1s = isNo;
      } break;
      //如果为深夜模式
      case kMode_LateNight: {  
        //如果中断计数1S时间到
        if (g_flag1s == isYes) {  
          g_flag1s = isNo;
          ioLed_EW_Yellow = isLedON;
          ioLed_SN_Yellow = isLedON;
        } else if (g_flag05s == isYes) {
          g_flag05s = isNo;
          ioLed_EW_Yellow = isLedOFF;
          ioLed_SN_Yellow = isLedOFF;
        }
        key_Monitor();  //监控键
      } break;
      //如果为其它模式
      default: {        
        key_Monitor();  //监控键
      } break;
    }
  }
}

上面给出编写主函数的例子。

一边编写程序,一边编译成代码,用仿真加载运行调试,不断修改完善。

06.总结与积累

同样的控制功能,程序有各种各样的写法,通常采用一种自己习惯的方式,但是也应该不断学习别人的优点,改变自己的的不好习惯。

当然,笔者更趋向于用实际电路调试,毕竟仿真和实际硬件往往存在不可预知的差异,有时候会出现很多奇怪的问题,而真实板子就没有哪些问题,前提是硬件要正常。



0

上一篇:基于51单片机的交通灯设计(二)-原理图

下一篇:已经是最后一篇

扫一扫关注微信公众号
评论列表
共0条评论
  • 这篇文章还没有收到评论,赶紧来抢沙发吧~