定时计数器实验电子音响 单片机报告.docx

上传人:b****6 文档编号:7694239 上传时间:2023-05-11 格式:DOCX 页数:20 大小:21.51KB
下载 相关 举报
定时计数器实验电子音响 单片机报告.docx_第1页
第1页 / 共20页
定时计数器实验电子音响 单片机报告.docx_第2页
第2页 / 共20页
定时计数器实验电子音响 单片机报告.docx_第3页
第3页 / 共20页
定时计数器实验电子音响 单片机报告.docx_第4页
第4页 / 共20页
定时计数器实验电子音响 单片机报告.docx_第5页
第5页 / 共20页
定时计数器实验电子音响 单片机报告.docx_第6页
第6页 / 共20页
定时计数器实验电子音响 单片机报告.docx_第7页
第7页 / 共20页
定时计数器实验电子音响 单片机报告.docx_第8页
第8页 / 共20页
定时计数器实验电子音响 单片机报告.docx_第9页
第9页 / 共20页
定时计数器实验电子音响 单片机报告.docx_第10页
第10页 / 共20页
定时计数器实验电子音响 单片机报告.docx_第11页
第11页 / 共20页
定时计数器实验电子音响 单片机报告.docx_第12页
第12页 / 共20页
定时计数器实验电子音响 单片机报告.docx_第13页
第13页 / 共20页
定时计数器实验电子音响 单片机报告.docx_第14页
第14页 / 共20页
定时计数器实验电子音响 单片机报告.docx_第15页
第15页 / 共20页
定时计数器实验电子音响 单片机报告.docx_第16页
第16页 / 共20页
定时计数器实验电子音响 单片机报告.docx_第17页
第17页 / 共20页
定时计数器实验电子音响 单片机报告.docx_第18页
第18页 / 共20页
定时计数器实验电子音响 单片机报告.docx_第19页
第19页 / 共20页
定时计数器实验电子音响 单片机报告.docx_第20页
第20页 / 共20页
亲,该文档总共20页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

定时计数器实验电子音响 单片机报告.docx

《定时计数器实验电子音响 单片机报告.docx》由会员分享,可在线阅读,更多相关《定时计数器实验电子音响 单片机报告.docx(20页珍藏版)》请在冰点文库上搜索。

定时计数器实验电子音响 单片机报告.docx

定时计数器实验电子音响单片机报告

实验四定时器实验

一、实验内容

1、由51内部定时器0,按方式1工作、即作为十六位定时器使用每0.l秒钟T1溢出中断一次。

P1口的P1.0接1个发光二极管。

要求编写程序模拟一时序控制装置。

开机以中断方式循环点亮,闪烁维持1s。

2、数码时钟程序,调用定时器中断来处理。

3、编制程序,利用P3口输出不同频率的脉冲通过扬声器发出不同频率音调。

了解计算机发声原理,学习使计算机发出不同音调声音的编程方法。

二、实验目的

1、学习89C51内部计数器的使用和编程方法。

2、进一步掌握中断处理程序的编程方法。

三、实验原理

1、定时常数的确定

定时器/计数器的输入脉冲周期与机器周期一样,为振荡器频率的1/l2。

本实验中时钟频率为12MHZ,现要采用中断方法来实现1秒延时,要在定时器1中设置一个时间常数,使其每隔10MS产生一次中断,CPU响应中断后将R0中计数值减一,令(R0)=100,即可实现1s延时。

时间常数可按下法确定:

机器周期=12÷晶振频率=12÷12×106=1×10-6S

N=t/Tcy=10×10-3/1×10-6=10000

需设初值为X,则(216-X)×1×10-6=0.1

X=65536-10000=55536=D8F0H

化为十六进制:

X=3800H,故初始值为了TH0=D8H,TL0=F0H

2、初始化程序

包括定时器初始化和中断系统初始化,主要是对IP、IE、TCON、TMOD的相应位进行正确的设置,并将时间常数送入定时器中、由于只有定时器中断,IP便不必设置。

如:

MOVTMOD,#01H;置T0工作于方式1

MOVTH0,#0D8H;装入计数初值

MOVTL0,#0F0H

SETBET0;T0开中断

SETBEA;CPU开中断

SETBTR0;启动T0

 

3、设计中断服务程序和主程序

中断服务程序要将时间常数重新送入定时器中,为下一次中断做准备。

主程序则用来控制发光二极管按要求闪烁。

