用STM32做了一个TIM+DMA的DAC波形发生器,无波形输出,烦大神...
时间:10-02
整理:3721RD
点击:
#include"stm32f10x_lib.h"
#include"stm32f10x_flash.h"
#include"stm32f10x_usart.h"
#define DAC1_D0R1_Address ((u32)0x40012400+0x2c)
#define DAC2_DOR2_Address ((u32)0x40012400+0x30)
u32 DAC1_ConvertedValue[32];
u32 DAC2_ConvertedValue[32];
/*
*/
/*********************************************************************
*函數名:RCC_DAC_Init(void)
*描述 :時鐘配置
*輸入 :無
*輸出 :無
*調用 :內部調用
**********************************************************************/
void RCC_Configuration(void)
{
ErrorStatus HSEStartUpStatus;
// RCC system reset(for debug purpose)
RCC_DeInit(); 7
// Enable HSE */
RCC_HSEConfig(RCC_HSE_ON);
// Wait till HSE is ready
HSEStartUpStatus = RCC_WaitForHSEStartUp();
if(HSEStartUpStatus == SUCCESS)
{
// Enable Prefetch Buffer
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
FLASH_SetLatency(FLASH_Latency_2);
RCC_HCLKConfig(RCC_SYSCLK_Div1);
// PCLK2 = HCLK
RCC_PCLK2Config(RCC_HCLK_Div1);
//PCLK1 = HCLK
RCC_PCLK1Config(RCC_HCLK_Div2);
// PLLCLK = 8MHz * 9 = 72 MHz
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_3);
//Enable PLL
RCC_PLLCmd(ENABLE);
// Wait till PLL is ready //
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
{
}
//Select PLL as system clock source
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
// Wait till PLL is used as system clock source
while(RCC_GetSYSCLKSource() != 0x08)
{
}
}
//Enable peripheral clocks -------------------------------------------------
//DMA clock enable
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);
//AFIO and GPIOA Periph clock enable
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA, ENABLE);
//DAC Periph clock enable
RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);
//TIM8 Periph clock enable
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);
}
/*
*/
/*********************************************************************
*函數名:void TIM6_Configuration(void)
*描述 :計時器配置
*輸入 :無
*輸出 :無
*調用 :內部調用
**********************************************************************/
void TIM6_Configuration(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);
TIM_DeInit(TIM6);
//根据音频采样率为44.1khz所以定时器设为2.26us触发DMA
//下一個更新事件裝入活動的自動重裝寄存器週期的值
TIM_TimeBaseStructure.TIM_Period = 1633;
//預分頻值 ,部位零時輸出始終需除以 TIM_Prescaler
TIM_TimeBaseStructure.TIM_Prescaler = 0;
//时钟分频
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_div1;
//向上计数方式
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
//根據TimeBaseStructure中指定的参数初始化TIMx 的时间基数单位
TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure);
//清除待處理標誌位
TIM_ITConfig(TIM6,TIM_IT_Update, ENABLE);
TIM_Cmd(TIM6, ENABLE);
}
/*
*/
/*********************************************************************
*函數名:GPIO_DAC_Init(void)
*描述 :DAC引腳配置
*輸入 :無
*輸出 :無
*調用 :內部調用
**********************************************************************/
void GPIO_DAC_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
//端口配置
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_4|GPIO_Pin_5;
//模擬輸出
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;
//50Hz
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
//初始化端口
GPIO_Init(GPIOA,&GPIO_InitStructure);
//將DAC端口初始化后設置為高電平
GPIO_SetBits(GPIOA,GPIO_Pin_4|GPIO_Pin_5);
}
/*
*/
/*********************************************************************
*函數名:DAC_All——Init
*描述 :DA轉換相關端口時鐘配置
*輸入 :無
*輸出 :無
*調用 :內部調用
**********************************************************************/
void DAC_All_Init(void)
{
//定義一個結構體
DAC_InitTypeDef DAC_InitType;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);
//选择定时器6作外部触发源
DAC_InitType.DAC_Trigger = DAC_Trigger_T6_TRGO;
//無波形產生
DAC_InitType.DAC_WaveGeneration=DAC_WaveGeneration_None;
//DAC輸出緩衝使能
DAC_InitType.DAC_LFSRUnmask_TriangleAmplitude=DAC_LFSRUnmask_Bit0;
DAC_InitType.DAC_OutputBuffer=DAC_OutputBuffer_Disable;
// 初始化DAC1、DAC2
DAC_Init(DAC_Channel_1|DAC_Channel_2,&DAC_InitType);
//設置數據右對齊,轉換值設置為0
DAC_SetChannel1Data(DAC_Align_12b_R,0);
//設置數據右對齊,轉換值設置為0
DAC_SetChannel2Data(DAC_Align_12b_R,0);
DAC_Cmd(DAC_Channel_1|DAC_Channel_2,ENABLE);
//DAC的DMA傳輸
DAC_DMACmd(DAC_Channel_1,ENABLE);
DAC_DMACmd(DAC_Channel_2,ENABLE);
}
/*
*/
/*********************************************************************
*函數名:DMA_DAC_Init(void)
*描述 :配置DAC的DMA傳輸方式
*輸入 :無
*輸出 :無
*調用 :內部調用
**********************************************************************/
void DMA_DAC_Init(void)
{
DMA_InitTypeDef DMA_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);
/* DMA通道配置*/
DMA_DeInit(DMA2_Channel3);
//DMA外設基DAC1地址
DMA_InitStructure.DMA_PeripheralBaseAddr = DAC1_D0R1_Address;
//DMA内存基地址
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&DAC1_ConvertedValue;
//外設作為數據傳輸的目的地
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
//定義DMA緩存的大小
DMA_InitStructure.DMA_BufferSize =32*16;
//外设寄存器地址固定
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
//内存地址固定
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
//設定外設的數據寬度為半字(16位)
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
//設定外設的數據寬度
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
//循环传输
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
//設置通道11的優先級為高
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
//申明非內存到內存傳輸
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA2_Channel3, &DMA_InitStructure);
DMA_Cmd(DMA2_Channel3, ENABLE);
DAC_DMACmd(DAC_Channel_1, ENABLE);
/**************/
/* DMA通道配置*/
DMA_DeInit(DMA2_Channel4);
//DMA外設基DAC2地址
DMA_InitStructure.DMA_PeripheralBaseAddr = DAC2_DOR2_Address;
//DMA内存基地址
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&DAC2_ConvertedValue;
//外設作為數據傳輸的目的地
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
//定義DMA緩存的大小
DMA_InitStructure.DMA_BufferSize =32*16;
//外设寄存器地址固定
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
//内存地址固定
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
//設定外設的數據寬度為半字(16位)
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
//設定外設的數據寬度
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
//循环传输
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
//設置通道11的優先級為高
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
//申明非內存到內存傳輸
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA2_Channel4, &DMA_InitStructure);
//使能DMA
/* Enable DMA channel1 */
DMA_Cmd(DMA2_Channel4, ENABLE);
DAC_DMACmd(DAC_Channel_2, ENABLE);
}
/*
*/
/*********************************************************************
*函數名:void DAC_DMA_TIM_Config(void)
*描述 :配置DAC的工作方式
*輸入 :無
*輸出 :無
*調用 :外部調用
**********************************************************************/
void DAC_DMA_TIM_Config(void)
{
RCC_Configuration();
TIM6_Configuration();
GPIO_DAC_Init();
DMA_DAC_Init();
DAC_All_Init();
}
主程序主要操作是在DAC2_ConvertedValue[32]数组中加入数据
,然后调用 DAC_DMA_TIM_Config()函数初始化DAC
只有开机时输出一个周期的波形,后续均没有波形,求大神指点啊
#include"stm32f10x_flash.h"
#include"stm32f10x_usart.h"
#define DAC1_D0R1_Address ((u32)0x40012400+0x2c)
#define DAC2_DOR2_Address ((u32)0x40012400+0x30)
u32 DAC1_ConvertedValue[32];
u32 DAC2_ConvertedValue[32];
/*
*/
/*********************************************************************
*函數名:RCC_DAC_Init(void)
*描述 :時鐘配置
*輸入 :無
*輸出 :無
*調用 :內部調用
**********************************************************************/
void RCC_Configuration(void)
{
ErrorStatus HSEStartUpStatus;
// RCC system reset(for debug purpose)
RCC_DeInit(); 7
// Enable HSE */
RCC_HSEConfig(RCC_HSE_ON);
// Wait till HSE is ready
HSEStartUpStatus = RCC_WaitForHSEStartUp();
if(HSEStartUpStatus == SUCCESS)
{
// Enable Prefetch Buffer
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
FLASH_SetLatency(FLASH_Latency_2);
RCC_HCLKConfig(RCC_SYSCLK_Div1);
// PCLK2 = HCLK
RCC_PCLK2Config(RCC_HCLK_Div1);
//PCLK1 = HCLK
RCC_PCLK1Config(RCC_HCLK_Div2);
// PLLCLK = 8MHz * 9 = 72 MHz
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_3);
//Enable PLL
RCC_PLLCmd(ENABLE);
// Wait till PLL is ready //
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
{
}
//Select PLL as system clock source
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
// Wait till PLL is used as system clock source
while(RCC_GetSYSCLKSource() != 0x08)
{
}
}
//Enable peripheral clocks -------------------------------------------------
//DMA clock enable
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);
//AFIO and GPIOA Periph clock enable
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA, ENABLE);
//DAC Periph clock enable
RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);
//TIM8 Periph clock enable
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);
}
/*
*/
/*********************************************************************
*函數名:void TIM6_Configuration(void)
*描述 :計時器配置
*輸入 :無
*輸出 :無
*調用 :內部調用
**********************************************************************/
void TIM6_Configuration(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);
TIM_DeInit(TIM6);
//根据音频采样率为44.1khz所以定时器设为2.26us触发DMA
//下一個更新事件裝入活動的自動重裝寄存器週期的值
TIM_TimeBaseStructure.TIM_Period = 1633;
//預分頻值 ,部位零時輸出始終需除以 TIM_Prescaler
TIM_TimeBaseStructure.TIM_Prescaler = 0;
//时钟分频
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_div1;
//向上计数方式
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
//根據TimeBaseStructure中指定的参数初始化TIMx 的时间基数单位
TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure);
//清除待處理標誌位
TIM_ITConfig(TIM6,TIM_IT_Update, ENABLE);
TIM_Cmd(TIM6, ENABLE);
}
/*
*/
/*********************************************************************
*函數名:GPIO_DAC_Init(void)
*描述 :DAC引腳配置
*輸入 :無
*輸出 :無
*調用 :內部調用
**********************************************************************/
void GPIO_DAC_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
//端口配置
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_4|GPIO_Pin_5;
//模擬輸出
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;
//50Hz
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
//初始化端口
GPIO_Init(GPIOA,&GPIO_InitStructure);
//將DAC端口初始化后設置為高電平
GPIO_SetBits(GPIOA,GPIO_Pin_4|GPIO_Pin_5);
}
/*
*/
/*********************************************************************
*函數名:DAC_All——Init
*描述 :DA轉換相關端口時鐘配置
*輸入 :無
*輸出 :無
*調用 :內部調用
**********************************************************************/
void DAC_All_Init(void)
{
//定義一個結構體
DAC_InitTypeDef DAC_InitType;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);
//选择定时器6作外部触发源
DAC_InitType.DAC_Trigger = DAC_Trigger_T6_TRGO;
//無波形產生
DAC_InitType.DAC_WaveGeneration=DAC_WaveGeneration_None;
//DAC輸出緩衝使能
DAC_InitType.DAC_LFSRUnmask_TriangleAmplitude=DAC_LFSRUnmask_Bit0;
DAC_InitType.DAC_OutputBuffer=DAC_OutputBuffer_Disable;
// 初始化DAC1、DAC2
DAC_Init(DAC_Channel_1|DAC_Channel_2,&DAC_InitType);
//設置數據右對齊,轉換值設置為0
DAC_SetChannel1Data(DAC_Align_12b_R,0);
//設置數據右對齊,轉換值設置為0
DAC_SetChannel2Data(DAC_Align_12b_R,0);
DAC_Cmd(DAC_Channel_1|DAC_Channel_2,ENABLE);
//DAC的DMA傳輸
DAC_DMACmd(DAC_Channel_1,ENABLE);
DAC_DMACmd(DAC_Channel_2,ENABLE);
}
/*
*/
/*********************************************************************
*函數名:DMA_DAC_Init(void)
*描述 :配置DAC的DMA傳輸方式
*輸入 :無
*輸出 :無
*調用 :內部調用
**********************************************************************/
void DMA_DAC_Init(void)
{
DMA_InitTypeDef DMA_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);
/* DMA通道配置*/
DMA_DeInit(DMA2_Channel3);
//DMA外設基DAC1地址
DMA_InitStructure.DMA_PeripheralBaseAddr = DAC1_D0R1_Address;
//DMA内存基地址
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&DAC1_ConvertedValue;
//外設作為數據傳輸的目的地
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
//定義DMA緩存的大小
DMA_InitStructure.DMA_BufferSize =32*16;
//外设寄存器地址固定
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
//内存地址固定
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
//設定外設的數據寬度為半字(16位)
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
//設定外設的數據寬度
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
//循环传输
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
//設置通道11的優先級為高
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
//申明非內存到內存傳輸
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA2_Channel3, &DMA_InitStructure);
DMA_Cmd(DMA2_Channel3, ENABLE);
DAC_DMACmd(DAC_Channel_1, ENABLE);
/**************/
/* DMA通道配置*/
DMA_DeInit(DMA2_Channel4);
//DMA外設基DAC2地址
DMA_InitStructure.DMA_PeripheralBaseAddr = DAC2_DOR2_Address;
//DMA内存基地址
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&DAC2_ConvertedValue;
//外設作為數據傳輸的目的地
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
//定義DMA緩存的大小
DMA_InitStructure.DMA_BufferSize =32*16;
//外设寄存器地址固定
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
//内存地址固定
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
//設定外設的數據寬度為半字(16位)
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
//設定外設的數據寬度
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
//循环传输
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
//設置通道11的優先級為高
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
//申明非內存到內存傳輸
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA2_Channel4, &DMA_InitStructure);
//使能DMA
/* Enable DMA channel1 */
DMA_Cmd(DMA2_Channel4, ENABLE);
DAC_DMACmd(DAC_Channel_2, ENABLE);
}
/*
*/
/*********************************************************************
*函數名:void DAC_DMA_TIM_Config(void)
*描述 :配置DAC的工作方式
*輸入 :無
*輸出 :無
*調用 :外部調用
**********************************************************************/
void DAC_DMA_TIM_Config(void)
{
RCC_Configuration();
TIM6_Configuration();
GPIO_DAC_Init();
DMA_DAC_Init();
DAC_All_Init();
}
主程序主要操作是在DAC2_ConvertedValue[32]数组中加入数据
,然后调用 DAC_DMA_TIM_Config()函数初始化DAC
只有开机时输出一个周期的波形,后续均没有波形,求大神指点啊
看都没人看一眼吗?
看了好几眼了,但自己真心不是大神,同志你要努力啊!
感谢你看了 好几眼,目前已经解决了 大致是外设地址定义错误,还有线初始化DAC在初始化GPIO 貌似是这样的 波形目前测量到了,具体还未调整,搞了这么久,终于有点进步,欣喜若狂
请问有源码吗 我也在做这个 好头疼 好多都不太会
上面已经说得很清楚了 稍微改下就可以了 你试试
上面已经说得很清楚了 稍微改下就可以了 你试试
“还有线初始化DAC在初始化GPIO”,小编,这个顺序有问题么?不都是先初始化GPIO在初始化DAC么?
是的,这是必须的
#define DAC1_D0R1_Address ((u32)0x40012400+0x2c)
#define DAC2_DOR2_Address ((u32)0x40012400+0x30)
DOR1,DOR2 是禁止用户写的,你地址用错了,具体要用DAC_DHR12R2_ADDR这类的地址,手册有说明
