电子线路设计专题实验报告西安交通大学.docx

上传人:b****5 文档编号:27945685 上传时间:2023-07-06 格式:DOCX 页数:31 大小:2.09MB
下载 相关 举报
电子线路设计专题实验报告西安交通大学.docx_第1页
第1页 / 共31页
电子线路设计专题实验报告西安交通大学.docx_第2页
第2页 / 共31页
电子线路设计专题实验报告西安交通大学.docx_第3页
第3页 / 共31页
电子线路设计专题实验报告西安交通大学.docx_第4页
第4页 / 共31页
电子线路设计专题实验报告西安交通大学.docx_第5页
第5页 / 共31页
点击查看更多>>
下载资源
资源描述

电子线路设计专题实验报告西安交通大学.docx

《电子线路设计专题实验报告西安交通大学.docx》由会员分享,可在线阅读,更多相关《电子线路设计专题实验报告西安交通大学.docx(31页珍藏版)》请在冰豆网上搜索。

电子线路设计专题实验报告西安交通大学.docx

电子线路设计专题实验报告西安交通大学

XX交通大学

电子信息与工程学院自动化科学与技术系

电子线路设计专题实验报告

 

实验名称 :

电子线路设计专题实验

实验者XX:

XX

实验者学号:

21105040XX

所在班级:

自动化1X

报告完成日期:

2021年5月11日

 

一、实验目的;

〔1〕熟悉单片机原理;

〔2〕掌握开发板上常见芯片的功能与用法;

〔3〕掌握单片机的开发软件:

KELL

〔4〕应用单片机,做一些简单的小应用〔电子时钟等〕

二、实验内容:

〔1〕创立一个工程将键盘阵列定义为0.1.2------E.F,编程实现键盘设置当前时间,再调用系统时钟,显示在LED显示屏上〔注意仔细阅读PCF8563资料〕,键盘设置当前日期显示在LCD显示屏上。

〔2〕利用D/A转换通道〔下行通道〕实现锯齿波发生器;输出〔1~5V〕固定电压转换成〔4~20mA〕电流。

〔3〕利用A/D转换通道〔上行通道〕实现数据采集,将采集信号显示在LED屏上。

程序要求分别具有平均值滤波、中值滤波和滑动滤波功能。

三、开发板简介:

图1  PH-I型51MCU学习系统实物照片

简介:

四、功能实现与关键代码:

〔1〕电子时钟:

在这一局部,有几个很重要的的程序模块:

包含1602初始化、写控制字、写字符等几个函数的1602.h;包含根据

总线协议编写的字节及多字节传输和接收函数的viic.h;实现键盘读取操作的key.h;实现不断读取时间芯片的值并显示在1602和led上显示日期时间的read函数等.以下是这几个重要的模块以及主函数程序。

1602.h〔包含1602初始化、写控制字、写字符等函数〕

//********检测是否忙、写控制字、写数据等********//

voidWriteW(uinta)

{

ptr=0xAFF0;

*ptr=a;

}

 

voidCheckBF(void)

{

uinti;

while

(1)

{

ptr=0xAFF1;

i=*ptr;

i&=0x80;

if(i==0)

break;

}

}

voidLCD_Init(void)

{

CheckBF();

WriteW(0x38);

CheckBF();

WriteW(0x01);

CheckBF();

WriteW(0x06);

CheckBF();

WriteW(0x0F);

CheckBF();

WriteW(0x80);

}

voidLCD_Init2(void)

{

CheckBF();

WriteW(0x0F);

CheckBF();

WriteW(0xC0);

}

voidWritD(unsignedcharkey_asc2)

{

CheckBF();

ptr=0xAF02;

*ptr=key_asc2;

}

 

viic.h〔包含根据

总线协议编写的字节及多字节传输和接收函数〕

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

字节数据传送函数

函数原型:

voidSendByte(ucharc);

功能:

将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对

此状态位进展操作.(不应答或非应答都使ack=0假)

发送数据正常,ack=1;ack=0表示被控器无应答或损坏。

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

voidSendByte(ucharc)

