如何用单片机编写一个八位循环计数器程序

如何用单片机编写一个八位循环计数器程序,第1张

x0为启动按钮,x1为停止按钮。y0~y7为8盏灯。程序在按下启动按钮后,灯1先亮,1秒(T0延时)后灭,1秒后(T1延时)灯2亮,依次循环。当按下x1后,循环结束。

按下x0后,m0得电为1并自保持,此时1秒计时器T0计时,1秒后T0常开点闭合1秒计时器T1计时,再过1秒T1计时结束常闭点断开T0线圈,

T0失电复位并断开T0常开点,此时T1线圈也失电复位,T1常闭点又闭合,T0得电重复上述计时过程。

第二个程序块:

当M0为1时,在T0触点的上升沿来时k3M10这个二进制数乘以2再写入k3M10中。

K3M10代表M10~M21共12个辅助继电器的组合,那么可以将K3M10看作是一个二进制数。程序未启动时,M10~M21均为0,那么这个二进制数为0;当程序启动时,在下一个程序块中利用了M0的上升沿置位M10,此时M10~M21为1,当T0触点的上升沿来时k3M10(此时为1)这个二进制数乘以2再写入k3M10中(写入后为2),2在二进制数中为10,此时M10失电,M11得电,可以认为M10把"1"交给了M11,以此类推。当第8个M17得电时,完成了一次循环。下一个T0上升沿来到时,M18得电,M17失电。此时下面的程序块利用了M18的上升沿重新置位M10并且将M18复位。这样程序又从M10得电开始循环下去了。

这个程序块的作用就是每次T0的上升沿来到时,“1”在M10~M17之间转移。

1、硬件仿真图

硬件部分比较简单,当键盘按键按下时它的那一行、那一列的端口为低电平。因此,只要扫描行、列端口是否都为低电平就可以确定是哪个键被按下。

2、主程序流程图

程序的主要思想是:将按键抽象为字符,然后就是对字符的处理。将 *** 作数分别转化为字符串存储, *** 作符存储为字符形式。然后调用compute()函数进行计算并返回结果。具体程序及看注释还有流程图。

3、Altium Designer画的PCB图

4、程序源代码

#include <reg51.h>#include <intrins.h>

#include <ctype.h>         

#include <stdlib.h>         

#define uchar unsigned char

#define uint unsigned int

uchar operand1[9], operand2[9]

uchar operator                 

void delay(uint)

uchar keyscan()

void disp(void)

void buf(uint value)

uint compute(uint va1,uint va2,uchar optor)

uchar code table[] = {0xc0,0xf9,0xa4,0xb0,0x99,

              0x92,0x82,0xf8,0x80,0x90,0xff} 

uchar dbuf[8] = {10,10,10,10,10,10,10,10}         

void delay(uint z)

{

uint x,y

for(x=zx>0x--)

  for(y=110y>0y--)

}

uchar keyscan()

{

  uchar skey                   

  P1 = 0xfe

  while((P1 &0xf0) != 0xf0)      

  {

      delay(3)                 

      while((P1 &0xf0) != 0xf0)  

      {

          switch(P1)              

          {

              case 0xee: skey = '7'break

              case 0xde: skey = '8'break

              case 0xbe: skey = '9'break

              case 0x7e: skey = '/'break   

              default:   skey = '#'

          }

          while((P1 &0xf0) != 0xf0)

             

      }

  }

  P1 = 0xfd 

  while((P1 &0xf0) != 0xf0)

  {

      delay(3)

      while((P1 &0xf0) != 0xf0)

      {

          switch(P1)

          {

              case 0xed: skey = '4'break

              case 0xdd: skey = '5'break

              case 0xbd: skey = '6'break

              case 0x7d: skey = '*'break

              default:   skey = '#'

          }

          while((P1 &0xf0) != 0xf0)

             

      }

  }

  P1 = 0xfb

  while((P1 &0xf0) != 0xf0)

  {

      delay(3)

      while((P1 &0xf0) != 0xf0)

      {

          switch(P1)

          {

              case 0xeb: skey = '1'break

              case 0xdb: skey = '2'break

              case 0xbb: skey = '3'break

              case 0x7b: skey = '-'break

              default: skey = '#'

          }

          while((P1 &0xf0) != 0xf0)

             

      }

  }

  P1 = 0xf7

  while((P1 &0xf0) != 0xf0)

  {

      delay(3)

      while((P1 &0xf0) != 0xf0)

      {

          switch(P1)

          {

              case 0xe7: skey = '$'break

              case 0xd7: skey = '0'break

              case 0xb7: skey = '='break

              case 0x77: skey = '+'break

              default:   skey = '#'

          }

          while((P1 &0xf0) != 0xf0)

             

      }

  }

  return skey

}

void main()

