"); //-->
玩了几天模拟电路,因做程控放大电路,需要输出可调电压,于是转战STM32上来了,采用DMA通道输出DAC,输出为一正弦波。
DAC配置略显简单,由于悟性不够,部分原因还是不懂。DMA通道传送DAC时,选取DAC_Channnel2程序很好使,而改为DAC_Channnel1时,相应地址等均作改变,但是就是没有波形输出,无果。
选用TIM2作定时器触发,TIM2在APB1上,最高频率36MHz,预分频系数为1时测出正弦波形频率经换算频率为72MHz,而预分频系数为2时,换算频率为36MHz,正常情况应该相等的,不明所以。查询资料,有博客上说,采用默认库配置,TIM2最高频率可以为72MHz,不理解。于是更改程序,自己配置时钟,预分频系数为1时依然为72MHz,而预分频系数为2时,频率为36MHz,无果
//purpose: DA转换,DAC1->PA4管脚输出转换后的模拟值 ,DAC2->PA5
// 产生正弦波频率= 主频/(TIM_Prescaler+1)/TIM_Period/产生一个正弦波的点数
#include "stm32f10x.h"
#define DAC_DHR12R2_Address 0x40007414 //相应地址通过数据手册和参考手册去查询
/* Init Structure definition */
DAC_InitTypeDef DAC_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
const uint16_t Sine12bit[32] = { //数据源用来产生波形
2047, 2447, 2831, 3185, 3498, 3750, 3939, 4056, 4095, 4056,
3939, 3750, 3495, 3185, 2831, 2447, 2047, 1647, 1263, 909,
599, 344, 155, 38, 0, 38, 155, 344, 599, 909, 1263, 1647};
uint32_t DualSine12bit[32];
uint32_t Idx = 0;
/* Private function prototypes -----------------------------------------------*/
void RCC_Configuration(void);
void TIM_Configuration(void);
void DAC_Configuration(void);
void DMA_Configuration(void);
void GPIO_Configuration(void);
int main(void)
{
/*!< At this stage the microcontroller clock setting is already configured,
this is done through SystemInit() function which is called from startup
file (startup_stm32f10x_xx.s) before to branch to application main.
To reconfigure the default setting of SystemInit() function, refer to
system_stm32f10x.c file
*/
// System Clocks Configuration
RCC_Configuration();
/* Once the DAC channel is enabled, the corresponding GPIO pin is automatically
connected to the DAC converter. In order to avoid parasitic consumption,
the GPIO pin should be configured in analog */
GPIO_Configuration();
TIM_Configuration();
DAC_Configuration();
for (Idx = 0; Idx < 32; Idx++)
{
DualSine12bit[Idx] = (Sine12bit[Idx] << 16) + (Sine12bit[Idx]); //双通道输出正弦波
}
DMA_Configuration();
/* Enable DMA for DAC Channel1 */
DAC_DMACmd(DAC_Channel_2, ENABLE);
/* TIM6 enable counter */
TIM_Cmd(TIM6, ENABLE);
while (1)
{
}
}
/**
* @brief Configures the different system clocks.
* @param None
* @retval None
*/
void RCC_Configuration(void)
{
//时钟配置,不使用库默认时钟配置
ErrorStatus HSEStartUpStatus; //定义外部高速晶体启动状态枚举变量
RCC_DeInit(); //复位RCC外部设备寄存器到默认值
RCC_HSEConfig(RCC_HSE_ON); //打开外部高速晶振
HSEStartUpStatus = RCC_WaitForHSEStartUp(); //等待外部高速时钟准备好
if(HSEStartUpStatus == SUCCESS) //外部高速时钟已经准别好
{
RCC_HCLKConfig(RCC_SYSCLK_Div1); //配置AHB(HCLK)时钟=SYSCLK
RCC_PCLK2Config(RCC_HCLK_Div1); //配置APB2(PCLK2)钟=AHB时钟
RCC_PCLK1Config(RCC_HCLK_Div2); //配置APB1(PCLK1)钟=AHB 1/2时钟
RCC_ADCCLKConfig(RCC_PCLK2_Div4); //配置ADC时钟=PCLK2 1/4
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); //配置PLL时钟 == 外部高速晶体时钟*9
RCC_ADCCLKConfig(RCC_PCLK2_Div4); //配置ADC时钟= PCLK2/4
RCC_PLLCmd(ENABLE); //使能PLL时钟
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) //等待PLL时钟就绪
{
}
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);//配置系统时钟 = PLL时钟
while(RCC_GetSYSCLKSource() != 0x08) //检查PLL时钟是否作为系统时钟
{
}
}
// DMA2 clock enable
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);
/* GPIOA Periph clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
/* DAC Periph clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);
/* TIM2 Periph clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);
}
void TIM_Configuration(void)
{
// Time base configuration
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
TIM_TimeBaseStructure.TIM_Period = 25-1; //计数周期25
TIM_TimeBaseStructure.TIM_Prescaler = 1-1; //预分频系数1
TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数
TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure);
// TIM6 TRGO selection */
TIM_SelectOutputTrigger(TIM6, TIM_TRGOSource_Update); //触发源更新
}
void DAC_Configuration(void)
{
// DAC channel1 Configuration
DAC_InitStructure.DAC_Trigger = DAC_Trigger_T6_TRGO; //DAC触发 TIM6触发
DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None; //不使用内部波形发生器
DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable; //关闭外部输出缓存
DAC_Init(DAC_Channel_1, &DAC_InitStructure); //用DAC输出波形,传输的数据比较多,所以采用DMA传输可以节省CPU的开支
DAC_Init(DAC_Channel_2, &DAC_InitStructure);
// Enable DAC Channel1: Once the DAC channel1 is enabled, PA.04 is automatically connected to the DAC converter
DAC_Cmd(DAC_Channel_1, ENABLE);
DAC_Cmd(DAC_Channel_2, ENABLE);
}
void DMA_Configuration(void)
{
DMA_DeInit(DMA2_Channel4); //将dma的通道寄存器设为默认值
DMA_InitStructure.DMA_PeripheralBaseAddr = DAC_DHR12R2_Address; //定义dma外设基地址
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&Sine12bit;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //外设作为数据传输的目的地
DMA_InitStructure.DMA_BufferSize = 32; //dma缓存大小
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址寄存器不变
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址寄存器 递增
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //外设数据宽度
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //工作在循环缓存模式,数据传输数目为0时,自动恢复配置初值
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //通道未被设置成内存到内存模式,与循环模式相对
DMA_Init(DMA2_Channel4, &DMA_InitStructure); //将DMA_InitStructure中指定的参数初始化dma的通道寄存器
// Enable DMA2 Channel4
DMA_Cmd(DMA2_Channel4, ENABLE); //使能通道
}
/**
* @brief Configures the different GPIO ports.
* @param None
* @retval None
*/
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Once the DAC channel is enabled, the corresponding GPIO pin is automatically
connected to the DAC converter. In order to avoid parasitic consumption,
the GPIO pin should be configured in analog */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5; //一旦DAC通道使能,相应的GPIO PA4,PA5自动与DAC的模拟输出相连,
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //为了避免避免寄生的干扰和额外的功耗,PA4 置成模拟输入
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
专栏文章内容及配图由作者撰写发布,仅供工程师学习之用,如有侵权或者其他违规问题,请联系本站处理。 联系我们
相关推荐
2010年英特尔杯大学生嵌入式设计大赛宣传片 ②
CRC 校验源码分析
[求助]那位有cygnal 下载Flash电路?
我想开一家虚拟公司
2003年嵌入式世界研讨暨展示会会议通知
大连Moblin研讨会视频 II
crc16 another one
LimX筹集2亿美元用于构建具身智能
RF2152构成的824~849MHz功率放大电路图
机器人技术将颠覆人工智能基础设施:未来之路何在
ComCapture 1.0
别监管人工智能模型,要监管人工智能的使用
CAN应用
RF2155可编程增益功率放大器引脚
IDF 2010 MeeGo展区QT介绍
RF2152构成的877~924MHz功率放大电路图
利用高压母线转换模块 (BCM) 为LED驱动器供电
cajviewer软件
Material公司的电池为每个角落提供电力
TACC借助 Horizon 系统探索高性能计算混合精度与 FP64 仿真技术
莫悲观,车企迎来盈利增长转折点
IEEE审议神经科技消费品的安全指南
类脑计算机也能做数学
2010年英特尔杯大学生嵌入式设计大赛宣传片 ③
“漏音”6G芯片技术击败了狭窄的太赫兹束限制
RF2162 900MHz线性放大器引脚
RF2155构成的915MHz功率放大器应用电路图
自己动手打造嵌入式Linux软硬件开发环境
RealTek推出无线芯片!
Gartner再度预测人工智能支出趋势