电子电路设计实验报告_第1页
电子电路设计实验报告_第2页
电子电路设计实验报告_第3页
电子电路设计实验报告_第4页
电子电路设计实验报告_第5页
已阅读5页,还剩23页未读 继续免费阅读

下载本文档

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

文档简介

1、电子线路专题实验一、实验要求:1. 认真阅读学习系统线路及相关资料2. 将键盘阵列定义为0. 1. 2- E. F,编程实现将键盘输入内容显示在LCD显示器上。3. 编程实现将日历、时钟显示在LED显示屏上(注意仔细阅读PCF8563资料),日历、时钟轮回显示。4. 利用D/A转换通道(下行通道)实现锯齿波发生器;输出(15V)固定电压转换成(420mA)电流。5. 利用A/D转换通道(上行通道)实现数据采集,将采集信号显示在LED屏上。程序要求分别具有平均值滤波、中值滤波和滑动滤波功能。6. 将按键阵列定义成与16个语音段对应,编写程序,实现按键播放不同的语音段。二、实验设计思路:本次实验用

2、c语言实现,主要包括LCD,LED,AD,DA,日历芯片,测温传感芯片。受到嵌入式系统实验的启发,将LCD,LED,I2C总线协议,键盘扫描模块接口写成一个文件库(放在library文件夹下),尽量做到调用时与底层硬件无关。通过调用库文件中的函数,实现代码的重用性。键盘,LCD的代码由于与嵌入式实验具有相通之处,因此可将高层的函数(与底层硬件无关的函数)方便地移植过来。三、实验设计:1.矩阵键盘扫描模块44的矩阵键盘,通过扫描可得到按下键的行列值,将行列值转换为相应的对应数字0F。函数GetKey()实现获得按键的键值。对于键盘模块对于对按键的键值识别主要是通过两次扫描而取得。对于第一次扫描,

3、给四行键全部赋予1,然后读回键盘值,对于第二次扫描,逐行为键盘送1,每次送1后再读回键盘值,若非零,说明此行有键按下,最终确定键值。通过调用GetKey函数构造GetChar()函数,实现获取键盘字符(0F)的功能。通过调用GetChar()函数构造GetDec()函数,实现获取键盘输入整数的功能,整数范围在099999。有按C键回退一格,按E清空当前未完输入,按F键结束输入的功能。程序代码:/键盘初始化,将标志位置1;void Key_Init(void) bKeyUp_Flag=1;/标志(全局变量)位置1/键盘扫描函数,得到键的行列位置;unsigned char GetScanKey(

4、void)unsigned char key, i, temp;unsigned char xdata * ptr;key=0xff;for (i=1; i0x10; i=1)/i的低4位为行数位,行依次检测循环4次ptr=0x8fff; * ptr =i;temp = * ptr; /取键盘IO口的值temp &= 0x0f; /屏蔽高四位if (temp!=0x00) /是否有有效键值 key = i4;/见说明 /*行值有效位(键盘的4个行SEL返回的值含有的有效位1)有且只有一位键值才有效否则返回无效键值*/if (temp=0xff) key=0xff;return key; tem

5、p=Key_Value_Tablekey&0x0f; /*列值有效位(键盘的4个列RL返回的值含有的有效位1)有且只有一位键值才有效否则返回无效键值*/if (temp=0xff) key=0xff;return key; key=Key_Value_Tablekey4*4+Key_Value_Tablekey&0x0f;/行对应的中间值的四倍与列对应的中间值之和即为按键编号015 /*行列组合后的值大于15无效*/if (key15) key=0xff;return key; bKeyUp_Flag=0;return key; /获得键盘输入字符int GetChar(void)unsign

6、ed char key=0xff;while(key=0xff)key=GetKey();/* wait input fix*/return (int)key_arrengekey);/* change to ASCII code and return*/获得键盘输入整数long GetDec(void)long out_dec = 0;/* result(decimal number) 数值范围099999*/unsigned char i,j;/* variable for character count*/int temp = 0;int key;for(i = 0;i6 ; )key

