用KEIL编写C语言程序实现:单片机是AT89C51,实现一个计时器,数码管为6为的,有三个按键接在P0上。

用KEIL编写C语言程序实现:单片机是AT89C51,实现一个计时器,数码管为6为的,有三个按键接在P0上。,第1张

你可以参考下面这个程序,这个是加计时器.把对应端口改下,计时改减就可以了.

数码管的显示网上大把,移植一下就可以了.

//--------LCD 1601 clock----------------------------------------

//---modified from a LCD1602 program,2012/11/21-----------------

#include<reg52.h>

#define uchar unsigned char

#define uint unsigned int

//----P3: key input for modify timer ---------------------------

#define KEY_IO P3

#define LCD_IO P0

sbit LCD_RS = P2^0

sbit LCD_RW = P2^1

sbit LCD_EN = P2^2

//----P1.2: timer speaker output-------------------------------

sbit SPK = P1^2

//----P2.4: timer LED indicator output------------------------

sbit LED = P2^4

bit new_s, modify = 0

char t0, sec = 50, min = 59, hour = 23

//char code LCD_line1[] = "Designed by ZELD"野孝

char code LCD_line2[] = "Timer: 00:00:00 "

char Timer_buf[] = "23:59:50"

//---------------------------------------------------

void delay(uint z)

{

uint x, y

for(x = zx >0x--) for(y = 100y >0y--)

}

//---------------------------------------------------

void W_LCD_Com(uchar com) //写指令

{

LCD_RS = 0 LCD_IO = com// LCD_RS和R/W都为低电平时,写入指令

LCD_EN = 1 delay(5)LCD_EN = 0//用EN输入一个高脉冲

}

//---------------------------------------------------

void W_LCD_Dat(uchar dat) //写数据

{

LCD_RS = 1 LCD_IO = dat// LCD_RS为高、R/W为低时,写入数据

LCD_EN = 1 delay(5)LCD_EN = 0//用EN输入一个旦羡高模脊拍脉冲

}

//---------------------------------------------------

void W_LCD_STR(uchar *s) //写字符串

{

while(*s) W_LCD_Dat(*s++)

}

//---------------------------------------------------

void W_BUFF(void) //填写显示缓冲区

{

Timer_buf[7] = sec % 10 + 48Timer_buf[6] = sec / 10 + 48

Timer_buf[4] = min % 10 + 48Timer_buf[3] = min / 10 + 48

Timer_buf[1] = hour % 10 + 48Timer_buf[0] = hour / 10 + 48

//W_LCD_Com(0xc0 + 7)W_LCD_STR(Timer_buf)

//1602 start from address C0H(second row),1601 start from 40H-------

W_LCD_Com(0x80 + 7)W_LCD_STR(Timer_buf)

}

//---------------------------------------------------

uchar read_key(void)

{

uchar x1, x2

KEY_IO = 255

x1 = KEY_IO

if (x1 != 255) {

delay(100)

x2 = KEY_IO

if (x1 != x2) return 255

while(x2 != 255) x2 = KEY_IO

if (x1 == 0x7f) return 0

else if (x1 == 0xbf) return 1

else if (x1 == 0xdf) return 2

else if (x1 == 0xef) return 3

else if (x1 == 0xf7) return 4

}

return 255

}

//---------------------------------------------------

void Init()

{

LCD_RW = 0

W_LCD_Com(0x38)delay(50)

W_LCD_Com(0x0c)

W_LCD_Com(0x06)

W_LCD_Com(0x01)

// W_LCD_Com(0x80)W_LCD_STR(LCD_line1)

// W_LCD_Com(0xC0)W_LCD_STR(LCD_line2)

W_LCD_Com(0x80)W_LCD_STR(LCD_line2)

TMOD = 0x01 //T0定时方式1

TH0 = 0x4c

TR0 = 1 //启动T0

PT0 = 1 //高优先级, 以保证定时精度

ET0 = 1

EA = 1

}

//---------------------------------------------------

void main()

