自己做了一个STM32F103VET6播放音乐的程序,但音调总是不对,听着根本不是那回事,不知道哪里出错了,求教大神
- /* USER CODE BEGIN Header */
- /**
- ******************************************************************************
- * @file : main.c
- * @brief : Main program body
- ******************************************************************************
- * @attention
- *
- * Copyright (c) 2026 STMicroelectronics.
- * All rights reserved.
- *
- * This software is licensed under terms that can be found in the LICENSE file
- * in the root directory of this software component.
- * If no LICENSE file comes with this software, it is provided AS-IS.
- ******************************************************************************
- */
- /* USER CODE END Header */
- /* Includes ------------------------------------------------------------------*/
- #include "main.h"
- /* Private includes ----------------------------------------------------------*/
- /* USER CODE BEGIN Includes */
- /* USER CODE END Includes */
- /* Private typedef -----------------------------------------------------------*/
- /* USER CODE BEGIN PTD */
- typedef struct
- {
- const uint16_t *wave;
- uint16_t len;
- uint16_t beat_ms;
- }MusicNote_t;
- /* USER CODE END PTD */
- /* Private define ------------------------------------------------------------*/
- /* USER CODE BEGIN PD */
- /* USER CODE END PD */
- /* Private macro -------------------------------------------------------------*/
- /* USER CODE BEGIN PM */
- /* USER CODE END PM */
- /* Private variables ---------------------------------------------------------*/
- DAC_HandleTypeDef hdac;
- DMA_HandleTypeDef hdma_dac_ch2;
- TIM_HandleTypeDef htim6;
- /* USER CODE BEGIN PV */
- //C4 1 do 262Hz
- const uint16_t note_C4[38]={
- 3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,
- 600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600
- };
- //D4 2 re 294Hz
- const uint16_t note_D4[34]={
- 3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,
- 600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600
- };
- //E4 3 mi 330Hz
- const uint16_t note_E4[30]={
- 3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,
- 600,600,600,600,600,600,600,600,600,600,600,600,600,600,600
- };
- //F4 4 fa 349Hz
- const uint16_t note_F4[29]={
- 3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,
- 600,600,600,600,600,600,600,600,600,600,600,600,600,600,600
- };
- //G4 5 sol 392Hz
- const uint16_t note_G4[26]={
- 3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,
- 600,600,600,600,600,600,600,600,600,600,600,600,600
- };
- //A4 6 la 440Hz
- const uint16_t note_A4[23]={
- 3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,
- 600,600,600,600,600,600,600,600,600,600,600
- };
- //B4 7 si 494Hz
- const uint16_t note_B4[20]={
- 3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,
- 600,600,600,600,600,600,600,600,600,600
- };
- //C5 高音1 523Hz
- const uint16_t note_C5[19]={
- 3500,3500,3500,3500,3500,3500,3500,3500,3500,
- 600,600,600,600,600,600,600,600,600,600
- };
- //休止符静音
- const uint16_t note_silence[2]={2048,2048};
- const MusicNote_t song[]=
- {
- //小和尚下山去化斋 6 3 6 3 | 6 3 2 1 6? 【句停顿180】
- {note_A4,23,220},{note_E4,30,220},{note_A4,23,220},{note_E4,30,220},
- {note_A4,23,220},{note_E4,30,220},{note_D4,34,220},{note_C4,38,220},{note_A4,23,440},
- {note_silence,2,180},
- //老和尚有交待 6 3 6 3 | 6 3 2 1 6? 【句停顿180】
- {note_A4,23,220},{note_E4,30,220},{note_A4,23,220},{note_E4,30,220},
- {note_A4,23,220},{note_E4,30,220},{note_D4,34,220},{note_C4,38,220},{note_A4,23,440},
- {note_silence,2,180},
- //山下的女人是老虎 5 6 i 6 5 3 | 2 3 2 1? 【句停顿180】
- {note_G4,26,220},{note_A4,23,220},{note_C5,19,220},{note_A4,23,220},{note_G4,26,220},{note_E4,30,220},
- {note_D4,34,220},{note_E4,30,220},{note_D4,34,220},{note_C4,38,440},
- {note_silence,2,180},
- //遇见了千万要躲开 5 6 i 6 5 3 | 2 3 2 1? 【句停顿180】
- {note_G4,26,220},{note_A4,23,220},{note_C5,19,220},{note_A4,23,220},{note_G4,26,220},{note_E4,30,220},
- {note_D4,34,220},{note_E4,30,220},{note_D4,34,220},{note_C4,38,440},
- {note_silence,2,180},
- //走过了一村又一寨 6 3 3 3 2 1 |6 2 2 1 6? 【句停顿180】
- {note_A4,23,220},{note_E4,30,220},{note_E4,30,220},{note_E4,30,220},{note_D4,34,220},{note_C4,38,220},
- {note_A4,23,220},{note_D4,34,220},{note_D4,34,220},{note_C4,38,220},{note_A4,23,440},
- {note_silence,2,180},
- //小和尚暗思揣 5 6 i 6 5 3 |5 6 5 3? 【句停顿180】
- {note_G4,26,220},{note_A4,23,220},{note_C5,19,220},{note_A4,23,220},{note_G4,26,220},{note_E4,30,220},
- {note_G4,26,220},{note_A4,23,220},{note_G4,26,220},{note_E4,30,440},
- {note_silence,2,180},
- //为什么老虎不吃人 6 6 6 i 2' 3' 2' i |6 5 3? 【句停顿180】
- {note_A4,23,220},{note_A4,23,220},{note_A4,23,220},{note_C5,19,220},{note_D4,34,220},{note_E4,30,220},{note_D4,34,220},{note_C5,19,220},
- {note_A4,23,220},{note_G4,26,220},{note_E4,30,440},
- {note_silence,2,180},
- //模样还挺可爱 6 3 3 3 2 1 |6 2 2 1 6? 【句停顿180】
- {note_A4,23,220},{note_E4,30,220},{note_E4,30,220},{note_E4,30,220},{note_D4,34,220},{note_C4,38,220},
- {note_A4,23,220},{note_D4,34,220},{note_D4,34,220},{note_C4,38,220},{note_A4,23,440},
- {note_silence,2,180},
- //老和尚悄悄告徒弟 3 3 3 5 6 i |6 6 6 i 2' 3' 2' i 【句停顿180】
- {note_E4,30,220},{note_E4,30,220},{note_E4,30,220},{note_G4,26,220},{note_A4,23,220},{note_C5,19,220},
- {note_A4,23,220},{note_A4,23,220},{note_A4,23,220},{note_C5,19,220},{note_D4,34,220},{note_E4,30,220},{note_D4,34,220},{note_C5,19,220},
- {note_silence,2,180},
- //这样的老虎最呀最厉害 3 3 3 5 6 i |6 6 6 i 2' 3' 5? 【句停顿180】
- {note_E4,30,220},{note_E4,30,220},{note_E4,30,220},{note_G4,26,220},{note_A4,23,220},{note_C5,19,220},
- {note_A4,23,220},{note_A4,23,220},{note_A4,23,220},{note_C5,19,220},{note_D4,34,220},{note_E4,30,220},{note_G4,26,440},
- {note_silence,2,180},
- //小和尚吓得赶紧跑 3 3 3 5 6 i | 2 2 2 2 5 5 【句停顿180】
- {note_E4,30,220},{note_E4,30,220},{note_E4,30,220},{note_G4,26,220},{note_A4,23,220},{note_C5,19,220},
- {note_D4,34,220},{note_D4,34,220},{note_D4,34,220},{note_D4,34,220},{note_G4,26,220},{note_G4,26,220},
- {note_silence,2,180},
- //师傅呀呀呀呀坏坏坏 3 3 2 3 5 6 |2 2 2 5 5?
- {note_E4,30,220},{note_E4,30,220},{note_D4,34,220},{note_E4,30,220},{note_G4,26,220},{note_A4,23,220},
- {note_D4,34,220},{note_D4,34,220},{note_D4,34,220},{note_G4,26,220},{note_G4,26,440},
- {note_silence,2,600}
- };
- #define SONG_LEN (sizeof(song)/sizeof(MusicNote_t))
- /* USER CODE END PV */
- /* Private function prototypes -----------------------------------------------*/
- void SystemClock_Config(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);
- /* USER CODE BEGIN PFP */
- void DAC_SetNote(const uint16_t *wave_tab,uint16_t len);
- /* USER CODE END PFP */
- /* Private user code ---------------------------------------------------------*/
- /* USER CODE BEGIN 0 */
- /* USER CODE END 0 */
- /**
- * @brief The application entry point.
- * @retval int
- */
- int main(void)
- {
- /* USER CODE BEGIN 1 */
- uint32_t idx=0;
- /* USER CODE END 1 */
- /* MCU Configuration--------------------------------------------------------*/
- /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
- HAL_Init();
- /* USER CODE BEGIN Init */
- /* USER CODE END Init */
- /* Configure the system clock */
- SystemClock_Config();
- /* USER CODE BEGIN SysInit */
- /* USER CODE END SysInit */
- /* Initialize all configured peripherals */
- MX_GPIO_Init();
- MX_DMA_Init();
- MX_DAC_Init();
- MX_TIM6_Init();
- /* USER CODE BEGIN 2 */
- DAC_SetNote(song[0].wave, song[0].len);
- HAL_TIM_Base_Start(&htim6);
- idx=1;
- /* USER CODE END 2 */
- /* Infinite loop */
- /* USER CODE BEGIN WHILE */
- while (1)
- {
- if(idx < SONG_LEN)
- {
- HAL_Delay(song[idx].beat_ms);
- DAC_SetNote(song[idx].wave, song[idx].len);
- idx++;
- }
- else
- {
- HAL_Delay(800);
- idx=0;
- DAC_SetNote(song[0].wave, song[0].len);
- idx=1;
- }
- /* USER CODE END WHILE */
- /* USER CODE BEGIN 3 */
- /* USER CODE END 3 */
- }
- }
- /**
- * @brief System Clock Configuration
- * @retval None
- */
- void SystemClock_Config(void)
- {
- RCC_OscInitTypeDef RCC_OscInitStruct = {0};
- RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
- RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
- RCC_OscInitStruct.HSEState = RCC_HSE_ON;
- RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
- RCC_OscInitStruct.HSIState = RCC_HSI_ON;
- RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
- RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
- RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL6;
- 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_2) != HAL_OK)
- {
- Error_Handler();
- }
- }
- /**
- * @brief DAC Initialization Function
- * @param None
- * @retval None
- */
- static void MX_DAC_Init(void)
- {
- /* USER CODE BEGIN DAC_Init 0 */
- /* USER CODE END DAC_Init 0 */
- DAC_ChannelConfTypeDef sConfig = {0};
- /* USER CODE BEGIN DAC_Init 1 */
- /* USER CODE END DAC_Init 1 */
- 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_2) != HAL_OK)
- {
- Error_Handler();
- }
- /* USER CODE BEGIN DAC_Init 2 */
- /* USER CODE END DAC_Init 2 */
- }
- /**
- * @brief TIM6 Initialization Function
- * @param None
- * @retval None
- */
- static void MX_TIM6_Init(void)
- {
- /* USER CODE BEGIN TIM6_Init 0 */
- /* USER CODE END TIM6_Init 0 */
- TIM_MasterConfigTypeDef sMasterConfig = {0};
- /* USER CODE BEGIN TIM6_Init 1 */
- /* USER CODE END TIM6_Init 1 */
- htim6.Instance = TIM6;
- htim6.Init.Prescaler = 35;
- htim6.Init.CounterMode = TIM_COUNTERMODE_UP;
- htim6.Init.Period = 99;
- htim6.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
- 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();
- }
- /* USER CODE BEGIN TIM6_Init 2 */
- /* USER CODE END TIM6_Init 2 */
- }
- static void MX_DMA_Init(void)
- {
- __HAL_RCC_DMA2_CLK_ENABLE();
- HAL_NVIC_SetPriority(DMA2_Channel4_5_IRQn, 0, 0);
- HAL_NVIC_EnableIRQ(DMA2_Channel4_5_IRQn);
- }
- static void MX_GPIO_Init(void)
- {
- __HAL_RCC_GPIOA_CLK_ENABLE();
- }
- /* USER CODE BEGIN 4 */
- void DAC_SetNote(const uint16_t *wave_tab,uint16_t len)
- {
- HAL_DAC_Stop_DMA(&hdac,DAC_CHANNEL_2);
- HAL_DAC_Start_DMA(&hdac, DAC_CHANNEL_2, (uint32_t *)wave_tab, len, DAC_ALIGN_12B_R);
- }
- /* USER CODE END 4 */
- void Error_Handler(void)
- {
- __disable_irq();
- while (1)
- {
- }
- }
- #ifdef USE_FULL_ASSERT
- void assert_failed(uint8_t *file, uint32_t line)
- {
- }
- #endif /* USE_FULL_ASSERT */
复制代码
|