7、=GetChar();/* 获取键值09 */if(key= 0)temp = key - 0;/* 获取数值0-9 */out_dec = out_dec * 10 + (long)temp;if(out_dec = 0)continue;/* 首位数据输入为0时,显示不变 */i+;LCD_putchar(key);/* 显示当前输入的数据 */continue;if(E= key) /* 当前输入清零 */out_dec = 0;back_cursol(i); /* 清显示区 */for(j=0;j=0);/函数功能描述:给显示数组赋初始值;void Led_Init(unsigned

8、char *show)unsigned char i;for (i=0;i8;i+) /在此处给显示数组赋值 *show= 0x00;show+;/函数功能描述:在LED上显示;void display(unsigned char *show)unsigned char i=1,j;unsigned char xdata *ptr;for (j=0; j8; j+)/八个数码管全部显示 ptr=0x8fff;/段选地址 *ptr=i;ptr=0x9fff;/位选地址/在此给*ptr赋值送字形码*ptr=Led_tableshowj;Delay_us1(30); *ptr=0x00;i 0x0f

9、)/* move cursor to right, if get to end of the line */cursol_x = 0;/* move to begin of the line */if(+cursol_y = 2)/* return, if over the second line */cursol_y = 0;/* return to begin of the line */LCD_setcursol(cursol_x, cursol_y);/* set cursor */=前移光标=voidback_cursol(int i)cursol_x -= i;LCD_setcur

10、sol(cursol_x, cursol_y);/* set cursor */=清屏=void LCD_clear(void)CheckBF();/* wait LCD process */WriteW(0x01);/* clear display */=写字符=voidLCD_putchar(int c)if(c = n)|(c = r)/* line feed code*/cursol_x = 0;cursol_y = 1;LCD_setcursol(cursol_x, cursol_y);/* set cursor*/CheckBF();/* wait LCD process*/Wri

11、teD(c);/* write Data-Register*/CheckBF();/* wait LCD process*/move_cursol();/* move cursor position*/=写字符串=voidLCD_puts(const unsigned char *s)for(; 0 != *s; s+)/* loop before null code */LCD_putchar(*s);/* display character on LCD */=写整数=voidLCD_putdec(long dec) /* 可打印的数据小于99999 */long num ;/* numb

12、er to be displayed*/int i;/* loop counter*/unsigned char str_buf5;/* buffer for data display*/num = dec;/* save number to be displayed */for(i = 0 ;num != 0; i+)/* confirm digit*/str_bufi = num % 10;/* get every digit number and save in buffer*/num= num / 10;if(i = 0)/* if number is 0*/LCD_putchar(0

13、);/* display 0 in LCD*/else/* if number is not 0*/for(-i; i = 0; i-)/* loop times of digits*/LCD_putchar(str_bufi + 0);/* after transfered into ASCII code*/* display in LCD*/ /十六进制码转换为ascii码unsigned char Key_ASC2(unsigned char key)unsigned char key_asc2;key_asc2=ASC2_Value_Tablekey;return key_asc2;4

14、.I2C总线协议I2C总线是由数据线SDA和时钟SCL构成的串行总线,可发送和接收数据。I2C总线在传送数据过程中共有三种类型信号,它们分别是:开始信号、结束信号和应答信号。 开始信号:SCL为高电平时,SDA由高电平向低电平跳变,开始传送数据。 结束信号:SCL为低电平时,SDA由低电平向高电平跳变,结束传送数据。 应答信号:接收数据的IC在接收到8bit数据后,向发送数据的IC发出特定的低电平脉冲,表示已收到数据。CPU向受控单元发出一个信号后,等待受控单元发出一个应答信号,CPU接收到应答信号后,根据实际情况作出是否继续传递信号的判断。若未收到应答信号,由判断为受控单元出现故障。协议代码

