用KEIL编写C语言程序实现:单片机是AT89C51,实现一个计时器,数码管为6为的,有三个按键接在P0上。
很简单,只是电路能用吗?单片机能驱动的了数码管码?
如果纯粹是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盏灯。