基于STM32波形信号发生器proteus仿真设计(仿真+程序+报告+讲解)

您所在的位置:网站首页 stm32输出正弦波可调幅值 基于STM32波形信号发生器proteus仿真设计(仿真+程序+报告+讲解)

基于STM32波形信号发生器proteus仿真设计(仿真+程序+报告+讲解)

2024-06-26 07:19:26| 来源: 网络整理| 查看: 265

基于STM32波形信号发生器proteus仿真设计(仿真+程序+报告+讲解)

仿真图proteus 8.9

程序编译器:keil 5

编程语言:C语言

设计编号:C0075

讲解仿真视频:

基于STM32的波形信号发生器proteus仿真设计

主要功能:

结合实际情况,基于STM32F103单片机设计一个四种波形发生器(正弦波、方波、三角波、锯齿波)。该系统应满足的功能要求为:

(1) 可以实现四种波形:正弦波、方波、三角波、锯齿波;

(2) 通过按键进行选择,频率可以调整;

(3) LCD液晶显示;

(4)设计出来之后用Proteus软件仿真出效果;

主要硬件设备:STM32F103单片机、DAC0832数模转换芯片、矩阵键盘、LCD12864液晶屏幕。

资料下载链接(可点击):

【腾讯文档】C0075 下载链接

以下为本设计资料展示图:

整体设计方案

四种波形发生器以STM32F103单片机作为整个系统的控制核心,应用其强大的处理速度,构成波形发生器系统。该系统具备将数字信号转换为模拟信号的能力。正弦波可以直接采用数学函数sin计算出来,送入单片机进行数据处理。经单片机运算后的数据送入DAC0832芯片将数字信号转换为模拟信号输出。其他的波形都可以采用自身的规律采用不同的算法实现。

img

图2-1 基于STM32单片机的四种波形发生器原理图

本系统硬件主要由矩阵键盘、D/A转换器、LCD12864显示系统、处理器等几部分组成。各模块的主要功能如下:

(1)矩阵键盘的功能是设置波形和频率,然后送入单片机。

(2) MCU的功能是识别键盘的数据并进行相对应的处理,然后转换出波形的数字信号和LCD显示的数据。

(3) LCD12864显示系统的功能是将设置的波形和频率显示出来。

系统的整体设计方案设计图如图2-2所示。

img

图2-2 系统的整体方案设计图

采用的是DAC0832芯片来做DA转换的,DAC0832将输出电压分成了0xFF(255)份,需要输出不同的波形我们需要给不同的数据,在这里我将所有的波形的一个周期分成了100份,定时器每隔一段时间中断一次,中断100次为一个周期。

正弦波采用数学计算公式sin来计算;

方波只需要在定时器前面50次给0,后面50次给最大值即可;

三角波只需要在定时器前面50次采用最大值的50分之一乘于它本身,后面50次相反即可;

锯齿波只需要在一个周期内,定时器中断一次就用他本身乘于电压最大值的100分之一即可;

测试波形如下所示:

三角波

img

锯齿波

img

方波

img

正弦波

img

程序:

img

img

main函数

#define KEY0 GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_10) //读取按键0 void Delay_Ms(u16 time); /*************** 配置Switch用到的I/O口 *******************/ void Init_GPIO_Switch(void) { GPIO_InitTypeDef GPIO_InitStructure; GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);//关闭jtag,使能SWD,可以用SWD模式调试 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); // 使能PC端口时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //PC0 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //设置成输入 GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化PC0 } /* Private functions ---------------------------------------------------------*/ /******************************************************************************* *功能名称:main *描述:主程序。 *输入:无 *输出:无 *返回:无 *******************************************************************************/ int main(void) { u8 i=0; RCC_ClocksTypeDef RCC_Clocks; //初始化程序 RCC_Configuration(RCC_PLLMul_4); //8M*4 == 32M RCC_GetClocksFreq(&RCC_Clocks); //获取片上时钟 Init_12864(); //初始化12864液晶 Key_Init(); Init_GPIO_Switch(); Init_GPIO_DAC0832(); Data0=25; TIM3_Int_Init(50+Data0,320); //频率:32000000/ 320 ==100 000 /100 == 1000 /50==20 LCD_P6x8Str(3,16," Sine Wave "); LCD_P6x8Str(7,6*2,"Frequency: 15 Hz"); while (1) { if(KEY0) { if(i!=2) { __set_PRIMASK(1); GPIO_ResetBits(GPIOB, ((uint16_t)0xC000)); } Key_Test(); i=2; } else{ if(i!=5) { TIM3_Int_Init(50+Data0,320); __set_PRIMASK(0); //使能TIMx外设 GPIO_ResetBits(GPIOB, ((uint16_t)0xC000)); } i=5; } } }