15、:sbit SCL=P10;sbit SDA=P11;/*/*功能:启动I2C总线/*void i2c_start() SDA=1;SCL=1;_nop_();_nop_();SDA=0;_nop_();_nop_();SCL=0;/*/*功能:停止I2C总线/*void i2c_stop()SDA=0;SCL=0;_nop_();_nop_();SCL=1; _nop_();_nop_();SDA=1;/*/*功能:应答I2C总线/*bit i2c_rec_ack()bit ack_flag;SDA=1;_nop_();_nop_();SCL=1;_nop_();_nop_();if(SDA

16、=0)ack_flag=1;elseack_flag=0;SCL=0;returnack_flag; void i2c_send_ack(void)SDA=0;_nop_();_nop_();SCL=1;_nop_();_nop_();SCL=0;_nop_();_nop_();SDA=1;/*/*功能:无应答I2C总线/*void i2c_send_noack()SDA=1;_nop_();_nop_();SCL=1; _nop_();_nop_();SCL=0;/*/*功能:往I2C总线发送数据/*void i2c_send_byte(unsigned char data_byte)uns

17、igned char i;for(i=0;i8;i+)SDA=(bit)(data_byte&0x80);_nop_();_nop_();SCL=1;_nop_();_nop_();SCL=0;data_byte=1;/*/*功能:从I2C总线接受数据/*unsigned char i2c_rec_byte()unsigned char i, temp;temp=0;for(i=0;i8;i+)temp0;len-)/连续发送LEN长度的字节数据i2c_send_byte(*ptr+);if(i2c_rec_ack()=0)return 0;i2c_stop();/发送I2C STOP信号re

18、turn 1; /*/*功能:从I2C总线上器件指定地址接收一个字节的数据/*unsigned char i2c_read_byte(unsigned char sla,unsigned char data_addr)unsigned int temp;i2c_start();/发送I2C START信号i2c_send_byte(sla);/发送从器件写命令if(i2c_rec_ack()=0)/检测应答信号return 0;i2c_send_byte(data_addr);/发送数据地址if(i2c_rec_ack()=0)/检测应答信号return 0;i2c_start();/重新发送

19、I2C START信号i2c_send_byte(sla|0x01);/发送器件从器读命令if(i2c_rec_ack()=0)/检测应答信号return 0;temp=i2c_rec_byte();i2c_send_noack();/接收最后一个字节后发送NOACK信号i2c_stop();/发送I2C STOP信号return temp;/*/*功能:从I2C总线上器件指定地址接收一个字节的数据/*bit i2c_read_nbyte(unsigned char sla,unsigned char data_addr,unsigned char *ptr,unsigned char len

20、)i2c_start();/发送I2C START信号i2c_send_byte(sla);/发送从器件写命令if(i2c_rec_ack()=0)/检测应答信号return 0;i2c_send_byte(data_addr);/发送数据地址if(i2c_rec_ack()=0)/检测应答信号return 0;i2c_start();/重新发送I2C START信号i2c_send_byte(sla|0x01);/发送器件从器读命令if(i2c_rec_ack()=0)/检测应答信号return 0;for(;len1;len-)/连续接收LEN-1长度的字节数据*ptr+=i2c_rec_

21、byte();i2c_send_ack();/发送ACK信号*ptr=i2c_rec_byte();/接收最后一个字节i2c_send_noack();/发送NOACK信号i2c_stop();/发送I2C STOP信号return 1;5. AD模块(SPI总线)利用TLC1549实现,TLC1549可以将输入的模拟量转换成数字量,并且是10位数字量,然后也是利用SPI总线一位一位的发送,因此需要传两字节的数据,高地址中的低两位有效,低地址中的八位都有效,传送过程结合时序图进行编程。模块使用的函数是模块驱动程序参考中的函数sbit SCLK=P12;sbit DIO=P13;sbit ADC

22、S=P14;sbit DACS=P15;void Before_Once_AD(void);/预采集uint adc_1549(void) ;/读取AD输出的10bit数据6. DA模块(SPI总线)利用TLC5615实现的,TLC5615也是利用SPI总线一位一位的传送,并且要求传送的数据是12位,因此需要传两字节的数据,分别放在HIGHD和LOWD中,12位数据是HIGHD中的八位和LOWD中的高四位,但是12为数据中的低两位又是无效的,所以只有10位有效数字。模块使用的函数是模块驱动程序参考中的函数 /函数功能描述:驱动TLC5615开始DA转换/dat为被转换的数字量void tlc5

23、615(uint dat) ;7.日历芯片PCF8563 是低功耗的CMOS 实时时钟日历芯片,它提供一个可编程时钟输出,一个中断输出和掉电检测器,所有的地址和数据通过I2 C 总线接口串行传递。每次读写数据后,内嵌的字地址寄存器会自动产生增量。按I2C 总线协议规约PCF8563 有唯一的器件地址0A2H。因此,可以由CPU把初始化的日历时钟通过总线接口串行传递写入PCF8563,由PCF8563以此为起点自动计时,再通过I2C总线串行接口从PCF8563读出内部的日历/时钟。这部分主要是在I2C总线协议的基础上进行通信,向芯片指定地址写入控制字,写入时间数据或读出时间数据。由于芯片中的实际

24、数据都是以BCD码形式存储,因此通信时需要进行十六进制数和BCD码的互相转换。具体设计函数包括向芯片写入时间,从芯片读出时间,码制转换。程序代码:/8bit 十六进制转bcd码unsigned char NUM2BCD(unsigned char x)return (x)/10)4)*10+(x)&0x0f);/*-函数说明:写入时间:秒,分,时,日,星期,月,年,BCD码-*/void wt_time(unsigned char *t)i2c_write_byte(0xA2,0x00,0x00);/开始计时i2c_write_nbyte(0xA2,0x02,t,7);/写入时间/*-读时间-

25、*/void rd_time(unsigned char *time)int i;unsigned char addr=0x02;unsigned char temp;for(i=0;i7;i+)temp=i2c_read_byte(0xA2,addr); if(i=0|i=1) /去掉无效位 /秒,分temp&=0x7f; if(i=2|i=3) /时,日temp&=0x3f; if(i=4) /星期temp&=0x07; if(i=5) /月temp&=0x1f;timei=temp; /Delay_ms(50); Delay_us(100); addr=addr+1; /页读须软件累加地

