STM32
直播中

Arvinhw

9年用户 899经验值
擅长:嵌入式技术
私信 关注
[问答]

STM32f103输出正弦波/锯齿波/方波的代码分享

STM32f103输出正弦波/锯齿波/方波的代码分享

回帖(1)

张桂兰

2021-12-14 10:56:21
main.c


#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 ,100 ,ENABLE ,SinWave ,100 ,ENABLE);//PA4输出为        10Hz的三角波;PA5输出为10Hz的正弦波
        printf("The Program is running!!!n");
        while(1)
        {/********KEY3为增加频率,KEY1为减少频率;*/
                static u16 f=1000;
                if( KEY_Scan(0)==4)
                        {
                                f +=10000;
                                if(f>15000)        f=15000;
                                Set_WaveFre( Wave_Channel_1 ,f);
                        }
                else if( KEY_Scan(0)==2)
                        {
                                f -=10000;
                                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=(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= (u16)(1.0*i/255*4095);
       
        }
        for( i=cycle/2;i         {
                D= (u16)(1.0*(cycle-i)/255*4095);
        }
}
/***** 生成方波输出表***************/
void FangTooth_Data( u16 cycle ,u16 *D)
{
        u16 i;
        for(i=0;i         {
        D=(u16)(1.0*cycle);
        }
        for(i=0;i         {
        D=(u16)0;
        }
}


/******************正弦波形表***********************/
#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|=0<<11;
                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|=0<<27;
                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);
}
举报

更多回帖

×
20
完善资料,
赚取积分