嵌入式系统及应用简易信号发生器.docx
《嵌入式系统及应用简易信号发生器.docx》由会员分享,可在线阅读,更多相关《嵌入式系统及应用简易信号发生器.docx(26页珍藏版)》请在冰豆网上搜索。
嵌入式系统及应用简易信号发生器
嵌入式系统及应用实验报告
简易信号发生器
作者:
学号:
班级:
电子1001
学院:
电子信息工程学院
作者:
学号:
班级:
电子1003
学院:
电子信息工程学院
简易信号发生器
北京交通大学.北京.100044
摘要:
本实验所设计的“简易信号发生器”在硬件上是基于“嵌入式开发平台”实验箱,其上搭载有ST公司的基于ARMCortex-M3内核的微控制器芯片STM32F103ZET6。
方案中使用此芯片作为主控芯片,控制矩阵键盘进行输入操作,同时控制LCD液晶进行图形用户界面的显示以及控制DAC芯片进行模拟波形的输出,除此之外使用MCU内部输出PWM波形,从而输出方波。
软件编程使用IAR编程环境,对实验平台上的硬件编写相应的初始化函数和驱动函数等。
最后使用示波器对输出的波形进行测量与评估。
关键词:
嵌入式开发;ARM;简易信号发生器;DAC;
中图分类号:
文献标志码:
A
信号发生器是一种能够产生多种波形,如三角波、锯齿波、矩形波(含方波)、正弦波的仪器。
函数信号发生器在电路实验和设备检测中具有十分广泛的用途。
通过对函数波形发生器的原理以及构成分析,可设计一个能变换出三角波、正弦波、方波的函数波形发生器。
本方案所设计的“简易信号发生器”能够产生三角波、锯齿波、矩形波(含方波)、正弦波。
方案中,主要通过定时器产生一定的时延来触发DMA,将一个已编好的“波形数组”通过DMA传送给DAC芯片产生模拟波形输出。
程序中通过改变定时器的时延,即可改变输出波形的频率。
此外,还编写了用户图形界面——基于LCD液晶的显示操作界面。
1系统总体设计
本章阐述“简易信号发生器”的整体设计方案,包括系统概述、设计要求、整体框图等。
1.1系统概述
本方案所设计的“简易信号发生器”所使用的硬件资源主要为实验室的“嵌入式开发平台”实验箱,其上搭载有ST公司的基于ARMCortex-M3内核的微控制器芯片STM32F103ZET6。
实验中使用此芯片为主控芯片,并使用实验平台上的外围电路(包括DAC、LCD、BNC端子等)来搭建电路,实现“简易信号发生器”的功能。
1.2设计要求
设计一个“简易信号发生器”,需要满足以下设计要求:
(1)设置用STM32的PWM输出引脚输出脉冲波形。
波形频率范围:
1Hz-100KHz,3位有效数字精度。
占空比1-99%,两位有效数字。
利用按键和LCD显示,设定频率和占空比。
(输出取自蜂鸣器的跳线端子)。
(2)利用电路板上DAC芯片ADS7302和STM32的DMA功能,将计算得到的模拟波形缓冲数据,通过DAC的通道A发送出去,在电路板DA1BNC端子测量输出波形。
注意输出模拟波形数据要使DAC芯片8位满幅度,DAC接受无极性源码0-255。
(3)在LCD上给出对脉冲输出和模拟输出的设定界面,用户可以指定信号参数,包括脉冲信号频率和占空比,模拟信号频率,调幅信号载频、调制频率和调制系数等。
1.3整体框图
由系统的整体设计要求,规划“简易信号发生器”的整体框图如下:
2硬件设计及实现
本章详细阐述设计“简易信号发生器”所使用的硬件电路平台,硬件电路的选用为软件的编程实现提供基础。
2.1整体硬件方案
本方案所使用的硬件电路主要为实验室的“嵌入式开发平台”实验箱,如图2-1所示,其上搭载有ST公司的基于ARMCortex-M3内核的微控制器芯片STM32F103ZET6,并搭配了LED流水灯、LCD液晶模块、独立按键、矩阵键盘模块、AD转换模块、DA转换模块、USART通信模块等电路,方便各种嵌入式实验的开发与调试。
图2-1“嵌入式开发平台”实验箱
本实验方案中,将使用此开发平台的核心板(MCU)模块、矩阵键盘模块、LCD液晶模块、DA转换模块。
下文将详细说明这些模块的特性与使用。
2.2核心板模块
核心板搭载了STM32F103ZET6芯片,如图2-2所示。
此芯片是意法公司(ST)出品的32位微控制器,使用ARM32位的Cortex‐M3内核,提供了最高72MHz工作频率,提供3.3V逻辑,适应通用板设计,能够高效地完成该实验平台所需的处理工作。
图2-2STM32F103ZET6核心板
对于本设计方案而言,此芯片具有以下特性可供参考与利用:
■内核:
ARM32-bitCortex™-M3CPU
–72MHz最高主频
■内存:
–256~512Kb闪存,64KbSRAM
–Flexiblestaticmemorycontroller(FSMC),提供4个片选信号,支持CF卡、
SRAM、PSRAM、NOR、NAND存储介质。
■DMA:
12通道DMA控制器
–支持外设:
定时器、I2C等
■13种通信接口
–2组I2C接口
■11个定时器(Timer)
–16位定时器,每个定时器有4个PWM输出通道
–SysTick定时器:
一个24位减数计数器
2.3矩阵键盘模块
矩阵键盘模块由一个4*4的矩阵键盘和一片CH452芯片构成,如图2-3所示。
电路采用I2C串行接口,CH452用于扫描4*4矩阵键盘。
当有按键按下时,能够向MCU申请一个外部中断,然后将按键编号传入MCU,供编程识别。
图2-3矩阵键盘模块
本设计方案中,使用到‘A’、‘B’、‘C’、‘D’、‘*’、‘#’六个按键,其对应的功能如下:
■A:
光标上移
■B:
光标下移
(由移动‘A’、‘B’可以选择主列表中的:
波形、频率、占空比)
■*:
光标左移
■#:
光标右移
(由移动‘*’、‘#’可以选择“波形”列表中的:
正弦波、三角波、锯齿波;以及“频率”
列表、“占空比”列表中需要修改的数字位)
■C:
增大数值
■D:
减小数值
(由移动‘C’、‘D’可以修改某一数字位上的数字大小,用以调整“频率”和“占空比”)
2.4LCD液晶电路
实验平台上所使用的彩色LCD液晶,如图2-4所示。
此液晶模块的型号为MzT35C1,使用HX8238-A作为TFT控制器,采用8位并行数据接口,点阵数为320*RGB*240。
图2-4LCD液晶
实验方案中,需要在LCD上给出对脉冲输出和模拟输出的设定界面,用户可以指定信号参数,包括脉冲信号频率和占空比,模拟信号频率等。
2.5DAC电路
板载DAC模块选用AD7302芯片,此芯片采用8位并行数据接口,含2路轨对轨模拟输出。
电路图如图2-5所示:
图2-5DAC模块电路(部分)
电路图中AD7302引脚的连接如下:
■DA_CS:
接至片选电路的输出。
片选电路由FSMC输出与74LS138构成。
■WR:
接至FSMC。
■LDAC、CLR:
分别接至核心板的PG14和PG15。
■D[0..7]:
接至FSMC。
■A[0]:
接至FSMC。
实验方案中,模拟信号(正弦波等)输出使用AD7302,为了方便DMA自动传送,将DAC芯片输出启动信号LDAC设定为一直为0(无条件输出),清零信号CLR设定为1(无效)。
为此,需要设定端口PG14和PG15为数字输出,且PG14=0,PG15=1。
2.6PWM输出电路
PWM输出取自蜂鸣器的跳线端子VOICE端(即直接由MCU引出)。
具体定义如图2-6所示。
图2-6PWM输出端子——VOICE端
3软件设计及实现
本章详细阐述“简易信号发生器”的软件编程方案,包括系统初始化、各模块的驱动程序编写、GUI显示、频率计算算法等。
3.1整体软件方案
软件编程需要建立在硬件电路的基础之上。
本方案的整体软件框架如图3-1所示:
图3-1“简易信号发生器”整体软件框架
3.2系统初始化
系统初始化阶段主要完成板上资源的初始化,包括MCU内模块初始化(时钟初始化、DMA初始化、TIM初始化等)、板上LCD液晶初始化(显示图形化界面)、片外DA芯片初始化等任务。
此阶段编程使用的函数主要为System_Init()、gTextOut()等。
其中,System_Init()函数结构如下:
intSystem_Init(void){
RCC_Configuration();/*系统时钟、GPIO时钟、FSMC时钟初始化*/
FSMC_Configuration();/*外部总线初始化*/
I2C_IO_init();/*软件I2C协议和引脚初始化*/
CH452_Init();/*数码管和矩阵键盘驱动芯片CH452初始化*/
LCD_Init();/*液晶模块初始化*/
TIM4_Configuration();/*PWM初始化*/
DA_Init();/*DAC模块初始化*/
DMA_Configuration();/*DMA初始化(未开启通道)*/
TIM2_Configuration();/*波形输出触发定时器初始化*/
SYSTICK_Configuration();/*系统定时器初始化*/
return1;
}
由此函数结构可知,System_Init()主要负责MCU片上模块的初始化的任务。
3.3模拟波形产生方案
本方案所设计的“简易信号发生器”能够产生“三角波”、“锯齿波”、“正弦波”这三种模拟波形。
由设计要求,利用电路板上DAC芯片AD7302和DMA功能,将计算得到的模拟波形缓冲数据,通过DAC的通道A发送出去,在电路板DA1的BNC端子测量输出波形。
因此,设计如下方案:
①建立三个波形查询表,分别为正弦波(table_sine)、三角波(table_triangle)、锯齿波(table_zigzag)的表。
②设置FSMC,构造“DAC地址”。
③使用DMA设置为“循环传送”模式,从“内存”向“DAC地址”传送波形查找表。
其中“DAC地址”由FSMC设置所确定。
④DMA传送的触发由TIM_2完成,设置TIM_2为一定频率ft,每触发一次,DMA完成一次传送。
⑤设置DAC芯片工作状态(PG14、PG15),初始化DA芯片。
⑥开启传送。
在程序中,所建立的“模拟波形查询表”的长度设置为80,其为需要传送至DA芯片8位数字输入端的数据,包含模拟波形的一个周期的数据。
若需要输出频率为fout的模拟波,则TIM_2触发DMA的频率为ft=fout*80。
“模拟波形查询表”程序代码如下:
constu8TABLE_LENGTH=80;//查询表数据长度
/*--------------------正弦波查询表--------------------*/
constu8table_sine[TABLE_LENGTH]={
128,137,147,157,167,176,185,194,202,210,217,224,230,236,241,245,248,251,253,254,
255,254,253,251,248,245,241,236,230,224,217,210,202,194,185,176,167,157,147,137,
127,118,108,98,88,79,70,61,53,45,38,31,25,19,14,10,7,4,2,1,
0,1,2,4,7,10,14,19,25,31,38,45,53,61,70,79,88,98,108,118};
/*--------------------三角波查询表--------------------*/
constu8table_triangle[TABLE_LENGTH]={
0,6,12,19,25,31,38,44,51,57,63,70,76,82,89,95,102,108,114,121,
127,133,140,146,153,159,165,172,178,184,191,197,204,210,216,223,229,235,242,248,
255,248,242,235,229,223,216,210,204,197,191,184,178,172,165,159,153,146,140,133,
127,121,114,108,102,95,89,82,76,70,63,57,51,44,38,31,25,19,12,6};
/*--------------------锯齿波查询表--------------------*/
constu8table_zigzag[TABLE_LENGTH]={
0,3,6,9,12,16,19,22,25,29,32,35,38,41,45,48,51,54,58,61,
64,67,70,74,77,80,83,87,90,93,96,99,103,106,109,112,116,119,122,125,
129,132,135,138,141,145,148,151,154,158,161,164,167,170,174,177,180,183,187,190,
193,196,199,203,206,209,212,216,219,222,225,228,232,235,238,241,245,248,251,254};
3.4方波产生方案
板载STM32芯片内部具有11个定时器(Timer),能够实现输入捕捉、输出比较、PWM输出功能。
本方案使用其中的通用定时器TIM_4来产生一路PWM波形,只需要对“预分频寄存器”、“周期寄存器”、“占空比寄存器”等进行设置即可。
其中,方波的占空比由“周期寄存器”与“占空比寄存器”决定。
对TIM_4的设置程序如下:
voidTIM4_Configuration(void)
{
//用于定时器初始化的数据结构
GPIO_InitTypeDefGPIO_InitStructure;
TIM_TimeBaseInitTypeDefTIM_TimeBaseStructure;
TIM_OCInitTypeDefTIM_OCInitStructure;
//打开GPIOB和TIM4外设模块时钟
//RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);
//设置PB8为TIM4_CH3output(drivebuzzer)
//即设置PB8为专用输出功能AFfunction
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStructure);
//时间基准的初始化TimeBaseconfiguration
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
TIM_TimeBaseStructure.TIM_Period=tim_period-1;//周期-----------------tim_period
TIM_TimeBaseStructure.TIM_Prescaler=tim_prescaler-1;//预分频--------------tim_prescaler
TIM_TimeBaseStructure.TIM_ClockDivision=0x0;
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;//向上计数
TIM_TimeBaseInit(TIM4,&TIM_TimeBaseStructure);
//比较通道3配置为PWM输出Channel3ConfigurationinPWMmode
TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_Pulse=tim_pulse;//初始脉冲宽度-----------tim_pulse
TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;//允许比较输出
TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;//输出的相位
TIM_OC3Init(TIM4,&TIM_OCInitStructure);
//启动定时器EnableTIM4
TIM_Cmd(TIM4,ENABLE);
}
3.5LCD液晶显示方案
LCD液晶显示功能主要由液晶函数库(lcdlib.c、bmp.c)中的函数实现。
由设计要求,需要在程序开始运行时,首先在LCD显示屏上显示出程序编写人的姓名和学号,停顿5秒钟后进入程序功能执行。
因此,需要首先选用“写字符串函数”进行显示,然后使用“系统定时器Systick”进行精确的5秒定时,再使用“绘图函数”与“写字符串函数”构造操作界面。
本实验方案中所使用的函数有:
//设定文本颜色
voidgTextColor(u32color);
//设定文本背景颜色
voidgTextBkColor(u32color);
//用先前指定的颜色以给定像素坐标为左上角的位置开始输出字符串
voidgTextOut(u32x,u32y,char*ch);
//用先前指定的颜色以给定像素坐标为左上角的位置开始输出格式化字符串
voidgFormatTextOut(u32x,u32y,char*format,...);
//用先前指定的颜色,两倍字体大小以给定像素坐标为左上角的位置开始输出字符串
voidgTextOut2(u32x,u32y,char*ch);
//用先前指定的颜色,两倍字体大小以给定像素坐标为左上角的位置开始输出格式化字符串
voidgFormatTextOut2(u32x,u32y,char*format,...);
//在给定坐标为左上角的矩形区域显示BMP格式图像
intgBMPDraw(intx0,inty0,constvoid*pBMP);
//绘制方框
voidgRectFrame(intx0,inty0,intx1,inty1,u32framecolor,u8fillflag,u32fillcolor);
3.6按键操作方案
按键扫描函数keyscan()位于主函数的while
(1)内,用于进行按键操作。
keyscan()函数的最外层为一个检测gKeyPressed的判断语句。
当矩阵键盘中的某个按键按下时,程序进入中断,将标志位gKeyPressed置位,表示有按键按下,在此情况下,keyscan()进入按键扫描与操作,使用“keychar=GetKey()”语句将所按下的按键值存储到keychar变量中,每一个按键对应一个操作。
具体操作流程如下框图所示:
其中,xlabel与ylabel用于确定光标的位置,wavelabel用于确定当前输出的波形的类型。
当每次按键操作后确定了光标的位置(xlabel,ylabel),就可以进行相应的GUI绘图操作,若是需要更改波形或是修改相应频率值、占空比值,则对相应变量(frequence、duty)进行修改。
所有操作完成后离开keyscan()函数。
此处需要注意的一点是,每次进入keyscan()函数对LCD液晶进行操作前都需要先关闭DMA传送,待离开keyscan()函数时,再开启DMA传送。
4系统调试
对此方案所设计的“简易信号发生器”进行调试,主要分为两个部分:
波形输出测量、LCD液晶显示测试。
首先对LCD液晶显示进行测试。
操作矩阵键盘,对每一个按下的按钮,LCD中均能产生相应操作,然后对绘图中出现的坐标偏移进行修正。
然后进行波形输出测量。
波形输出包括模波形和方波。
其中,方波的测量只需将示波器探头接至蜂鸣器的跳线端子VOICE的PWM脚;模拟波形的测量则使用开发平台上的BNC端子输出波形来进行测量。
通过观察示波器波形,使用示波器上的测量工具(measure按钮——频率、占空比)来对波形的精度进行测量。
在调试过程中,也发现了一系列问题:
①LCD与DMA的冲突问题。
当设置了FSMC后,MCU为LCD与DA芯片各自分配了相应的地址线(LCD的起始为0x60000010,DA芯片的起始为0x60000008),同属于FSMC的Bank1,使用相同的读写时序。
因此,程序启动后开启DMA传送。
此时,当有LCD操作访问“LCD地址”时,可能因为先前对“DAC地址”的读写时序未结束,而造成总线冲突,此时MCU将停止DMA对DAC的传送。
最终研究出一个避免此现象的方法:
每次进入keyscan()函数对LCD液晶进行操作前都需要先关闭DMA传送,待离开keyscan()函数时,再开启DMA传送。
②模拟波形最高频率限制问题。
在测试模拟波形频率的过程中,发现模拟波形的最高频率只能到达50KHz。
仔细检查程序并确保程序无逻辑上错误,并检查了电路后,排除了AD7302的最高输出频率限制,最后判断可能是DMA的最高传输速率的限制。
目前并无明确的解决方案,不过可以通过尝试使用DDS芯片来产生更高频率的模拟波。
③定时器分频值设定的问题。
按照设计要求,需要产生1Hz~100KHz的模拟波形,因此,需要对