小弟最近再做一个刺激仪,项目截止时间临近,我却卡在了正弦信号发生上,已经找了两天了也没发现问题所在,在此求论坛大神帮忙分析分析。
我使用STM32的DMA2+DAC1来产生正弦波,参考自网上的程序
DAC1和TIM6设置如下:
void Dac1_Dma_Init(u16 arr)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
DAC_InitTypeDef DAC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE ); //使能PORTA通道时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC | RCC_APB1Periph_TIM6, ENABLE ); //使能DAC通道和定时器6时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; // 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_SetBits(GPIOA,GPIO_Pin_4) ;//PA.4 输出高 DAC1
TIM_TimeBaseStructure.TIM_Period = arr; //初装值 72 每秒产生1 000 000次更新
TIM_TimeBaseStructure.TIM_Prescaler = 72;
TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure);
TIM_SelectOutputTrigger(TIM6, TIM_TRGOSource_Update); //使用更新事件作为触发输出
DAC_InitStructure.DAC_Trigger = DAC_Trigger_T6_TRGO; //转换触发为tim6的更新
DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;
DAC_SetChannel1Data(DAC_Align_12b_R,0); //
DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable; //不使用输出缓冲放大器
DAC_Init(DAC_Channel_1, &DAC_InitStructure);
DAC_Cmd(DAC_Channel_1, ENABLE); //使能DAC1
DAC_SetChannel1Data(DAC_Align_12b_R, 0); //12位右对齐数据格式设置DAC值
// TIM_Cmd(TIM6, ENABLE); //使能TIM6
}
DMA设置如下:
void MYDMA_Config(DMA_Channel_TypeDef* DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)
{
DMA_InitTypeDef DMA_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE); //使能DMA传输
DMA_DeInit(DMA_CHx); //将DMA的通道1寄存器重设为缺省值
DMA2_MEM_LEN=cndtr;
DMA_InitStructure.DMA_PeripheralBaseAddr = cpar; //DMA外设ADC基地址
DMA_InitStructure.DMA_MemoryBaseAddr = cmar; //DMA内存基地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //数据传输方向,从内存读取发送到外设
DMA_InitStructure.DMA_BufferSize = cndtr; //DMA通道的DMA缓存的大小
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址寄存器不变
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址寄存器递增
DMA_InitStructure.DMA_PeripheralDataSize = DMA_MemoryDataSize_HalfWord; //数据宽度为16位
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //数据宽度为16位
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //工作在循环模式
DMA_InitStructure.DMA_Priority = DMA_Priority_High; //DMA通道 x拥有中优先级
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //DMA通道x没有设置为内存到内存传输
DMA_Init(DMA_CHx, &DMA_InitStructure); //根据DMA_InitStruct中指定的参数初始化DMA的通道USART1_Tx_DMA_Channel所标识的寄存器
}
主函数中调用相关函数并启动定时器:
Dac1_Dma_Init(100);
MYDMA_Config(DMA2_Channel3,DAC_DHR12R1_Address,(u32)sinu_buffer,800);
DMA_Cmd(DMA2_Channel3, ENABLE);
DAC_DMACmd(DAC_Channel_1, ENABLE);
TIM_Cmd(TIM6, ENABLE); //使能TIM6
sinu_buffer是正弦表地址
DAC_DHR12R1_Address定义为#define DAC_DHR12R1_Address 0x40007408
可是就是不出正弦信号,哪位大神给分析一下,小弟先谢过了。
注释有些是错误的,因为是修改了原子的开发板的程序,有些注释没改掉
使能软件触发DAC_SoftwareTriggerCmd
谢谢您的帮助,加上这段代码后果然有信号输出了,不过信号是乱的,后来我又试着改了一下,发现在DMA的时钟开启后要过一段延时再配置其寄存器,才能输出正确信号,但我用STM32的其他模块的时候都是开启时钟后直接配置寄存器的,不知道这是不是STM32的BUG。
请问楼主当时遇到的情况具体是怎么样的?我现在也调到了一个DAC DMA程序的问题,不过是与自制的上位机的函数信号发生器面板相连,奇怪的是只有几个特定的情况的有波形,其他一概没有波行输出!回复的话请直接发我邮箱
405288375@qq.com