单片机
返回首页

STM32F103ZET6任意频率正弦波+三角波工程源码

2019-10-15 来源:eefocus

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        {

                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        {

                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);

}


进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • 家用电源无载自动断电装置的设计与制作

  • PIC单片机控制的遥控防盗报警器电路

  • 使用ESP8266从NTP服务器获取时间并在OLED显示器上显示

  • 开关电源的基本组成及工作原理

  • RS-485基础知识:处理空闲总线条件的两种常见方法

  • 基于TDA2003的简单低功耗汽车立体声放大器电路

    相关电子头条文章