4、音阶由不同频率的方波产生,音的节拍由延时子程来实现。

延时子程序实现基本延时时间,节拍值只能是它的整数倍。

音阶与频率的关系如下表所示。

方波的频率由定时器控制。

定时器计数溢出后,产生中断,将P1.7口取反即得周期方波。

每个音阶相应的定时器初值可按下法计算:

晶振为6.144MHZ时,音阶“1”相应的定时器初值为x,则

1÷262×2=(216-X)×12÷6.144×1016

可得X=64559D=FC2FH,其它音节可同样求得,见下表:

(单位:

HZ,X为16进制)

音调

4

5

6

7

1

2

3

4

频率

175*2

196*2

220*2

247*2

262*2

294*2

330*2

349*2

X

FA

FA

FB

FC

FC

FC

FC

FD

49

E6

7E

0C

2F

8F

F8

23

5

6

7

1

2

3

392*2

440*/2

494*2

523*2

587*2

659*2

FD

FD

FD

FE

FE

FE

73

BA

FA

18

4C

94

 

四、实验电路及连线

P1.0接发光二极管L1。

(其他电路参考学习板说明书蜂鸣器与时钟部分)

 

五、参考程序

程序一、

ORG0000h

AJMPmain

ORG000bh

AJMPint_timer

ORG0030h

main:

MOVtmod,#01h;设置定时器工作方式01

MOVth0,#high(65536-10000);

MOVtl0,#low(65536-10000);设10MS初始值。

MOVie,#82h;设置中断允许寄存器

MOV30h,#10;

MOV31h,#10;30H和31H是两个软件计数器。

SETBtr0;启动定时

AJMP$;等待中断

int_timer:

;定时器0中断服务程序。

MOVth0,#high(65536-10000);

MOVtl0,#low(65536-10000);重设10MS定时。

DJNZ30h,l1;

MOV30h,#10;

DJNZ31h,l1;

MOV31h,#10;软件计数

CPLp1.0;10*10*10MS=1S时间到,P1.0取反

l1:

RETI;中断返回

END

程序二、

/*

数码管精确时钟

*/

#include//包含头文件

sbitbuz=P1^4;

sbitled=P2^0;

#defineshumaP0

sbitLED_0=P2^0;

sbitLED_1=P2^1;

sbitLED_2=P2^2;

sbitLED_3=P2^3;

unsignedcharm,n;

unsignedintd;

unsignedintcodeton[7];

voiddisplay(unsignedchard1,unsignedchard2,unsignedchard3,unsignedchard4);

/*=====0-9=====A-G=====*/

unsignedchara[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,

0x80,0x90,0x88,0x83,0xc6,0x86,0x8e,0x82};

//共阳极数码管的段码0123456789ABCDEF

//定时初值计算方法:

以5ms为例,5ms=5000us,0xffff-5000/1.085即为TH和TL的值

voidint1()interrupt3//T1中断,时间是5ms

{

unsignedchard1,d2,d3,d4;

TR1=0;//关中断

TH1=0xed;//装定时器初值实现5ms定时

TL1=0xff;

ET1=1;//开中断

TR1=1;

d4=(d%60)%10;//把时间拆分为分和秒

d3=(d%60)/10;

d2=(d/60)%10;

d1=(d/60)/10;

display(d1,d2,d3,d4);//显示分秒

n++;

if(n>=200)//5ms的中断,循环200次,d加一次,所以d是1秒跳1次

{

n=0;

d++;

}

}

voidmain(void)

{

unsignedinti;

d=0;

m=1;

TMOD=0x10;//设置为T1定时器

TH1=0xed;//装定时器初值

TL1=0xff;

TR1=1;//开中断

ET1=1;

EA=1;

while

(1)

{

}

}

//中断专用的显示函数

voiddisplay(unsignedchard1,unsignedchard2,unsignedchard3,unsignedchard4)

{

if(m==1)

{

LED_0=0;//使能该数码管控制位

LED_1=LED_2=LED_3=1;//其他控制位无效

shuma=a[d1];//按照数据点亮该数码管

}

if(m==2)

{

LED_1=0;

LED_0=LED_2=LED_3=1;

shuma=a[d2];

}

if(m==3)

{

LED_2=0;

LED_1=LED_0=LED_3=1;

shuma=a[d3];

}

if(m==4)

{

LED_3=0;

LED_1=LED_2=LED_0=1;

shuma=a[d4];

}

m++;//数码管位循环扫描

if(m>=5)

m=1;

}