{  

  uint value1, value2, value       

  uchar ckey, cut1 = 0, cut2 = 0 

  uchar operator                   

  uchar i, bool = 0

init:                                 

  buf(0)                         

  disp()

  value = 0

  cut1 = cut2 = 0

  bool = 0

  for(i = 0i <9i++)

  {

      operand1[i] = '\0'

      operand2[i] = '\0'

  }                               

  while(1)

  {

      ckey = keyscan()         

      if(ckey != '#')

      {

          if(isdigit(ckey))      

          {

              switch(bool)  

              {

                  case 0:

                          operand1[cut1] = ckey

                          operand1[cut1+1] = '\0'

                          value1 = atoi(operand1)

                          cut1++

                          buf(value1)

                          disp()

                          break

                  case 1:

                          operand2[cut2] = ckey

                          operand2[cut2+1] = '\0'

                          value2 = atoi(operand2)

                          cut2++

                          buf(value2)

                          disp()

                          break                     

                  default: break

              }

          }

          else if(ckey=='+'||ckey=='-'||ckey=='*'||ckey=='/')

          {

              bool = 1 

              operator = ckey

              buf(0)

              dbuf[7] = 10

              disp()

          }

          else if(ckey == '=')

          {

              value = compute(value1,value2,operator)

              buf(value)

              disp()

              while(1)                  

              {

                  ckey = keyscan()

                  if(ckey == '$')        

                      goto init

                  else

                      {

                          buf(value)

                          disp()

                      }

              }

          }

          else if(ckey == '$')

          {    goto init}

      }

      disp()

  }

}

uint compute(uint va1,uint va2,uchar optor)

{

  uint value

  switch(optor)

  {

      case '+' : value = va1+va2   break

      case '-' : value = va1-va2   break

      case '*' : value = va1*va2   break

      case '/' : value = va1/va2   break 

      default :  break

  }

  return value

}

void buf(uint val)

{

  uchar i

  if(val == 0)

  {

      dbuf[7] = 0

      i = 6

  }

  else

      for(i = 7val >0i--)

      {

          dbuf[i] = val % 10

          val /= 10

      }

  for( i >0i--)

      dbuf[i] = 10

}

void disp(void)

{

  uchar bsel, n

  bsel=0x01

  for(n=0n<8n++)

  {

      P2=bsel

      P0=table[dbuf[n]]

      bsel=_crol_(bsel,1)

      delay(3)

      P0=0xff

  }

}

扩展资料:

PROTEUS 是单片机课堂教学的先进助手

PROTEUS不仅可将许多单片机实例功能形象化,也可将许多单片机实例运行过程形象化。前者可在相当程度上得到实物演示实验的效果,后者则是实物演示实验难以达到的效果。

它的元器件、连接线路等却和传统的单片机实验硬件高度对应。这在相当程度上替代了传统的单片机实验教学的功能,例:元器件选择、电路连接、电路检测、电路修改、软件调试、运行结果等。

课程设计、毕业设计是学生走向就业的重要实践环节。由于PROTEUS提供了实验室无法相比的大量的元器件库,提供了修改电路设计的灵活性、提供了实验室在数量、质量上难以相比的虚拟仪器、仪表,因而也提供了培养学生实践精神、创造精神的平台

随着科技的发展,“计算机仿真技术”已成为许多设计部门重要的前期设计手段。它具有设计灵活,结果、过程的统一的特点。可使设计时间大为缩短、耗资大为减少,也可降低工程制造的风险。相信在单片机开发应用中PROTEUS也能茯得愈来愈广泛的应用。

使用Proteus 软件进行单片机系统仿真设计,是虚拟仿真技术和计算机多媒体技术相结合的综合运用,有利于培养学生的电路设计能力及仿真软件的 *** 作能力;

在单片机课程设计和全国大学生电子设计竞赛中,我们使用 Proteus 开发环境对学生进行培训,在不需要硬件投入的条件下,学生普遍反映,对单片机的学习比单纯学习书本知识更容易接受,更容易提高。

实践证明,在使用 Proteus 进行系统仿真开发成功之后再进行实际制作,能极大提高单片机系统设计效率。因此,Proteus 有较高的推广利用价值。

参考资料来源:百度百科-protues

TMOD高四位是负责定时器1的 *** 作,低4位负责定时器0的 *** 作。

而每个四位中的M1和M0负责控制定时器工作方式,其中

M1M0 = 00, 定时器工作在方式0

M1M0 = 01,方式1

M1M0 = 10,方式2

M1M0 = 11,这种设置只对定时器0有效,表示定时器0工作方式

因此,T1工作在方式0,TMOD = 00000000

T1工作在方式1,TMOD = 00010000


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/11011329.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-13
下一篇 2023-05-13

发表评论

登录后才能评论

评论列表(0条)

保存