| 本帖最后由 wenyangzeng 于 2017-2-26 21:51 编辑 
 收到《我与STM32共成长》奖品STM32F413 Nucleo,谢谢社区。应该为它发一贴。
 
 
   
 STM32F413ZHT6是Cortex-M4内核,
 主频:100MHz,125DMIPS
 1.5MB Flash,320KB RAM
 低功耗:运行模式115μA/MHz,停止模式18μA
 增强型批量数据采集模式(eBAM)
 更多的外设:10通道UART,3通道CAN, 低功耗定时器,
 另外还比F412多了2路DAC。
 
 未能找到官方演示代码中关于F413 DAC的演示,本次评测与各位分享对F413进行DAC配置的步骤方法。
 
 选用通道:DAC通道1(GPIOA4);
 输出信号:1KHZ正弦波
 信号处理方式:DMA,12位DAC
 触发源:TIM6
 
 
   
 STM32F413 Nucleo板上HSE晶振没有焊接,我们选用内部时钟源HSI作为系统时钟源,并配置为100MHZ。
 
 
   
 使能DAC通道1
 
 
   
 使能TIM6,用它来触发DAC
 
 
   
 配置DAC1:
 Output Buffer:Enable
 Trigger:Timer 6 Trigger Out event
 Wave generation mode:disable
 
   配置TIM6
 Prescaler(PSC - 16 bits value):0
 Counter Mode:Up
 Counter Period(AutoReload Registor:0xc40
 Trigger Event Selection:Update Event
 
   
 配置DMA传输
 DMARequest  :DAC1
 Stream  :  DMA1 Stream  5
 Direction :   Menory To Preipheral
 Priority  :  Low
 Mode   : Circular
 Inceement Address : Memory
 Data width  :Half Word
 
 代码:
 
 复制代码#include "main.h"
#include "stm32f4xx_hal.h"
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};
DAC_HandleTypeDef hdac;
DMA_HandleTypeDef hdma_dac1;
TIM_HandleTypeDef htim6;
void SystemClock_Config(void);
void Error_Handler(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_DAC_Init(void);
static void MX_TIM6_Init(void);
int main(void)
{
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_DAC_Init();
  MX_TIM6_Init();
  while (1)
  {
  }
}
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct;
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
  __HAL_RCC_PWR_CLK_ENABLE();
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = 16;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLM = 16;
  RCC_OscInitStruct.PLL.PLLN = 200;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 2;
  RCC_OscInitStruct.PLL.PLLR = 2;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3) != HAL_OK)
  {
    Error_Handler();
  }
  HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
  HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}
static void MX_DAC_Init(void)
{
  DAC_ChannelConfTypeDef sConfig;
  hdac.Instance = DAC;
  if (HAL_DAC_Init(&hdac) != HAL_OK)
  {
    Error_Handler();
  }
  sConfig.DAC_Trigger = DAC_TRIGGER_T6_TRGO;
  sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;
  if (HAL_DAC_ConfigChannel(&hdac, &sConfig, DAC_CHANNEL_1) != HAL_OK)
  {
    Error_Handler();
  }
         if (HAL_DAC_Start_DMA(&hdac, DAC_CHANNEL_1,(uint32_t *) Sine12bit,32, DAC_ALIGN_12B_R) != HAL_OK)
  {
   
 Error_Handler();
  }
}
static void MX_TIM6_Init(void)
{
  TIM_MasterConfigTypeDef sMasterConfig;
  htim6.Instance = TIM6;
  htim6.Init.Prescaler = 0;
  htim6.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim6.Init.Period = 0xc40;
  if (HAL_TIM_Base_Init(&htim6) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim6, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
HAL_TIM_Base_Start(&htim6);
}
static void MX_DMA_Init(void) 
{
  __HAL_RCC_DMA1_CLK_ENABLE();
  HAL_NVIC_SetPriority(DMA1_Stream5_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA1_Stream5_IRQn);
}
static void MX_GPIO_Init(void)
{
  __HAL_RCC_GPIOA_CLK_ENABLE();
}
在函数 MX_DAC_Init()末尾要添加:
 
 if (HAL_DAC_Start_DMA(&hdac, DAC_CHANNEL_1,(uint32_t *) Sine12bit,32, DAC_ALIGN_12B_R) != HAL_OK)
 {
 Error_Handler();
 }
 在函数MX_TIM6_Init(()末尾要添加:
 HAL_TIM_Base_Start(&htim6);
 
 不知道为什么ST 不把启动定时器、启动DAC、启动ADC等等语句一并在STM32CUBE MX中添加进去,弄得我们这些菜鸟在老老实实按照STM32CUBE MX配置、编译完后,发现程序不能得到正确运行结果,搞得团团转,最后才知道是这个定时器并没有启动、那个DAC并没有激活。如果是因为某个外设有多种启动方式,至少可以把不同的启动方式注释后加入函数中供菜鸟们选择。让STM32CUBE MX更“傻瓜”点不是更好吗?呵呵!
 
 
   
 运行结果
 现在,PA4可以输出1KHZ正弦波了,而主芯片在运行完外设初始化后竟然没有消耗任何资源在这个DAC上,相比采用PWM输出正弦波更具优势。不错不错!
 
 
 
 
 
 
 
 
 
 
 
 
 | 
Cube配置后都需要人工启动对应的函数。。。默认都是配置不工作。。
查官方手册可知,虚拟串口是通过USART3连接的,USART10无法直接通过RS232与PC机连接,必须经过TTL-RS232电路转换。