89c51单片机程序设计!!!

作者&投稿:红垂 (若有异议请与网页底部的电邮联系)
用C语言编写AT89C51单片机程序,设计一个智能数字钟。~

#include
#define uint unsigned int
#define uchar unsigned char

sbit QB1=P1^0;
sbit QB2=P1^1;//数码管段选
sbit QB3=P1^2;
sbit QB4=P1^3;
sbit QB5=P1^4;
sbit QB6=P1^5;
sbit fm=P1^6; //蜂鸣器
sbit s1=P2^4; //s5按键,切换显示
sbit s2=P2^3; //s2按键,设置调时
sbit s3=P2^2; //s3按键,加1
sbit s4=P2^1; //s4按键,减1

sbit led1=P0^0;
sbit led2=P0^1;
sbit led3=P0^2;

uchar count;
uchar sec,minu,hour,day,week,mon;
uchar n_sec,n_minu,n_hour;
uint year;
uchar set_2=1,set_1=1;
uchar hs,hg,mis,mig,ss,sg;
uchar nhs,nhg,nms,nmg,nss=0,nsg=0;
uchar ms,mg,ds,dg,w;
uchar code table[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,
0X90,0X88,0X83,0XC6,0XA1,0X8E,0X86,0xbf}; //0~F,-,共阳
//uchar code tableyi[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
//0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40};//0-F,-,共阴
uchar code table_d[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,
0x87,0xff,0xef}; //0~9数组,带小数点

uchar table1[]={31,31,29,31,30,31,30,31,31,30,31,30,31}; //闰年
uchar table2[]={31,31,28,31,30,31,30,31,31,30,31,30,31}; //非闰年

void delay(uint); //延时函数
void timer0(); //走时中断函数
void jishi(); //计时函数
void key_change(); //切换显示按键函数
void key_set(); //设置时间按键函数
void disp(uchar,uchar,uchar,uchar,uchar,uchar); //显示函数
void zd_clock(); //整点报时函数
void nz_clock(); //闹钟函数
uchar incone(uchar); //加1函数
uchar decone(uchar); //减1函数
void set_time(); //设置时间函数
void set_clock(); //设置闹钟函数
void set_mdw(); //设置月日星期函数


void main() //主函数
{
EA=1;
ET0=1;
TR0=1;
TMOD=0x01;
TH0=0x4c; //50ms初值 晶振11.0592
TL0=0x00;
hour=23;minu=59;sec=49; //赋初值:11点59分0秒
n_hour=12;n_minu=56;n_sec=0; //闹钟赋初值12点1分0秒
year=2008;mon=5;day=14;week=3;//年月日星期赋初值2008年5月11日星期天;祝天下所有母亲节日快乐
while(1)
{
hs=hour/10; //时分秒HH.MM.SS
hg=hour%10;
mis=minu/10;
mig=minu%10;
ss=sec/10;
sg=sec%10;

ms=mon/10; //月日-星期MM.DD.-W
mg=mon%10;
ds=day/10;
dg=day%10;
w=week;

nhs=n_hour/10; //闹钟定时HH.MM.SS
nhg=n_hour%10;
nms=n_minu/10;
nmg=n_minu%10;
nss=n_sec/10;
nsg=n_sec%10;

key_change(); //s4按键扫描
key_set(); //s2按键扫描
set_time(); //设置时间
set_mdw(); //设置月日星期
set_clock(); //设置闹钟
if(set_1==1) //正常走时显示
{
disp(hs,hg,mis,mig,ss,sg);
}
if(set_1==2) //设置时间,LED1闪亮
{
disp(hs,hg,mis,mig,ss,sg);
if(sec%2==0)
{led2=1;led3=1;led1=~led1;}
// else
// {led1=1;}
}
if(set_1==3) //正常显示月日-星期
{
disp(ms,mg,ds,dg,16,w);
}
if(set_1==4) //设置月日-星期,LED2闪亮
{
disp(ms,mg,ds,dg,16,w);
if(sec%2==0)
{led1=1;led3=1;led2=~led2;}

// else
// {led2=1;}
}

if(set_1==5) //正常显示定时
{
disp(nhs,nhg,nms,nmg,nss,nsg);
}
if(set_1==6) //设置闹钟定时,LED3闪亮
{
disp(nhs,nhg,nms,nmg,nss,nsg);
if(sec%2==0)
{led1=1;led2=1;led3=~led3;}

// else
// {led3=1;}
}

zd_clock(); //整点报时
nz_clock(); //闹钟
}


}

