《单片机原理与实验教程》课件第8章_第1页
《单片机原理与实验教程》课件第8章_第2页
《单片机原理与实验教程》课件第8章_第3页
《单片机原理与实验教程》课件第8章_第4页
《单片机原理与实验教程》课件第8章_第5页
已阅读5页,还剩123页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第8章综合设计性实验

实验一DS18B20温度采集实验

实验二D/A转换实验实验三A/D转换实验实验四IIC总线实验实验五SPI总线实验实验六实时时钟DS12C887实验实验七8255A并口扩展实验实验一DS18B20温度采集实验

一、实验目的

(1)掌握单片机与1wire(一线器)的通信原理与编程方法。(2)掌握LED动态显示的方法。(3)了解温度传感器的原理。二、实验原理关于DS18B20的工作原理,请读者参考Dallas公司的资料。AT89S52控制DS18B20完成温度转换必须经过三个步骤:初始化、ROM操作指令、存储器操作指令。必须先启动DS18B20开始转换,再读出温度转换值。本实验系统挂接一个DS18B20芯片,可使用默认的12位转换精度,外接供电电源,单片机与DS18B20的接口用的是单片机的P2.4口。

三、实验内容

(1)参考给出的流程图(图8-1),在Keil编译环境下编制程序,要求采集温度并判断温度所处范围,如果超出报警温度范围则报警;报警通过实验箱上的蜂鸣器实现,报警温度可以通过键盘设置;最后,生成*.HEX文件。(2)通过ISP将生成的*.HEX文件下载到单片机中,运行程序。(3)观测LCD上显示的温度数据,通过键盘操作控制报警温度。图8-1

DS18B20温度采集系统流程图四、参考程序

//DS18B20温度传感器程序

#include<reg52.h>

#defineAlarm10

sbitBeep=P3∧4;

sbitDQ=P2∧4;//数据传输线接单片机的相应引脚unsignedchartempL=0,tempH=0;//设全局变量

unsignedcharflag=0;

unsignedinttemperature,negtemper;//温度值保存在

temperature里

unsignedcharidataaddrdat[2]={0x0,0x0};unsignedchartab[]={0xc0,0xf9,0xa4,0xb0,

/*01234*/0x99,0x92,0x82,0xf8,0x80,0x90};

/*56789*/unsignedchartab1[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};unsignedchardispbuf[3]={0,0,0};unsignedcharwarning=20;biton=0,off=1;//*************************

//延时子程序//**voiddelay(unsignedinti){while(i--);}voidbeep(biti){Beep=i;}//*****************************//初始化程序Init_DS18B20(void){

unsignedcharx=0;DQ=1; //DQ先置高

delay(8); //稍延时

DQ=0; //发送复位脉冲

delay(85); //延时(>480μs)

DQ=1; //拉高数据线

delay(14); //等待(15~60μs)

x=DQ; //用x的值来判断初始化有没有成功,DS18B20存在的//话x=0,否则x=1

delay(20);}//***********************//读一个字节ReadOneChar(void) //主机数据线先从高电平拉至低电平,保持1ms以上,再[JP]//使数据线升为高电平,从而产生读信号

{unsignedchari=0; //每个读周期最短的持续时间为60μs,各个读周期

//之间必须有1ms以上的高电平恢复期

unsignedchardat=0;

for(i=8;i>0;i--) //一个字节有8位

{DQ=1;delay(1);DQ=0;dat>>=1;DQ=1;dat|=0x80;delay(4);}return(dat);}//***********************

//写一个字节WriteOneChar(unsignedchardat){unsignedchari=0;//数据线从高电平拉至低电平,产生写起始信号

//15ms之内将所需写的位送到数据线上

for(i=8;i>0;i--)//在15~60ms之间对数据线进行采样,如果是高电平//就写1,低电平则写0{DQ=0; //在开始另一个写周期前必须有1ms以上的高电平恢复期

DQ=dat&0x01;

delay(5);

DQ=1;

dat>>=1;}delay(4);}//**************************ReadTemperature(void){Init_DS18B20(); //初始化

WriteOneChar(0xcc);//跳过读序列号的操作

WriteOneChar(0x44); //启动温度转换

delay(125); //转换需要一点时间,延时

Init_DS18B20(); //初始化

WriteOneChar(0xcc); //跳过读序列号的操作

