参考基于stm32的信号发生器
- 格式:doc
- 大小:193.50 KB
- 文档页数:40
课程设计报告设计课题:基于STM32的信号发生器设计专业班级:电气与信息工程通信二班学生姓名:马晓琪指导教师:赵浩宇设计时间:信号发生器一.实验概述本系统以低功耗单片机stm32为主控器件,分为微控制器、FPGA、DA转换器、功率放大等模块,实现了一个能产生任意波形的波形发生器。
本设计利用单片机生成各种波形的数据,将数据传输给RAM存储器,通过后级的DA转换器实现波形的产生。
系统采用触摸屏方式输入波形参数和手绘波形,频率1HZ步进可调,峰-峰值可在0到10V之间任意调节。
电路设计条理清晰,人机交互界面友好,控制方便,很好地完成了题目的所有基本和发挥要求。
二.实验要求与目的实验要求:设计简易函数信号发生器系统实验目的:掌握应用嵌入式系统生成函数信号的方法三.实验内容与实验设备实验内容:a)设计程控放大器电路b)设计嵌入式系统电路及程序,实现信号发生器基本功能,可以产生三种标准波形:正玄波、三角波和方波;c)编写嵌入式系统程序,实现函数信号发生器功能,可以对标准波形设计频率、周期、最大值、最小值、峰峰值、偏移量和方波占空比。
d)编写嵌入式系统程序,实现随机信号发生器功能,输出在手写板上描绘的波形。
e)编写嵌入式系统程序,实现通讯功能,可以通过RS232接口设置输出信号。
实验设备:a)示波器、信号发生器、万用表b)STC单片机开发板、C8051F开发板、STM32开发板实验器件: STM32F103ZET6、ADUC7026四.方案比较1.1波形生成方案方案一:采用锁相式频率合成方案这种方案利用锁相环将压控振荡器VCO的输出频率锁定在所需频率上。
这种方案具有很好的窄带跟踪特性,很好的选择所需频率。
但由于模拟方法合成的正弦波参数(如:幅度,频率,相位)都很难被控制,难以满足实现任意波形的要求。
方案二:采用STM32单片机生成波形,由于是软件滤波,所以不会有寄生的高次谐波分量,生成的波形比较纯净。
它的特点是价格低、性能高,在低频范围内稳定性好、操作方便、体积小、耗电少。
经比较,方案二既可满足课程设计的基本要求又能充分发挥其优势,电路简单,易控制,性价比高,所以采用该方案1.2任意波形的生成原理方案一:触摸屏绘制波形以触摸屏作为操作界面,用户可在触摸屏上输入波形参数及绘制波形。
此方法操作简易,并且可绘制任意波形,但是对编程者要求较高,故选择相对简单的用键盘输入数据。
方案二:用键盘输入数据采用键盘输入,这是最基本的方法。
优点是输入值精确。
但用户自定义输入时无法自由输入想要的特殊波形,而且输入数据繁琐,操作麻烦,由于实现相对简单,故本实验采用该方案。
五.系统设计分析(A )硬件部分(系统采样256个数据,采用8位DA 转换器,因此RAM 地址位设置为8位,数据位设置为8位。
微控制器先进行数据收集处理,生成各种波形的归一化数据,然后存储在256位的数组里,根据幅值要求乘以相应的系数,最终生成可以存放在RAM 里的数据。
本系统采用12位DA 转换器,最大输出电压为5Vpp ,功率放大为2倍,所以系统最大的输出电压可以达到10Vpp ,可计算出最小电压分辨率为:电压分辨率:K=10/4096(V )(在具体实现时,它(1)扫描键盘,获得列扫描码和行状态码,从而确定被按下的按键的键值; (2)根据键值,通过散转表,跳转到相应的键功能处理部分; (3)进入键处理部分,完成键功能; (4)完成一次键输入工作。
通过键盘对单片机系统进行设置,每按一次键,键盘都会有上述的处理过程,每次仅能完成一个键功能。
在实际设置波形参数时,一个参数需要多个键功能来实现,那么相应的键盘也要多次完成键值识别,跳转键处理的工作过程。
(D)函数参数设置(1)正弦波归一化数据生成函数S(t)=sin(t) /(2K)(2)三角波归一化数据生成函数T(t)=t/(63 *2K) (t<64)T(t)=(127-t)/(63 *2K) (64<t<128)T(t)=(t-128)/(63 *2K) (128<t<192)T(t)=(255-t)/(63 *2K) (192<t<256)(3)方波归一化数据生成函数根据电压分辨率可以得出方波归一化数据生成函数为:F(t)= 1/(2k) (0<t<128)F(t)= - 1/(2k) (128<t<256)(4)5次谐波数据的生成函数W(t)=a*sin(t)+ b*sin(2t+m)+ c*sin(3t+n)+d* sin(4t+p)+ e*sin(5t+q) 此函数要求幅值和相位参数:(5)正弦波、方波、三角波线性组合波数据生成函数D(t)=a*S(t)+ b*F(t+m)+ c*T(t+n)(E)实验参考程序/*----------------------------------------------------------------------------* 功能:STM32 DAC 数模转换(正弦波/矩形波/三角波)输出实验* 说明:按SW5 输出正弦波/ 按SW4 输出矩形波/ 按SW3 输出三角波, 输出端口PA4*----------------------------------------------------------------------------*/#include <stdio.h>#include <stm32f10x_lib.h> // STM32F10x Library Definitions#include "STM32_Reg.h" // STM32 register and bit Definitions #include "STM32_Init.h" // STM32 Initialization#include "common.h"#include "sine_wave_1024.h"// 输出端口: PA4#define SINE_W A VE 1//sine 正弦波#define RECT_W A VE 2//rectangular 矩形波#define HACKLE_WA VE 3//hackle 三角波UINT8 flag = 0;UINT8 func = SINE_W A VE;/*----------------------------------------------------------------------------MAIN function*----------------------------------------------------------------------------*/int main (void){UINT16 i = 0;UINT32 *pDAC_BASE = (UINT32 *)DAC_BASE;stm32_Init(); // STM32 setupLED_Init();//打开DAC时钟使能RCC->APB1ENR |= (UINT32)(1 << 29);//设置DAC控制参数*(pDAC_BASE + 0x00) = (0x01 << 0)| (0x00 << 2) | (0x04 << 3) | (0x03 << 6) | (0x0b << 8);*(pDAC_BASE + 0x04) = 0x01printf(" --------------- Program start --------------- \r\n");while (TRUE) // Loop forever{if(!Get_SW5()){func = SINE_WA VE;}else if(!Get_SW4()){func = RECT_W A VE;}else if(!Get_SW3()){func = HACKLE_WA VE;}switch(func){case SINE_W A VE://------------------------------------------------------------- #ifdef SINE_W A VEif(i < 1024) i+=2;else i = 0;*(pDAC_BASE + 0x08) = Sine_W A VE[i] << 4;#endif//------------------------------------------------------------- break;case RECT_W A VE:#ifdef RECT_W A VEfor(i=0;i<2000;i++)*(pDAC_BASE + 0x08) = 0x0fff;for(i=0;i<2000;i++)*(pDAC_BASE + 0x08) = 0;#endif//------------------------------------------------------------- break;case HACKLE_WA VE:#ifdef HACKLE_WA VEif(flag){flag = 0;while(TRUE){if(i < 4096) i += 1;else break;*(pDAC_BASE + 0x08) = i;}}else{flag = 1;while(TRUE){if(i > 0) i -= 1;else break;*(pDAC_BASE + 0x08) = i;}}#endifbreak;default:break;}//-------------------------------------------------------------} // end while} // end main/*---------------------------------------------------------------------------- * 设置方向*----------------------------------------------------------------------------*/void Set_IO_direction(UINT8 PORT, UINT8 GPIO, UINT8 Value){RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;if(PORT == PORT_A){if(GPIO < 8){GPIOA->CRL &= ~(0x0f << (GPIO * 4)); //Clr used bitGPIOA->CRL |= (Value << (GPIO * 4)); //Set used bit }else{GPIOA->CRH &= ~(0x0f << (GPIO * 4 - 8 * 4));//Clr used bitGPIOA->CRH |= (Value << (GPIO * 4 - 8 * 4));//Set used bit }}if(PORT == PORT_B){if(GPIO < 8){GPIOB->CRL &= ~(0x0f << (GPIO * 4)); //Clr used bitGPIOB->CRL |= (Value << (GPIO * 4)); //Set used bit }else{GPIOB->CRH &= ~(0x0f << (GPIO * 4 - 8 * 4));//Clr used bitGPIOB->CRH |= (Value << (GPIO * 4 - 8 * 4));//Set used bit }}if(PORT == PORT_C){if(GPIO < 8){GPIOC->CRL &= ~(0x0f << (GPIO * 4)); //Clr used bitGPIOC->CRL |= (Value << (GPIO * 4)); //Set used bit }else{GPIOC->CRH &= ~(0x0f << (GPIO * 4 - 8 * 4));//Clr used bitGPIOC->CRH |= (Value << (GPIO * 4 - 8 * 4));//Set used bit }}if(PORT == PORT_D){if(GPIO < 8){GPIOD->CRL &= ~(0x0f << (GPIO * 4)); //Clr used bitGPIOD->CRL |= (Value << (GPIO * 4)); //Set used bit }else{GPIOD->CRH &= ~(0x0f << (GPIO * 4 - 8 * 4));//Clr used bitGPIOD->CRH |= (Value << (GPIO * 4 - 8 * 4));//Set used bit }}if(PORT == PORT_E){if(GPIO < 8){GPIOE->CRL &= ~(0x0f << (GPIO * 4)); //Clr used bitGPIOE->CRL |= (Value << (GPIO * 4)); //Set used bit }else{GPIOE->CRH &= ~(0x0f << (GPIO * 4 - 8 * 4));//Clr used bitGPIOE->CRH |= (Value << (GPIO * 4 - 8 * 4));//Set used bit }}}/*---------------------------------------------------------------------------- SendCharWrite character to Serial Port.*----------------------------------------------------------------------------*/int SendChar (int ch) {while (!(USART2->SR & USART_FLAG_TXE));USART2->DR = (ch & 0x1FF);return (ch);}/*---------------------------------------------------------------------------- GetKeyRead character to Serial Port.*----------------------------------------------------------------------------*/int GetKey (void) {while (!(USART2->SR & USART_FLAG_RXNE));return ((int)(USART2->DR & 0x1FF));}void LED_Init(void){Set_IO_direction(PORT_E,LED1,OUTPUT);Set_IO_direction(PORT_E,LED2,OUTPUT);Set_IO_direction(PORT_E,LED3,OUTPUT);Set_IO_direction(PORT_E,LED4,OUTPUT);Set_IO_direction(PORT_B,SW2,INPUT);Set_IO_direction(PORT_B,SW3,INPUT);Set_IO_direction(PORT_E,SW4,INPUT);Set_IO_direction(PORT_E,SW5,INPUT);Turn_OFF_LED1();Turn_OFF_LED2();Turn_OFF_LED3();Turn_OFF_LED4();}/*----------------------------------------------------------------------------insert a delay time.*----------------------------------------------------------------------------*/void delay(unsigned int nCount){for(; nCount != 0; nCount--);}正弦波归一化程序:tosin[256]={0x80,0x83,0x86,0x89,0x8d,0x90,0x93,0x96,0x99,0x9c,0x9f,0xa2, 0xa5,0xa8,0xab,0xae,0xb1,0xb4,0xb7,0xba,0xbc,0xbf,0xc2,0xc5,0xc7,0xca,0xcc,0xcf,0xd1,0xd4,0xd6,0xd8,0xda,0xdd,0xdf,0xe1,0xe3,0xe5,0 xe7,0xe9,0xea,0xec,0xee,0xef,0xf1,0xf2,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfd,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xf f,0xff,0xff,0xff,0xff,0xff,0xfe,0xfd,0xfd,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,0xf6,0xf5,0xf4,0xf2,0xf1,0xef,0xee,0xec,0x ea,0xe9,0xe7,0xe5,0xe3,0xe1,0xde,0xdd,0xda,0xd8,0xd6,0xd4,0xd1,0xcf,0xcc,0xca,0xc7,0xc5,0xc2,0xbf,0xbc,0xba,0xb7,0x b4,0xb1,0xae,0xab,0xa8,0xa5,0xa2,0x9f,0x9c,0x99,0x96,0x93,0x90,0x8d,0x89,0x86,0x83,0x80,0x80,0x7c,0x79,0x76,0x72,0x6f, 0x6c,0x69,0x66,0x63,0x60,0x5d,0x5a,0x57,0x55,0x51,0x4e,0x4c,0x48,0x45,0x43,0x40,0x3d,0x3a,0x38,0x35,0x33,0x30,0x2e,0x2b, 0x29,0x27,0x25,0x22,0x20,0x1e,0x1c,0x1a,0x18,0x16,0x15,0x13,0x11,0x10,0x0e,0x0d,0x0b,0x0a,0x09,0x08,0x07,0x06,0x05,0x04, 0x03,0x02,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02 ,0x02,0x03,0x04,0x05,0x06,0x07 ,0x08,0x09,0x0a,0x0b,0x0d,0x0e,0x10,0x11,0x13,0x15,0x16,0x18,0x1a,0x1c,0x1e,0x20,0x22,0x25,0x27,0x29,0x2b,0x2e,0x30,0x33, 0x35,0x38,0x3a,0x3d,0x40,0x43,0x45,0x48,0x4c,0x4e,0x51,0x55,0x57,0x5a,0x5d,0x60,0x63,0x66 ,0x69,0x6c,0x6f,0x72,0x76,0x79, 0x7c,0x80 };六.数据测试与测试分析(1)输出波形频率范围测试测试数据见下表:条件:峰峰值为5V。