单片机学习小组
直播中

张龙祥

8年用户 1230经验值
擅长:连接器
私信 关注

STM32如何使用DMA产生正弦波/三角波/方波?

STM32如何使用DMA产生正弦波/三角波/方波?

回帖(1)

洪欣意

2022-1-21 11:17:31
一:思想
使用stm32产生波形当然肯定要用到DAC了,这是必不可少的,虽然stm32自带三角波生成器,但这里我们主要用dma,这样不论想生成什么波形都可以,只要构造出相应函数列表;


二:函数列表实现


主要就是采样法,在一个波形图上选取多个点,然后把相应数值存起来,等待调用(DMA循环调用),然后通过DAC把数值转换,最后近似得到波形,这种方法其实也就是数学中的描点法;
正弦波:


u16 D_sin[256];
void SineWave_Data()
{
        u16 i;
        for( i=0;i<=255;i++)
        {
                D_sin=(u16)(4095*(sin(i*2*3.1415926/255)+1)/2);
        }
}


方波:


u16 D_fang[N];
void Fang_Data()
{
        u16 i;
        for(i=0;i         {
                D_fang= (u16)(0);
        }
        for( i=N/2;i         {
                D_fang=(u16)(4095);
        }
}


三角波:


u16 D_saw[N];
void Saw_Data()
{
        u16 i;
        for( i=0;i         {
                D_saw= (u16)(4095*2*i/N);
        }
        for( i=N/2;i         {
                D_saw= (u16)(2*4095*(N-i)/N);
        }
}


把生成的数存到相应的数组里就行,等待DMA调用;


三:按键控制频率增减:
//按键初始化


void KEY_init()
{
        RCC->APB2ENR|=1<<2;     //使能PORTA时钟
        RCC->APB2ENR|=1<<4;     //使能PORTC时钟
        //JTAG_Set(SWD_ENABLE);        //关闭JTAG,开启SWD
        GPIOA->CRL&=0XFFFFFFF0;        //PA0设置成输入          
        GPIOA->CRL|=0X00000008;   
        GPIOA->CRH&=0X0FFFFFFF;        //PA15设置成输入          
        GPIOA->CRH|=0X80000000;                          
        GPIOA->ODR|=1<<15;                   //PA15上拉,PA0默认下拉
        GPIOC->CRL&=0XFF0FFFFF;        //PC5设置成输入          
        GPIOC->CRL|=0X00800000;   
        GPIOC->ODR|=1<<5;                   //PC5上拉
}


//主函数按键控制部分


//方波和正弦波按键控制
if(KEY_0 == 0 && mode==0 )
        {
                delay_ms(10);
                fang_Hz +=1;
                saw_Hz +=1;
                mode=1;
        }
else if(KEY_1==0 && mode==0)
        {
                delay_ms(10);
                fang_Hz -=1;
                saw_Hz -=1;
                mode=1;
        }
if(KEY_0 == 1 && KEY_1==1)
                mode=0;
Init_config(fang_Hz,saw_Hz);//将按键控制加入


四:DAC,DMA,TIME初始化;
//这里只列举正弦波


//DAC初始化
void Dac1_Init()//用于正弦波产生
{
        RCC->APB1ENR|=1<<29; //使能 DAC 时钟
        RCC->APB2ENR|=1<<2; //使能 PORTA 时钟
        GPIOA->CRL&=0XFFF0FFFF;
        GPIOA->CRL|=0X00000000; //PA4 模拟输入
        DAC->CR|=1<<0; //使能 DAC1
        DAC->CR|=1<<2; //使用触发功能 TEN1=1
        DAC->CR|=0<<1; //DAC1 输出缓存不使能 BOFF1=1
        DAC->CR|=4<<3; //DAC TIM2 TRGO,不过要 TEN1=1 才行
        DAC->CR|=0<<6; //不使用波形发生
        DAC->CR|=0<<8;//幅值设置
        DAC->CR|=1<<12;//DAC1 DMA 使能
        DAC->DHR12R1=0;
}
//DMA初始化
void DMA2_init1()
{
            RCC->AHBENR|=1<<1; //开启 DMA2 时钟
                        delay_ms(5); //等待 DMA 时钟稳定
                        DMA2_Channel3->CPAR=(u32)&(DAC->DHR12R1);                  //DMA2 外设地址
                        DMA2_Channel3->CMAR=(u32)D_sin;         //DMA2,存储器地址
                        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传输
}
//定时器初始化
void TIM2_Int_Init(u16 arr)//初始化TIM2--正弦
{
        RCC->APB1ENR|=1<<0; //TIM2 时钟使能
        TIM2->CR1|=0<<4;//向上计数模式
        TIM2->ARR=arr; //设定计数器自动重装值
        TIM2->PSC=0; //预分频器 7200,得到 10Khz 的计数时钟 频率=72000/(899+1)=80Khz
        TIM2->CR2|=2<<4; //选择更新事件作为触发中断(TRGO)
        TIM2->CR1|=0x01; //使能定时器2
}


五:总结
以上就可以生成正弦波了,但是还缺少一点点东西把他们组织起来,大家自行添加就行;由于本人才学疏浅,不能将思路很好的梳理,只能提供代码供大家参考;
举报

更多回帖

×
20
完善资料,
赚取积分