WriteOneChar(0xbe); //读温度寄存器(头两个值分别为温度的低位和高位)tempL=ReadOneChar(); //读出温度的低位LSBtempH=ReadOneChar(); //读出温度的高位MSBtemperature=(tempH*256)+tempL;//温度转换,对高、低位做相应的运算,转化为//实际温度return(temperature);}//****************************voidDispbuf(unsignedinttemper){

dispbuf[2]=(temper>>4)/10; //取十位

dispbuf[1]=(temper>>4)%10; //取个位

if(temper&0x8) //小数位

dispbuf[0]=0x55;

elsedispbuf[0]=0;

}unsignedchargetkey() //键盘扫描程序{

P2=0xff;

P2=0xfe;

if((P2&0xff)![KG-*3]=0xfe)

{

delay(5000);

if((P2&0xff)![KG-*3]=0xfe)

returnP2;

elseP2=0xfd;

}elseP2=0xfd;

if((P2&0xff)![KG-*3]=0xfd)

{

delay(5000);

if((P2&0xff)![KG-*3]=0xfd)

returnP2;

elseP2=0xfb;

}

elseP2=0xfb;

if((P2&0xff)![KG-*3]=0xfb){

delay(5000);

if((P2&0xff)![KG-*3]=0xfb)

returnP2;

elseP2=0xf7;

}

elseP2=0xf7;

if((P2&0xff)![KG-*3]=0xf7)

{

delay(5000);

if((P2&0xff)![KG-*3]=0xf7)

returnP2;

elsereturnP2=0xfe;

}

} Inter0_process()interrupt2//外部中断1

{

unsignedcharkey;

inti;

unsignedchardis=0x01;

unsignedintj;

for(j=5000;j>0;j--) {

key=getkey(); //取键值

if(key==0xee) //如1键按下,则温度值递增

{

warning++;

delay(8000);

}

if(key==0xed)

{ //如5键按下,则温度值递减

warning--;

delay(8000);

}if(key==0x77) //按下16键则退出中断

j=1;

for(i=0;i<2;i++) //设置两位报警值,并在LED上显示

{

P1=dis;

dis<<=1;

if(i==0)

P0=tab[warning%10];

else

P0=tab[warning/10];

delay(200);

}dis=0x01;

}}//****************************

//主程序

main(){

unsignedchari,npos=0x01;P0=0xff;

P2=0xff;

P1=0xff;

EX1=1;//开中断1

IT1=1;//下降沿触发

ET1=1;

EA=1;//开总中断

while(1){

if((temperature&0xf000)==0xf000)

//判断是否是负温度

{ReadTemperature();

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

//4位显示

{

negtemper=(~temperature)+1;//取原码

Dispbuf(negtemper);//取位值

P1=npos;

npos<<=1;//循环使能if(i==1)

//第二位显示有点

{

P0=tab1[dispbuf[i]];//查表显示

delay(700);

}

elseif(i==3)

//显示负号

P0=0xbf;

else {

P0=tab[dispbuf[i]];

delay(700);

}

}

npos=0x01;

}

else

//如不是负温度

{

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

//为负则显示3位{

ReadTemperature(); //读温度值

Dispbuf(temperature);

if(((temperature>>4)&0xff)>=warning) //温度值大于报警温度值则报警

beep(on); //蜂鸣器响else

beep(off); //不响

P1=npos;

npos<<=1; P0=tab1[dispbuf[i]];

else

P0=tab[dispbuf[i]];

delay(100);

}

npos=0x01;

}

}五、实验仪器和设备

Keil软件、AT89S52实验平台、AtmelISP在线编程软件、DS18B20温度传感器实验模块。六、思考与分析

(1)说明1wire的工作原理。(2)说明DS18B20的控制原理。

实验二D/A转换实验一、实验目的

(1)理解D/A转换芯片DAC0832与单片机的接口方法及编程方法。

(2)了解D/A转换的基本原理。

(3)了解单片机系统中扩展D/A转换的基本方法。二、实验原理

DAC0832内部具有输入寄存器和DAC寄存器两级数据寄存器,它不需要外加其他电路便可以与单片机的数据总线相连。DAC0832的引脚说明如下:

·D0~D7:8位数据输入。

