当前位置:文档之家› 西安交通大学电子系统设计专题实验.(DOC)

西安交通大学电子系统设计专题实验.(DOC)

电子系统设计专题实验报告实验一、基于 AVR ATMega128 的硬件(PCB)设计 一、 实验目的和要求目的: (1)掌握印制电路板设计的基本原则及印制电路板的设计制作流程。

(2)掌握 Protel DXP 2004 SP2 软件的基本功能。

(3)在 Protel DXP 2004 SP2 软件平台,完成电路图到 PCB 图的设计制作过 程。

要求: (1)根据实验要求, 完成原理图的设计,并在 Protel DXP 2004 SP2 软件平台 上设计制作出相应的 PCB 图。

(2)要求 PCB 图布局布线美观,抗干扰性能强。

图中所用到的元件封装必须 符合实际的元件尺寸。

二、 实验设备及设计开发环境操作系统: XP 软件:Protel DXP 2004 SP 2三、 实验内容根据 ATMega128 的电路图设计一个单片机电路板,其中包括基本电路、复位 电路、时钟振荡器(ISP、键盘、RT Clock)。

MCU 原理图如图四、 实验步骤1. 创建新的工程项目,并新建原理图图纸 2. 设置工程参数,包括基本原理图参数设置。

3. 绘制原理图:在元件库中查找所用元件,并进行必要说明,如标签、总线、 端口等。

4. 放置各个模块与图纸合适位置,方便之后端口的对接及导入。

5. 对原理图进行电气检查,编译查错时,直至消除后保存原理图。

6. 创建新的 PCB 文件,并对 PCB 进行正确合理的参数设置(注意:在设置尺 寸时,不宜设置太小,不利于元件布局及布线),保存文件。

7. 导入原理图,将元件合理放置,原则:组合功能的元件(键盘开关)有序放 置在一起,使得各个元件布线交叉尽可能的少。

8. 对电路板自动布线,进行规则检查,注意检查 PCB 有没有缺线、缺元件的 情况修改错误的地方,并注意印刷线路的宽度设置,不宜太宽。

9. 重复步骤 8,对电路板布局不断进行修改优化,直到 PCB 的规则检查没有警告、错误,电路板元件布局思路清晰,布线方式正确合理。

10. 对工程文件进行保存,完成整个硬件设计流程。

五、 实验结果1.整体电路原理图如图2.PCB 图如下图(手动放置元件位置,自动布线):六、 实验总结硬件是设计的基础,认真学习掌握硬件设计的原理有助于更好的在软件 层面进行设计。

同时一个正确标准的项目设计方案,方便设计人员阅读的同 时,可以更高效的实现加工。

将理论上的电路原理图真真实实的做成了可以加工生产的电路板, 又一 次真切的感受到了理论与实际的联系。

电路图不再仅仅是停留在纸面和考试中 的分析对象,更是可以加工成为电路板,是设计实现实际功能的基础。

布线过程中, 看着元件之间密密麻麻的线路,也深切体会到优秀的设计对 于实际生产的重要性,对于实现的难易程度,容错能力,产品性能等多方面都 有着重大的影响。

这就要求设计人员,不仅仅是能够实现产品的功能,而是尽 可能将设计做到最好。

这也对我们学习提出了更高的要求,做一件事情不难, 难的是做好一件事情。

实验二、按键灭灯软件程序设计 一. 实验目的和任务要求根据规则要求实现按键灭灯小游戏的基本功能, 演示游戏过程并计算显示最 终游戏结果。

规则: 1. LED 灯随机地出现;每次闪一个灯; 2. 在 1s 内按键可以把灯灭掉; 3. 超时没按键或按错键,则灯换一个位置; 4. 每灭一个灯,马上会闪亮另外一个灯; 5. 计算 10 次灯的分数。

比如 按错一次 -5;超时一次-3;及时灭一次 +1-3 分。

使用 timer 来计时比较准确。

显示结果。

二. 实验设备及软件开发环境1. 单片机平台:AVR ATmega128 实验开发板; 2. 开发环境平台: 计算机,Windows XP 操作系统,软件开发平台:AVR Studio 4.16 集成开 发软件;WinAVR(GCC) 20080610 C 语言编译器; 下载编程工具:JTAGICE mkII 在线仿真器;三. 实验的电路原理1.LED 指示灯的硬件电路连接如下图所示。