{

ucharBitt;

for(Bitt=0;Bitt<8;Bitt++)/*要传送的数据长度为8位*/

{

if((c<

elseSDA=0;

_Nop();

SCL=1;/*置时钟线为高,通知被控器开场接收数据位*/

_Nop();

_Nop();/*保证时钟高电平周期大于4μs*/

_Nop();

_Nop();

_Nop();

SCL=0;

}

_Nop();

_Nop();

SDA=1;/*8位发送完后释放数据线,准备接收应答位*/

_Nop();

_Nop();

SCL=1;

_Nop();

_Nop();

_Nop();

if(SDA==1)ack=0;

elseack=1;/*判断是否接收到应答信号*/

SCL=0;

_Nop();

_Nop();

}

 

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

字节数据传送函数

函数原型:

ucharRcvByte();

功能:

用来接收从器件传来的数据,并判断总线错误(不发应答信号),

发完后请用应答函数。

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

ucharRcvByte()

{

ucharretc;

ucharBitt;

retc=0;

SDA=1;/*置数据线为输入方式*/

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

{

_Nop();

SCL=0;/*置时钟线为低,准备接收数据位*/

_Nop();

_Nop();/*时钟低电平周期大于4.7μs*/

_Nop();

_Nop();

_Nop();

SCL=1;/*置时钟线为高使数据线上数据有效*/

_Nop();

_Nop();

retc=retc<<1;

if(SDA==1)retc=retc+1;/*读数据位,接收的数据位放入retc中*/

_Nop();

_Nop();

}

SCL=0;

_Nop();

_Nop();

return(retc);

}

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

应答子函数

原型:

voidAck_I2c(bita);

功能:

主控器进展应答信号,(可以是应答或非应答信号)

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

voidAck_I2c(bita)

{

if(a==0)SDA=0;/*在此发出应答或非应答信号*/

elseSDA=1;

_Nop();

_Nop();

_Nop();

SCL=1;

_Nop();

_Nop();/*时钟低电平周期大于4μs*/

_Nop();

_Nop();

_Nop();

SCL=0;/*清时钟线,钳住I2C总线以便继续接收*/

_Nop();

_Nop();

}

 

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

向有子地址器件发送多字节数据函数

函数原型:

bitISendStr(ucharsla,ucharsuba,ucahr*s,ucharno);

功能:

从启动总线到发送地址,子地址,数据,完毕总线的全过程,从器件

地址sla,子地址suba,发送内容是s指向的内容,发送no个字节。

如果返回1表示操作成功,否那么操作有误。

注意:

使用前必须已完毕总线。

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

//*

bitISendStr(ucharsla,ucharsuba,uchar*s,ucharno)

{

uchari;

Start_I2c();//启动总线

SendByte(sla);//发送器件地址

if(ack==0)return(0);

SendByte(suba);//发送器件子地址

if(ack==0)return(0);

for(i=0;i

{

SendByte(*s);//发送数据

if(ack==0)return(0);

s++;

}

Stop_I2c();//完毕总线

return

(1);

}

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

向有子地址器件读取多字节数据函数

函数原型:

bitISendStr(ucharsla,ucharsuba,ucahr*s,ucharno);

功能:

从启动总线到发送地址,子地址,读数据,完毕总线的全过程,从器件

地址sla,子地址suba,读出的内容放入s指向的存储区,读no个字节。

如果返回1表示操作成功,否那么操作有误。

注意:

使用前必须已完毕总线。

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

bitIRcvStr(ucharsla,ucharsuba,uchar*s,ucharno)

{

uchari;

Start_I2c();/*启动总线*/

SendByte(sla);/*发送器件地址*/

if(ack==0)return(0);

SendByte(suba);/*发送器件子地址*/

if(ack==0)return(0);

Start_I2c();

SendByte(sla+1);

if(ack==0)return(0);

for(i=0;i

{

*s=RcvByte();/*发送数据*/

Ack_I2c(0);/*发送就答位*/

s++;

}

*s=RcvByte();

Ack_I2c

(1);/*发送非应位*/

Stop_I2c();/*完毕总线*/

return

(1);

}

 

key.h〔实现键盘读取操作的〕

//**********************************有关键盘的函数********************************************//

unsignedcharcodeKey_Value_Table[16]=//有关行列值

{0xff,0x00,0x01,0xff,0x02,0xff,0xff,0xff,

0x03,0xff,0xff,0xff,0xff,0xff,0xff,0xff

};

bitbKeyUp_Flag;

voidKey_Init(void)

{

bKeyUp_Flag=1;//标志位置1

}

unsignedcharGetScanKey(void)

{

unsignedcharkey,i,temp;

unsignedcharxdata*ptr;

key=0xff;

for(i=1;i<0x10;i<<=1)//i的低4位为行数位,行依次检测循环4次

{

ptr=0x8fff;

*ptr=i;

temp=*ptr;//取键盘IO口的值

temp&=0x0f;//屏蔽高四位

if(temp!

=0x00)//是否有有效键值

{

key=i<<4;//取行数位的值并将其放入返回值高4位

key|=temp;//列数位的值放入返回值低4位

break;

}

}

returnkey;//返回行位〔高四〕和列位〔低四〕

}

unsignedcharGetKey(void)

{

unsignedcharkey,temp;

if(!

bKeyUp_Flag)//判断标志,是0执行

/*按键程序执行一次后会将bKeyUp_Flag标志位清零,执行此段程序,长按键无效返回无效值

直至按键无效返回无效按键值,置"1"标志位。

按键输入恢复有效*/

{

key=GetScanKey();

if(key==0xff)//没有按键,置标志位

bKeyUp_Flag=1;

else//保持按键

return0xff;

}

key=GetScanKey();

if(key==0xff)//没有按键

returnkey;

else//有按键有效

temp=key;//取键值

Delay_ms(20);//延时20ms消抖

key=GetScanKey();//键盘扫描

if(key!

=temp)//判断两次键值是否一样,排除干扰信号影响确认有效信号

{

key=0xff;

returnkey;

}

else//取键值

{

temp=Key_Value_Table[key>>4];

/*行值有效位(键盘的4个行SEL返回的值含有的有效位"1")有且只有一位键值才有效否那么返回无效键值*/

if(temp==0xff)

{

key=0xff;

returnkey;

}

temp=Key_Value_Table[key&0x0f];

/*列值有效位(键盘的4个列RL返回的值含有的有效位"1")有且只有一位键值才有效否那么返回无效键值*/

if(temp==0xff)

{

key=0xff;

returnkey;

}

key=Key_Value_Table[key>>4]*4+Key_Value_Table[key&0x0f];

/*行列组合后的值大于15无效*/

if(key>15)

{

key=0xff;

returnkey;

}

bKeyUp_Flag=0;

returnkey;

}

}

 

实现不断读取时间芯片的值并显示在1602和led上显示日期时间的read函数

voidread()

{

unsignedcharrd[7];//作为读8563数据的缓存区

unsignedchari;

while

(1)

{

IRcvStr(0xA2,0x02,rd,0x7);

rd[0]=rd[0]&0x7f;//秒

rd[1]=rd[1]&0x7f;//分

rd[2]=rd[2]&0x3f;//时

rd[3]=rd[3]&0x3f;//日

rd[4]=rd[4];//

rd[5]=rd[5]&0x1f;//月

rd[6]=rd[6];//年

td_table[2]=rd[6]/16;//数据分解

td_table[3]=rd[6]%16;

td_table[4]=rd[5]/16;

td_table[5]=rd[5]%16;

td_table[6]=rd[3]/16;

td_table[7]=rd[3]%16;

td_table[8]=rd[2]/16;

td_table[9]=rd[2]%16;

td_table[10]=rd[1]/16;

td_table[11]=rd[1]%16;

td_table[12]=rd[0]/16;

td_table[13]=rd[0]%16;

//LED上显示

ptr=0x9fff;//先清零

*ptr=0x00;

ptr=0x8fff;

*ptr=0xff;

//依次显示秒、分、时

ptr=0x9fff;

*ptr=qiduan_table[td_table[13]];

ptr=0x8fff;

*ptr=0x01;

Delay_ms

(1);

ptr=0x9fff;

*ptr=qiduan_table[td_table[12]];

ptr=0x8fff;

*ptr=0x02;

 

Delay_ms

(1);

ptr=0x9fff;

*ptr=qiduan_table[td_table[11]];

ptr=0x8fff;

*ptr=0x08;

Delay_ms

(1);

ptr=0x9fff;

*ptr=qiduan_table[td_table[10]];

ptr=0x8fff;

*ptr=0x10;

Delay_ms

(1);

Delay_ms

(1);

ptr=0x9fff;

*ptr=qiduan_table[td_table[9]];

ptr=0x8fff;

*ptr=0x40;

Delay_ms

(1);

ptr=0x9fff;

*ptr=qiduan_table[td_table[8]];

ptr=0x8fff;

*ptr=0x80;

Delay_ms

(1);

ptr=0x9fff;//先清零

*ptr=0x00;

ptr=0x8fff;

*ptr=0xff;

 

//LCD上显示日期

LCD_Init();

LCD_Init2();

WritD(ASC2_Value_Table[td_table[0]]);

WritD(ASC2_Value_Table[td_table[1]]);

WritD(td_table[2]+29);

WritD(ASC2_Value_Table[td_table[3]]);

WritD(0x20);

WritD(0x20);

WritD(0x20);

WritD(ASC2_Value_Table[td_table[5]]);

WritD(0x20);

WritD(0x20);

WritD(0x20);

WritD(ASC2_Value_Table[td_table[6]]);

WritD(ASC2_Value_Table[td_table[7]]);

}

}

 

main函数

voidmain()

{

unsignedinti;

Key_Init();

ptr=0x9fff;//先清零

*ptr=0x00;

ptr=0x8fff;

*ptr=0xff;

LCD_Init();

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

{

WritD(tishi_table1[i]);

Delay_ms(200);

}

LCD_Init2();

for(i=13;i<23;i++)

{

WritD(tishi_table1[i]);

Delay_ms(200);

}

Delay_s(4);

if(Test_key())

{

Input_data();

inition();

read();

}

}

〔2〕利用D/A转换通道〔下行通道〕实现锯齿波发生器

这一局部重要的代码片段是对tlc5615的操作以及在main函数中实现正弦等波形,下面是实现正弦波

voidtlc5615()(实现DA转换)

voidtlc5615(unsignedintdat)

{

unsignedcharx;

CS=1;

SCLK=0;

Delay_us(500);

DIO=0;

CS=0;

dat=dat<<6;

for(x=0;x<12;x++)

{

DIO=dat&0x8000;

SCLK=1;

dat=dat<<1;

SCLK=0;

}

CS=1;

}

 

main函数

unsignedcharkey=0x0ff;

unsignedcharxdata*ptr;

unsignedfloatvol=0;

floatadd=0.000383;

floattemp=0;

intmain()

{

LCD_Init();

Key_Init();

ptr=0x8FF;

*ptr=0x00;

//屏幕全部归位

Delay_s(4);

Check_Busy();

write_(0x01);//显示屏清

Check_Busy();

while

(1)

{

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

{

vol=500*(sin(i*0.01)+1)

//tlc5615(vol);

}

}

}

〔3〕利用A/D转换通道〔上行通道〕实现数据采集,将采集信号显示在LED屏上。

这一局部重要的代码片段有:

对1549芯片的操作,将电压显示在led上〔三位小数〕的display函数。

以下粘贴局部代码段:

adc_1549〔不断采集端口数据,并送至CPU〕

inttlc1549()

{

intdata_out=0;

unsignedchari;

DIO=0;

SCLK=0;

CS=1;

_nop_();

CS=0;//start

for(i=1;i<=10;i++)

{

SCLK=1;

data_out<<=1;

if(DIO)data_out|=0x01;

SCLK=0;

}

CS=1;

Delay_us(21);

return(data_out);

}

disp_voltage函数〔将电压显示在LED和LCD上〔三位小数〕的函数〕由于时间仓促只显示了小数点后两位

voiddisp_voltage(int*disp)

{

unsignedcharxdata*ptr;

if(disp[2]>=0x5)

{

disp[2]=0x5;

disp[1]=0x0;

disp[0]=0x0;

}

ptr=0x8fff;

*ptr=0x01;

ptr=0x9fff;

*ptr=map[*(disp)];

Delay_us(50);

*ptr=0x00;

ptr=0x8fff;

*ptr=0x02;

ptr=0x9fff;

*ptr=map[*(disp+1)];

Delay_us(50);

*ptr=0x00;

ptr=0x8fff;

*ptr=0x04;

ptr=0x9fff;

*ptr=(map[*(disp+2)])|0x80;

Delay_us(50

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

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1