·Iout1和Iout2:DAC电流输出1和DAC电流输出2,Iout1和Iout2之和为一常量。

·RFB:反馈信号输入端。DAC0832的输出是电流型的,为了取得电压输出需在电压输出端接运算放大器,RFB即为运算放大器的反馈电阻端。反馈电阻在片内。

·ILE:允许输入锁存信号。

·和:锁存输入数据的写信号和锁存输入寄存器输出数据的写信号。:传送控制信号。:片选信号。

DAC0832的输出是电流型的,但实际应用中往往需要电压输出信号,所以电路中采用运算放大器来使电流转换为电压。本实验系统采用的参考电压为5V,所以当数字量输入在00H~FFH范围时电压输出量为0~+5V,这种方式称单极型输出。若电压输出为±5V,则称为双极型输出。实际应用中需要单极性输出,也需要双极型输出,所以电路应用两片运放LM741来实现两种极性的输出。此实验系统的原理图如图8-2所示。DAC0832与单片机接口:DAC0832的D0~D7接单片机P0口;DAC0832的片选信号端接单片机的P2.7,为了避免模块之间的冲突,P2.7通过跳线J505与DAC0832相连。DAC0832的WR信号接单片机的写信号WR,U506和U507是单运放LM741,完成电流到电压和正负电压的转换。单片机对DAC0832的控制过程:使能、,向寄存器中写入需转换数据。图8-2

DAC0832应用原理图

三、实验内容

(1)将扩展板的电源J501与主板的电源接口J2或J14连接起来;将扩展板的信号接口J500与主板的信号接口J15或J13连接起来;将主板上的拨插开关5、6、7、8拨到ON。

(2)在Keil编程环境下编写程序,完成实验功能。本实验参考程序完成的实验功能是在主板数码管上显示“2.7”V电压,同时使DAC0832的输出为2.7V电压。编程时,控制DAC0832的控制码为:×255,取其整数部分为138,十六进制为0X8AH。在数码管上显示“2.7”字样。

(3)编译生成.HEX文件,将.HEX文件下载到实验系统中。观察数码管上显示的数据,并用万用表测量J502(OUTPUT)的电压值。四、参考程序

//2.7V直流电压输出实例

#include<reg51.h>

#include<absacc.h>

#defineDAC0832XBYTE[0X7FFF]//DAC0832使能P2.7

#defineVref5

//参考电压Vref=5V

unsignedcharLED_seg[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};

//段码

unsignedcharLED_seg1[10]={0X40,0X79,0X24,0X30,0X19,0X12,0X02,0X78,0X00,0X10};

//段码

unsignedcharLED_bit[4]={0x01,0x02,0x04,0x08};

//位码voiddelay(unsignedlongn) //延时函数

{

for(;n>0;n--);

}

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

voidconvert(unsignedintn) //分解位函数

{

unsignedchari=0;

n=n/10;

while(i<4)

{

LED_buf[i]=(unsignedchar)(n%10);

n=n/10;i++;

}

}

voiddisplay(void) //显示函数

{

unsignedchari;

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

{

if(i==2)P0=LED_seg1[LED_buf[i]];

elseP0=LED_seg[LED_buf[i]];

P1=LED_bit[i];

delay(100);

}

}voidchange(unsignedinta) //输出函数

{

unsignedchari;

i=(unsignedchar)(a/100*255/Vref/10);

DAC0832=i;

}

voidmain(void){

unsignedinta=2.7*1000; //输出2.7V电压

while(1)

{

convert(a);

display(); //显示

change(a); //输出

delay(100);

}

}五、实验仪器和设备

Keil软件、AT89S52实验平台、AtmelISP在线编程软件、示波器、电压表等。六、思考与分析

修改程序为三角波和锯齿波输出,不需要显示。实验三A/D转换实验

一、实验目的(1)掌握ADC0809与单片机的接口方法及其编程方法。(2)了解A/D变换芯片ADC0809的工作原理。(3)通过实验了解单片机如何进行数据采集。二、实验原理

A/D转换器大致有三类:一类是双积分A/D转换器,特点是精度高,抗干扰性好,价格便宜,但转换速度慢;一类是逐次逼近A/D转换器,特点是精度、速度、价格均适中;另一类是并行A/D转换器,特点是速度快,但价格昂贵。本实验用的ADC0809属第二类,是8位A/D转换器,每采集一次数据一般需100μs,A/D转换结束后会自动产生EOC信号。