void timer0() interrupt 1 //50ms中断函数

{
TMOD=0x01;
TH0=0x4c; //50ms初值 晶振11.0592
TL0=0x00;
count++;
if(count==20)
{
count=0;
sec++;
jishi(); //调计时函数
}
}

void jishi() //计时函数
{
if(sec==60)
{
sec=0;
minu++;
if(minu==60)
{
minu=0;
hour++;
if(hour==24)
{ hour=0;
day++;
week++;
if(week==8)
{week=0;}
if(year%4==0&&year%100!=0||year%400==0) //闰年
{
if(day==table1[mon]+1)
{
day=0;
mon++;
if(mon==13)
{mon=0;year++;}
}
}
else //非闰年
{
if(day==table2[mon]+1)
{
day=0;
mon++;
if(mon==13)
{mon=0;year++;}
}
}

}
}
}
}

void key_change() //s1按键扫描
{
if(s1==0)
{
delay(200);
if(s1==0)
{
set_1++;
while(!s1);
if(set_1==7)
{set_1=1;}
}
}
}


void key_set() //s2按键扫描
{
if(s2==0)
{
delay(10);
if(s2==0)
{
set_2++;
while(!s2);
if(set_2==4)
{set_2=1;}
}
}
}
void disp(uchar a1,uchar a2,uchar a3,uchar a4,uchar a5,uchar a6) //显示函数
{
QB1=1;
QB2=0;
QB3=0;
QB4=0;
QB5=0;
QB6=0;
P3=table[a1]; //段码送P0口
delay(10); //延时一小会
QB1=0;
QB2=1;
QB3=0;
QB4=0;
QB5=0;
QB6=0;
P3=table[a2]; //第2个数码管显示,带小数点
delay(10);
QB1=0;
QB2=0;
QB3=1;
QB4=0;
QB5=0;
QB6=0;

P3=table[a3]; //第3个数码管显示
delay(10);
QB1=0;
QB2=0;
QB3=0;
QB4=1;
QB5=0;
QB6=0;

P3=table[a4]; //第4个数码管显示,带小数点
delay(10);
QB1=0;
QB2=0;
QB3=0;
QB4=0;
QB5=1;
QB6=0;

//第5个数码管显示
P3=table[a5];
delay(10);
QB1=0;
QB2=0;
QB3=0;
QB4=0;
QB5=0;
QB6=1;

P3=table[a6]; //第6个数码管显示
delay(10);
QB1=0;
QB2=0;
QB3=0;
QB4=0;
QB5=0;
QB6=0;

}

void zd_clock() //整点报时函数
{
if(minu==59&&(sec==53||sec==55||sec==57))
{
fm=0;
delay(5);
fm=1;
delay(5);
}
fm=0;
if(minu==59&&sec==59)
{
fm=0;
delay(5);
fm=1;
delay(5);
fm=0;
}
}

void nz_clock() //闹钟函数
{
if(hour==n_hour&&minu==n_minu&&sec==n_sec)
//if((sec%2==0)&&sec<30)
{
fm=0;
delay(1);
fm=1;
delay(1);
}
}

void set_time() //设置时间函数
{
if(set_1==2)
{
if(set_2==1)
{
hour=incone(hour);
if(hour==24)
{hour=0;}
// if(hour<0)
// {hour=23;}
hour=decone(hour);

}
if(set_2==2)
{
minu=incone(minu);
if(minu==60)
{minu=0;}
// if(minu<0)
// {minu=59;}
minu=decone(minu);

}
}
}

void set_mdw() //设置月日星期函数
{
if(set_1==4)
{
if(set_2==1)
{
mon=incone(mon);
if(mon==13)
{mon=1;}
mon=decone(mon);
// if(mon==0)
// {mon=12;}
}
if(set_2==2)
{
day=incone(day);
if(day==32)
{day=0;}
day=decone(day);
// if(day==0)
// {day=0;}
}
if(set_2==3)
{
week=incone(week);
if(week==8)
{week=0;}
week=decone(week);
// if(week==0)
// {week=7;}
}
}
}

