完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
一:思想
使用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 } 五:总结 以上就可以生成正弦波了,但是还缺少一点点东西把他们组织起来,大家自行添加就行;由于本人才学疏浅,不能将思路很好的梳理,只能提供代码供大家参考; |
|
|
|
只有小组成员才能发言,加入小组>>
3188 浏览 9 评论
2878 浏览 16 评论
3381 浏览 1 评论
8813 浏览 16 评论
3979 浏览 18 评论
9611浏览 3评论
981浏览 3评论
502浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
505浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2227浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-9-20 13:49 , Processed in 0.724718 second(s), Total 45, Slave 37 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号