程序三、秒计时器

#include//包含头文件

#defineshumaP0//对显示用数码管进行数据口和控制口的定义

sbitLED_0=P2^0;

sbitLED_1=P2^1;

sbitLED_2=P2^2;

sbitLED_3=P2^3;

unsignedcharm,n;//临时变量

unsignedintd;//秒计时器

voiddisplay(unsignedchard1,unsignedchard2,unsignedchard3,unsignedchard4);

//数码管显示函数声明,利用中断方式

/*=====0-9=====A-G=====*/

unsignedchara[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,

0x80,0x90,0x88,0x83,0xc6,0x86,0x8e,0x82};

//共阳极数码管的段码0123456789ABCDEF

//定时初值计算方法:

以5ms为例,5ms=5000us,0xffff-5000/1.085即为TH和TL的值

voidint1()interrupt3//T1中断,时间是5ms

{

unsignedchard1,d2,d3,d4;

TR1=0;//关中断

TH1=0xed;//装定时器初值实现5ms定时

TL1=0xff;

ET1=1;//开中断

TR1=1;

d4=(d%60)%10;//分离秒计数值到千、百、十、各位方便数码管显示

d3=(d%60)/10;

d2=(d/60)%10;

d1=(d/60)/10;

display(d1,d2,d3,d4);//数码管以中断方式显示

n++;

if(n>=200)//5毫秒程序,每200周期更新一次

{

n=0;

d++;//每秒计数值加1

}

}

voidmain(void)

{

d=0;

m=1;

TMOD=0x10;//设置为T1定时器

TH1=0xed;//装定时器初值

TL1=0xff;

TR1=1;//开中断

ET1=1;

EA=1;

while

(1)

{

}

}

 

程序四、

/*时钟程序,本程序采用外元件DS1302时钟IC,使用此IC不增加系统资源,要时钟时直接去读取就可以了本IC跟ADC0831一样以串口方式传送数据,不同的是协议,只要你读懂它的串口协议,就可以用P口来模拟协议进行

,这样更能使你对传送数据协议的了解,在看本程序之前,先看看芯片的串口协议*/

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

//在学习本实验的时候,务必把J-LED的跳线帽,拔到OFF方向,关闭发光二极管

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

#include

#include

sbitSCL2=P1^3;//SCL2定义为P1口的第3位脚,连接DS1302SCL和ADC0831SCL脚

sbitSDA2=P1^4;//SDA2定义为P1口的第4位脚,连接DS1302SCL和ADC0831SDA脚

//sbitCS2=P1^6;//CS2定义为P2口的第6位脚,连接ADC0831CS脚

sbitRST=P2^5;//DS1302片选脚

sbitwei1=P2^0;

sbitwei2=P2^1;

sbitwei3=P2^2;

sbitwei4=P2^3;

unsignedcharcodetable[]={0xC0,0xF9,0xA4,0xB0,

0x99,0x92,0x82,0xF8,

0x80,0x90,0x88,0x83,

0xC6,0xA1,0x86,0x8E};//共阳数码管码表

//变量定义---------------------------------------------------------------------------------------

unsignedcharl_tmpdate[8]={0x00,0x00,0x0c,0x0d,0x04,0x09,0x01,0};//预设数据,秒分时,日月年,星期

unsignedcharl_tmpdisplay[4]={0,0,0,0};

codeunsignedcharwrite_rtc_address[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};

codeunsignedcharread_rtc_address[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};

//函数声明-------------------------------------------------------------------------------------

voiddelay();//延时子函数,5个空指令

voidDelay_xuS(unsignedintx);

voidled_display(unsignedchar*temp);

voidWrite_Ds1302_byte(unsignedchartemp);

voidWrite_Ds1302(unsignedcharaddress,unsignedchardat);

unsignedcharRead_Ds1302(unsignedcharaddress);

voidRead_RTC(void);//readRTC

voidSet_RTC(void);//setRTC

 

voidmain(void)//入口函数

