一、准备工作:
有关CUBEMX的初始化配置,参见我的另一篇blog:【STM32+HAL】CUBEMX初始化配置
二、所用工具:
1、芯片: STM32F407ZGT6
2、STM32CubeMx软件
3、IDE: MDK-Keil软件
4、STM32F4xxHAL库
三、实现功能:
1、DAC+DMA输出波形
2、按键切换波形及频率
3、串口打印当前波形以及频率值
四、HAL库配置 (初始配置完成):
1、开启DAC
这里开启的是通道一
Output Buffer:关闭后可输出更低的电压值
Trigger:触发方式,这里选择TIM2定时器触发
Wave generation mode:关闭后可输出自定义波形
2、开启DMA
Mode:选择循环
Data Width:发送数据长度,半字即可
3、配置定时器
初始化定时器触发频率为1:84MHZ / 84 / 100 =1000HZ
触发事件选择“更新触发事件”
4、配置按键
根据你的原理图选择合适的参数
5、配置中断优先级
至此,CUBEMX配置完成
五、KEIL填写代码:
1、初始化DAC、DMA、TIM2
HAL_TIM_Base_Start(&htim2);
HAL_DAC_SetValue(&hdac, DAC_CHANNEL_1,DAC_ALIGN_12B_R,0);
HAL_DAC_Start(&hdac, DAC_CHANNEL_1);
2、按键中断改变波形频率
直流电压:0-3V,按键可调,步进0.1V
方波:Vpp=3V,频率1k-10k,步进1k
三角波:Vpp=3V,频率5k-10k,步进1k
正弦波:Vpp=3V,频率25k-50k,步进5k
MC波:自定义波形,频率200HZ,VPP=2V
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
UNUSED(GPIO_Pin);
if(GPIO_Pin == GPIO_PIN_0){ //按键切换波形
HAL_Delay(20);
if(GPIO_Pin == GPIO_PIN_0){
dac_mode=(dac_mode+1)%5; //一共5种波形
switch(dac_mode){
case 0: //直流电压
dy_10=0;
pl_100=2;
HAL_DAC_Stop_DMA(&hdac, DAC_CHANNEL_1);
//HAL_DAC_Stop(&hdac, DAC_CHANNEL_1);
HAL_Delay(3);
HAL_DAC_SetValue(&hdac, DAC_CHANNEL_1,DAC_ALIGN_12B_R,dy);
HAL_DAC_Start(&hdac, DAC_CHANNEL_1);
break;
case 1: //方波
pl_100=10;
dy_10=30;
finds(65625/pl_100/10,&B,&C);
HAL_DAC_Stop(&hdac, DAC_CHANNEL_1);
HAL_Delay(3);
HAL_DAC_Start_DMA(&hdac, DAC_CHANNEL_1, (uint32_t*)&Square, 128, DAC_ALIGN_12B_R);break;
case 2: //三角波
pl_100=50;
finds(65625/pl_100/10,&B,&C);
dy_10=30;
HAL_DAC_Stop_DMA(&hdac, DAC_CHANNEL_1);
HAL_Delay(3);
HAL_DAC_Start_DMA(&hdac, DAC_CHANNEL_1, (uint32_t*)&Triangle, 128, DAC_ALIGN_12B_R);break;
case 3: //正弦波
pl_100=250;
finds(262500/pl_100/10,&B,&C);
dy_10=30;
HAL_DAC_Stop_DMA(&hdac, DAC_CHANNEL_1);
HAL_Delay(3);
HAL_DAC_Start_DMA(&hdac, DAC_CHANNEL_1, (uint32_t*)&Sin, 32, DAC_ALIGN_12B_R);break;
case 4: //MC波
pl_100=2;
TIM2->ARR=100-1;
TIM2->PSC=36-1;
dy_10=20;
HAL_DAC_Stop_DMA(&hdac, DAC_CHANNEL_1);
HAL_Delay(3);
HAL_DAC_Start_DMA(&hdac, DAC_CHANNEL_1, (uint32_t*)&MC, 300, DAC_ALIGN_12B_R);
break;
default:break;
}
}
}
if(GPIO_Pin == GPIO_PIN_8){ //按键切换电压
HAL_Delay(20);
if(GPIO_Pin == GPIO_PIN_8){
if(dy_10 > 30) dy_10=0;
else dy_10=dy_10+1;
dy=dy_10*4096/33+20;
//HAL_DAC_Stop(&hdac, DAC_CHANNEL_1);
HAL_DAC_SetValue(&hdac, DAC_CHANNEL_1,DAC_ALIGN_12B_R,dy);
HAL_DAC_Start(&hdac, DAC_CHANNEL_1);
}
}
if(GPIO_Pin == GPIO_PIN_9){ //按键切换频率
HAL_Delay(20);
if(GPIO_Pin == GPIO_PIN_9){
switch(dac_mode){
case 1: pl_100 = (pl_100>=100)?10:pl_100+10;finds(65625/pl_100/10,&B,&C);break;
case 2: pl_100 = (pl_100>=100)?50:pl_100+10;finds(65625/pl_100/10,&B,&C);break;
case 3: pl_100 = (pl_100>=500)?250:pl_100+50;finds(262500/pl_100/10,&B,&C);break;
default: pl_100 = 2;break;
}
}
}
printf("模式:%s 频率:%dHz Vpp:%.1fV\r\n\r\n\r\n\r\n",Mode[dac_mode],pl_100*100,(double)dy_10/10); //串口输出
}
3、自定义函数finds
此函数计算当频率pl给定时,PSC和ARR乘积何时最接近pl
void finds(int A, int *B, int *C) {
int sqrtA = sqrt(A),ii;
for (ii = sqrtA; ii > 0; ii--) {
if (A % ii == 0) {
int j = A / ii;
if (j <= 65535) {
*B = ii;
*C = j;
break;
}
}
}
TIM2->ARR=*C-1;
TIM2->PSC=*B-1;
}
完工
六、原理讲解
STM32CubeMX学习笔记(20)——DAC接口使用(输出正弦波)
【STM32】HAL库 STM32CubeMX教程十---DAC
STM32cubemx教程 DAC+TIM+DMA文章来源:https://www.toymoban.com/news/detail-784189.html
七、源码提供(包括各波形的数据数组)
STM32DAC+DMA输出波形文章来源地址https://www.toymoban.com/news/detail-784189.html
到了这里,关于【STM32+HAL】DAC+DMA输出波形实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!