void set_clock() //设置闹钟函数
{
if(set_1==6)
{
if(set_2==1)
{
n_hour=incone(n_hour);
if(n_hour==24)
{n_hour=0;}
n_hour=decone(n_hour);
if(n_hour==0)
{n_hour=0;}
}
if(set_2==2)
{
n_minu=incone(n_minu);
if(n_minu==60)
{n_minu=0;}
n_minu=decone(n_minu);
if(n_minu==0)
{n_minu=0;}
}
}

}

uchar incone(uchar n) //加1函数
{
if(s3==0)
{ delay(200);
if(s3==0)
{
n++;
while(!s3);
}
}
return(n);
}

uchar decone(uchar m) //减1函数
{
if(s4==0)
{
delay(200);
if(s4==0)
{
m--;
while(!s4);
if(m<0)
{m=0;}
}
}
return(m);
}

void delay(uint k) //延时函数
{
uint i,j;
for(i=k;i>0;i--)
for(j=80;j>0;j--);
}

就是7段编码和移位寄存器,移位,进位等运算的过程,这个设计比较简单,你可以从秒的个位到十位进位开始做,进位处理好之后,剩下就都是反复的过程

题目的要求可以理解为,将电压的变化以二进制数字的形式表示出来(即用发光

二极管来表示二进制数)。

硬件需要单片机、发光二极管、ad转化器(如TLC549)

下面提供一个例子。

/********************************************************************

* 文件名  : TLC549.c

* 描述    :  TLC549是一个新型的AD转换器,具有8位的分辨率,具有控制简单,体积小的优点。

***********************************************************************/

#include<reg52.h>

#include<intrins.h>

#define uchar unsigned char

#define uint  unsigned int 

sbit AD_Out = P3^4;    //TLC549输出端

sbit CS = P1^4;     //TLC549片选信号

sbit AD_In = P1^3;             //TLC549输入端

    

/********************************************************************

* 名称 : AD_Change(void)

* 功能 : TLC549驱动程序

* 输入 : 无

* 输出 : temp (电压值)

***********************************************************************/

uchar AD_Change(void)

{

 uchar i,temp = 0;

 AD_In = 0;

 _nop_();

 _nop_();

 CS = 0;

 _nop_();

 _nop_();

 _nop_();

 _nop_();

 if(AD_Out == 1) temp += 1;

 for(i=0; i<8; i++)

 {

  AD_In = 1;

  _nop_();

  _nop_();  

  AD_In = 0;

  _nop_();

  _nop_();

  if(i != 7)

  {

   temp = temp << 1;

   if(AD_Out == 1) temp += 1;

  }

 }

 CS = 1;

 return temp; 

}

/********************************************************************

* 名称 : Main()

* 功能 : 主函数

* 输入 : 无

* 输出 : 无

***********************************************************************/

void Main(void)

{

 while(1)

 {

 

 P0= AD_Change(); 

 }

}

其中,R12是一个电位器,通过调节可以使P0口的八个led亮灭模拟数字量输出。



办法比较多,89c51自己是不带ad的,那么外接ad程序比较麻烦,你这对电压也不测量精确值,所以用不着ad,只要能区分电压值不同就行了。考虑到程序的简单,就用比较器,比如说接五个比较器,阈值分别为1v、2v、3v、4v、5v,把他们的输入端接在一起,输出端接在单片机的五个io口上,再接五个发光二极管在另外五个io口上,发光二极管的另一端分别串个限流电阻接在电源上,硬件完成了。程序就好写多了,只要判断五个比较器输出端电平,然后控制相应的灯亮灭就行了。比较器也不一定五个,三个两个也一样,这样精度就不太高而已。不过程序就几行代码。简单。

是作业吧??你想用什么解决方案呢?ADC有逐次比较型ADC0804并行输出和差分电压V-T串行输出.

用什么口做检测?什么口输出?

还有,这种题目书上都有例子,你依葫芦画瓢就可以自定搞定的

呵呵 刚开始学单片机吧 ,学会控制io口的高低电平是最基本的,一定要到达随意控制的程度,这样你就可以体会到单片机的乐趣了。
提示一下,先想想怎样把发光二极管点亮。

用A/D芯片,将模拟量转换成数字量