ADC0809的引脚含义如下:

·IN0~IN7:8路模拟通道输入,由ADDA、ADDB、ADDC三条线选择。

·ADDA、ADDB、ADDC:模拟通道选择线,比如000时选择0通道,111时选择7通道。

·D7~D0:数据线,三态输出,由OE(输出允许信号)控制输出与否。

·OE:输出允许,该引线为高电平时,打开三态缓冲器,将转换结果放到D0~D7上。

·ALE:地址允许锁存,其上升沿将ADDA、ADDB、ADDC三条引线的信号锁存,经译码选择对应的模拟通道。ADDA、ADDB、ADDC可接单片机的地址线,也可接数据线。ADDA接低位线时,ADDC接高位线。

·START:转换启动信号,在模拟通道选通之后,由START上的正脉冲启动A/D转换过程。转换时间至少100μs。

·EOC(endofconversion):转换结束信号,在START信号之后,A/D开始转换。EOC输出低电平时,表示转换在进行中,当转换结束时,数据已锁存在输出锁存器之后,EOC变为高电平。EOC可视作被查询的状态信号,亦可用来申请中断。

·REF+、REF-:基准电压输入信号。

·CLOCK:时钟输入端,时钟频率上限为1280kHz。

ADC0809在实验平台中的电路如图8-3所示。ADC0809输入通道的控制是由单片机的P2.0、P2.1和P2.2引脚完成的,跳线J504连通单片机I/O口与U501的锁存使能。EOC与单片机的中断0(INT0)相连,当数据转换完成时,EOC向单片机发送中断请求,单片机响应中断,读取转换数据(也可采用查询方式)。ADC0809的D0~D7与单片机的P0口相连。单片机的ALE信号经过74LS74二分频后,作为ADC0809的时钟信号。U504是与非门CD4001,用于和单片机的P2.3产生A/D的片选和使能信号。P2.3为低电平,且当WR信号来(为低电平)时,送到A/D转换器的ALE和START引脚为高电平,启动A/D转换。同样,当RD信号来时使能OE信号,A/D转换器向总线上发送数据。实验时,对ADC0809的控制过程是:通过P2.0,P2.1和P2.2选择模拟量输入通道;通过P2.3和WR信号启动A/D转换;等待转换结束标志EOC;输出数据使能OE;读取转换数据。图8-3

ADC0809在实验平台中的电路三、实验内容

(1)将扩展板的电源J501与主板的电源接口J2或J14连接起来;将扩展板的信号接口J500与主板的信号接口J15或J13连接起来;将主板上的拨插开关5、6、7、8拨到ON。

(2)在Keil编程环境下编写程序,完成实验功能。本实验参考程序完成的实验功能是调节可调电阻R500,改变ADC0809的0通道模拟输入电压,能够在主板数码管上显示转换电压值。

(3)在Keil环境下编程,编译生成.HEX文件,将.HEX文件下载到实验系统中。调节电位器R500观察数码管上显示的数据;用万用表测量J502的IN0的电压值,比较数码管上的显示值和万用表的测量值,两个值应相差不大。相差太大则表示A/D变换不对。A/D转换流程图见图8-4。图8-4

A/D转换流程图四、参考程序

C51程序:

#include<reg51.h>

#include<absacc.h>

//start由P2.3控制,用高位地址作为通道选择和A/D片选信号

#defineIN0XBYTE[0xF0FF]

sbitAD_BUSY=P3∧2; //转换结束引脚——EOC

unsignedcharLED_seg[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};

//段码

unsignedcharLED_seg1[10]={0X40,0X79,0X24,0X30,0X19,0X12,0X02,0X78,0X00,0X10};

//段码unsignedcharLED_bit[4]={0x01,0x02,0x04,0x08};

voiddelay(unsignedlongn) //延时函数

{for(;n>0;n--);}

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

voidconvert(unsignedintn) //分解位函数{

unsignedchari=0;

n=n*100/51;

while(i<4)

{

LED_buf[i]=(unsignedchar)(n%10);

n=n/10;i++;

}

}voiddisplay(void) //显示函数{

unsignedchari;

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

{

if(i==2)P0=LED_seg1[LED_buf[i]];

elseP0=LED_seg[LED_buf[i]];

P1=LED_bit[i];

delay(100);

}

}

