欢迎来到三一文库! | 帮助中心 三一文库31doc.com 一个上传文档投稿赚钱的网站
三一文库
全部分类
  • 研究报告>
  • 工作总结>
  • 合同范本>
  • 心得体会>
  • 工作报告>
  • 党团相关>
  • 幼儿/小学教育>
  • 高等教育>
  • 经济/贸易/财会>
  • 建筑/环境>
  • 金融/证券>
  • 医学/心理学>
  • ImageVerifierCode 换一换
    首页 三一文库 > 资源分类 > DOC文档下载  

    单片机原理与应用课程设计-设计并实现两路相位可调方波信号发生器.doc

    • 资源ID:3262412       资源大小:1.18MB        全文页数:46页
    • 资源格式: DOC        下载积分:6
    快捷下载 游客一键下载
    会员登录下载
    微信登录下载
    三方登录下载: 微信开放平台登录 QQ登录   微博登录  
    二维码
    微信扫一扫登录
    下载资源需要6
    邮箱/手机:
    温馨提示:
    用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP免费专享
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    单片机原理与应用课程设计-设计并实现两路相位可调方波信号发生器.doc

    武汉理工大学单片机原理与应用课程设计课程设计任务书学生姓名: 专业班级: 电信0806 指导教师: 工作单位: 信息工程学院 题目: 单片机原理与应用课程设计设计并实现两路相位可调方波信号发生器 初始条件:(1)Proteus仿真软件或XL1000综合仿真试验仪一台;(2)先修课程:微机原理与接口技术、单片机原理。要求完成的主要任务: (包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)输出两路方波信号,键盘控制频率和两信号的相位差,频率范围和变化步长值自定,相位03600,相位差变化步长值自定。用双踪示波器观察。(能做到频率和相位差两参数独立变化更好)。具体完成以下任务:1. 完成系统的方案设计,给出系统框图。2. 完成系统的硬件设计,给出硬件电路图和系统资源分配表。3. 完成系统的软件设计,给出程序流程图和程序清单。4. 运用Proteus仿真软件对所设计的系统进行调试和仿真,直到预定的功能全部仿真通过,给出仿真结果;如果条件允许,将程序下载到XL1000综合仿真试验仪,验证系统功能。5. 对所设计的系统进行性能分析(精度、实用性、成本等)。6. 完成课程设计报告。时间安排:总体设计和硬件设计 二天软件设计 一天调试 一天写报告,答辩 一天参考书目:1 李群芳、 张士军,单片微型计算机与接口技术, 电子工业出版社,20082 张毅刚、彭喜元、董继成,单片机原理及应用,高等教育出版社,20043 赵晓安,MCS-51单片机原理及应用,天津大学出版社,2001指导教师签名: 年 月 日系主任(或责任教师)签名: 年 月 日目录1 总体设计31.1 目标要求31.2设计方案比较31.3系统方框图42硬件设计52.1单片机概述52.1.1 80C51引脚说明62.2最小系统设计82.3 数码管显示电路83.软件设计93.1 软件设计思想93.2 主控程序设计93.2.1主程序设计思想93.2.2主程序设计流程图103.2.3主控程序113.3 计算溢出次数子程序设计153.3.1计算溢出次数子程序设计主要思想153.3.2计算溢出次数子程序设计流程图163.3.3 计算溢出次数子程序163.3 定时器中断1程序设计173.3.1 定时器1程序设计思想173.3.2定时器中断0程序设计流程图183.3.3 定时器1程序183.4 定时器中断0程序设计203.4.1 定时器中断0程序设计流程图203.4.2定时器中断0程序203.5 程序清单214系统调试和制作334.1调试工具keil说明334.2调试内容334.2.1 中断程序运行时间调试334.2.2 测试相位变化时的输出334.2.3 调试工具调试总结334.3 整体制作344.3.1 仿真软件介绍344.3.2 仿真及实物制作过程344.3.3 仿真整体电路图344.3.4 运行结果显示364.3.5 运行结果说明405 性能分析415.1 主要性能介绍415.2 误差分析416 心的与体会427 参考文献44两路相位可调方波信号发生器1 总体设计1.1 目标要求用单片机产生两路频率相位可调的方波信号。输出方波的频率范围为1Hz-200Hz,频率误差比小于0.5%。要求用“增加”、“减小”2个按钮改变方波给定频率,按钮每按下一次,给定频率改变的步进步长为1Hz,当按钮持续按下的时间超过2秒后,给定频率以10次/秒的速度连续增加(减少),输出方波的频率要求在数码管上显示。相位最小步进值为1度,也可以行10度步进,且可以进行左移,右移。开机默认输出频率为5Hz。1.2设计方案比较两路相位可调方波信号发生器中可以有两种思路来产生方波信号,其一是利用延时来实现,其二是利用51单片机自带的定时器来实现。如果使用延时来控制,一是容易产生误差;二是相位调节会有诸多不变。而利用51单片机自带的定时器不仅可以产生精确的定时而且还可以通过控制定时器的工作来产生相位差。基于此,此次课程设计选用方案二,即利用定时器来实现方波输出,相位变化。1.3系统方框图2硬件设计2.1单片机概述单片微型计算机(Single-Chip Microcomputer),简称单片机。就是将微处理器(CPU)、存储器(存放程序或数据的ROM和RAM)、总线、定时器/计数器、输入/输出接口(I/O口)和其他多种功能器件集成在一块芯片上的微型计算机。本次课程设计选用的是MCS-51系列单片机中的80C51。MCS-51单片机包含中央处理器(CPU)、程序存储器(ROM)、数据存储器(RAM)、定时器/计数器、并行I/O接口、串行I/O接口和中断系统等几大单元。其内部结构框图如图1所示。 图1 51内部系统结构中央处理器由运算器、控制器组成。8051的CPU包含以下功能部件: (1)8位CPU。(2)布尔代数处理器,具有位寻址能力。(3)128B内部RAM数据存储器,21个专用寄存器。(4)4KB内部掩膜ROM程序存储器。(5)2个16位可编程定时器/计数器。(6)32位(4×8位)双向可独立寻址的I/O口。(7)1个全双工UART(异步串行通信口)。(8)5个中断源、两级中断优先级的中断控制器。(9)时钟电路,外接晶振和电容可产生1.2MHz12 MHz的时钟频率。(10)外部程序/数据存储器寻址空间均为64KB。(11)111条指令,大部分为单字节指令。(12)单一+5V电源供电,双列直插40引脚DIP封装。内部结构如图2所示图2 51内部结构MCS-51单片机中有两个16位的定时器/计数器T0和T1,它们由4个8位寄存器(TL0, TH0, TL1和TH1)组成,2个16位定时器/计数器是完全独立的。可以单独对这4个寄存器进行寻址,但不能把T0和T1当做16位寄存器来使用。2.1.1 80C51引脚说明MCS-51系列单片机中的8031、8051及8751均采用40Pin封装的双列直接DIP结构,右图是它们的引脚配置,40个引脚中,正电源和地线两根,外置石英振荡器的时钟线两根,4组8位共32个I/O口,中断口线与P3口线复用。现在我们对这些引脚的功能加以说明。MCS-51系列单片机中的8031、8051及8751均采用40Pin封装的双列直接DIP结构,右图是它们的引脚配置,40个引脚中,正电源和地线两根,外置石英振荡器的时钟线两根,4组8位共32个I/O口,中断口线与P3口线复用。现在我们对这些引脚的功能加以说明。如图5所示。图5 51单片机引脚图Pin9:RESET/Vpd复位信号复用脚,当80C51通电,时钟电路开始工作,在RESET引脚上出现24个时钟周期以上的高电平,系统即初始复位。初始化后,程序计数器PC指向0000H,P0-P3输出口全部为高电平,堆栈指针写入07H,其它专用寄存器被清“0”。RESET由高电平下降为低电平后,系统即从0000H地址开始执行程序。然而,初始复位不改变RAM(包括工作寄存器R0-R7)的状态,80C51的初始态。80C51的复位方式可以是自动复位,也可以是手动复位,见下图4。此外,RESET/Vpd还是一复用脚,Vcc掉电其间,此脚可接上备用电源,以保证单片机内部RAM的数据不丢失。Pin30:ALE/当访问外部程序器时,ALE(地址锁存)的输出用于锁存地址的低位字节。而访问内部程序存储器时,ALE端将有一个1/6时钟频率的正脉冲信号,这个信号可以用于识别单片机是否工作,也可以当作一个时钟向外输出。更有一个特点,当访问外部程序存储器,ALE会跳过一个脉冲。如果单片机是EPROM,在编程其间,将用于输入编程脉冲。Pin29:当访问外部程序存储器时,此脚输出负脉冲选通信号,PC的16位地址数据将出现在P0和P2口上,外部程序存储器则把指令数据放到P0口上,由CPU读入并执行。Pin31:EA/Vpp程序存储器的内外部选通线,8051和8751单片机,内置有4kB的程序存储器,当EA为高电平并且程序地址小于4kB时,读取内部程序存储器指令数据,而超过4kB地址则读取外部指令数据。如EA为低电平,则不管地址大小,一律读取外部程序存储器指令。显然,对内部无程序存储器的8031,EA端必须接地。2.2最小系统设计51单片机最小系统需要一个时钟电路和一个复位电路,如果P0口用作I/O口的话,还需要在P0口加上10K的上拉电阻。复位电路与时钟电路见图6。图6 常见的复位与时钟电路2.3 数码管显示电路由于51单片机I/O口驱动能力有限,无法直接驱动数码管,所以加入一块驱动芯片74HC244。加入74HC244后可以直接驱动数码管显示。此处使用数码管动态显示,P0口控制数码管段选,P2.0P2.2进行P2口的位选。如图7图7数码管显示电路3.软件设计3.1 软件设计思想任务分析:方波信号的产生实质上就是在定时器溢出中断次数达到规定次数时,将输出I/O管脚的状态取反。由于频率范围最高为200Hz,即每个周期为5ms(占空比1:1,即高电平2.5ms,低电平2.5 ms),开始时由于将过多程序放在中断中运行造成时间过长而无法使用8位自动重装模式提高精度,在经过修改后两个定时器中断均采用8为自动重装模式进行定时。    涉及以下几个方面的问题:按键的扫描、功能键的处理、计时功能以及数码管动态扫描显示等。问题的难点在按键连续按下超过2S的计时问题及如何跟踪当前频率进行相位变化等问题    系统的整体思路:主程序在初始化变量和寄存器之后,扫描按键,根据按键的情况执行相应的功能,然后在数码显示频率的值,显示完成后再回到按键扫描,如此反复执行。定时器1中断程序主要用来方波的产生、按键连续按下超过2S后频率值以10Hz/s递增(递减)。定时器0用来产生第二路的方波及进行第二路与第一路的相位变化。3.2 主控程序设计 3.2.1主程序设计思想主程序完成对按下各键对应的功能的实现,其中对于键盘检测中最麻烦的地方在于如何检测此键是否为长时间按下及如何进行相位变化处理。此处采用用当前值和上一次按键值相比较的方法来检测是否为长时间按下某键。处理相位变化时,当相位差超过180度时要设置一路二路反向输出标志。 3.2.2主程序设计流程图 3.2.3主控程序void main()init(); while(1) key_val=scan_key(); /扫描按键if(key_val=2) init();else if(key_val=3) N=N+0.00555;if(N>=1&&flag=1)flag=0;N=0.000001;else if(N>1)flag=1;N=N-1;xw_show=xw_show+1;if(xw_show>360)xw_show=0; else if(key_val=4) N=N+0.05555;if(N>=1&&flag=1)flag=0;N=0.0000001;else if(N>=1)flag=1;N=N-1;/elsexw_show=xw_show+10;if(xw_show>360)xw_show=0; else if(key_val=5) if(N<0.26&&flag=0)N=0.000000001;xw_show=0;else if(N<1&&flag=0)N=N-0.25;xw_show=xw_show-45;if(N<0.25&&flag=1)flag=0;N=1.000000001-(0.25-N);xw_show=xw_show-45;if(N<1&&flag=1)N=N-0.25;xw_show=xw_show-45; else if (key_val!=key_val_old) /说明有键按下或弹起 key_val_old=key_val; if (key_val!=255) /说明键按下 state_val=0; /清除连续按键标志 sec_over_num=0; switch (key_val) case 0: /增1键if(hz_shu<200) hz_shu+;elsehz_shu=200; T1_over_num=get_T1_over_num(hz_shu); break; case 1: /减1键 if(hz_shu>=2) hz_shu-; else hz_shu=1; T1_over_num=get_T1_over_num(hz_shu); break; else /说明键弹起 state_val=0; second=0; else /一直按下或弹起 if (key_val!=255) state_val=1; /连续按键 else state_val=0; /没有按键按下,一直处于弹起状态 if(state_val=1&&second>=2&&sec_over_num>=5000)/连续按键且超过一秒 / TR1=0; sec_over_num=0; switch (key_val) case 0: if(hz_shu<190) hz_shu=hz_shu+10; /增10Hz/秒 else hz_shu=200; T1_over_num=get_T1_over_num(hz_shu); break; case 1: if(hz_shu>10) hz_shu=hz_shu-10; /减10/秒 else hz_shu=1; T1_over_num=get_T1_over_num(hz_shu); break; / TR1=1; led_show(); /数码管显示,动态扫描 T2_over_num=get_T2_over_num(hz_shu); 3.3 计算溢出次数子程序设计3.3.1计算溢出次数子程序设计主要思想 主要使用了C51有专门的库文件MATH.H里面一个个函数它是这样定义的extern float modf(float x, float *ip)调用它之后,整数部分被放入*ip, 小数部分作为返回值。这样就可以进行四舍五入的判断,减小计算溢出次数的误差。3.3.2计算溢出次数子程序设计流程图3.3.3 计算溢出次数子程序(1)计算当前频率下的溢出次数unsigned int get_T1_over_num(unsigned char p) /p为频率数unsigned int *k,h; double f; f=(double)p; /转化为浮点数 f=0.5/f; /半个周期的时间 f=f/0.0002; /中断溢出数=f/0.00025; h=f; /取整/四舍五入 if (modf(f,k)>=0.5) h=h+1; return h;(2)计算当前频率下的改变固定相位的溢出次数unsigned int get_T2_over_num(unsigned char p) /p为频率数 int *s,h; double l; l=(double)p; /转化为浮点数 l=N*0.5/l; /选取相位的时间 l=l/0.000055; / h=l; /取整/四舍五入 if (modf(l,s)>=0.5) h=h+1; return h;3.3 定时器中断1程序设计3.3.1 定时器1程序设计思想 主要完成一路方波信号的产生,并对长按键是的计时。为避免两个定时器中断冲突,且能够产生相位差,所以定时器0的中断在定时器1中开启。3.3.2定时器中断0程序设计流程图3.3.3 定时器1程序void timer1() interrupt 3 /T1中断 T1_cnt+;if(T1_cnt>T1_over_num) /半周期的计数到达 T1_cnt=0; pulse_out=pulse_out;/反复取反,产生方波 ET0=1;TR0=1; if(state_val=1)/连续按键 if (sec_over_num<5000) /计时未到1s sec_over_num+; else /计时到1s时,执行else的代码 if(second<2) /当超过2秒,second一直为2,直到松开按键 second+; /连续按下键少于2秒时,second继续增1。 3.4 定时器中断0程序设计3.4.1 定时器中断0程序设计流程图3.4.2定时器中断0程序void timer0() interrupt 1T2_cnt+;if(T2_cnt>T2_over_num)T2_cnt=0;if(flag=0) pulse_out1=pulse_out;else pulse_out1=pulse_out;ET0=0;TR0=0;3.5 程序清单/*变量的定义: hz_shu: 设定的频率数 T1_over_num: 根据设定频率计算后的,定时器溢的出次数值 T1_cnt: 定时器计数溢出数 sec_over_num: 计算1s内的计数 second: 连续按键的计时 state_val: 连续按下的标志 0=按键已经弹起;1=按键一直按下去 led_seg_code: 数码管7段码*/#include "reg51.h"#include "math.h"sbit pulse_out=P30;sbit pulse_out1=P31;/-unsigned char data hz_shu,second,key_val,key_val_old,yanshi=1,flag;unsigned int data sec_over_num,xw_show;double N=0.000000001; int data T1_cnt,T1_over_num,T2_cnt,T2_over_num;unsigned char data state_val; char code led_seg_code10=0x3f,0x06,0x05b,0x04f,0x66,0x6d,0x7d,0x07,0x7f,0x6f;/led_seg_code0-9代表0-9的7段码void led_show();/-void delay(unsigned int i)/延时 unsigned int j,k; for(k=i;k>0;-k)for(j=110;j>0;-j);/-unsigned char scan_key() unsigned char i,k; i=P1; if (i=0xff) k=255; /无键按下 else /有键按下 led_show(); /延时去抖动 if(i!=P1) k=255; else switch (i) case 0xfe: k=0; break; / case 0xfd: k=1; break; case 0xfb: k=2; break; case 0xf7: k=3; break; case 0xef: k=4; break; case 0xdf: k=5; break; if(k=2|k=3|k=4|k=5) while(P1!=0xff) led_show ; /只有按下复位和相位移动式进行松手检测 return k;/-void led_show()unsigned char i,j;i=hz_shu%10; /显示个位P0=led_seg_codei;P2=0xfe;delay(5);i=hz_shu%100/10; /显示十位P0=led_seg_codei;P2=0xfd;delay(5);i=hz_shu%1000/100; /显示百位P0=led_seg_codei;P2=0xfb;delay(5);j=xw_show%10; /显示个位P0=led_seg_codej;P2=0xdf;delay(5);j=xw_show%100/10; /显示十位P0=led_seg_codej;P2=0xbf;delay(5); /显示百位j=xw_show/100;P0=led_seg_codej;P2=0x7f;delay(5);/-/unsigned int get_T2_over_num(unsigned char p) /p为频率数 int *s,h; double l; l=(double)p; /转化为浮点数 l=N*0.5/l; /延时四分之一个周期的时间 l=l/0.000055; / h=l; /取整/四舍五入 if (modf(l,s)>=0.5) h=h+1; return h;/unsigned int get_T1_over_num(unsigned char p) /p为频率数unsigned int *k,h; double f; f=(double)p; /转化为浮点数 f=0.5/f; /半个周期的时间 f=f/0.0002; /中断溢出数=f/0.00025; h=f; /取整/四舍五入 if (modf(f,k)>=0.5) h=h+1; return h;/* C51有专门的库文件MATH.H,里面有个函数 它是这样定义的extern float modf(float x, float *ip); 调用它之后,整数部分被放入*ip, 小数部分作为返回值。*/-void timer1() interrupt 3 /T1中断 T1_cnt+;if(T1_cnt>T1_over_num) /半周期的计数到达 T1_cnt=0; pulse_out=pulse_out;/反复取反,产生方波 ET0=1;TR0=1; if(state_val=1)/连续按键 if (sec_over_num<5000) /计时未到1s sec_over_num+; else /计时到1s时,执行else的代码 if(second<2) /当超过2秒,second一直为2,直到松开按键 second+; /连续按下键少于2秒时,second继续增1。 /-void init()pulse_out=0; /初始化各变量 pulse_out1=0; N=0.000001; flag=0; hz_shu=5; xw_show=0; T1_cnt=0; T2_cnt=0; state_val=0; second=0; sec_over_num=0; T1_over_num=get_T1_over_num(hz_shu); /初始化51的寄存器 TMOD=0x22;/用T1,T0计时 T1,T0为8位自动重装方式。 TH1=0x38; TL1=0x38; TH0=0xc9; /0.7ms 55=(256-x)*12/12 -> x=c9 TL0=0xc9; EA=1; /开中断 ET1=1;/ TR0=1; TR1=1; /定时器T1void main()init(); while(1) key_val=scan_key(); /扫描按键if(key_val=2) init();else if(key_val=3) N=N+0.00555;if(N>=1&&flag=1)flag=0;N=0.000001;else if(N>1)flag=1;N=N-1;xw_show=xw_show+1;if(xw_show>360)xw_show=0; else if(key_val=4) N=N+0.05555;if(N>=1&&flag=1)flag=0;N=0.0000001;else if(N>=1)flag=1;N=N-1;xw_show=xw_show+10;if(xw_show>360)xw_show=0; else if(key_val=5) if(N<0.26&&flag=0)N=0.000000001;xw_show=0;else if(N<1&&flag=0)N=N-0.25;xw_show=xw_show-45;if(N<0.25&&flag=1)flag=0;N=1.000000001-(0.25-N);xw_show=xw_show-45;if(N<1&&flag=1)N=N-0.25;xw_show=xw_show-45; else if (key_val!=key_val_old) /说明有键按下或弹起 key_val_old=key_val; if (key_val!=255) /说明键按下 state_val=0; /清除连续按键标志 sec_over_num=0; switch (key_val) case 0: /增1键if(hz_shu<200) hz_shu+;elsehz_shu=200; T1_over_num=get_T1_over_num(hz_shu); break; case 1: /减1键 if(hz_shu>=2) hz_shu-; else hz_shu=1; T1_over_num=get_T1_over_num(hz_shu); break; else /说明键弹起 state_val=0; second=0; else /一直按下或弹起 if (key_val!=255) state_val=1; /连续按键 else state_val=0; /没有按键按下,一直处于弹起状态 if(state_val=1&&second>=2&&sec_over_num>=5000)/连续按键 / TR

    注意事项

    本文(单片机原理与应用课程设计-设计并实现两路相位可调方波信号发生器.doc)为本站会员(李主任)主动上传,三一文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知三一文库(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    经营许可证编号:宁ICP备18001539号-1

    三一文库
    收起
    展开