{

 

Set_RTC();//设定时间

Delay_xuS(5);

while

(1){

Read_RTC();

switch(l_tmpdate[0]/5)//设计每个5秒交替显示年月日时分秒

{

case0:

case2:

case4:

case6:

case8:

case10:

l_tmpdisplay[0]=l_tmpdate[1]/16;//数据的转换,因我们采用数码管0~9的显示,将数据分开

l_tmpdisplay[1]=l_tmpdate[1]&0x0f;

l_tmpdisplay[2]=l_tmpdate[0]/16;

l_tmpdisplay[3]=l_tmpdate[0]&0x0f;

break;

case1:

case3:

case5:

case7:

case9:

case11:

l_tmpdisplay[0]=l_tmpdate[4]/16;

l_tmpdisplay[1]=l_tmpdate[4]&0x0f;

l_tmpdisplay[2]=l_tmpdate[3]/16;

l_tmpdisplay[3]=l_tmpdate[3]&0x0f;

break;

default:

break;

}

led_display(l_tmpdisplay);

}

}

/*-------------------------------------------------

功能:

数码管显示子程序

-------------------------------------------------*/

voidled_display(unsignedchar*temp)

{

wei1=0;//点亮第一个数码管

P0=table[temp[0]];

Delay_xuS(5);

wei1=1;

wei2=0;//点亮第二个数码管

P0=table[temp[1]];

Delay_xuS(5);

wei2=1;

wei3=0;//点亮第三个数码管

P0=table[temp[2]];

Delay_xuS(5);

wei3=1;

wei4=0;//点亮第四个数码管

P0=table[temp[3]];

Delay_xuS(5);

wei4=1;

}

voiddelay(void)//空5个指令

{

unsignedchari=10;

while(i)

i--;

}

/*-------------------------------------------------

功能100uS延时子程序

-------------------------------------------------*/

voidDelay_xuS(unsignedintx)

{

unsignedinti,j;

for(i=0;i

{

for(j=0;j<50;j++);

}

}

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

voidWrite_Ds1302_Byte(unsignedchartemp)

{

unsignedchari;

for(i=0;i<8;i++)//循环8次写入数据

{

SCL2=0;

SDA2=temp&0x01;//每次传输低字节

temp>>=1;//右移一位

SCL2=1;

}

}

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

voidWrite_Ds1302(unsignedcharaddress,unsignedchardat)

{

RST=0;

_nop_();

SCL2=0;

_nop_();

RST=1;

_nop_();//启动

Write_Ds1302_Byte(address);//发送地址

Write_Ds1302_Byte(dat);//发送数据

RST=0;//恢复

}

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

unsignedcharRead_Ds1302(unsignedcharaddress)

{

unsignedchari,temp=0x00;

RST=0;

_nop_();

SCL2=0;

_nop_();

RST=1;

_nop_();

Write_Ds1302_Byte(address);

for(i=0;i<8;i++)//循环8次读取数据

{

SCL2=1;

_nop_();

if(SDA2)

temp|=0x80;//每次传输低字节

SCL2=0;

temp>>=1;//右移一位

}

RST=0;

_nop_();

SCL2=1;

SDA2=0;

return(temp);//返回

}

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

voidRead_RTC(void)//读取日历

{

unsignedchari,*p;

p=read_rtc_address;//地址传递

for(i=0;i<7;i++)//分7次读取年月日时分秒星期

{

l_tmpdate[i]=Read_Ds1302(*p);

p++;

}

}

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

voidSet_RTC(void)//设定日历

{

unsignedchari,*p,tmp;

for(i=0;i<7;i++){

tmp=l_tmpdate[i]/10;

l_tmpdate[i]=l_tmpdate[i]%10;

l_tmpdate[i]=l_tmpdate[i]+tmp*16;

}

Write_Ds1302(0x8E,0X00);

p=write_rtc_address;//传地址

for(i=0;i<7;i++)//依次写入秒时分,日月年,星期

{

Write_Ds1302(*p,l_tmpdate[i]);

p++;

}

Write_Ds1302(0x8E,0x80);

}

程序五、音乐程序八月桂花香

ORG0000H

LJMPSTART

ORG000BH

INC20H;中断服务,中断计数器加1

MOVTH0,#0DBH

MOVTL0,#0FEH;12M晶振,形成10毫秒中断

RETI

START:

CPLP3.4

MOVSP,#50H

MOVTH0,#0DBH

MOVTL0,#0FEH

MOVTMOD,#01H

MOVIE,#82H

MUSIC0:

NOP

MOVDPTR,#DAT;表头地址送DPTR

MOV20H,#00H;中断计数器清0

MOVB,#00H;表序号清0

MUSIC

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 农林牧渔 > 林学

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2