c51单片机怎么用两个按键控制两个数码管的加减,加到99就好,求程序
1、首先先在proteus画出仿真图,方便仿真程序。2、接着来编写程序,先来写入头函数。2、根据自己在proteus画的图,定义一下管脚根据你的原理图进行编写。3、然后写一个延时函数,来调节流水灯的时间间隔延时时间自己定义。4、下图就是主函数,包括流水灯的反复循环和j流水灯的方向。5、检查没有错误,...

单片机C51实验求程序!求大神!!!
include <reg51.h> define uchar unsigned char uchar c;void zfzs(void);void delay();void main(void){ zfzs();while(1){ c=0x00;SBUF=c;\/\/输出数据到SBUF,启动串行口输出 P1=SBUF;delay();c=~c;SBUF=c;P1=SBUF;\/\/输出数据到SBUF,启动串行口输出 } while(TI);TI=0;\/\/串行口...

C51单片机中有源蜂鸣器的程序怎么写啊,还有就是,有源蜂鸣器是高电平触发...
由于单片机驱动能力有限,常常连接三极管驱动蜂鸣器。这得看三极管的型号,不同的型号程序稍有不同。主要是设置是“1”还是“0”驱动,这得看你的电路的连接。1)如果连接PNP三极管驱动,设置P3_3=0,则蜂鸣器一直响;如果设置 P3_3=0;\/\/响 delay_500ms();P3_3=1;\/\/不响 delay_500ms();\/\/...

编程,单片机C51编程
可根据用户在菜单中的选择项对测点进行某些设置,或者进行某些特殊的显示,例如对某个测点的实时曲线显示等。程序设计根据需求,首先建立一个结构,并定义一个结构变量kbdtabst ruct 。结构变量就是把多个不同类型的变量结合在一起形成的一个组合型变量,构成一个结构的各个变量称为结构元素。该结构中共有6...

c51单片机数码管静态显示程序
include<reg52.h> define uchar unsigned char uchar code table[11] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};\/\/共阴 void Delay(uint i)\/\/延时时间约为 10ms * x { uchar x;for(x=0;x<=1827;x++);} void Main(void){ uchar i = 0;for(i=0;i<...

单片机c51,数码管显示1.~9.的c语言程序怎么编?
; }}dingshiqi1()interrupt 1{ static unsigned char a,b; a++; if(a>5) { a=0; b++; if(b>9) b=0; P2=shu[b]; } }这是简化的仿真图,实际电路上要有限流电阻。否则要烧IO或者数码管。

单片机C51程序如何分成好几个.c和.h文件
string.c 那么你就可以在你说明了的.C文件中调用它,这样一个模块可以在很多处调用,使得编程复杂度降低。程序编译时把你所说明的文件复制到你调用处程序就可以运行了。.H文件是对单片机一些端口及一些常用的程序的库说明,比如我们在程序中用到端口一即P1,我们能够用它是因为在库中已对它进行了说明...

c51单片机中断程序中的interrupt1,2,3是由什么决定的?
interrupt X是指用的第几个中断。。1~2~3是由中断向量表决定的。也就是由单片机的中断入口地址的顺序决定的。这个是硬件决定的软件不能改变。例如外部中断0就是interrupt 0 定时器0 是interrupt 1 外部中断1是interrupt 2 定时器2是interrupt 3 串口是interrupt 4 ...

c51单片机程序实例
include<reg51.h>#define uchar unsigned charuchar tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00}; \/\/0到9uchar num,cnt,disn;uchar keyval,disk;uchar led[]={1,2,3,4};void dealdat(uchar a){led[0]=0;led[1]=0;led[2]=0;led[3]=0;led[a]=...

麻烦大神用单片机c51,编0-99共阳极计数器程序,谢谢!
include<reg51.h>#define uchar unsigned char;uchar distab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00}; \/\/0到fuchar number,dat,time;void t0isr() interrupt 1{TH0=(65536-5000)\/256;TL0=(65536-5000)%256;number++;if...

钦州市19753056277: 89c51单片机程序设计!!!
匡索济克: 办法比较多,89c51自己是不带ad的,那么外接ad程序比较麻烦,你这对电压也不测量精确值,所以用不着ad,只要能区分电压值不同就行了.考虑到程序的简单,就用比较器,比如说接五个比较器,阈值分别为1v、2v、3v、4v、5v,把他们的输入端接在一起,输出端接在单片机的五个io口上,再接五个发光二极管在另外五个io口上,发光二极管的另一端分别串个限流电阻接在电源上,硬件完成了.程序就好写多了,只要判断五个比较器输出端电平,然后控制相应的灯亮灭就行了.比较器也不一定五个,三个两个也一样,这样精度就不太高而已.不过程序就几行代码.简单.

