标题:
STM32F103ZET6任意频率正弦波+三角波工程源码
[打印本页]
作者:
来打酱油
时间:
2018-11-14 17:47
标题:
STM32F103ZET6任意频率正弦波+三角波工程源码
STM32F103输出正弦波源程序,大家可以参考下
单片机源程序如下:
#include "sys.h"
#include "usart.h"
#include "delay.h"
#include "key.h"
#include "led.h"
#include "STM32_WaveOutput.h"
int main(void)
{
Stm32_Clock_Init(9); //系统时钟设置
uart_init(72,9600); //串口初始化为9600
delay_init(72); //延时初始化
LED_Init();
KEY_Init(); //初始化与按键连接的硬件接口
SineWave_Init( SawToothWave ,10 ,ENABLE ,SinWave ,10 ,ENABLE);//PA4输出为 10Hz的三角波;PA5输出为10Hz的正弦波
printf("The Program is running!!!\n");
while(1)
{/********KEY3为增加频率,KEY1为减少频率;(变化量为100)***测试不好用*****/
// static u16 f=1000;
// if( KEY_Scan(0)==4)
// {
// f +=100;
// if(f>15000) f=15000;
// Set_WaveFre( Wave_Channel_1 ,f);
// }
// else if( KEY_Scan(0)==2)
// {
// f -=100;
// if(f<=20) f=5;
// Set_WaveFre( Wave_Channel_1 ,f);
// }
LED0=!LED0;
delay_ms(500);
}
}
复制代码
#include "STM32_WaveOutput.h"
#include "delay.h"
/********生成正弦波形输出表***********/
void SineWave_Data( u16 cycle ,u16 *D)
{
u16 i;
for( i=0;i<cycle;i++)
{
D[i]=(u16)((Um*sin(( 1.0*i/(cycle-1))*2*PI)+Um)*4095/3.3);
}
}
/********生成锯齿波形输出表***********/
void SawTooth_Data( u16 cycle ,u16 *D)
{
u16 i;
for( i=0;i<cycle;i++)
{
D[i]= (u16)(1.0*i/255*4095);
}
}
/******************正弦波形表***********************/
#ifdef Sine_WaveOutput_Enable
u16 SineWave_Value[256]; //已用函数代替
#endif
/******************锯齿波形表***********************/
#ifdef SawTooth_WaveOutput_Enable
u16 SawToothWave_Value[256]; //已用函数代替
#endif
/******DAC寄存器地址声明*******/
#define DAC_DHR12R1 (u32)&(DAC->DHR12R1) //DAC通道1输出寄存器地址
#define DAC_DHR12R2 (u32)&(DAC->DHR12R2) //DAC通道2输出寄存器地址
/****************引脚初始化******************/
void SineWave_GPIO_Config(u8 NewState1 ,u8 NewState2)
{
RCC->APB2ENR|=1<<2; //使能PORTA时钟
if( NewState1!=DISABLE)
{
GPIOA->CRL&=0xFFF0FFFF;
GPIOA->CRL&=0x00030000;
GPIOA->ODR|=(1<<4);
}
if( NewState2!=DISABLE)
{
GPIOA->CRL&=0xFF0FFFFF;
GPIOA->CRL&=0x00300000;
GPIOA->ODR|=(1<<5);
}
}
/******************DAC初始化*************************/
void SineWave_DAC_Config(u8 NewState1 ,u8 NewState2)
{
RCC->APB2ENR|=1<<2; //使能PORTA时钟
RCC->APB1ENR|=1<<29; //使能DAC时钟
GPIOA->CRL&=0XFFF0FFFF;
GPIOA->CRL|=0X00000000;//PA4 模拟输入
if( NewState1!=DISABLE)
{
DAC->CR|=1<<0; //使能DAC通道1
DAC->CR|=1<<1; //DAC1输出缓存不使能 BOFF1=1
DAC->CR|=1<<2; //使用触发功能 TEN1=1
DAC->CR|=0<<3; //3、4、5=100时为TIM2 TRGO事件触发
DAC->CR|=0<<4; //
DAC->CR|=1<<5; //
DAC->CR|=0<<6; //不使用波形发生
DAC->CR|=0<<8; //屏蔽、幅值设置
DAC->CR|=1<<12; //DAC1 DMA使能
}
if( NewState2!=DISABLE)
{
DAC->CR|=1<<16; //使能DAC通道2
DAC->CR|=1<<17; //DAC2输出缓存不使能 BOFF1=1
DAC->CR|=1<<18; //使用触发功能 TEN2=1
DAC->CR|=0<<19; //3、4、5=100时为TIM2 TRGO事件触发
DAC->CR|=0<<20; //
DAC->CR|=0<<21; //
DAC->CR|=0<<22; //不使用波形发生
DAC->CR|=0<<24; //屏蔽、幅值设置
DAC->CR|=1<<28; //DAC1 DMA使能
DAC->DHR12R1=0;//使能通道1
DAC->DHR12R2=0;//使能通道2
}
}
/*********定时器配置************/
void SineWave_TIM_Config( u32 Wave1_Fre ,u8 NewState1 ,u32 Wave2_Fre ,u8 NewState2)
{
if( NewState1!=DISABLE)RCC->APB1ENR|=1<<0; //TIM2时钟使能
if( NewState2!=DISABLE)RCC->APB1ENR|=1<<4; //TIM6时钟使能
TIM2->PSC=0x0; //预分频器不分频
TIM2->CR1|=0<<4;//向上计数模式
TIM6->PSC=0x0;
TIM6->CR1|=0<<4;//向上计数模式
if( NewState1!=DISABLE)
{
TIM2->ARR=Wave1_Fre;
TIM6->CR1|=0x01; //使能定时器6
TIM2->CR2 &= (u16)~((u16)0x0070);//设置TIM2输出触发为更新模式
TIM2->CR2 |=0x0020;//设置TIM2输出触发为更新模式
}
if( NewState2!=DISABLE)
{
TIM6->ARR = Wave2_Fre; //设置输出频率
TIM2->CR1|=0x01; //使能定时器2
TIM6->CR2 &= (u16)~((u16)0x0070);//设置TIM2输出触发为更新模式
TIM6->CR2 |=0x0020;//设置TIM2输出触发为更新模式
}
}
/*********DMA配置***********/
void SineWave_DMA_Config( u16 *Wave1_Mem ,u8 NewState1 ,u16 *Wave2_Mem ,u8 NewState2)
{
RCC->AHBENR|=1<<1; //开启DMA2时钟
delay_ms(5); //等待DMA时钟稳定
if( NewState1!=DISABLE)
{
DMA2_Channel3->CPAR=DAC_DHR12R1; //DMA1 外设地址
DMA2_Channel3->CMAR=(u32)Wave1_Mem; //DMA1,存储器地址
DMA2_Channel3->CNDTR=256; //DMA2,传输数据量
DMA2_Channel3->CCR=0X00000000; //复位
DMA2_Channel3->CCR|=1<<4; //从存储器读
DMA2_Channel3->CCR|=0<<6; //外设地址非增量模式
DMA2_Channel3->CCR|=1<<7; //存储器增量模式
DMA2_Channel3->CCR|=1<<8; //外设数据宽度为16位
DMA2_Channel3->CCR|=1<<10; //存储器数据宽度16位
DMA2_Channel3->CCR|=1<<12; //最高优先级
DMA2_Channel3->CCR|=1<<13; //最高优先级
DMA2_Channel3->CCR|=0<<14; //非存储器到存储器模式
DMA2_Channel3->CCR|=1<<5; //循环发送模式
DMA2_Channel3->CCR|=1<<0; //开启DMA传输
}
if( NewState2!=DISABLE)
{
DMA2_Channel4->CPAR=DAC_DHR12R2; //DMA1 外设地址
DMA2_Channel4->CMAR=(u32)Wave2_Mem; //DMA1,存储器地址
DMA2_Channel4->CNDTR=256; //DMA2,传输数据量
DMA2_Channel4->CCR=0X00000000; //复位
DMA2_Channel4->CCR|=1<<4; //从存储器读
DMA2_Channel4->CCR|=0<<6; //外设地址非增量模式
DMA2_Channel4->CCR|=1<<7; //存储器增量模式
DMA2_Channel4->CCR|=1<<8; //外设数据宽度为16位
DMA2_Channel4->CCR|=1<<10; //存储器数据宽度16位
DMA2_Channel4->CCR|=1<<12; //最高优先级
DMA2_Channel4->CCR|=1<<13; //最高优先级
DMA2_Channel4->CCR|=0<<14; //非存储器到存储器模式
DMA2_Channel4->CCR|=1<<5; //循环发送模式
DMA2_Channel4->CCR|=1<<0; //开启DMA传输
}
}
void MyTIM_SetAutoreload(TIM_TypeDef* TIMx, u16 Autoreload)
{
/* Check the parameters */
assert_param(IS_TIM_ALL_PERIPH(TIMx));
/* Set the Autoreload Register value */
TIMx->ARR = Autoreload;
}
/***********正弦波初始化***************/
//u8 Wave1 波形1
//u16 Wave1_Fre 波形1频率(Hz)
//u8 NewState1 波形1状态(忽略)
//u8 Wave2 波形2
//u16 Wave2_Fre 波形2频率(Hz)
//u8 NewState2 波形2状态(忽略)
//调用exp: SineWave_Init( SawToothWave ,10 ,ENABLE ,SinWave ,10 ,ENABLE);//三角波,10Hz,正弦波,10Hz
void SineWave_Init(u8 Wave1,u16 Wave1_Fre,u8 NewState1,u8 Wave2,u16 Wave2_Fre,u8 NewState2)
{
u16 *add1,*add2;
u16 f1=(u16)(72000000/sizeof(SineWave_Value)*2/Wave1_Fre);
u16 f2=(u16)(72000000/sizeof(SineWave_Value)*2/Wave2_Fre);
SineWave_Data( N ,SineWave_Value); //生成波形表1
SawTooth_Data( N ,SawToothWave_Value);//生成波形表2
if( NewState1!=DISABLE)
{
if( Wave1==0x00) add1=SineWave_Value;
else add1=SawToothWave_Value;
}
if( NewState2!=DISABLE)
{
if( Wave2==0x00) add2=SineWave_Value;
else add2=SawToothWave_Value;
}
SineWave_GPIO_Config( ENABLE ,ENABLE); //初始化引脚
SineWave_TIM_Config( f1 , NewState1 ,f2 ,NewState2); //初始化定时器
SineWave_DAC_Config(NewState1 ,NewState2); //初始化DAC
SineWave_DMA_Config( add1 ,NewState1 ,add2 ,NewState2); //初始化DMA
if( NewState1!=DISABLE) TIM2->CR1|=0x01; //使能定时器2; //使能TIM2,开始产生波形
if( NewState2!=DISABLE) TIM6->CR1|=0x01; //使能定时器2; //使能TIM6,开始产生波形
}
void Set_WaveFre( u8 Wave_Channel ,u16 fre)
{
TIM_TypeDef* TIMX;
u16 reload;
if( Wave_Channel==0x00) TIMX = TIM2;
else if(Wave_Channel==0x01) TIMX = TIM6;
reload=(u16)(72000000/512/fre);
MyTIM_SetAutoreload( TIMX ,reload);
}
复制代码
所有资料51hei提供下载:
stm32F103正弦波.rar
(349.17 KB, 下载次数: 172)
2018-11-14 17:46 上传
点击文件名下载附件
下载积分: 黑币 -5
作者:
waerdeng
时间:
2018-11-14 21:08
学习一下,谢谢分享。
作者:
jxdhust
时间:
2019-8-7 10:38
学习,感谢分享。
作者:
lin19981015
时间:
2019-8-8 09:41
您好,没有看懂您分享的附件,能麻烦您告知一下吗?谢谢
作者:
L_Asura
时间:
2019-10-14 11:53
感谢楼主的帮助
作者:
L_Asura
时间:
2019-10-14 11:53
学习一下,嘻嘻
作者:
kending
时间:
2019-11-14 11:47
优秀,优秀,优秀
作者:
kending
时间:
2019-11-14 11:50
您好,没有看懂您分享的附件,能麻烦您告知一下吗?谢谢
作者:
E58DHHDCRHCRTH
时间:
2019-12-25 12:48
谢谢楼主值得一看
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1