2.数码管硬件电路连接如下图所示。

3.矩阵键盘硬件电路连接如图 6-1 所示。

按键灭灯程序由以上三大部分构成,将 led 灯与键盘按键编码对应起来,实现按键对 led 灯的控制,最后将总得分显示在数码管上。

软件设计的难度不大,主要在于 led 灯与键盘按键端口的对应。

四. 软件设计及关键过程分析软件设计流程图 游戏开始: 蜂鸣器提示PORTE |= (1 << PE3); 使 PA3 输出高电平,使蜂鸣器鸣叫 延迟一段时间之后关闭蜂鸣器设置中断计时器的 参数,计时时间 1s中断计时函数 SIGNAL(SIG_OUTPUT_COMPARE1A)执行换灯程序 switchLed() No 亮灯计数 count<10Yes调用函数 ledkeepping(){ PORTB = ~random[number]; }执行亮灯程序有无按键按下No中断计时 1s,进入中断函数 grade=grade+2;Yes按键是否正确No按键不正确,不加分 grade=grade+0;Yes按键正确加分 grade=grade+5;游戏结束 显示游戏总得分 grade数码管显示 PORTB = code[calculate()(number)]; 其中,calculate 函数计算相应位码显示得分五. 程序运行结果1.根据随机数组 random[10]使得 led 灯“随机”亮起2.十次亮灯结束,数码管显示总得分六. 实验总结软件编程设计的难度不大,关键在于如何使得 led 灯与键盘按键端口对应, 并实现按键正确时将对应的 led 灯“灭掉”。

具体实现时,采取当按键正确就切 换到下一个随机 led 灯, 而不是去改变按键对应的 led 灯的端口值,一定程度上 使得问题简化。

程序采用将学过的知识模块联合, 主要由 led 灯, 键盘, 数码管三部分构成。

实验中也发现了一些问题: 当按键时间过长时,可能使得下一个 led 灯亮时也判断到了该按键已经按 下,错误的记录下该按键,得分记录不准确。

处理思路: 当下一个 led 灯亮起, 且判断到有按键按下时, 判断按键是否与之前按键编 码相同,如果不同,则为一次独立的按键;如果相同,则为上一个 led 灯的延迟 按键,需重新对键盘进行一次 scan。

