找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3|回复: 0
打印 上一主题 下一主题
收起左侧

求大神帮忙看一下STM32F103VET6的音乐播放程序 音调总是不对

[复制链接]
跳转到指定楼层
楼主
ID:61140 发表于 2026-8-31 18:44 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
自己做了一个STM32F103VET6播放音乐的程序,但音调总是不对,听着根本不是那回事,不知道哪里出错了,求教大神
  1. /* USER CODE BEGIN Header */
  2. /**
  3.   ******************************************************************************
  4.   * @file           : main.c
  5.   * @brief          : Main program body
  6.   ******************************************************************************
  7.   * @attention
  8.   *
  9.   * Copyright (c) 2026 STMicroelectronics.
  10.   * All rights reserved.
  11.   *
  12.   * This software is licensed under terms that can be found in the LICENSE file
  13.   * in the root directory of this software component.
  14.   * If no LICENSE file comes with this software, it is provided AS-IS.
  15.   ******************************************************************************
  16.   */
  17. /* USER CODE END Header */
  18. /* Includes ------------------------------------------------------------------*/
  19. #include "main.h"
  20. /* Private includes ----------------------------------------------------------*/
  21. /* USER CODE BEGIN Includes */
  22. /* USER CODE END Includes */
  23. /* Private typedef -----------------------------------------------------------*/
  24. /* USER CODE BEGIN PTD */
  25. typedef struct
  26. {
  27.     const uint16_t *wave;
  28.     uint16_t len;
  29.     uint16_t beat_ms;
  30. }MusicNote_t;
  31. /* USER CODE END PTD */
  32. /* Private define ------------------------------------------------------------*/
  33. /* USER CODE BEGIN PD */
  34. /* USER CODE END PD */
  35. /* Private macro -------------------------------------------------------------*/
  36. /* USER CODE BEGIN PM */
  37. /* USER CODE END PM */
  38. /* Private variables ---------------------------------------------------------*/
  39. DAC_HandleTypeDef hdac;
  40. DMA_HandleTypeDef hdma_dac_ch2;
  41. TIM_HandleTypeDef htim6;

  42. /* USER CODE BEGIN PV */
  43. //C4 1 do 262Hz
  44. const uint16_t note_C4[38]={
  45. 3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,
  46. 600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600
  47. };
  48. //D4 2 re 294Hz
  49. const uint16_t note_D4[34]={
  50. 3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,
  51. 600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600
  52. };
  53. //E4 3 mi 330Hz
  54. const uint16_t note_E4[30]={
  55. 3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,
  56. 600,600,600,600,600,600,600,600,600,600,600,600,600,600,600
  57. };
  58. //F4 4 fa 349Hz
  59. const uint16_t note_F4[29]={
  60. 3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,
  61. 600,600,600,600,600,600,600,600,600,600,600,600,600,600,600
  62. };
  63. //G4 5 sol 392Hz
  64. const uint16_t note_G4[26]={
  65. 3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,
  66. 600,600,600,600,600,600,600,600,600,600,600,600,600
  67. };
  68. //A4 6 la 440Hz
  69. const uint16_t note_A4[23]={
  70. 3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,
  71. 600,600,600,600,600,600,600,600,600,600,600
  72. };
  73. //B4 7 si 494Hz
  74. const uint16_t note_B4[20]={
  75. 3500,3500,3500,3500,3500,3500,3500,3500,3500,3500,
  76. 600,600,600,600,600,600,600,600,600,600
  77. };
  78. //C5 高音1 523Hz
  79. const uint16_t note_C5[19]={
  80. 3500,3500,3500,3500,3500,3500,3500,3500,3500,
  81. 600,600,600,600,600,600,600,600,600,600
  82. };
  83. //休止符静音
  84. const uint16_t note_silence[2]={2048,2048};

  85. const MusicNote_t song[]=
  86. {
  87.     //小和尚下山去化斋 6 3 6 3 | 6 3 2 1 6? 【句停顿180】
  88.     {note_A4,23,220},{note_E4,30,220},{note_A4,23,220},{note_E4,30,220},
  89.     {note_A4,23,220},{note_E4,30,220},{note_D4,34,220},{note_C4,38,220},{note_A4,23,440},
  90.     {note_silence,2,180},

  91.     //老和尚有交待 6 3 6 3 | 6 3 2 1 6? 【句停顿180】
  92.     {note_A4,23,220},{note_E4,30,220},{note_A4,23,220},{note_E4,30,220},
  93.     {note_A4,23,220},{note_E4,30,220},{note_D4,34,220},{note_C4,38,220},{note_A4,23,440},
  94.     {note_silence,2,180},

  95.     //山下的女人是老虎 5 6 i 6 5 3 | 2 3 2 1? 【句停顿180】
  96.     {note_G4,26,220},{note_A4,23,220},{note_C5,19,220},{note_A4,23,220},{note_G4,26,220},{note_E4,30,220},
  97.     {note_D4,34,220},{note_E4,30,220},{note_D4,34,220},{note_C4,38,440},
  98.     {note_silence,2,180},

  99.     //遇见了千万要躲开 5 6 i 6 5 3 | 2 3 2 1? 【句停顿180】
  100.     {note_G4,26,220},{note_A4,23,220},{note_C5,19,220},{note_A4,23,220},{note_G4,26,220},{note_E4,30,220},
  101.     {note_D4,34,220},{note_E4,30,220},{note_D4,34,220},{note_C4,38,440},
  102.     {note_silence,2,180},

  103.     //走过了一村又一寨 6 3 3 3 2 1 |6 2 2 1 6? 【句停顿180】
  104.     {note_A4,23,220},{note_E4,30,220},{note_E4,30,220},{note_E4,30,220},{note_D4,34,220},{note_C4,38,220},
  105.     {note_A4,23,220},{note_D4,34,220},{note_D4,34,220},{note_C4,38,220},{note_A4,23,440},
  106.     {note_silence,2,180},

  107.     //小和尚暗思揣 5 6 i 6 5 3 |5 6 5 3? 【句停顿180】
  108.     {note_G4,26,220},{note_A4,23,220},{note_C5,19,220},{note_A4,23,220},{note_G4,26,220},{note_E4,30,220},
  109.     {note_G4,26,220},{note_A4,23,220},{note_G4,26,220},{note_E4,30,440},
  110.     {note_silence,2,180},

  111.     //为什么老虎不吃人 6 6 6 i 2' 3' 2' i |6 5 3? 【句停顿180】
  112.     {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},
  113.     {note_A4,23,220},{note_G4,26,220},{note_E4,30,440},
  114.     {note_silence,2,180},

  115.     //模样还挺可爱 6 3 3 3 2 1 |6 2 2 1 6? 【句停顿180】
  116.     {note_A4,23,220},{note_E4,30,220},{note_E4,30,220},{note_E4,30,220},{note_D4,34,220},{note_C4,38,220},
  117.     {note_A4,23,220},{note_D4,34,220},{note_D4,34,220},{note_C4,38,220},{note_A4,23,440},
  118.     {note_silence,2,180},

  119.     //老和尚悄悄告徒弟 3 3 3 5 6 i |6 6 6 i 2' 3' 2' i 【句停顿180】
  120.     {note_E4,30,220},{note_E4,30,220},{note_E4,30,220},{note_G4,26,220},{note_A4,23,220},{note_C5,19,220},
  121.     {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},
  122.     {note_silence,2,180},

  123.     //这样的老虎最呀最厉害 3 3 3 5 6 i |6 6 6 i 2' 3' 5? 【句停顿180】
  124.     {note_E4,30,220},{note_E4,30,220},{note_E4,30,220},{note_G4,26,220},{note_A4,23,220},{note_C5,19,220},
  125.     {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},
  126.     {note_silence,2,180},

  127.     //小和尚吓得赶紧跑 3 3 3 5 6 i | 2 2 2 2 5 5 【句停顿180】
  128.     {note_E4,30,220},{note_E4,30,220},{note_E4,30,220},{note_G4,26,220},{note_A4,23,220},{note_C5,19,220},
  129.     {note_D4,34,220},{note_D4,34,220},{note_D4,34,220},{note_D4,34,220},{note_G4,26,220},{note_G4,26,220},
  130.     {note_silence,2,180},

  131.     //师傅呀呀呀呀坏坏坏 3 3 2 3 5 6 |2 2 2 5 5?
  132.     {note_E4,30,220},{note_E4,30,220},{note_D4,34,220},{note_E4,30,220},{note_G4,26,220},{note_A4,23,220},
  133.     {note_D4,34,220},{note_D4,34,220},{note_D4,34,220},{note_G4,26,220},{note_G4,26,440},

  134.     {note_silence,2,600}
  135. };
  136. #define SONG_LEN  (sizeof(song)/sizeof(MusicNote_t))
  137. /* USER CODE END PV */

  138. /* Private function prototypes -----------------------------------------------*/
  139. void SystemClock_Config(void);
  140. static void MX_GPIO_Init(void);
  141. static void MX_DMA_Init(void);
  142. static void MX_DAC_Init(void);
  143. static void MX_TIM6_Init(void);
  144. /* USER CODE BEGIN PFP */
  145. void DAC_SetNote(const uint16_t *wave_tab,uint16_t len);
  146. /* USER CODE END PFP */

  147. /* Private user code ---------------------------------------------------------*/
  148. /* USER CODE BEGIN 0 */
  149. /* USER CODE END 0 */

  150. /**
  151.   * @brief  The application entry point.
  152.   * @retval int
  153.   */
  154. int main(void)
  155. {
  156.   /* USER CODE BEGIN 1 */
  157.   uint32_t idx=0;
  158.   /* USER CODE END 1 */

  159.   /* MCU Configuration--------------------------------------------------------*/
  160.   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  161.   HAL_Init();

  162.   /* USER CODE BEGIN Init */
  163.   /* USER CODE END Init */

  164.   /* Configure the system clock */
  165.   SystemClock_Config();

  166.   /* USER CODE BEGIN SysInit */
  167.   /* USER CODE END SysInit */

  168.   /* Initialize all configured peripherals */
  169.   MX_GPIO_Init();
  170.   MX_DMA_Init();
  171.   MX_DAC_Init();
  172.   MX_TIM6_Init();

  173.   /* USER CODE BEGIN 2 */
  174.   DAC_SetNote(song[0].wave, song[0].len);
  175.   HAL_TIM_Base_Start(&htim6);
  176.   idx=1;
  177.   /* USER CODE END 2 */

  178.   /* Infinite loop */
  179.   /* USER CODE BEGIN WHILE */
  180.   while (1)
  181.   {
  182.       if(idx < SONG_LEN)
  183.       {
  184.           HAL_Delay(song[idx].beat_ms);
  185.           DAC_SetNote(song[idx].wave, song[idx].len);
  186.           idx++;
  187.       }
  188.       else
  189.       {
  190.           HAL_Delay(800);
  191.           idx=0;
  192.           DAC_SetNote(song[0].wave, song[0].len);
  193.           idx=1;
  194.       }
  195.     /* USER CODE END WHILE */

  196.     /* USER CODE BEGIN 3 */
  197.     /* USER CODE END 3 */
  198.   }
  199. }

  200. /**
  201.   * @brief System Clock Configuration
  202.   * @retval None
  203.   */
  204. void SystemClock_Config(void)
  205. {
  206.   RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  207.   RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  208.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  209.   RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  210.   RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  211.   RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  212.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  213.   RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  214.   RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL6;
  215.   if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  216.   {
  217.     Error_Handler();
  218.   }

  219.   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
  220.                               |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  221.   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  222.   RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  223.   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  224.   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  225.   if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  226.   {
  227.     Error_Handler();
  228.   }
  229. }

  230. /**
  231.   * @brief DAC Initialization Function
  232.   * @param None
  233.   * @retval None
  234.   */
  235. static void MX_DAC_Init(void)
  236. {
  237.   /* USER CODE BEGIN DAC_Init 0 */
  238.   /* USER CODE END DAC_Init 0 */
  239.   DAC_ChannelConfTypeDef sConfig = {0};
  240.   /* USER CODE BEGIN DAC_Init 1 */
  241.   /* USER CODE END DAC_Init 1 */
  242.   hdac.Instance = DAC;
  243.   if (HAL_DAC_Init(&hdac) != HAL_OK)
  244.   {
  245.     Error_Handler();
  246.   }
  247.   sConfig.DAC_Trigger = DAC_TRIGGER_T6_TRGO;
  248.   sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;
  249.   if (HAL_DAC_ConfigChannel(&hdac, &sConfig, DAC_CHANNEL_2) != HAL_OK)
  250.   {
  251.     Error_Handler();
  252.   }
  253.   /* USER CODE BEGIN DAC_Init 2 */
  254.   /* USER CODE END DAC_Init 2 */
  255. }

  256. /**
  257.   * @brief TIM6 Initialization Function
  258.   * @param None
  259.   * @retval None
  260.   */
  261. static void MX_TIM6_Init(void)
  262. {
  263.   /* USER CODE BEGIN TIM6_Init 0 */
  264.   /* USER CODE END TIM6_Init 0 */
  265.   TIM_MasterConfigTypeDef sMasterConfig = {0};
  266.   /* USER CODE BEGIN TIM6_Init 1 */
  267.   /* USER CODE END TIM6_Init 1 */
  268.   htim6.Instance = TIM6;
  269.   htim6.Init.Prescaler = 35;
  270.   htim6.Init.CounterMode = TIM_COUNTERMODE_UP;
  271.   htim6.Init.Period = 99;
  272.   htim6.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  273.   if (HAL_TIM_Base_Init(&htim6) != HAL_OK)
  274.   {
  275.     Error_Handler();
  276.   }
  277.   sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
  278.   sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  279.   if (HAL_TIMEx_MasterConfigSynchronization(&htim6, &sMasterConfig) != HAL_OK)
  280.   {
  281.     Error_Handler();
  282.   }
  283.   /* USER CODE BEGIN TIM6_Init 2 */
  284.   /* USER CODE END TIM6_Init 2 */
  285. }

  286. static void MX_DMA_Init(void)
  287. {
  288.   __HAL_RCC_DMA2_CLK_ENABLE();
  289.   HAL_NVIC_SetPriority(DMA2_Channel4_5_IRQn, 0, 0);
  290.   HAL_NVIC_EnableIRQ(DMA2_Channel4_5_IRQn);
  291. }

  292. static void MX_GPIO_Init(void)
  293. {
  294.   __HAL_RCC_GPIOA_CLK_ENABLE();
  295. }

  296. /* USER CODE BEGIN 4 */
  297. void DAC_SetNote(const uint16_t *wave_tab,uint16_t len)
  298. {
  299.     HAL_DAC_Stop_DMA(&hdac,DAC_CHANNEL_2);
  300.     HAL_DAC_Start_DMA(&hdac, DAC_CHANNEL_2, (uint32_t *)wave_tab, len, DAC_ALIGN_12B_R);
  301. }
  302. /* USER CODE END 4 */

  303. void Error_Handler(void)
  304. {
  305.   __disable_irq();
  306.   while (1)
  307.   {
  308.   }
  309. }

  310. #ifdef USE_FULL_ASSERT
  311. void assert_failed(uint8_t *file, uint32_t line)
  312. {
  313. }
  314. #endif /* USE_FULL_ASSERT */
复制代码

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表