dsp课程设计报告--TMS320C5416的信道编码器设计 本文关键词:信道,编码器,课程设计,报告,设计
dsp课程设计报告--TMS320C5416的信道编码器设计 本文简介:嵌入式系统A(DSP)课程设计报告题目TMS320C5416的信道编码器设计学院自动化与电气工程学院专业班级学号学生姓名任课教师完成日期摘要摘要循环码是一种系统码,通常前K位是信息码元,后R位是监督码元。它除具有线性分组码的一般性质外,还具有循环性,也据好循环性,也就是说当循环码中的任一码组循环移动
dsp课程设计报告--TMS320C5416的信道编码器设计 本文内容:
嵌入式系统A(DSP)
课程设计报告
题
目
TMS320C5416的信道编码器设计
学
院
自动化与电气工程学院
专业班级
学
号
学生姓名
任课教师
完成日期
摘要
摘
要
循环码是一种系统码,通常前K位是信息码元,后R位是监督码元。它除具有线性分组码的一般性质外,还具有循环性,也据好循环性,也就是说当循环码中的任一码组循环移动一位后,所的的码组仍为该循环码的一个准用码组。它是在严密的代数基础上建立起来的,具有许多特殊代数的性质,因此有助于按照所要求的纠错能力系统的构成这类码,并且简化译码方法。循环码还具易实现的特点,编码和译码的设备都不太复杂,而且性能良好,不仅能纠正独立的随机错误,也能纠正突发错误。本课程设计主要介绍了循环码的特点以及循环码的编、译码原理在DSP课程设计中,系统应用平台为TIC5416芯片,使用CCS软件,通过正确编写并运行程序,进行仿真,使得运行结果与理论分析一致,实现设计目的。
关键词
DSP;循环码;编码;译码;CCS;仿真
目
录
摘要………………………………………………………………….………………….1
1
引言………………………………………………………………………………………3
1.1
选题的背景与意义…………………….………………………….………………4
1.2
TMS320C5416DSP及开发系统的特点………………………………………….4
1.3
TMS320C5416DSP在音频处理领域中的应用…………………………………4
参考文献…………………………………………………………………………….….5
2
整体设计……………………………………………………….…………………………5
2.1整体方案的选择………………………………………………………….………5
2.2各模块功能的概述…………………………………………………….…….……6
3具体模块(或硬件/软件/程序)分析…………………………….…………….9
3.1
生成多项式和循环码的生成矩阵……………………………….………………8
3.2
系统原理图……………………………………………………………….9
4系统调试及运行结果……………………………………………………………10
5
设计总结与展望………………………………………………………………………….13
1
引言
循环码是线性分组码中最重要的一种子类,是目前研究得比较成熟的一类码。循环码具有许多特殊的代数性质,这些性质有助于按照要求的纠错能力系统地构造这类码,并且简化译码算法,并且目前发现的大部分线性码与循环码有密切关系。循环码还有易于实现的特点,很容易用带反馈的移位寄存器实现其硬件。正是由于循环码具有码的代数结构清晰、性能较好、编译码简单和易于实现的特点,因此在目前的计算机纠错系统中所使用的线性分组码几乎都是循环码。它不仅可以用于纠正独立的随机错误,而且也可以用于纠正突发错误。它具有下面性质:1、封闭性(线性性)。任何许用码组的线性和还是许用码组。由此性质可以知线性码都是全零码,且最小码距就是码重。2、循环性。任何许用的码组循环移位后的码组还是许用码组。3、每个信息码组长度k=3,则有23=8个不同的信息码组。4、每个信息组加四个监督码元,信息码C6
C5
C4
监督码C3
C2
C1
C0
例如:
则这组码元称为(7,3)线性分组码上式可以完整地表示为:
C6=1*C6+0*C5+0*C4
C5=0*C6+1*C5+0*C4
C4=0*C6+0*C5+0*C4
C3=1*C6+0*C5+1*C4
C2=1*C6+1*C5+1*C4
C1=1*C6+1*C5+0*C4
C0=0*C6+1*C5+1*C4
本课程实际主要是通过仿真纠错编码系统(开发平台为TIC5416芯片)。对输入随机数字信号进行循环纠错编码后,送入含噪信道,在接收端再进行解码和检纠错,改变信道误码率大小,测试接收信号与发送信号之间的误码率,分析该种纠错编码系统的抗噪声性能。模型设计应该符合工程实际,模块参数设置必须与原理相符合,处理结果和分析结论应该一致,而且应符合理论。
1.1
选题的背景与意义
综合运用我们所学过的知识,以达到巩固所学知识,提高我们思考问题、分析问题和解决问题能力的目的。进一步学习了循环码编、译码原理,循环码要通过DSP实现编写程序,仿真出循环码编码前和译码后,以及纠错后的波形了解信道编码技术,学习使用CCS5000实验了解DSP中.asm,以及.cmd文件的使用方法的基本功能。
1.2
TMS320C5416DSP及开发系统的特点
TMS320C5416DSP芯片,是一种低功耗、高性能的定点DSP芯片。它的主要特点有:运算速度快,可达160
MIPS。优化的CPU结构:内部有1个40位的算术逻辑单元(ALU)、2个40位的累加器、2个40位的加法器、1个乘法器和1个40位的桶型移位器、有4条内部总线和2个地址发生器。多总线结构:包括3条独立的16位数据总线和1条23位的地址总线。低功耗方式:TMS320C5416DSP可以在3.3
V,1.6
V的低电压下工作,3种低功耗方式(IDLE1,IDLE2和IDLE3)可以节省DSP功耗。智能外设:包括软件可编程等待状态寄存器、可编程PLL时钟发生器、1个16位的计数器、6个DMA控制器、3个多通道缓冲串行口(McBSP0-2)和与外部处理器通信的HPI(Host
Post
Interface)接口。
CCS是TI推出的用于开发其DSP芯片的集成环境(IDE)。CCS是一个开放环境可以通过设置不同的驱动完成不同环境的支持,CCS
setup配置程序是用来定义DSP芯片和目标板类型。本课程设计采用的是CCS5000。
1.3在音频处理领域中的应用
DSP
技术在音频处理领域的应用越来越广。目前,在很多语音处理系统中都用到了语音录放模块,采集现场的声音并存储起来供以后回放。语音处理系统的实时性、功耗、体积、以及对语音信号的保真度都是很影响系统性能的关键因素。
参考文献
[1]
王金龙.DSP设计与实验教程.机械工业出版社,2007
[2]
周霖.DSP通信工程技术应用.国防工业出版社,2004
[3]
曹志刚,钱亚生.现代通信原理.清华大学出版社,1992
[4]
苗长云等主编.现代通信原理及应用.电子工业出版社,2005
[5]
桑林,郝建军,刘丹.数字通信.北京邮电大学出版社,2002
[6]
樊昌信,曹丽娜.通信原理.国防工业出版社,2008
2
整体设计
2.1整体方案的选择
算法模拟阶段。在这一阶段主要是根据设计任务确定系统的技术指标。首先应根据系统需求进行算法仿真和高级语言
(如MATLAB)模拟实现,以确定最佳算法,并初步
确定相应的参数。
DSP
芯片及外围芯片的确定阶段。根据算法的运算速度、运算精度和存储要求等参数选择DSP
芯片及外围芯片。
软硬件设计阶段。首先按照选定的算法和DSP
芯片,对系统的哪些功能用软件实现,哪些功能用硬件实现进行初步分工。然后,根据系统技术指标要求着手进行硬件设计,完成DSP芯片外围电路和其它电路,根据系统技术指标要求和所确定的硬件编写。
硬件和软件调试阶段。硬件调试一般采用硬件仿真器进行。软件调试一般借助DSP
开发工具如软件模拟器、DSP
开发系统或仿真器进行。
系统集成和测试阶段。硬件和软件调试分别调试完成后,将软件脱离开发系统,装入所设计的系统,形成所谓的样机,并在实际系统中运行,以评估样机是否达到了所要求的技术指标。若系统测试符合指标,则样机的设计完毕。
DSP系统设计流程图
2.2各模块功能的概述
循环码概述
循环码最大的特点就是码字的循环特性,所谓循环特性是指:循环码中任一许用码组经过循环移位后,所得到的码组仍然是许用码组。若(
…
)为一循环码组,则(
…
)、(
…
)、……还是许用码组。也就是说,不论是左移还是右移,也不论移多少位,仍然是许用的循环码组。
软件模块
DSP软件发送数据
DSP软件接收数据
编码模块
为了方便对编码结果进行验证,程序使用探针(Probe
Point)从PC文件中读取比特数据,编码完成后再用探针将其写入PC文件,其(5,2)循环码的编译流程如下图。
(5,2)循环码编码流程图
(5,2)循环码译码流程图
3具体模块分析
3.1生成多项式和循环码的生成矩阵
循环码完全由其码长n和生成多项式构成。其中g(D)是一个能除尽的n-k阶多项式。阶数低于n并能被g(D)除尽的一组多项式就构成一个(n,k)循环码。也就是说,阶数小于n-1且能被g(D)除尽的每个多项式都是循环码的许用码组。
(全0码字除外)称为生成多项式,用g(x)表示。可以证明生成多项式g(x)具有以下特性:
(1)g(x)是一个常数项为1的r=n-k次多项式;(2)g(x)是Xn+1的一个因式;(3)该循环码中其它码多项式都是g(x)的倍式。
为了保证构成的生成矩阵G的各行线性不相关,通常用g(x)来构造生成矩阵,这时,生成矩阵G(x)可以表
其中,因此,一旦生成多项式g(x)确定以后,该循环码的生成矩阵就可以确定,进而该循环码的所有码字就可以确定。显然,式(8-28)不符合形式,所以此生成矩阵不是典型形式,不过,可以通过简单的代数变换将它变成典型矩阵。
(5,2)循环码的全部码字如下表:
序号
码字
信息位
a4
a3
监督位
a2
a1
a0
1
0
0
0
0
0
2
0
1
1
0
1
3
1
1
0
1
0
4
1
0
1
1
0
通过上表可以构造(5,2)循环码生成矩阵和生成多项式,这个循环码主要参数为,n=5,k=2,r=3。从表中可以看到,其生成多项式可以用第2码字构造
g(x)=x3+x2+1
G=
10110
01101
在实际循环码设计过程中,通常只给出码长和信息位数,这就需要设计生成多项式和生成矩阵,这时可以利用g(x)所具有基本特性进行设计首先,生成多项式g(x)是的一个因式,其次g(x)是一个r次因式。因此,就可以先对进行因式分解,找到它的r次因式。
3.2系统原理图
C5416它的主要特点有:运算速度快,可达160
MIPS。优化的CPU结构:内部有1个40位的算术逻辑单元(ALU)、2个40位的累加器、2个40位的加法器、1个乘法器和1个40位的桶型移位器、有4条内部总线和2个地址发生器。多总线结构:包括3条独立的16位数据总线和1条23位的地址总线。低功耗方式:TMS320C5416DSP可以在3.3
V,1.6
V的低电压下工作,3种低功耗方式(IDLE1,IDLE2和IDLE3)可以节省DSP功耗。智能外设:包括软件可编程等待状态寄存器、可编程PLL时钟发生器、1个16位的计数器、6个DMA控制器、3个多通道缓冲串行口(McBSP0-2)和与外部处理器通信的HPI(Host
Post
Interface)接口。此最小系统包括HPI主机接口,MCBSP串行接口,因为用来与外设连接,所以没有画出外设,此外包括时钟系统,电源系统,JTAG仿真接口。
最小系统原理图
4系统调试及运行结果
功能调试
一、下面介绍具体实现步骤:
1)
新建一个工程,这里假设工程所在目录以及名称为:C:/ti/myprojects/encode。
2)
新建一个.asm源文件,其源代码见附件所示,将其写入并保存在工程所在目录中。这里假设该文件所在目录及文件名称为C:/ti/myprojects/encode/encode.asm。具体的程序如下:
CRC:STM
#(DATA_ADDR),AR6
;得到输入数据的地址
LEDAR6+,A
;得到第一个数据加载到寄存器A
AND
#00FFh,A
;屏蔽到A的高位数据
LD
#AR6+,8,B
;第二个数据加载到寄存器B的高位
RPTB
CRC_ONCE_END-1
;循环开始
AND
#00FF00h,B
;屏蔽掉B的低位数据
ANDM
#00FFh,*AR6
;
ORAR6+,B
;第三个数据加载到寄存器B的低位
ADD
#TABLE_ADDR,A
;得到表格中所要数据的实际地址
READA(table_data)
LD(table_data),A
;到数据加载到寄存器A
XORA,B
;将所得到的表中数据与实际的数据异或
STM#0,B
;寄存器B的高位赋0
LD
B,_8
;将寄存器B中的高8位数据赋值给A作为新的相对地址
STEB,8
;寄存器也左移8位,空出低8位加载新数据
NOP
CRC_ONCE_END
;循环结束
3)
新建一个.cmd文件,其源代码如下,将其写入并保存在工程所在目录。这里假设该文件所在目录及文件名称为C:/ti/myprojects/encode/encode.cmd。其cmd程序如下:
encode.obj
-o
encode.out
-m
encode.
map
-e
start
MEMORY
{
PAGE
0:
VECS:origin
=
0xff80,length
=
0x80
PROG:origin
=
0x1000,length
=
0x1000
PAGE
1:
DATA:origin
=
0x2000,length
=
0x1000
STACK:origin
=
0x3000,length
=
0x1000
}
SECTIONS
{
.vectors:{}>VECS
PAGE
0
.text:{}>PROG
PAGE
0
.data:{}>DATA
PAGE
1
}
4)
将以上两个文件添加到步骤(1)所建的工程中,至此关于循环编码的工程已经建好。此时工程视图窗口应如下图所示。
循环码工程图
5)
为方便编辑,本课程设计采用的PC文件为文本文件。这里可将新建编码数据Unencode_Data.txt文件复制到工程所在目录下,作为输入使用,同时在该目录下新建一个文本文件(后缀为.txt)作为输出使用,假定其文件名con_encodebits.txt。这里需要主要的是,Unencode_Data.txt作为DSP读取的数据文件,它需要满足一定的格式,即在数据前要加入文件头,对于本例格式如下图所示。
比特数据图
6)
执行菜单命令“project”—“rebuild
all”对工程进行编译、汇编和链接,然后执行菜单命令“file”—“load
Program”,选择“encode.out”并打开,将Build生成的程序加载到DSP中,此时汇编窗口出现如图所示的标志。
7)
设置FileI/O从PC文件中读取数据,设置完成以后如图所示。
文件输入设置图
设置FileI/O从PC文件中写入数据,设置完成以后如图所示:
文件输入设置完成图
8)
运行程序,当处理完所有输入比特数据后,单击确定进入下一步。
9)
打开输入和输出数据文件以及MATLAB中生成的编码数据文件Encode_Data.txt进行对比,验证编码程序是否正确,如果所示。
编码前后对比图
5
设计总结与展望
总结和展望
通过以上内容可以实现二进制循环码编码和解码设计和仿真目的,并能在译码过程中实现数无失真的恢复原始信号。
本次课程设计在刚开始的过程中无从下手,手忙脚乱,时间又紧迫,不懂相关原理,不知道做课程设计的步骤,后来通过查看资料,先弄明白其原理,然后对照原理图建立模块,在模块建立后遇到了一些问题,但通过有效的方法,网上查找相关资料实在不懂就向老师请教,最终了解清楚此课程设计所需的算法,了解课程设计的核心部分,从而正确建立模块和设置参数,最后用理论进行验证,得到运行结果与理论结果一致。这次课程设计让我学到了很多东西,不仅锻炼了我的动手能力,加深了对循环码有关知识的了解,也使我对课程设计的流程有了一定的了解,让我深刻了解到理论联系实际的重要性,并且增加了自己的自信,这次课程设计自己独立完成,获得了成功的喜悦,同时提高了我的动手实践和组织能力,这次设计培养了我的设计思维,增加了实际操作能力,并让我收获了很多,给我很多启迪。使我受益匪浅,对我以后的工作和学习是一笔宝贵的财富。
13
篇2:Java面向对象课程设计报告画图板毕业设计(论文)
Java面向对象课程设计报告画图板毕业设计(论文)word格式 本文关键词:毕业设计,面向对象,课程设计,格式,报告
Java面向对象课程设计报告画图板毕业设计(论文)word格式 本文简介:《面向对象程序设计课程设计》指导书课程设计名称:面向对象程序设计课程设计指导老师:牛志毅课程设计周(时)数:2周指导方式:集体辅导与个别辅导相结合课程设计适用专业:信息与计算机科学课程设计教材及主要参考资料:《Java程序设计与案例》刘宝林主编,高等教育出版社服务课程名称:面向对象程序设计一、课程设
Java面向对象课程设计报告画图板毕业设计(论文)word格式 本文内容:
《面向对象程序设计课程设计》指导书
课程设计名称:面向对象程序设计课程设计
指导老师:牛志毅
课程设计周(时)数:2周
指导方式:集体辅导与个别辅导相结合
课程设计适用专业:信息与计算机科学
课程设计教材及主要参考资料:
《Java程序设计与案例》刘宝林主编,高等教育出版社
服务课程名称:面向对象程序设计
一、课程设计教学目的及基本要求
通过本课程设计,使学生了解面向对象程序的开发思想、方法和步骤,掌握开发工具的使用,提高综合运用所学的理论知识和方法独立分析和解决问题的能力,进一步提高其开发应用程序的能力。
要求明确本次课程设计所要用到的技术点并到网上搜索以及查阅相关的书籍来搜集资料。通过编写一个基于JAVA的应用系统综合实例,来掌握Java语言编程技巧。并学会编制结构清晰、风格良好的、数据结构适当的Java语言程序,从而具备解决综合性实际问题的能力。
二、设计题目及要求(二选一)
⑴
设计一个图书信息管理系统
①图书信息包括图书编号、书名、作者、出版社、出版日期、图书简介及图书类别等。
②本系统功能描述:
图书信息录入功能;
图书信息浏览功能;
查询功能(至少一种查询方式);
图书信息修改功能;
及其它你认为必要的功能。
⑵
设计一个画图软件
①用户界面友好;
②能绘制基本形状的图形;
③可设置图形的颜色、线条的粗细和填充等属性;
④可将画好的图保存至文件,并能从文件中读取。
三、设计报告的要求
设计结束后要写出课程设计报告,以作为整个课程设计评分的书面依据和存档材料。设计报告以规定格式的电子文档书写、打印并装订,排版及图、表要清楚、工整。内容及要求如下:
封面:题目、班级、姓名、学号、指导教师和完成日期。
正文包括以下7个内容:
①课题说明
以无歧义的陈述说明程序设计的任务。
②程序设计思路
简要说明程序设计的思路。
③程序源代码
给出源代码及注释。
④程序测试
给出程序主要运行界面截图。
⑤设计总结
经验和体会等。
⑥参考文献
列出参考的相关资料和书籍。
五、课程设计考核方法及成绩评定
课程设计结束时,要求学生提交课程设计报告(附源程序)及可运行的软件系统。
课程设计成绩分两部分,设计报告占50%,设计作品占50%。
附件:课程设计报告封面和参考程序。
32
湖南科技学院
课程设计报告
课程名称:
面向对象程序设计课程设计
课程设计题目:
画图板
系:
专
业:
年级、班:
姓
名:
学
号:
指导教师:
职
称:
2012年6月
1.
课题的任务和要求
设计一个画图软件
①用户界面友好;
②能绘制基本形状的图形;
③可设置图形的颜色、线条的粗细和填充等属性;
④可将画好的图保存至文件,并能从文件中读取。
2.
程序设计思路
该课题的任务是设计一个画图软件,要求能绘制基本形状的图形;同时可以设置图形的颜色、线条的粗细和是否填充等属性;并且可以将画好的图形以某种格式,比如说JPG保存至文件,并能从文件中读取某种格式的图像文件并显示出来。
首先,作为画图板,应该能够绘制基本的图形,像“铅笔“,“直线“,“矩形“,“椭圆“,”圆”,同时考虑到实用性,画图板应该能够提供橡皮擦,设置线条粗细,颜色,背景颜色的功能。在鼠标停留在按钮上时,按钮上应该提供显示提示文字,通过设置JButton的setText方法即可达到要求,在使用线条工具来绘制线条时,如果设置图形过于粗大,要求绘制出来图形能够消除锯齿,思路是在设置Graphics2D的大小时,设置Graphics2D,setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);即可达到要求
第二,考虑到平时画图时,总是喜欢按住shift来绘制45°,90°的线条,为方便用户,画图板也必须提供相应的功能,思路是判断线条的角度,如果角度大于0°同时小于45°,则绘制45°的斜线,如果线条的角度大于45°小于90°,则绘制90度的直线。
第三,关于设置背景颜色,考虑到美观,使用了渐变背景色,思路是在设置Graphics2D的背景色时,通过绘制不同透明度的条纹背景,与设置不同级别的透明度来达到绘制渐变背景色的目的。
第四,关于画图板,在提供通用的功能的同时,应该能够提供一些扩展功能,这是课程设计的一项基本要求,对于扩展功能我提供了绘制圆角矩阵,三角形,3D立方体,和绘制f(x)=A*sin(Bx)+C*cos(Cx),绘制重叠椭圆等扩展功能,绘制圆角矩阵是通过Graphics2D的drawRoundRect来实现的,而3D立方体则是通过fill3DRect实现的,而三角形是通过绘制首尾相连的三条直线来实现的。而正余弦曲线则完全是通过计算出曲线的值,然后绘制一小段直线,通过绘制很多这样的小直线相连来达到绘制正余弦曲线的目的。的值,然后绘制一小段直线,通过绘制很多这样的小直线相连来达到绘制正余弦曲线的目的。而重叠椭圆的实现则是通过Graphics2D的draw(new
Ellipse2D.Double(x1,y1,85,90);绘制一个椭圆,然后translate(x1,y1);
将
Graphics2D
上下文的原点平移到当前坐标系中的点(x1,y1),在计算d=m*mathPI/180的值,rotate(d);
将当前的
Graphics2D
Transform
与旋转转换连接,然后,translate(-x1,-y1);
将Graphics2D
上下文的原点平移到当前坐标系中的点(-x1,-y1)。draw(new
Ellipse2D.Double(x1,y1,85,90));再来绘制一个椭圆,通过这样的处理,来绘制一个在一个圆平面且重叠的椭圆图形。
第五,关于设置是否填充的问题,对于直线来说,是否填充是没有实际意义的,所以不予考虑,释放填充应该考虑圆,椭圆,圆角矩阵,三角形,对于圆和椭圆的填充是通过调用
Graphics2D
的drawOval方法实现的,圆角矩阵则是通过调用Graphics2D的drawRoundRect来实现的,而三角行的填充则是通过调用Graphics2D的fillPolygon方法来实现的.而填充与否的判断则是通过isfill的真与假来实现的.
第六,要求能够保存图形与打开已有的图形,这是通过使用BufferedImage来缓存绘制的图形,然后使用ImageIO将绘制的图形在重新绘制一次再保存到指定的位置,从而实现了文件的保存,打开文件时,考虑到实用性与方便,提供了预览图像的功能,通过继承Jpanel,将选得的图片通过setIcon绘制在出来,实现预览的功能。打开是通过ImageIO将图片绘制在面板上。为方便用户,提供了一个File的菜单,菜单中提供了新建,保存,打开,退出的功能。
第七,考虑到美观,使用了观感器的图形界面。主要是通过观感管理器来实现的。UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());对于背景颜色则是通过设置渐变背景颜色来实现的。
第八,在用户退出时,要求能询问用户是否保存作品,考虑到菜单中有保存的选项,所以通过菜单退出时没有提供询问是否保存的功能,而在实际生活中,考虑到有时候会忘记保存,所以通过右上角窗口退出时必须询问是否保存,是否保存则是通过JOptionPane.showConfirmDialog来实现的,当用户选择Yes时,保存文件。其他则直接退出。
根据课题要求,首先对要实现的功能类型抽象出一个公共的基类Drawing,子类Line,Rectange,Oval,Pencil,RoundRect,Circle,Rect3D,Triangle,SinCos,Tuo,Eraser通过继承基类来实现不同的功能,在使用时,通过基类来调用不同的子类,很好地体现了面向对象的Java语言的多态,抽象,继承的思想。用户通过选择不同的按钮来绘制图形,这主要是利用按钮监听将不同的绘图功能绑定到不同的按钮上,通过监听用户的选择来创建不同的子类,通过子类绘制不同的图形。
3.
源代码及注释
package
myclass;
import
java.awt.*;
import
java.awt.event.*;
import
java.awt.geom.Ellipse2D;
import
java.awt.geom.Rectangle2D;
import
java.awt.image.BufferedImage;
import
java.beans.PropertyChangeEvent;
import
java.beans.PropertyChangeListener;
import
java.io.*;
import
java.util.ArrayList;
import
java.util.Random;
import
javax.imageio.ImageIO;
import
javax.swing.*;
import
javax.swing.event.*;
import
javax.swing.filechooser.FileFilter;
import
javax.swing.filechooser.FileNameExtensionFilter;
import
javax.swing.filechooser.FileView;
import
javax.swing.text.StyledEditorKit.ForegroundAction;
import
org.omg.CORBA.FREE_MEM;
import
org.w3c.dom.css.Rect;
public
class
DrawingBoard
{
public
static
void
main(String[]
args)
{
DrawGraphic
newPad
=
new
DrawGraphic();
//创建窗口对象
}
}
class
DrawGraphic
extends
JFrame
{
private
JButton
choices[];
//
按钮数组
private
String
names[]
=
{
“铅笔“,“直线“,“矩形“,“椭圆“,“圆角矩阵“,“圆“,“3D立方体“,“三角形“,“椭圆重叠“,“正余弦曲线“,“橡皮擦“,“背景色“,“颜色“};
//
按钮上的文本
private
String
tipText[]
=
{
“自由绘制“,“绘制直线“,“绘制矩形“,“绘制椭圆“,“绘制圆角矩阵“,“绘制圆“,“绘制3D立方体“,“绘制三角形“,“椭圆重叠“,“正余弦曲线“,“橡皮檫“,“设置透明背景色“,“选择颜色“};
//
按钮的提示字串
JToolBar
buttonBar;
//
工具条
Drawing
[]itemlist=new
Drawing[1000];
JCheckBox
fillCheckBox;//复选框
JSlider
strokeSlider;//滑动条
int
index=0;
private
int
currentType=1;//当前选择
private
Color
color=Color.black;//颜色
private
float
currentstroke=1.0f;//线条粗细
private
boolean
currentfill=false;//是否填充
private
boolean
isShiftDown
=
false;//释放按下shift键
private
JLabel
statusBar;
//
状态栏
private
double
A=0,B1=0,C=0,D=0;//f(x)=A*sin(B*x)+C*cos(D*x);
private
DrawPanel
drawingArea;
//
画图区域
private
JPanel
sliderPanel;//放置滑动条的面板
private
int
width
=
1000,height
=
600;
//
画图区域初始大小
private
JFileChooser
chooser;//颜色选择
private
BufferedImage
bi=null;//
最后的图形要保存下来,使用缓冲图像
private
Graphics
gg;//
图像专用画笔
public
DrawGraphic()
{
//窗口的构造方法
//super(“画板“);
//显式调用父类的带参构造方法,设置窗口标题为“画板“this.setTitle(“画板“);
//窗口的标题也通过窗口的属性来设置
JMenuBar
menuBar
=
new
JMenuBar();
//
创建菜单条
choices
=
new
JButton[names.length];
//
创建按钮数组
buttonBar
=
new
JToolBar(JToolBar.HORIZONTAL);
//
创建工具条对象,水平
drawingArea
=
new
DrawPanel();
//
创建画图区域
for
(int
i
=
0;
i
getWidth())
icon
=
new
ImageIcon(icon.getImage()
.getScaledInstance(getWidth(),-1,Image.SCALE_DEFAULT));//图片太大,设置为缩略图
setIcon(icon);
}
}
});
}
}
void
SaveFile()//保存文件功能
{
int
s
=
chooser.showSaveDialog(null);
Graphics2D
g2d=(Graphics2D)gg;
for(int
i=0;i
0))
{
try{
A=Double.parseDouble(s);//将String类型转换为double类型
}catch(NumberFormatException
e)
{
flag=false;
}
itemlist[index].A=A;
}
else
flag=false;
if(flag)//A正确设置B的值
{
s
=
(String)JOptionPane.showInputDialog(“请输入Sin(BX)中的参数B)“);
}
if((s
!=
null)
//将String类型转换为double类型
}catch(NumberFormatException
e)
{
flag=false;
}
itemlist[index].B1=B1;
}
else
flag=false;
if(flag)
{
s=(String)JOptionPane.showInputDialog(“请输入Sin(AX)*C中的参数
C“);
}
if((s
!=
null)
//将String类型转换为double类型
}catch(NumberFormatException
e)
{
flag=false;
}
itemlist[index].C=C;
}
else
flag=false;
if(flag)
{
s=(String)JOptionPane.showInputDialog(“请输入Cos(BX)*D中的参数
D“);
}
if((s
!=
null)
//将String类型转换为double类型
}catch(NumberFormatException
e)
{
flag=false;
}
itemlist[index].D=D;
}
}
}
class
Drawing
implements
Serializable
{
int
x1,x2,y1,y2;
ArrayList
pointList=new
ArrayList(
);
Color
color;//颜色
float
stroke;//粗细
int
type;//选择
boolean
fill=false;//是否填充
boolean
isShiftDown=false;//释放按下shift键
public
double
A,B1,C,D,sum;//正余弦曲线参数值
void
draw(Graphics2D
g2d){}//画图函数
}
class
Line
extends
Drawing//绘制直线
{
void
draw(Graphics2D
g2d)
{
g2d.setPaint(color);
g2d.setStroke(new
BasicStroke(stroke,BasicStroke.CAP_ROUND,BasicStroke.JOIN_BEVEL));
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);//防止锯齿
if(isShiftDown)//按下shift键
{
double
x
=
x2
-
x1;
double
y
=
y2
-
y1;
double
length
=
Math.hypot(x,y);
double
sin
=
Math.abs(y
/
length);
if
(0
0)
y
=
x;
else
y
=
-x;
}
else
{
if
(x
y
>
0)
x
=
y;
篇3:北京邮电大学课设基于MSP430的简单信号发生器的设计
北京邮电大学课设基于MSP430的简单信号发生器的设计 本文关键词:北京,邮电大学,信号发生器,简单,设计
北京邮电大学课设基于MSP430的简单信号发生器的设计 本文简介:基于MSP430的信号发生器设计报告学院:电子工程学院班级:2013211212组员:唐卓浩(2012211069)王旭东(2013211134)李务雨(2013211138)指导老师:尹露课程设计报告——基于MSP430的信号发生器的设计学院:电子工程学院班级:2013211212小组成员:唐卓浩
北京邮电大学课设基于MSP430的简单信号发生器的设计 本文内容:
基于MSP430的信号发生器
设计报告
学院:电子工程学院
班级:2013211212
组员:唐卓浩(2012211069)
王旭东(2013211134)
李务雨(2013211138)
指导老师:尹露
课程设计报告——基于MSP430的信号发生器的设计
学院:电子工程学院班级
:2013211212
小组成员:
唐卓浩(2012211069)
王旭东(2013211134)李务雨(2013211138)
一、摘要
信号发生器是电子实验室的基本设备之一,目前各类学校广泛使用的是标准产品,虽然功能齐全、性能指标较高,但是价格较贵,且许多功能用不上。本设计介绍一款基于MSP430G2553
单片机的信号发生器。该信号发生器虽然功能及性能指标赶不上标准信号发生器,但能满足一般的实验要求,且结构简单,成本较低。本次需要完成的任务是以MSP430
LaunchPad的单片机为控制核心、DAC模块作为转换与按键电路作为输入构成的一种电子产品。MSP430
LaunchPad单片机为控制核心,能实时的进行控制;按键输入调整输出状态,DAC0832将单片机输出的数字信号转化为模拟量,经运放放大后,在示波器上输出。在本次程序设计中充分利用了单片机内部资源,涉及到了中断系统、函数调用等。
关键字:信号发生器
MSP430
单片机
数模转换
二、设计要求
以msp430单片机为核心,通过一个DA(数字模拟)转换芯片,将单片机输出的方波、三角波、正弦波(数字信号)转换为模拟信号输出。提供芯片:msp430G2553、DAC0832、REF102、LM384、OP07。参考框图如下:
图1
硬件功能框图
1、基本要求
(1)
供电电压
VDD=
5V~12V;(√)
(2)
信号频率:5~500Hz(可调);(√)
(3)
输出信号电压可调范围:≥0.5*VDD,直流偏移可调:≥0.5*VDD;(√)
(4)
完成输出信号切换;(√)
(5)
方波占空比:平滑可调20%~80%;(√)
(6)
通带内正弦波峰峰值稳定度误差:≤±10%(负载1K)。(√)
2、发挥部分
(1)
信号频率:5~2000Hz(可调);(√)
(2)
多通道同时输出同频正弦波,方波,三角波。(频率可调);
(3)
输出频率与幅度可调的正弦波与余弦波,相位误差≤±5度;
(4)
自由发挥。
三、实验器材
MSP430G2553单片机(Texas
Instrument);DAC0832模数转换芯片;REF102高精度电压基准;OP07运算放大器;阻值不同的电阻及电位器若干;电容若干;导线若干。
1、
MSP430G2553单片机
TI的MSP430G2系列Launchpad开发板是一款适用于TI最新MSP430G2xx系列产品的完整开发解决方案。其基于USB
的集成型仿真器可提供为全系列MSP430G2xx器件开发应用所必需的所有软、硬件。LaunchPad具有集成的DIP插座,可支持多达20个引脚,从而使MSP430
Value
Line器件能够简便地插入LaunchPad电路板中。此外,其还可提供板上Flash仿真工具,以直接连接至PC
轻松进行编程、调试和评估。此外,它还提供了从MSP430G2xx器件到主机PC或相连目标板的9600波特率的UART串行连接。
MSP430G2系列Launchpad开发板的特性:
(1)USB
调试与编程接口无需驱动即可安装使用,且具备高达9600波特的UART
串行通信速度;
(2)支持所有采用PDIP14或PDIP20封装的MSP430G2xx和MSP430F20xx器件;
(3)两个按钮可实现用户反馈和芯片复位;
(4)器件引脚可通过插座引出,既可以方便的用于调试,也可用来添加定制的扩展板。
(5)由此易知,MSP430单片机将用于系统的控制部分。
2、
DAC0832模数转换芯片
DAC模块主要由DAC0832和OPA227PA运算放大器组成。DAC0832是8分辨率的D/A转换集成芯片。与微处理器完全兼容。这个DA芯片以其价格低廉、接口简单、转换控制容易等优点,在单片机应用系统中得到广泛的应用。其主要参数如下:
(1)分辨率为8位;
(2)电流稳定时间1us;
(3)可单缓冲、双缓冲或直接数字输入;
(4)只需在满量程下调整其线性度;
(5)单一电源供电(+5V~+15V);
(6)低功耗,20mW
其引脚功能如下:
(1)D0~D7:8位数据输入线,TTL电平,有效时间应大于90ns(否则锁存器的数据会出错);
(2)ILE:数据锁存允许控制信号输入线,高电平有效;
(3)CS:片选信号输入线(选通数据锁存器),低电平有效;
(4)WR1:数据锁存器写选通输入线,负脉冲(脉宽应大于500ns)有效。由ILE、CS、WR1的逻辑组合产生LE1,当LE1为高电平时,数据锁存器状态随输入数据线变化换,LE1的负跳变时将输入数据锁存;
(5)XFER:数据传输控制信号输入线,低电平有效,负脉冲(脉宽应大于500ns)有效;
(6)WR2:DAC寄存器选通输入线,负脉冲(脉宽应大于500ns)有效。由WR2、XFER的逻辑组合产生LE2,当LE2为高电平时,DAC寄存器的输出随寄存器的输入而变化,LE2的负跳变时将数据锁存器的内容打入DAC寄存器并开始D/A转换。
(7)IOUT1:电流输出端1,其值随DAC寄存器的内容线性变化;
(8)IOUT2:电流输出端2,其值与IOUT1值之和为一常数;
(9)Rfb:反馈信号输入线,改变Rfb端外接电阻值可调整转换满量程精度;
(10)Vcc:电源输入端,Vcc的范围为+5V~+15V;
(11)VREF:基准电压输入线,VREF的范围为-10V~+10V;
(12)AGND:模拟信号地;
(13)DGND:数字信号地
3、
REF102高精度电压基准
REF102是高精度10V电压基准集成电路。由于REF102无需外加恒温装置,因而功耗低、升温快、稳定性好、噪声低。REF102的输出电压几乎不随供电电源电压及负载变化。通过调整外接电阻,输出电压的稳定性及温度漂移可降至最校11.4V至36V的单电源供电电压及优异的全面性能使REF102成为仪器、A/D、D/A及高精度直流电源应用的理想选择。
REF102的特点:
(1)高精度输出:+10V
0.0025V
(2)超低温度漂移:≤2.5ppm/℃
(3)高稳定性:5ppm/1000小时(典型值)
(4)高负载调整率:≤1ppm/V,≤10ppm/mA
(5)宽供电电压范围:11.4VDC至36VDC
(6)低噪声
(7)低静态电流:≤1.4Ma
REF102的引脚:(2)为芯片电源脚,电压范围是11.4V~36V;(4)为公共引脚;(5)为外接调整电阻脚,调整输出电压稳定度及温度漂移;(6)为输出引脚;(8)为输出噪声衰减。
4、
OP07运算放大器
OP07芯片是一种低噪声,非斩波稳零的双极性运算放大器集成电路。由于OP07具有非常低的输入失调电压(对于OP07A最大为25μV),所以OP07在很多应用场合不需要额外的调零措施。OP07同时具有输入偏置电流低(OP07A为±2nA)和开环增益高(对于OP07A为300V/mV)的特点,这种低失调、高开环增益的特性使得OP07特别适用于高增益的测量设备和放大传感器的微弱信号等方面。
OP07芯片引脚功能说明:1和8为偏置平衡(调零端),2为反向输入端,3为正向输入端,4接地,5空脚
6为输出,7接电源。
四、硬件电路设计
1、
整体设计思路
方案一:控制部分由MSP430G2553实现,波形产生采用单片压控函数发生器(MAX038等),可同时产生频率可控可变的正弦波、三角波、方波。
优缺点:简单易行,采用专用芯片,系统体积大大减小;但频率步进的步长很难控制,并且整个设计中MSP430G2553仅完成简单的控制功能,资源没有充分利用。
方案二:由MSP430G2553实现对专门的DDS芯片(如AD9850)的控制,产生各种波形。
优缺点:此方案产生波形的频率稳定度高,易于程控。但DDS芯片价格高,系统成本高。
方案三:由MSP430G2553结合DAC0832实现各种波形的产生。
优缺点:此方案可以充分利用MSP430G2553上的资源,降低系统成本,但是产生波形频率较低。
综上,方案三充分利用MSP430G2553的资源,外围电路简单、系统成本较低,可以满足信号发生器的要求,所以最终采用方案三。
2、
硬件控制模块
这次试验共有三个按键输入,分别作为切换波形,加频,减频。
一个滑动变阻器作为占空比的调节,一个作为幅度的调节,一个作为直流偏置的调节。按键直接采用分压法给一个高电位,当按下去的时候相当于接地也就输出了低电平。占空比的调节在于分压法,让滑动变阻器所占电压在0~2.5伏,从而输给芯片产生相应的占空比,再输出。
3、
DAC0832的模块
其八位数据输入接MSP430的八位数据输出,通过Iout1端口输出。使能端与430相连,电源接12V。Iout2接地,f不接。
4、
放大模块
采用了反向放大电路,电源输入电压是12伏,放大了5倍左右。
同时在放大电路前并联一个滑动变阻器100K,通过它来调节整个DAC对应的输出负载电阻,也就可以达到改变电压的幅度的目的。
效果如下(由于该方波是2KHz的方波,频率较高因此边沿看上去不垂直):
5、
直流偏置
采用反向加法电路通过改变直流的接入电阻调节直流电压的大小。图如下,u1为放大之后的输入,u2为-12伏的电压。R1,3,6都是5K的电阻,R2位100k的电位器。则Uout1=12*5/R2-U1,这就达到了直流偏置的效果。
效果见下图:
五、
软件程序设计
1、
设计指标与功能
(1)波形产生和切换。正弦波、三角波和方波依次切换,采样点均为100个。
(2)频率调节。从5Hz到2000Hz可调,步进5Hz,一共400个有效频率点。
(3)占空比调节。从20%到83%平滑可调,使用ADC10连续采集滑动变阻输出电压实现。
2、
软件模块介绍
(1)
变量及宏定义
#define
SWITCH_SIG_TYPE(BIT0)
//P1.0
#define
ADD_FREQ(BIT1)
//P1.1
#define
SUB_FREQ(BIT2)
//P1.2
#define
DAC_WR(BIT3)
//P1.3
#define
ADC10_IN_PORT(BIT4)
//P1.4
#define
P1_IN_PORTS
~(SWITCH_SIG_TYPE
+
ADD_FREQ
+
SUB_FREQ
+
ADC10_IN_PORT)
#define
P1_OUT_PORTSDAC_WR
//
3:DAC
WR
#define
P1_INTERRUPT
(SWITCH_SIG_TYPE
+
ADD_FREQ
+
SUB_FREQ)
#define
P2_OUT_PORTS
(0xff)
//
DAC
data
in
#define
TOTAL_SAMPLING_POINTS100
#define
MAX_FREQ_STEPS400
#define
ENABLE_WR_PORTP1OUT
//当前的波形,0表示正弦波,1是三角波,2是方波
inttccr0_now;
//表示当前的计数初值
uintccr0_idx;
//表示当前计数初值在表中的索引号
ucharpoint_now;
//表示现在采用点的索引值
intduty_circle;
//表示当前的方波高电平的点数,用于表示占空比。
const
long
tccr0_table[MAX_FREQ_STEPS]={32000,.,78,75
};
//5-2000Hz每隔5Hz频率对应的计数器初值表,一个400个频点。
const
uchar
sin_data[TOTAL_SAMPLING_POINTS]={.};
//正弦值表,100点。
const
uchar
tria_data[TOTAL_SAMPLING_POINTS]={.};
//三角波值表,100点。
(2)
基本时钟系统
MSP430x2xx家族的单片机的基本时钟系统模块如下图所示:
MSP430有四个时钟源:LFXT1CLK、XT2CLK、DCOCLK和VLOVLK,系统时钟使用BCSCTL1寄存器设置。下面的初始化代码将系统的时钟时钟源设置为16MHz,DCO的频率设置为16MHz。
void
init_DCO(){
BCSCTL1
=
CALBC1_16MHZ;
DCOCTL
=
CALDCO_16MHZ;
}
上述的每一个时钟源都可以驱动时钟信号电路产生周期时钟信号,一共有三种独立的时钟信号,分别是MCLK、SMCLK和ACLK,其时钟源可以任意指定。这些时钟由寄存器BCSCTL2设置。
BCSCTL2
=
SELM_1
+
DIVM_0;
//
SELMx位置SELM_1,选择MCLK的时钟源为DCOCLK,DIVM_0分频比为1
BCSCTL2
//
SELS位为0表示将SMCLK的时钟源设置为DCOCLK
(3)
定时器A
定时器A是一个16位的计时器,有三种计数模式,可配置任意时钟源驱动,多种capture/compares模式和寄存器。
定时器A的工作模式如下表所示
MCx
模式
工作方式
00
Stop
停止计时
01
Up
mode
从0到TACCR0循环计数
10
Continous
mode
从0到0FFFFH循环计数
11
Up/down
mode
从0计时到TACCR0再回到0循环
定时器的计数模式和时钟源的选择由寄存器TACTL设置。
定时器的中断的产生主要依赖capture/compare寄存器的设置。MSP430x2xx家族一共有三套独立的capture/compare寄存器,可以独立产生中断。
本程序使用的是连续计数模式,计数和中断产生方式如下图所示。本程序只是用了capture/compare寄存器TACCR0和TACTL0产生中断。
void
init_timer_A0(void){
TACTL
|=
TASSEL_2
+
MC_2;
//
TASSELx置TASSEL_2选择SMCLK作为时钟源,
//
MC_2设置技术模式为连续模式
TACCR0
=
tccr0_now;//设置捕获/比较寄存器0的初值
TACCTL0
|=
CCIE;//
捕获/比较寄存器0的中断使能
}
(4)
单片机ADC10
MSP430的ADC是一个十位的模数转换模块,转换出的数字范围为0~1023。转换值的计算公式为:
ADC10一共有两大类工作方式,第一种是直接转换方式,该模式主要的特点是转换后的数据直接存放在ADC10MEM寄存器中。第二种是数据传输方式,主要特点是会将数据自动存放在内存中用户定义好数组中。
在直接转换方式中又有四种模式:
CONSEGx
模式
工作方式
00
单通道单次转换
一个通道输入,只转换一次,下一次转换的触发需要用户手动设置。
01
多通道顺序转换
多通道输入,每个通道依次转换一次,下一次转换的触发需要用户手动设置。
10
单通道循环转换
一个通道输入,下一次转换的触发自动触发。
11
多通道顺序循环
多个通道输入,每个通道依次转换,下一次转换自动触发。
ADC10的中断可选择在数据在ADC10MEM里准备好后触发。
本程序使用的是单通道单次转换,并且不设置ADC10中断,而是在主函数的while(1)循环中手动处理采集数据的时序。之所以不采用中断模式是因为在MSP430中默认不能中断嵌套,当ADC10中断进入时,定时器中断就无法进入,从而影响定时器的精度,另外如果开启中断嵌套,那么中断处理将会更复杂,因此权衡考虑后选择该工作方式。这种方式下ADC10在主程序中执行转换和处理,而定时器中断可以按时进入,保证了定时器的精度。转换的流程如下图所示:
ADC10的参考电平可以有多种选择,如下所示:
本程序选择的是第二种参考电平设置。其中VREF+是ADC10内置的参考电平,将ADC10CTL0寄存器的REF2_5V位置1,表示该电平为2.5V。Vss是MSP430的20号引脚,将其接地,表示最低参考电平为0。因此转换值的计算公式为NADC=1023*Vin/2.5。
初始化函数如下:
void
init_ADC10(void){
ADC10CTL1
|=
INCH_4;
//
A4通道,P1.4输入模拟值。
ADC10CTL1
|=
SHS_0;
//
Sample-and-hold
source
select
ADC10SC
ADC10CTL1
|=
ADC10SSEL_3;//
时钟源为SMCLK
ADC10CTL1
//
数据存储格式,表示使用ADC10MEM的低十位存储数据
ADC10CTL1
|=
CONSEQ_0;//
单通道单转换模式
ADC10AE0
=
ADC10_IN_PORT;//P1.4输入模拟值
ADC10CTL0
//
屏蔽中断
ADC10CTL0
|=
SREF_1
+
ADC10SHT_0
+
REF2_5V
+
REFON;
//
VR+
=
2.5V,VR-
=
Vss
=
0
//REFON开启内部参考电平
ADC10CTL0
//
REFOUT位置1会将参考电压输出到P1.3和P1.4上,不需要因此置0.
ADC10CTL0
|=
ADC10ON;//打开ADC10
}
主程序循环如下,采集数据到占空比的转换算法为右移4位再加20:
while(1){
ADC10CTL0
//关闭采样使能
while(ADC10CTL1
//检测是否忙
ADC10CTL0
|=
ENC
+
ADC10SC;//打开采样使能,开始转换
while(ADC10CTL1
//检测是否忙
int
adc_data
=
ADC10MEM;//读取数据
duty_circle
=(adc_data
>>4)+20;
//占空比限制在
20(20%)~83(83%)之间
//采集到的数据是0~1023
//右移四位就是0~63
//加20就是20~83
//总采样点数是100点
//占空比就是20/100=20%
~
83/100=83%
之间
}
(5)
端口I/O与中断
MSP430有P1、P2一共十六个通用IO口。其功能分配如下
端口
功能
I/O方向
P2.0
–
P2.7
输出8位数据到DAC
输出
P1.0
按键中断,切换波形
输入
P1.1
按键中断,增加频率
输入
P1.2
按键中断,减小频率
输入
P1.3
DAC的WR信号
输出
P1.4
ADC10的模拟输入口
输入
主要初始化端口方向、功能以及中断,程序如下:
void
init_port_io(void){
P2DIR=
P2_OUT_PORTS;//
设置输出端口P2.0~P2.7
P2REN=0x00;//
不使用上/下拉电阻
P2SEL=0x00;//
端口的功能为IO
P2SEL2=0x00;//
端口的功能为IO
P1DIR//
P1.0
P1.1
p1.2
p1.4输入
P1DIR|=
P1_OUT_PORTS;//
P1.3输出给DAC
WR
P1REN=0x00;
P1SEL=0x00;
P1SEL2=0x00;
}
void
init_port_interrupt(void){
P1IES|=
P1_INTERRUPT;//相应位置1表示下降沿触发
P1IE|=
P1_INTERRUPT;//输入位中断使能
P1IFG//清除标志位
}
五、功能实现
1、
波形输出及切换
波形的输出主要靠定时器周期性触发中断,然后将波形值数组中的值依次循环写到P2上。流程图如下:
波形切换靠按键中断以及改变波形类型标志变量curr_signal_type实现,流程图如下:
获得如下结果:
2、
频率调节
波形的频率调节通过改变计时器初值TACCR0来实现,所需的频率计算公式为
波频率
=
CPU时钟频率/(采样点数*定时器初值)
流程图如下:
为了能够使得频率可达到2000Hz,需要适当减小采样点数。在没有实现最大2000Hz时,采样电视为200点,将点数减少到100点,并适当减小DAC的WR信号的宽度,以达到在更高速的情况下能够将数据写入DAC。
结果如下。
产生5Hz的正弦波:
产生2.145KHz的正弦波
3、
占空比调节
占空比的调节主要靠ADC10采集电位器输入电压并按照一定的算法算出高电平持续的点数duty_circle来表示占空比。
采集转换的流程图如下
相应的产生方波的逻辑为:
20%占空比:
80%占空比:
六、问题及解决方案
1、
三角波和方波没有波形
最开始三角波的每一个采样点的值是由程序计算出来的,程序如下所示:
case
1:
//triangle
if
(point_now
#define
SWITCH_SIG_TYPE(BIT0)
//P1.0
#define
ADD_FREQ(BIT1)
//P1.1
#define
SUB_FREQ(BIT2)
//P1.2
#define
DAC_WR(BIT3)
//P1.3
#define
ADC10_IN_PORT(BIT4)
//P1.4
#define
P1_IN_PORTS
~(SWITCH_SIG_TYPE
+
ADD_FREQ
+
SUB_FREQ
+
ADC10_IN_PORT)
#define
P1_OUT_PORTSDAC_WR
//
3:DAC
WR
#define
P1_INTERRUPT
(SWITCH_SIG_TYPE
+
ADD_FREQ
+
SUB_FREQ)
#define
P2_OUT_PORTS
(0xff)
//
DAC
data
in
#define
TOTAL_SAMPLING_POINTS100
#define
MAX_FREQ_STEPS400
#define
ENABLE_WR_PORTP1OUT
inttccr0_now;
uintccr0_idx;
ucharpoint_now;
intpush_key;
intduty_circle;
const
long
tccr0_table[MAX_FREQ_STEPS]={
32000,16000,10666,8000,6400,5333,4571,4000,3555,3200,2909,2666,2461,2285,2133,2000,1882,1777,1684,1600,1523,1454,1391,1333,1280,1230,1185,1142,1103,1066,1032,1000,969,941,914,888,864,842,820,800,780,761,744,727,711,695,680,666,653,640,627,615,603,592,581,571,561,551,542,533,524,516,507,500,492,484,477,470,463,457,450,444,438,432,426,421,415,410,405,400,395,390,385,380,376,372,367,363,359,355,351,347,344,340,336,333,329,326,323,320,316,313,310,307,304,301,299,296,293,290,288,285,283,280,278,275,273,271,268,266,264,262,260,258,256,253,251,250,248,246,244,242,240,238,237,235,233,231,230,228,226,225,223,222,220,219,217,216,214,213,211,210,209,207,206,205,203,202,201,200,198,197,196,195,193,192,191,190,189,188,187,186,184,183,182,181,180,179,178,177,176,175,174,173,172,172,171,170,169,168,167,166,165,164,164,163,162,161,160,160,159,158,157,156,156,155,154,153,153,152,151,150,150,149,148,148,147,146,146,145,144,144,143,142,142,141,140,140,139,139,138,137,137,136,136,135,135,134,133,133,132,132,131,131,130,130,129,129,128,128,127,126,126,125,125,125,124,124,123,123,122,122,121,121,120,120,119,119,118,118,118,117,117,116,116,115,115,115,114,114,113,113,113,112,112,111,111,111,110,110,109,109,109,108,108,108,107,107,107,106,106,105,105,105,104,104,104,103,103,103,102,102,102,101,101,101,100,100,100,100,99,99,99,98,98,98,97,97,97,96,96,96,96,95,95,95,94,94,94,94,93,93,93,93,92,92,92,91,91,91,91,90,90,90,90,89,89,89,89,88,88,88,88,87,87,87,87,86,86,86,86,86,85,85,85,85,84,84,84,84,83,83,83,83,83,82,82,82,82,82,81,81,81,81,81,80,80,80,78,75};
//
cpu_freq
//
ccr0
=
-----------------------------------
//
sig_freq
total_sampling_points
const
uchar
sin_data[TOTAL_SAMPLING_POINTS]={127,135,143,151,159,167,174,182,189,196,203,209,215,221,226,231,235,239,243,246,249,251,253,254,254,254,254,253,252,250,247,245,241,237,233,228,223,218,212,206,199,192,185,178,171,163,155,147,139,131,123,115,107,99,91,83,76,69,62,55,48,42,36,31,26,21,17,13,9,7,4,2,1,0,0,0,0,1,3,5,8,11,15,19,23,28,33,39,45,51,58,65,72,80,87,95,103,111,119,127};
const
uchar
tria_data[TOTAL_SAMPLING_POINTS]={0,5,10,15,20,26,31,36,41,46,52,57,62,67,72,78,83,88,93,98,104,109,114,119,124,130,135,140,145,150,156,161,166,171,176,182,187,192,197,202,208,213,218,223,228,234,239,244,249,255,255,249,244,239,234,228,223,218,213,208,202,197,192,187,182,176,171,166,161,156,150,145,140,135,130,124,119,114,109,104,98,93,88,83,78,72,67,62,57,52,46,41,36,31,26,20,15,10,5,0};
#pragma
vector
=
TIMER0_A0_VECTOR
__interrupt
void
timer_A0(void){
if(point_now
>=
TOTAL_SAMPLING_POINTS){
point_now
=0;
}
switch(curr_signal_type){
case0:
//
sin;
write_dac(sin_data[point_now]);
break;
case1:
//
triangle
write_dac(tria_data[point_now]);
break;
case2:
//
box
if(point_now
=3){
curr_signal_type
=0;
}
}elseif(push_key
if(ccr0_idx
>=
MAX_FREQ_STEPS){
ccr0_idx
=0;
}
tccr0_now
=
tccr0_table[ccr0_idx];
}elseif(push_key
if(ccr0_idx
>=
MAX_FREQ_STEPS){
ccr0_idx
=
MAX_FREQ_STEPS
-1;
}
tccr0_now
=
tccr0_table[ccr0_idx];
}
P1IFG
//清除标志位
}
void
init_vars(){
curr_signal_type
=0;
point_now
=0;
ccr0_idx
=
MAX_FREQ_STEPS
/2-1;//初始
1kHz
tccr0_now
=
tccr0_table[ccr0_idx];
duty_circle
=
TOTAL_SAMPLING_POINTS
/2;//初始50%
占空比
}
void
init_DCO(){
BCSCTL1=
CALBC1_16MHZ;
DCOCTL=
CALDCO_16MHZ;
BCSCTL2=
SELM_1
+
DIVM_0;
//
select
DCO
as
the
source
of
MCLK
BCSCTL2
//
select
DCO
as
the
source
of
SMCLK
}
void
init_timer_A0(void){
TACTL|=
TASSEL_2
+
MC_2;//
SMCLK
source
and
Mode
continous
TACCR0=
tccr0_now;
TACCTL0
|=
CCIE;//
interrupt
enable
_EINT();
}
void
init_port_io(void){
P2DIR=
P2_OUT_PORTS;//
P2
11111111b
all
out
P2REN=0x00;//
disable
pull
up/down
resistor
P2SEL=0x00;//
io
function
is
selected
P2SEL2
=0x00;
P1DIR
//
P1.0
P1.1
p1.2
p1.4
in
P1DIR
|=
P1_OUT_PORTS;//
P1.3
for
DAC
WR
P1REN=0x00;
P1SEL=0x00;
P1SEL2
=0x00;
}
void
init_port_interrupt(void){
P1IES|=P1_INTERRUPT;//置1,下降沿触发
P1IE|=P1_INTERRUPT;//中断使能
P1IFG//清除标志位
}
void
init_ADC10(void){
ADC10CTL1
|=
INCH_4;//
A4
channel
for
convertion,P1.4
in
ADC10CTL1
|=
SHS_0;
//
Sample-and-hold
source
select
ADC10SC
ADC10CTL1
|=
ADC10SSEL_3;//
SMCLK
16M
ADC10CTL1
//
straght
binary
format
ADC10CTL1
|=
CONSEQ_0;//
Single
channel
single
convertion
ADC10AE0=
ADC10_IN_PORT;//
P1.4
in
ADC10CTL0
//
disable
interrupt
ADC10CTL0
|=
SREF_1
+
ADC10SHT_0
+
REF2_5V
+
REFON;
//
V+
=
2.5V,V-
=
Vss
=
0
ADC10CTL0
//
diasable
refout
to
p1.3
p1.4
ADC10CTL0
|=
ADC10ON;//
enable
adc
}
void
main(void){
WDTCTL
=
WDTPW
|
WDTHOLD;//
Stop
watchdog
timer
init_vars();
init_port_io();
init_port_interrupt();
init_DCO();
init_timer_A0();
init_ADC10();
_bis_SR_register(GIE);//全局中断使能
while(1){
ADC10CTL0
//关闭采样使能
while(ADC10CTL1
//检测是否忙
ADC10CTL0
|=
ENC
+
ADC10SC;//打开采样使能,开始转换
while(ADC10CTL1
//检测是否忙
int
adc_data=
ADC10MEM;//读取数据
duty_circle=(adc_data
>>4)+20;
//占空比限制在
20(20%)~83(83%)之间
//采集到的数据是0~1023
//右移四位就是0~63
//加20就是20~83
//总点数是100点
//占空比就是20/100=20%
~
83/100=83%
之间
}
}
28
/
29