voidmain(void) //主函数

{

unsignedinta=0;

convert(a);

display();

while(1){

IN0=0; //开始转换

delay(10);

while(AD_BUSY==0); //等待转换结束

a=IN0;

convert(a);

display(); //显示

delay(100);

}

}五、实验仪器和设备

Keil软件、AT89S52实验平台、AtmelISP在线编程软件、示波器、电压表等。六、思考与分析(1)说明ADC的控制方法。(2)如何选择ADC?ADC有哪些重要参数?

实验四IIC总线实验

一、实验目的(1)了解IIC(I2C)总线的特点。(2)掌握IIC器件的读写程序设计方法及与AT89S5X连接的接口电路设计方法。二、实验原理

IIC采用两根I/O线,一根时钟线(SCL串行时钟线),一根数据线(SDA串行数据线),实现全双工的同步数据通信。IIC总线通过SCL/SDA两根线使挂接到总线上的器件相互进行信息传递。在AT89S52实验开发板上,单片机的P3.6(WR)通过跳线J406连接AT24C02第6脚SCL为串行时钟输入线;单片机的P3.7(RD)连接AT24C02第5脚SDA为串行数据输入、输出线,见图8-5。SDA和SCL都需要和正电源间各接一个5.1kΩ的上拉电阻。第7脚是写保护,需要接地才能写入。图8-5

AT24C04应用原理图三、实验内容

(1)将扩展板的2*13接口J401与主板ND1000_002的2*13接口J5或J12连接起来。

(2)将IIC的WP用跳线帽与地连接;将J406用跳线帽连接。

(3)将ND1000_002上的拨插开关5、6、7、8拨到ON。(4)给系统供电(+5V)。

(5)将用Keil软件生成的.HEX文件烧入AT89S52芯片中。

(6)此时可以看到数码管显示一个从2402中读出的值,通、断电或复位一次它的值就增加1。

(7)当按下INT1键时计数的值清零,数码管显示零。程序流程图如图8-6所示。四、参考程序

C51程序:

#include<reg51.h>

sbitSDA=P3∧7;

sbitSCL=P3∧6;

sbitreset=P3∧3;

//函数声明

unsignedcharLED_seg[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};

//共阳极

unsignedcharLED_bit[4]={0x01,0x02,0x04,0x08}; //数码

unsignedLED_buf[6]={0,0,0,0}; //数码unsignedchari2c_read(unsignedchar);voidi2c_write(unsignedchar,unsignedchar);voidi2c_send8bit(unsignedchar);unsignedchari2c_receive8bit(void);voidi2c_start(void);voidi2c_stop(void);biti2c_ack(void);voiddelay(unsignedintj)//延时{

while(j--);}voidconvert(unsignedlongn){

unsignedchari=0;

while(i<4)

{

LED_buf[i]=(unsignedchar)(n%10);

n=n/10;i++;

}}

//====================================voidmain(void){

unsignedchardd,i,j;

dd=i2c_read(0x00);

dd++;

j=dd;

i2c_write(0x00,dd);

while(1)

{

convert(dd);

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

{

P0=LED_seg[LED_buf[i]];

P1=LED_bit[i];

delay(500);

}if(reset==0)

{

dd=0x00;

i2c_write(0x00,dd);//写入0x00

}

}

}/*====================================i2c_write(地址,数据),写一个字节====================================*/voidi2c_write(unsignedcharAddress,unsignedcharData){

do{

i2c_start();

i2c_send8bit(0xA0);

}while(i2c_ack());

i2c_send8bit(Address);

i2c_ack();

i2c_send8bit(Data);

i2c_ack();

i2c_stop();}/*====================================i2c_read(地址,数据),读一个字节===================================*/unsignedchari2c_read(unsignedcharAddress){

unsignedcharc;

do{

i2c_start();

i2c_send8bit(0xA0);

}while(i2c_ack());//=1,表示无确认,再次发送

i2c_send8bit(Address);

i2c_ack();do{

i2c_start();

i2c_send8bit(0xA1);

}while(i2c_ack());

c=i2c_receive8bit();

i2c_ack();

i2c_stop();

return(c);}//=====================================//发送开始信号voidi2c_start(void){

SDA=1;

