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

供稿:hz-xin.com     日期:2024-05-03
单片机程序,使用keil 编程,用Atmel,AT89C51编的

很简单,只是电路能用吗?单片机能驱动的了数码管码?
如果纯粹是Protues玩,那就无所谓了。
利用定时计数器的计数功能,取GATE=1,C/T=1
BT2接INT0
BT3接T0

JB BT1,CLEAR

clear程序段中对P2清零

#include#define uchar unsigned charuchar tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00}; //0到9uchar num;uchar led[]={1,2,3,4};void t0isr() interrupt 1{TH0=(65536-5000)/256;TL0=(65536-5000)%256;switch(num){case 0:P2=0x01;break;case 1:P2=0x02;break;case 2:P2=0x04;break;case 3:P2=0x08;break;default:break;}P0=~tab[led[num]];num++;num&=0x03;}main(){TMOD=0x11;TH0=(65536-5000)/256;TL0=(65536-5000)%256;TR0=1;ET0=1;EA=1;while(1);}

按照你的要求写的程序如下,你拿去测试吧!

 

#include "REG52.H"

sbit SHUG_01 = P2^0;    //数码管1

sbit SHUG_02 = P2^1;    //数码管2

sbit SHUG_03 = P2^2;    //数码管3

sbit SHUG_04 = P2^3;    //数码管4

sbit SHUG_05 = P2^4;    //数码管5

sbit SHUG_06 = P2^5;    //数码管6


 

sbit    KEY0_01 = P0^0;    //按键  启动或停止

sbit    KEY0_02 = P0^1;    //按键  加

sbit    KEY0_03 = P0^2;    //按键减


 

#define     LED_DATA        P1      //P1数据端口

unsigned char value_temp = 0;

unsigned char value_shio = 23;

unsigned char value_feno = 59;

unsigned char value_miao = 59;


 

unsigned char code   value_tab0[]={0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90}; //共阳极

unsigned char code   value_tab1[]={0x40, 0x79, 0x24, 0x30, 0x19, 0x12, 0x02, 0x78, 0x00, 0x10}; //共阳极 

 

/*

 * 延时1ms延时子函数

**/

void Delay_1ms(unsigned int Time)

{

 unsigned int x, y;

 for(x = Time; x > 0; x--)

  for(y = 120; y > 0; y--);

}


 

/*

 * 按键开关【启动和停止】子函数

**/

void Scan_keyoutCmd(void)

{

 if(KEY0_01 == 0)           

 {

  Delay_1ms(10);         

  if(KEY0_01 == 0)           

  {

   TR0 = ~ TR0;   

  }

  while(KEY0_01 == 0);         

 } 


 

 if(KEY0_02 == 0)           

 {

  Delay_1ms(10);           

  if(KEY0_02 == 0)           

  {

   value_miao--;   

   if(value_miao == -1)

   {

    value_feno--;

    value_miao = 59;

    if(value_feno == 0)

    {

     value_shio--;

     value_feno = 59;

     if(value_shio == 0)

     {

      value_shio = 23;

     }

    } 

   }

   while(KEY0_02 == 0);       

  }

 } 


 

 if(KEY0_03 == 0)           

 {

  Delay_1ms(10);         

  if(KEY0_03 == 0)         

  {

   value_miao++;   

   if(value_miao == 60)

   {

    value_miao = 0;

    value_feno++;

    if(value_feno == 60)

    {

     value_feno = 0;

     value_shio++; 

     if(value_shio == 24)

     {

      value_shio = 0;

     }

    } 

   }

    while(KEY0_03 == 0);          //检测松手

  }

 } 

}


 

/*

 * 程序运行【启动和停止】子函数

**/

void Disp_layledketCmd(void)

{

 /***小时***/

 SHUG_01 = 1;   

 LED_DATA = value_tab0[value_shio / 10];   /*******小时的十位数显示***************/

 Delay_1ms(5);

 SHUG_01 = 0;

 SHUG_02 = 1;

 LED_DATA = value_tab1[value_shio % 10];   /*******小时的个位数显示***************/

 Delay_1ms(5);

 SHUG_02 = 0;


 

 /***分钟***/

    SHUG_03 = 1;   

 LED_DATA = value_tab0[value_feno / 10];   /*******分钟的十位数显示***************/

 Delay_1ms(5);

 SHUG_03 = 0;

 SHUG_04 = 1;

 LED_DATA = value_tab1[value_feno % 10];   /*******分钟的个位数显示***************/

 Delay_1ms(5);

 SHUG_04 = 0;


 

 /***秒钟***/

    SHUG_05 = 1;   

 LED_DATA = value_tab0[value_miao / 10];   /*******秒钟的十位数显示***************/

 Delay_1ms(5);

 SHUG_05 = 0;

 SHUG_06 = 1;

 LED_DATA = value_tab0[value_miao % 10];   /*******秒钟的个位数显示***************/

 Delay_1ms(5);

 SHUG_06 = 0;

}


 

void Tero_Init(void)

{

 TMOD = 0x01;

 TH0 = (65536 - 50000) / 256;

 TL0 = (65536 - 50000) % 256;

 ET0 = 1;

 TR0 = 1;

 EA = 1;

}


 

/*

 * 函数主体

**/

int main(void)