钦州市19753056277: 单片机89c51 编写简单程序 -
匡索济克: 如果确定是有符号的数那还不好搞? 把每个数读到ACC里. JZ的话,不要管它 JNZ的话 判断ACC.7,JB 就把它放到60H以后 JNB就把它放到50H开始的单元 也就是 MAIN: MOV R0,#30H MOV R1,#50H MOV R2,#60H G0: MOV A,@R0 JZ G1 JB ...

钦州市19753056277: 请单片机高手进来帮一下忙,谢谢了,急需,用89C51单片机语言编写跑马灯程序 -
匡索济克: 以12MHz晶振为例 ORG 000H AJMP START START:SETB C ;跑马灯,一直循环255次...MOV R0,#0FFH MOV A,#0 JX1:RLC A MOV P1,A LCALL DELAY500MS DJNE R0,JX1 SETB C MOV R0,#8 MOV A,#0 JX:RLC A ;P1.0>>>P1.7依次亮1...

钦州市19753056277: 89c51单片机编程 -
匡索济克: 电阻值是模拟量,单片机是不能直接处理的,需经过AD转换.比如将通光时电阻值转换为1,遮光转换为0.这样就得到了触发信号,再接着写接到触发信号后单片机的动作即可

钦州市19753056277: 求给单片机89C51编个程序 -
匡索济克: 这个没法写,因为你用什么AD采样芯片,你用什么显示,LCD,LED,是否需要数字滤波什么的...都没说,AD采样主要是看你用什么芯片,不同芯片程序完全不同,不过你起码能抽象一个函数叫 get_adc()来得到采样值,然后如果需要对采样值滤波,就需要个滤波算法来对采样进行处理这有是一段程序,也可以没有, 然后计算出一个稳定的采样值,是AD值,需要转换成安培单位(根据你的做实验的数据统计如果线性不好还要做线性化处理)... 最后就是周期的更新LCD或LED的显示,不同设备程序不同... 一般应该会用LCD,就像计算器欧姆表上的那种显示屏,很简单,查看一下LCD的使用说明书,关键看你用哪一款...

钦州市19753056277: 89C51单片机“跑马灯”汇编程序怎么设计?参考一下. -
匡索济克: START: SETB C MOV A,#0FEH HERE: MOV P0,A ACALL DELAY ACALL DELAY RLC A JC HERE CLR A MOV P0,A ACALL DELAY ACALL DELAY THERE: SETB C RRC A MOV P0,A ACALL DELAY ACALL DELAY JNB P0.0,THERE SJMP START DELAY: MOV R3,#200 D2: MOV R2,#250 D1: DJNZ R2, D1; DJNZ R3,D2; RET END

钦州市19753056277: 怎么用c语言写单片机89C51的程序,要写的程序是,0~99秒的秒表,到99s停止,并且有滴的一声 -
匡索济克: 用一个定时器,加一个蜂鸣器就可以做啊.对于单片机的学习 可以采用吴:鉴 鹰开发板学习.

钦州市19753056277: 新手学单片机.要在89C51上实现点亮一个LED?要怎么写C程序?用P1.1口接一个LED.一定要用C写. -
匡索济克: #include<reg51.h> main() {P1^1=0;//点亮P1.1的LED灯while(1);//等待 }

钦州市19753056277: 求单片机89C51数字钟的设计,要用C语言程序,四位数码管的.谢谢~~ -
匡索济克: P1口片选 P3口位选 P3.0对应最右边那个 P3.3对应最左边那个 数码管共阳四位 不显示小数点#include <reg52.h> typedef unsigned char uint8; typedef unsigned int uint16; uint8 number[]={0xFC,0x60,0xDA,0xF2,0x66, 0xB6,0xBE,0xE0,0xFE,0xF6};...

钦州市19753056277: 用89C51单片机设计一个流水灯. -
匡索济克: #include<reg52.h>//头文件 sbit duan=P1^6;//定义数码管的段选使能控制端 sbit wei=P1^7;//定义数码管的位选使能控制端 unsigned char led_code[]={0xff,0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//定义数组 void Delay_ms(unsigned int x);//子函...

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网