SCL=1;

SDA=0;

SCL=0;

//return;}//发送结束信号voidi2c_stop(void){

SCL=0;

SDA=0;

SCL=1;

SDA=1;

//return;}//发送接收确认信号bit

i2c_ack(void){

bitack;

SDA=1;

SCL=1;

delay(200);

if(SDA==1)ack=1;

elseack=0;

SCL=0;

return(ack);}//送8位数据voidi2c_send8bit(unsignedcharb){

unsignedchari=8;

while(i--)

{

SCL=0;

SDA=(bit)(b&0x80);b<<=1;

SCL=1;

}

SCL=0;}//IIC接收8位数据unsignedchari2c_receive8bit(void){

unsignedchari=8;

unsignedchardat=0;

SDA=1;

while(i--)

{

dat<<=1;

SCL=0;

SCL=1;

dat|=SDA;

}

SCL=0;

return(dat);}五、实验仪器和设备

Keil软件、AT89S52实验平台、ISP在线编程软件。六、思考与分析

(1)说明IIC总线的操作过程。(2)说明24C04的操作过程。

实验五SPI总线实验一、实验目的(1)了解SPI总线的特点。(2)掌握SPI器件的读写程序设计方法及与AT89S5x连接的接口电路设计方法。(3)掌握模拟SPI总线编程方法。二、实验原理

SPI(SerialPeripheralInterface,串行外设接口)总线系统是一种同步串行外设接口,它可以使MCU与各种外围设备以串行方式进行通信以交换信息。外围设备有FlashRAM、网络控制器、LCD显示驱动器、A/D转换器和MCU等。SPI总线系统可直接与各个厂家生产的多种标准外围器件直接接口,该接口一般使用4条线:串行时钟线(SCK)、主机输入/从机输出数据线MISO、主机输出/从机输入数据线MOSI和低电平有效的从机选择线CS(有的SPI接口芯片带有中断信号线INT,有的SPI接口芯片没有主机输出/从机输入数据线MOSI)。由于SPI系统总线一共只需3~4位数据线即可实现与具有SPI总线接口功能的各种I/O器件进行接口,而扩展并行总线则需要8根数据线、8~16位地址线、2~3位控制线,因此,采用SPI总线接口可以简化电路设计,节省很多常规电路中的接口器件和I/O口线,提高设计的可靠性。由此可见,在MCS51系列等不具有SPI接口的单片机组成的智能仪器和工业测控系统中,当传输速度要求不是太高时,使用SPI总线可以增加应用系统接口器件的种类,提高应用系统的性能。

AT93C46与单片机的接口如图8-7所示:单片机的T0作为AT93C46的时钟信号(SCK);单片机的A15作为AT93C46的片选信号(CS),片选通过跳线J403完成;单片机的A14作为AT93C46的数据输入(MOSI);单片机的A13作为AT93C46的数据输出(MISO)。AT93C46的ORG外接低电平时,表示AT93C46是作为128×8存储器使用的,如果ORG接高电平,则表示AT93C46是作为64×16存储器使用的。本实验中ORG接低电平。图8-7

AT93C46的应用原理图对于不带SPI串行总线接口的MCS51系列单片机来说,可以使用软件来模拟SPI的操作,包括串行时钟、数据输入和数据输出。对于不同的串行接口外围芯片,它们的时钟时序是不同的。对于在SCK的上升沿输入(接收)数据和在下降沿输出(发送)数据的器件,一般应将其串行时钟输出口P3.4的初始状态设置为1,而在允许接口后再置P3.4为0。这样,MCU在输出1位SCK时钟的同时,将使接口芯片串行左移,从而输出1位数据至单片机的P2.5(A13)口(模拟MCU的MISO线),此后再置P2.5为1,使MCS51系列单片机从A14(模拟MCU的MOSI线)输出1位数据(先为高位)至串行接口芯片。至此,模拟1位数据输入/输出便宣告完成。此后再置P1.1为0,模拟下一位数据的输入/输出……依此循环8次,即可完成一次通过SPI总线传输8位数据的操作。注意:模拟的SPI总线调试最好用存储示波器调试,这样可以看到完整波形,读者需详细阅读AT93C46文档中的时序部分内容。三、实验内容

(1)将扩展板的2*13接口J401与ND1000_002的2*13接口J5或J12连接起来。