{

uint i, j

uchar Key

Init()

while(1) {

//-------------------------------

if (new_s) { //如果出现了新的一秒, 修改时间

new_s = 0 sec++ sec %= 60

if(!sec) { min++ min %= 60

if(!min) { hour++hour %= 24}

}

W_BUFF() //写显示

//-------------------------------

if (!sec &&!min) { //整点报时

for (i = 0i <200i++) {

SPK = 0for (j = 0j <100j++)

SPK = 1for (j = 0j <100j++)

} }

}

//-------------------------------

Key = read_key() //读出按键

switch(Key) { //分别处理四个按键

case 0: modify = 1break

case 1: if(modify) {min++ min %= 60 W_BUFF()break}

case 2: if(modify) {hour++hour %= 24W_BUFF()break}

case 3: modify = 0break

} }

}

//---------------------------------------------------

void timer0(void) interrupt 1 //T0中断函数, 50ms执行一次

{

TH0 = 0x4c

t0++t0 %= 20 //20, 一秒钟

if(t0 == 0) {new_s = 1LED = ~LED}

if(modify) LED = 0

}

//===================================================

//12M晶振

//共阴数码管

#include <reg51.h>

sbit red=P1^0

sbit green=P1^1

sbit yellow=P1^2

bit flag=1

unsigned char code duan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}

unsigned char code wei[ ]={0xfd,0xfe}

unsigned char time=35

void main()

{

  void show_time()

  void show_light()

  EA=1

  ET0=1

  TMOD=0x01

  TH0=(65536-50000)/256

  TL0=(65536-50000)%256

  TR0=1

  red=0

  while(1)

  {

      show_time()

      show_light()

  }

}

void show_time()

{

  void delay()

  unsigned char num=time,i

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

  {

      P2=wei[i]

      P0=duan[num%10]

      delay()

      P0=0x00

      num/=10

  }

}

void delay()

{

  int i

  for(i=1000ii--)

}

void show_light()

{

  if(flag)

  {

      if(!time)

      {

          flag=0

          red=1

          green=0

          time=35

      }

  }

  else

  {

      if(time>0&&time<4)

      {

          green=1

          yellow=0

     液数轮 }       

 毕并     if(!time)

      {

          yellow=1

          red=0

          flag=1

          time=35

      }

  }

}

void dec_sec() interrupt 1

{

  static count=0

  TH0=(65536-50000)/256

  TL0=(65536-50000)%256

  if(++count==20)

  {

     闹信 count=0

      time--

  }

}

#include<reg52.h>

#define uchar unsigned char

#define duan P0 //共阴数码管的阳极端口

sbit wei1=P2^4 //共阴数码管的阳极端口,我的是四位的,下面语句中把1,2关了,只用到了3,4。

sbit wei2=P2^5

sbit wei3=P2^6

sbit wei4=P2^7

uchar code num[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//共阴数码管0~9的十六进制码

void delay(uchar xms)//软件延时

{

int i,j

for(i=xmsi>0i--)

for(j=125j>0j--)

}

void display(int tens,ones) //用来显示数字的函数,显示此时的十位,个亩尘位。

{

int i,j

for(i=2i>0i--)//通过改变i和j的值,可以改段掘变计时时间。

for(j=50j>0j--)

{

wei3=1//扫描原理。

wei4=0

duan=num[tens]

delay(5)

wei3=0

wei4=1

duan=num[ones]

delay(5)

}

}

void main()

{

int onesp=0,tensp=0//定义ones place和tens place。

wei1=0

wei2=0

while(1)

{

for(tensp=9tensp>=0tensp--)

{

for(onesp=9onesp>=0onesp--)

{

display(tensp,onesp)//调用函数握耐核显示此时的数字。

}

}

}

}

这个程序测试可用,从99计数到00。只用了比较简单知识,不涉及定时器和系统中断。不懂可以追问。


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

原文地址:https://54852.com/yw/12321266.html

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

发表评论

登录后才能评论

评论列表(0条)

    保存