{

 P1 = P2 = P3 = 0x00;

 Tero_Init();

 

 while(1)

 {

  Scan_keyoutCmd();

  Disp_layledketCmd();  //执行应运程序 

 } 

}


 

/*

 * 定时器中断服务程序

**/

void Tmero()interrupt 1

{

 TH0 = (65536 - 50000) / 256;

 TL0 = (65536 - 50000) % 256;

 value_temp++;

 if(value_temp == 20)

 {

  value_temp = 0;

  value_miao--;

  if(value_miao == 0)

  {

   value_feno--;

   value_miao = 59;

   if(value_feno == 0)

   {

    value_shio--;

    value_feno = 59;

    if(value_shio == 0)

    {

     value_shio = 23;

    }

   }


 

  }

 } 

}



你可以参考下面这个程序,这个是加计时器.把对应端口改下,计时改减就可以了.
数码管的显示网上大把,移植一下就可以了.
//--------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 = z; x > 0; x--) for(y = 100; y > 0; y--);
}
//---------------------------------------------------
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 + 48; Timer_buf[6] = sec / 10 + 48;
Timer_buf[4] = min % 10 + 48; Timer_buf[3] = min / 10 + 48;
Timer_buf[1] = hour % 10 + 48;Timer_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 = 0; i < 200; i++) {
SPK = 0; for (j = 0; j < 100; j++);
SPK = 1; for (j = 0; j < 100; j++);
} }
}
//-------------------------------
Key = read_key(); //读出按键
switch(Key) { //分别处理四个按键
case 0: modify = 1; break;
case 1: if(modify) {min++; min %= 60; W_BUFF(); break;}
case 2: if(modify) {hour++; hour %= 24; W_BUFF(); break;}
case 3: modify = 0; break;
} }
}
//---------------------------------------------------
void timer0(void) interrupt 1 //T0中断函数, 50ms执行一次
{
TH0 = 0x4c;
t0++; t0 %= 20; //20, 一秒钟
if(t0 == 0) {new_s = 1; LED = ~LED;}
if(modify) LED = 0;
}
//===================================================

用KEIL 为89S51单片机写个C语言音乐程序
答:0x21,0xE1,0x8C,0xD8,0x68,0xE9,0x5B,0x8F, //1,2,3,4,5,6,7,8,i 0xEE,0x44, 0x6B,0xB4,0xF4,0x2D,0x47,0x77,0xA2,0xB6,0xDA,0xFA,0x16,};void delay(unsigned char t){ unsigned char t1...

用keil. c语言编写每隔一秒亮一个灯,总共8个灯
答:include<reg52.h> include<intrins.h> define uchar unsigned char define uint unsigned int uchar a=0,i=8;void main(){ uchar t;TMOD=1; //初始化定时器0 TH0=(65535-50000)/256;//设定50ms计时初值 TL0...

编写一个C语言程序,显示如下菜单并实现相应的菜单选择功能
答:/*本程序没有采用严格的措施防止错误的输入,所以请在看源程序之后再输入。运行后会有如下提示:“请输入你的选择及整数n(用逗号来间隔):”这时可以输入这样的选择:“1,2”,即求2的立方 “2,125”,即求125的...

...keil调试),帮忙设计一个轻触开关的C语言程序。谢谢。。(汇编指令...
答:include<reg52.h> define uchar unsigned char define uint unsigned int uchar c,d,x,y;sbit a=P2^6;sbit b=P2^7;uchar code table[]={0xfe,0xfd,0xfb,0xf7,0xef };void delay(uint z){ uint x,y;for(...

【单片机,C语言】用C语言做个程序,在Keil 软件下运行,要求在里面,谢谢...
答:include <REG52.H> include "SoundPlay.h"void Delay1ms(unsigned int count){ unsigned int i,j;for(i=0;i<count;i++)for(j=0;j<120;j++);} //***Music unsigned char code Music_Girl[]={ 0x17,0x02...

...从keil编写程序(C语言)到单片机工作,usb电源,com接口)
答:第4步:加载程序。把我们编写的c文件加载进入 看到左边 source group1,点击右键,选择倒数第四项 “add files...”进入add框,选择你刚才保存的main.c文件,然后add 看到 左边source group1下面是不是加载上main.c了 第...

keil软件用单片机控制8个LED流水灯来回点亮(C语言程序)
答://程序中使用_crol_函数,所以要包含头文件"intrins.h"include "intrins.h"void delay(unsigned int t){ unsigned int i,j;for(i=t;i>0;i--)for(j=110;j>0;j--);} main(){ unsigned char temp;temp=0xfe...

急求KEIL C51 红绿灯程序!(用C语言!)
答://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 ...

我在keil软件 用c语言写51单片机的时候发现?
答:寄存器算是个中介,数据从内存取出临时存放到寄存器,然后将当时用不上的数据又从寄存器回写到内存,这样就解决了寄存器共享问题了;另外,你在调试时,再打开个反汇编窗口,跟踪C语音程序的汇编代码,就更清楚了;...

Keil中怎么实现按键一次显示一盏灯,按键两次显示两盏灯?
答:应该是用keil写C语言程序实现,声明一个变量num计按键次数,按键一次num加1,大于2再回1,再用if语句判断num的值确定显示1或2盏灯。