(2)将AT93C46的J405用跳线帽与地连接;将J403用跳线帽连接。

(3)将ND1000_002上的拨插开关5、6、7、8拨到ON。

(4)给系统供电(+5V)。

(5)在Keil环境下编写程序,要求上电后写入10个数据,分别是0~9,写入后,将写入的数据循环读出,然后显示。最后,清0,编译生成.HEX文件,烧AT89S52芯片中。

(6)数码管显示一个从AT93C46中读出的值。四、参考程序

93C46读写程序实例:

#include<reg51.h>

#include<intrins.h>

//defineOPcode

#defineOP_EWEN_H0x00//00writeenable

#defineOP_EWEN_L0x60//11XXXXXwriteenable

#defineOP_EWDS_H0x00//00disable

#defineOP_EWDS_L0x00//00XXXXXdisable

#defineOP_WRITE_H0x40//01A6-A0writedata

#defineOP_READ_H0x80//10A6-A0readdata

#defineOP_ERASE_H0xc0//11A6-A0eraseaword

#defineOP_ERAL_H0x00//00eraseall

#defineOP_ERAL_L0x40//10XXXXXeraseall#defineOP_WRAL_H0x00//00writeall#defineOP_WRAL_L0x20//01XXXXXwriteallsbitCS=P2∧7;sbitSK=P3∧4;sbitDI=P2∧6;sbitDO=P2∧5;unsignedcharcodedis_code[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};unsignedcharLED_bit[4]={0xF1,0xF2,0xF4,0xF8};unsignedLED_buf[4]={0,0,0,0};voidewen();voidewds();voiderase();voidwrite(unsignedcharaddr,unsignedcharindata);unsignedcharread(unsignedcharaddr);voidinop(unsignedcharop_h,unsignedcharop_l);voidshin(unsignedcharindata);unsignedcharshout();voiddelayms(unsignedcharms);voiddelay(unsignedcharn);//---------------main函数-----------------main(){

unsignedchari,j;

CS=0;

SK=0;

DI=1;

DO=1;

ewen();

erase();

for(i=0;i<10;i++)//写入显示代码到AT93C46

{write(i,dis_code[i]);

delay(10);//-------------

}

ewds();

i=0;

while(1){

j=read(i);

P0=j;//循环读取AT93C46内容,并输出到P0口

P1=LED_bit[0];

i++;

i&=0x0F;

if(i==0x0A)i=0;

delayms(250);

delayms(250);

}}//---------------主函数--------------------voidwrite(unsignedcharaddr,unsignedcharindata)

//写入数据indata到addr{

inop(OP_WRITE_H,addr);

shin(indata);

CS=0;

delayms(10);}unsignedcharread(unsignedcharaddr)//读取addr处的数据{

unsignedcharout_data;

inop(OP_READ_H,addr);

delay(10);

out_data=shout();

CS=0;

returnout_data;}voidewen(){

inop(OP_EWEN_H,OP_EWEN_L);

CS=0;}voidewds(){

inop(OP_EWDS_H,OP_EWDS_L);

CS=0;}voiderase(){

inop(OP_ERAL_H,OP_ERAL_L);

delayms(30);

CS=0;}voidinop(unsignedcharop_h,unsignedcharop_l){

unsignedchari;

SK=0;

DI=1;

CS=1;

delay(10);

SK=1;

delay(20);

SK=0;

delay(10);

DI=(bit)(op_h&0x80);//先移入指令码高位

SK=1;

delay(10);

op_h<<=1;SK=0;

delay(10);

DI=(bit)(op_h&0x80);//移入指令码次高位

SK=1;

delay(10);

SK=0;

op_l<<=1;

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

{

DI=(bit)(op_l&0x80);//先移入高位

SK=1;

delay(10);

op_l<<=1;

SK=0;

}

DI=1;}voidshin(unsignedcharindata)//移入数据{

unsignedchari;

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

{

DI=(bit)(indata&0x80);//先移入高位

SK=1;

delay(10);

indata<<=1;

SK=0;

}

DI=1;}unsignedcharshout(void)//移出数据{

unsignedchari,out_data;

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

{

SK=1;

delay(10);

out_data<<=1;

SK=0;

out_data|=(unsignedchar)DO;

}