波形信号部分

/*************** 配置DAC用到的I/O口 *******************/ void Init_GPIO_DAC0832(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE); // 使能PC端口时钟 GPIO_InitStructure.GPIO_Pin = ((uint16_t)0x03FF); //选择对应的引脚 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz GPIO_Init(GPIOC, &GPIO_InitStructure); //初始化PC端口 GPIO_SetBits(GPIOC, ((uint16_t)0x00FF)); // 高 GPIO_ResetBits(GPIOC, ((uint16_t)0x00FF)); // 低 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); // 使能PC端口时钟 GPIO_InitStructure.GPIO_Pin = ((uint16_t)0xC000); //选择对应的引脚 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化PC端口 GPIO_SetBits(GPIOC, ((uint16_t)0xC000)); // 高 GPIO_ResetBits(GPIOC, ((uint16_t)0xC000)); // 低 time=0; ADC_CS_WR(0); mode=0; //默认输出正弦波 freq=100; //默认频率 AM=255; //最大幅度 } void DAC_0832_Data(uint8_t Data) { GPIO_ResetBits(GPIOC,~Data); GPIO_SetBits(GPIOC,Data); } void sine_wave(u8 location)//输出正弦波 { double x=(double)location/50*PI;//把0-100放缩到0-2派(pai,没有那个符号) u8 y=(sin(x)*(AM/2)+(AM/2));//算出y,并放缩到0-254(因为ADC范围0-AM,芯片落后) DAC_0832_Data(y); } void squ_wave(u8 location)//方…… { if(location DAC_0832_Data(location*AM/100); //用(100-location)也以变成反向锯齿 } //通用定时器中断初始化 //这里时钟选择为APB1的2倍,而APB1为36M //arr:自动重装值。 //psc:时钟预分频数 //这里使用的是定时器3! void TIM3_Int_Init(u16 arr,u16 psc) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能 TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 计数到5000为500ms TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值 10Khz的计数频率 TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式 TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位 TIM_ITConfig( //使能或者失能指定的TIM中断 TIM3, //TIM3 TIM_IT_Update , ENABLE //使能 ); // TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE); NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //TIM3中断 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占优先级0级 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //从优先级3级 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能 NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器 TIM_Cmd(TIM3, ENABLE); //使能TIMx外设 // TIM_Cmd(TIM3, DISABLE); } void TIM3_IRQHandler(void) //TIM3中断 { switch(mode) { case W_SINE:sine_wave((u8)(time*freq/100)%100);break;//计算出波的位置 case W_SQU:squ_wave((u8)((time*freq/100)%100));break; case W_TRI:tri_wave((u8)((time*freq/100)%100));break; case W_SAW:saw_wave((u8)((time*freq/100)%100));break; } time++; if(time>=100)//计数100次 time=0; }

按键识别

/************************************ 按键表盘为: 1 2 3 A 4 5 6 B 7 8 9 C * 0 # D ************************************/ u8 ee,Data0=0; void Key_Test(void) { int num; char Freq[3]={'\0'}; num = Key_Scan(); if(ee!=num) switch(num) { case 0: LCD_P6x8Str(1,1,"0"); break; case 1: LCD_P6x8Str(1,1,"1"); break; case 2: LCD_P6x8Str(1,1,"2"); break; case 3: LCD_P6x8Str(1,1,"3"); break; case 4: LCD_P6x8Str(1,1,"4"); break; case 5: LCD_P6x8Str(1,1,"5"); break; case 6: LCD_P6x8Str(1,1,"6"); break; case 7: LCD_P6x8Str(1,1,"7"); break; case 8: LCD_P6x8Str(1,1,"8"); break; case 9: LCD_P6x8Str(1,1,"9"); break;// case 'A': LCD_P6x8Str(1,1,"A"); mode=0;LCD_P6x8Str(3,16," Sine Wave "); break; case 'B': LCD_P6x8Str(1,1,"B"); mode=1;LCD_P6x8Str(3,16," Square wave "); break; case 'C': LCD_P6x8Str(1,1,"C"); mode=2;LCD_P6x8Str(3,16,"Ttiangular wave"); break; case 'D': LCD_P6x8Str(1,1,"D"); mode=3;LCD_P6x8Str(3,16," Sawtooth Wave "); break; case '#': LCD_P6x8Str(1,1,"#"); if(Data0>=5)Data0-=5; Freq[0]=(20-Data0/5)/10+'0';Freq[1]=(20-Data0/5)%10+'0'; LCD_P6x8Str(7,6*13,Freq); break; case '*': LCD_P6x8Str(1,1,"*"); if(Data0


【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