26、址8语音芯片这部分直接使用了模块驱动程序参考中的函数,ISD_WR_APC2(uchar voiceValue)函数可以调节音量,0xa8对应最大音量,0xaf对应最小音量。play_open(unsigned int AddST,unsigned int AddEN)函数可以根据播放的首尾地址播放不同的音乐。9.库文件定义和使用一个模块的文件包括头文件(*.h)和源文件(*.c)。在头文件中进行函数的声明,在对应源文件中将头文件首先包含进来,然后对函数进行具体定义实现。使用时用到了某个模块,先将头文件include进来,然后在工程中添加对应的C文件。千万不要忽略了头文件中的#ifndef,这

27、是一个很关键的东西。比如你有两个C文件,这两个C文件都include了同一个头文件。而编译时,这两个C文件要一同编译成一个可运行文件,于是问题来了,大量的声明冲突。还是把头文件的内容都放在#ifndef和#endif中吧。不管你的头文件会不会被多个文件引用,你都要加上这个。一般格式是这样的:#ifndef #define .#endif四、实验过程:1.键盘和LCD的测试功能描述:初始状态:LCD上第一行显示0:get char,第二行显示1:get decimal。按0进入获取字符并显示的状态,按字符F退出返回初始状态,按1进入获取整数并显示状态(整数范围:099999),当键入99999时

28、退出返回初始状态。主要代码:#lcdtest.c#void main(void)unsigned char key,flag;long dec;LCD_Init();/lcd初始化Key_Init();LCD_clear();while(1)LCD_setcursol(0,0);LCD_puts(0:get char);LCD_setcursol(0,1);LCD_puts(1:get decimal);flag=GetChar();if(flag=0|flag=1)break;LCD_clear();LCD_setcursol(0,0);while(1)if(flag=0)key=GetCh

29、ar();LCD_putchar(key);if(key=F)break;/当按F时跳出if(flag=1)LCD_setcursol(0,0);dec=GetDec();LCD_clear();LCD_putdec(dec);if(dec=99999)break;/当输入整数为99999时跳出2.LCD和LED显示日历功能描述:初始状态LCD显示欢迎界面,提示按F键进入,按F后进入提示菜单,按0选择程序中默认的日期设定,按1选择手动设定日期,依次按照提示键入日期。日期设定后在LCD上显示全部日期信息,LED上显示时分秒。主要代码:#calendar.c#unsigned char show8

30、=0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00;/led显示数值表unsigned char time7=0x01;/秒,分,时,日,星期,月,年(BCD码)/*-函数说明:软件设定时间:秒,分,时,日,星期,月,年,BCD码-*/void set_time(unsigned char *time)LCD_clear();LCD_setcursol(0,0);LCD_puts(Set year(099):);LCD_setcursol(0,1);time6=NUM2BCD(unsigned char)(GetDec();LCD_clear();LCD_setc

31、ursol(0,0);LCD_puts(Set month(112):);LCD_setcursol(0,1);time5=NUM2BCD(unsigned char)(GetDec();LCD_clear();LCD_setcursol(0,0);LCD_puts(Set day:);LCD_setcursol(0,1);time3=NUM2BCD(unsigned char)(GetDec();LCD_clear();LCD_setcursol(0,0);LCD_puts(Set weekday(06):);LCD_setcursol(0,1);time4=NUM2BCD(unsigned

32、 char)(GetDec();LCD_clear();LCD_setcursol(0,0);LCD_puts(Set hour(023):);LCD_setcursol(0,1);time2=NUM2BCD(unsigned char)(GetDec();LCD_clear();LCD_setcursol(0,0);LCD_puts(Set minute(059):);LCD_setcursol(0,1);time1=NUM2BCD(unsigned char)(GetDec();LCD_clear();LCD_setcursol(0,0);LCD_puts(Set second(059):);LCD_setcursol(0,1);

温馨提示

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

最新文档

评论

0/150

提交评论