return(out_data);}voiddelayms(unsignedcharms)//延时子程序{

unsignedchari;

while(ms--)

{

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

}}voiddelay(unsignedcharn){

for(;n>0;n--);}

五、实验仪器和设备

Keil软件、AT89S52实验平台、ISP在线编程软件、示波器。六、思考与分析(1)说明单片机完成SPI总线操作的方法。(2)修改程序为每次上电后将0~9存储器里面的内容读出,然后加1,显示。实验六实时时钟DS12C887实验一、实验目的

(1)理解单片机并口编程方法。(2)掌握DS12C887的编程方法。(3)了解DS12C887的原理。(4)了解实时时钟的设计方法。二、实验原理

DS12C887是Dallas公司开发的实时时钟芯片。DS12C887可以提供实时时钟/日历、时间报警、三个可屏蔽中断、一个可编程方波输出、113B电池供电的静态RAM。DS12C887内部集成了一个晶体和一个锂电池,采用DIP(双列直插)封装方式。DS12C887在32H地址增加了100个字节的存储器。DS12C887能够自动调整31天和30天的月份,期间可以在24小时和12小时方式(AM/PM)间切换。在芯片内部有一个精确的温度补偿电路,用于检测电源电压的状态。当电源电压的变化超出允许范围时,内部电源切换到备用电池供电。

DS12C887主要应用在嵌入式系统、仪表、安全系统、网络交换机、路由器等方面。

DS12C887在该实验系统中的应用及读写信号与单片机的接口如图8-8所示。A15通过跳线J407作为DS12C887的片选信号。实验系统工作原理:INT0用于进入设置,当该键按下时,就进入时间设置,再次按下时,进入下一个时间设置,此点可以参考后面的参考程序的操作。DOWN和UP用于减少和增加当前设置的值,OK用于退出时间设置。图8-8

DS12C887应用原理图三、实验内容

(1)将扩展板的电源J501与主板的电源接口J2或J14连接起来;将扩展板的信号接口J500与主板的信号接口J15或J13连接起来;将主板上的液晶跳线接上。

(2)在Keil编程环境下编写程序,完成实验功能要求:能显示年月日,而且时间能够通过键盘设置。

(3)编译生成.HEX文件,并将.HEX文件下载到实验系统中,观察液晶屏上显示的数据,同时用键盘设置时间参数。四、参考程序

//说明:6位数码管显示时,分,秒;键盘可调时间

//晶振为11.0592MHz

#include<reg51.h>

#include<absacc.h>

sbitRESET=P3∧2; //键盘

sbitOK=P3∧4; //键盘

sbitINC=P2∧1; //键盘

sbitDEC=P2∧2; //键盘

sbitRS=P1∧0;//指令和数据寄存器

sbitRW=P1∧1;//读写控制

sbitE=P1∧2;//片选

sbitFLAG=P0∧7;//忙信号

#defineucharunsignedchar#definetime_aXBYTE[0x7f0a]//控制寄存器A#definetime_bXBYTE[0x7f0b] //控制寄存器B#definedata_IOP0uchartime[12]={0};ucharxdata*addr=0x7f00;//P2.7片选,低电平有效ucharyear,month,day,hour,minute,second;//声明函数voidget_time(void);voidintial(void);intial_lcd();voidbusy();voidw_com(ucharcom);voidw_dat(uchardat);voiddisplay();voiddelay(unsignedlongN);voiddisplayD(ucharj);voidconvert(void);voidINT0_ISR();voidget_time(void){

year=*(addr+9);

month=*(addr+8);

day=*(addr+7);

hour=*(addr+4);

minute=*(addr+2);

second=*addr;}voidintial(void){

time_a=0x70;

time_b=0x8e;//可以设置12、24小时制 *(addr+2)=0x00;//分初值:30 *(addr+4)=0x0C; //时初值:12 *(addr+7)=0x10; //日初值:16 *(addr+8)=0x07; //月初值:07 *(addr+9)=0x07; //年初值:07

time_a=0x27;

time_b=0x1e;//设置最高位为0,芯片更新,正常运行}//-----------------液晶显示--------------intial_lcd(){

RS=0;

RW=0;

E=0;

delay(100);

w_com(0x38);

w_com(0x38);

w_com(0x38);//显示为8位两行字符

w_com(0x08);

w_com(0x01);

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论