附录 1 软件源代码#include <avr/io.h> #include <util/delay.h> #include <stdio.h> #include <avr/signal.h> #include "digitron.h" #define LINE1_SCAN() PORTC = (PORTC | _BV(PC7)) & ~_BV(PC6) #define MASK 0xFF #include "led.h" uint8_t code[10] = { 0xC0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8, 0x80,0x90 }; uint8_t random[11] = { 0x01,0x04,0x02,0x10,0x40,0x80,0x02,0x08, 0x80,0x20,0x40 }; uint8_t led_sel=0x01; int number=1,grade=0,count=0; int com = 1; void system_init() //系统初始化 { //关闭 8 个 LED 灯 DDRB = 0xff; //设置 PB 端口为输出 DDRC |= _BV(PC5); //设置 PC5 为输出 PORTC |= _BV(PC5); //置 PC5 为高电平,使能 led 锁存 PORTB = 0xff; PORTB = PB_MASK; DDRB = PB_MASK; PORTC |= _BV(LED_CS); DDRC |= _BV(LED_CS); //关闭数码管显示 DDRG |= _BV(PG3); //设置 PG3 为输出,PG3 控制数码管的位选择锁存器; DDRG |= _BV(PG4); //设置 PG4 为输出,PG4 控制数码管的段码锁存器; PORTG |= _BV(PG3); //使能数码管位选择锁存器 PORTG &= ~_BV(PG4); PORTB = 0x00; //关闭字型码锁存器 DDRB = 0xff; //设置端口 PB 为输出 //送数码管位码 //关闭 8 个 led 灯 PORTC &= ~_BV(PC5); //PC5 置低,关闭 led 锁存器器PORTG &= ~_BV(PG3); //关闭数码管位选择锁存器PORTG |= _BV(PG4); //使能段码锁存器PORTB = 0xff; //送段码PORTG &= ~_BV(PG4); //关闭段码锁存器//关闭蜂鸣器DDRE |= _BV(PE3);PORTE |= _BV(PE3); //喇叭电路断开,喇叭停止鸣响}void DIG_Init(){PORTB = ~PB_MASK;DDRB = PB_MASK;PORTG &= 0x00;DDRG |= _BV(DIG_CS1) | _BV(DIG_CS2);}void KP_Init(){// CHIP_Init();系统端口初始化DDRB = 0xFF;DDRC = 0xFF;DDRD = 0xFF;DDRE = 0xFF;DDRF = 0xFF;DDRG = 0xFF;PORTD = 0x00;PORTE = 0x08;PORTF = 0x00;PORTC |= 0x20;PORTB = 0xFF;PORTC = 0x02;PORTG |= 0x18;PORTB = 0x00;PORTG = 0x00;// 键盘端口初始化PORTC &= 0x3F;DDRC |= 0xC0;PORTB = 0xFF;DDRB = 0x00;uint8_t KP_read(){_delay_ms(10);asm("nop");uint8_t read = PINB;return read;}uint8_t KP_scan(){uint8_t code = MASK;uint8_t key = MASK;//scan the first lineLINE1_SCAN();LINE1_SCAN();code = KP_read();if(code != MASK){_delay_ms(10);code = KP_read();if(code != MASK){switch(code){case 0xFE:key = 0x01;break; case 0xFD:key = 0x02;break; case 0xFB:key = 0x04;break; case 0xF7:key = 0x08;break; case 0xEF:key = 0x10;break; case 0xDF:key = 0x20;break; case 0xBF:key = 0x40;break; case 0x7F:key = 0x80;break; }}}//if no key is pressed, return 0x00 return key;}void LED_Init(){PORTB = PB_MASK;DDRB = PB_MASK;PORTC |= _BV(LED_CS);DDRC |= _BV(LED_CS);}int calculate(int number){switch (number){case 0:return grade/10;break;case 1:return grade%10;break;default:return 10;}}//亮灯程序不变k;void ledkeepping(){LED_Init();PORTB = ~random[number];_delay_ms(5);}//亮灯程序void switchLed(){TCNT1H = 0x00; //T/C1计数值清零 TCNT1L = 0x00;LED_Init();PORTB = ~random[number];number=number+1;count=count+1;_delay_ms(5);if(number==10){number=1;}if(count>10){TCCR1B = 0x00;}}//中断程序SIGNAL(SIG_OUTPUT_COMPARE1A){TCNT1H = 0x00; //T/C1计数值清零TCNT1L = 0x00;grade=grade+2;switchLed();}void DIG_Dispaly();{com=1;for(number = 0; number < 2; number++){PORTG |= _BV(DIG_CS2);PORTG &= ~_BV(DIG_CS1);PORTB = code[calculate()(number)];PORTG |= _BV(DIG_CS1);PORTG &= ~_BV(DIG_CS2);PORTB = com;com *= 2;PORTG &= ~_BV(DIG_CS1);PORTG &= ~_BV(DIG_CS2);_delay_ms(2);}}int main(void){system_init(); //系统初始化PORTE |= (1 << PE3); //使PA3输出高电平,使蜂鸣器鸣叫_delay_ms(100);_delay_ms(100);PORTE |= (1 << PE3); //使PA3输出高电平,使蜂鸣器不响TCCR1B = 0x00; //中断控制寄存器清零,停止T/Cl计数OCR1AH = 0xAA; //设置8MHz、256分频、定时1s的比较值,OCR1AL = 0x12; //与TCNTl的计数值进行比较,若匹配产生中断 TCCR1A = 0x00; //T/C1普通端口模式TCCR1B = 0x04; //启动定时器T/C1,256分频TIMSK |= 0x10; //使能C/Tl比较匹配中断sei(); //允许全局中断while(1){if(count<10){KP_Init();uint8_t led_press,led_temp;led_press=KP_scan();ledkeepping();KP_Init();led_temp=KP_scan();if(led_press!=MASK){if(led_press!=led_temp){if(led_press==random[number]) {grade=grade+5;}else{grade=grade+0;}switchLed();_delay_ms(5);}}else{ledkeepping();_delay_ms(1);}}else{DIG_Init();//数码管初始化DIG_Dispaly();//数码管显示得分}}}。

相关主题