기술나눔

STM32 하이브리드 버전(HAL 라이브러리, 뮤직박스, 알람시계, 도트 매트릭스 스크린, 온도 및 습도)

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

1. 디자인 설명

이 설계는 STM32MP157A 고성능 마이크로컨트롤러를 핵심 제어 장치로 사용하여 포괄적인 임베디드 시스템을 신중하게 구성합니다. 이 시스템은 버저, 디지털 튜브 디스플레이, 도트 매트릭스 스크린, 온도 및 습도 센서, LED 표시기 및 버튼과 같은 다양한 주변 모듈을 교묘하게 통합하여 풍부한 기능과 쉬운 작동을 갖춘 하이브리드 스마트 장치를 구성합니다. 직렬 통신을 통해 사용자는 시스템의 작동 모드를 유연하게 전환하고 알람 시계, 뮤직 박스 재생, 온도 및 습도 모니터링 및 제어와 같은 기본 기능을 쉽게 구현할 수 있습니다.

핵심 하드웨어

  • 메인 컨트롤 유닛: 강력한 처리 기능과 풍부한 주변 장치 인터페이스를 갖춘 STM32MP157A 마이크로 컨트롤러를 사용하여 시스템에 견고한 하드웨어 기반을 제공합니다.

소프트웨어 플랫폼

  • 개발 도구: 직관적이고 사용하기 쉬운 통합 개발 환경인 STM32CUBEIDE를 사용하면 소프트웨어 프로그래밍 및 디버깅 효율성이 크게 향상되어 시스템 소프트웨어의 안정성과 신뢰성이 보장됩니다.

시스템 기능 하이라이트

  1. 유연한 모드 전환: 직렬 통신을 통해 사용자는 알람 시계, 뮤직 박스 재생, 온도 및 습도 모니터링의 세 가지 모드 간에 쉽게 전환하여 다양한 시나리오의 사용 요구 사항을 충족할 수 있습니다.

  2. 동적 정보 표시: 시스템의 정보 표시 창으로 도트 매트릭스 화면은 현재 작업 모드에 따라 해당 한자를 표시할 수 있습니다(예: "시계"는 알람 시계 모드를 나타내고 "톤"은 뮤직 박스 모드를 나타내고 "통과"는 온도 및 습도 모니터링을 위한 단순화된 로고로 간주되어 사용자에게 직관적인 작동 피드백을 제공합니다.

  3. 버튼 상호작용 경험: 사용자의 상호 작용 경험을 충분히 고려한 디자인으로 뮤직 박스의 속도 및 볼륨 조정, 노래 전환, 일시 중지/재생 제어, 시간 조정 및 설정과 같은 버튼을 눌러 각 모드에서 해당 기능 작업을 수행할 수 있습니다. 알람 시계, 알람 시계 끄기 등.

  4. 온도와 습도의 지능적인 제어 : 시스템에는 온도 및 습도 센서가 내장되어 있어 환경 상태를 실시간으로 모니터링하고 직렬 포트를 통해 사용자 지시를 받아 온도 및 습도의 상한 및 하한 임계값을 조정할 수 있습니다. 환경 매개변수가 설정 범위를 초과하면 LED 표시등이 경계 알림으로 켜져 사용자가 적시에 조치를 취할 수 있도록 도와줍니다.

2. 기본 구성 정보

뮤직 박스는 이전에 생성되었으므로 구성이 변경되지 않습니다.STM32 오르골

        

3. STM32CUBEIDE 구성

1. 타이머--100ms

2. PWM 구성(부저--PB6)

3. 직렬 포트 구성

핀에 주의하세요

4. IIC 구성 (온도 및 습도, 디지털 튜브, 도트 매트릭스 스크린)

5. GPIO 구성(LED 및 버튼)

6. 국립비씨

4. 프로그래밍

(1) 오르골 코드

뮤직박스는 이전에 작성되었으므로 여기서는 이전 작업을 반복하지 않겠습니다. 직렬 포트 및 모드 변환을 추가하겠습니다.

         STM32 오르골

시리얼 음악 제어 기능

  1. //串口音乐控制函数
  2. void music_kz(){
  3. if(EN_music == 1)//启动
  4. play_music(list,Low_volume);
  5. else
  6. __HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_1,0);//设置音量
  7. if(strcmp("music volume increase",(char *)uart4_data)==0){
  8. uart4_data[0] = '0';
  9. Low_volume = Low_volume + Low_volume_cnt;
  10. if(Low_volume >= 10)
  11. Low_volume = 10;
  12. }
  13. if(strcmp("music volume reduction",(char *)uart4_data)==0){
  14. Low_volume = Low_volume - Low_volume_cnt;
  15. if(Low_volume <= 0)
  16. Low_volume = 0;
  17. }
  18. if(strcmp("music speed increase",(char *)uart4_data)==0){
  19. uart4_data[0] = '0';
  20. music_speed_i++;
  21. music_speed_i = music_speed_kz(music_speed_i);
  22. }
  23. if(strcmp("music speed reduction",(char *)uart4_data)==0){
  24. uart4_data[0] = '0';
  25. music_speed_i--;
  26. music_speed_i = music_speed_kz(music_speed_i);
  27. }
  28. if(strcmp("music next song",(char *)uart4_data)==0){
  29. uart4_data[0] = '0';
  30. list++;
  31. if(list > list_max){
  32. list = list_max;
  33. }
  34. }
  35. if(strcmp("music previous song",(char *)uart4_data)==0){
  36. list--;
  37. uart4_data[0] = '0';
  38. if(list < 0){
  39. list = 0;
  40. }
  41. }
  42. if(strcmp("music start",(char *)uart4_data)==0){
  43. EN_music = 1;
  44. }
  45. if(strcmp("music stop",(char *)uart4_data)==0){
  46. EN_music = 0;
  47. }
  48. }

버튼 모드 제어

모드 변수를 이용하여 모드를 표현하며, 다음 3개의 버튼은 동일합니다.

  1. void EXTI0_IRQHandler(void)
  2. {
  3. /* USER CODE BEGIN EXTI0_IRQn 0 */
  4. if(HAL_GPIO_ReadPin(GPIOG, GPIO_PIN_0) == 0 && mode == 0)//确保数据稳定
  5. {
  6. //每次按下解决 音量�??????? Low_volume_cnt
  7. Low_volume = Low_volume + Low_volume_cnt;
  8. if(Low_volume >= 10)
  9. Low_volume = 0;
  10. }
  11. if(HAL_GPIO_ReadPin(GPIOG,GPIO_PIN_0)==GPIO_PIN_RESET && mode == 1) {
  12. shi_clock++;
  13. fen_shi_clock=fen_clock/10;
  14. fen_ge_clock=fen_clock%10;
  15. shi_shi_clock=shi_clock/10;
  16. shi_ge_clock=shi_clock%10;
  17. if(shi_clock>=24)
  18. {
  19. shi_clock=0;
  20. }
  21. miao_shi_clock=miao_clock/10;
  22. miao_ge_clock=miao_clock%10;
  23. fen_shi_clock=fen_clock/10;
  24. fen_ge_clock=fen_clock%10;
  25. shi_shi_clock=shi_clock/10;
  26. shi_ge_clock=shi_clock%10;
  27. buf[0]=smg_number[shi_shi_clock];
  28. buf[1]=smg_number[shi_ge_clock];
  29. buf[3]=smg_number[fen_shi_clock];
  30. buf[4]=smg_number[fen_ge_clock];
  31. buf[6]=smg_number[miao_shi_clock];
  32. buf[7]=smg_number[miao_ge_clock];
  33. }
  34. /* USER CODE END EXTI0_IRQn 0 */
  35. HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
  36. /* USER CODE BEGIN EXTI0_IRQn 1 */
  37. /* USER CODE END EXTI0_IRQn 1 */
  38. }

(2) 모드 전환

모드 변수 전환

  1. void uart_mode(){
  2. if(strcmp("mode = music",(char *)uart4_data)==0){
  3. mode = 0;
  4. }
  5. if(strcmp("mode = clock",(char *)uart4_data)==0){
  6. mode = 1;
  7. }
  8. if(strcmp("mode = sensor",(char *)uart4_data)==0){
  9. mode = 2;
  10. }
  11. }

도트 매트릭스 스크린 글꼴 라이브러리

  1. uint8_t DZP_data[6][34]={
  2. {0xAA,0x55,
  3. 0xFD,0xFF,0xFE,0xFF,0xC0,0x07,0xFF,0xFF,0xF7,0xDF,0xFB,0xBF,0x00,0x01,0xFF,0xFF,
  4. 0xE0,0x0F,0xEF,0xEF,0xEF,0xEF,0xE0,0x0F,0xEF,0xEF,0xEF,0xEF,0xE0,0x0F,0xEF,0xEF},//
  5. {0xAA,0x55,
  6. 0xEF,0xDF,0xEF,0xDF,0xC3,0xDF,0xDF,0xDF,0xBE,0x03,0x42,0xDB,0xEE,0xDB,0xEE,0xDB,
  7. 0x02,0xDB,0xEE,0x03,0xEE,0xDB,0xEF,0xDF,0xEB,0xDF,0xE7,0xDF,0xEF,0xDF,0xFF,0xDF},////1//
  8. {0xAA,0x55,
  9. 0xF7,0xBF,0xF7,0xBF,0xF7,0xBF,0xEC,0x07,0xEF,0xBF,0xCF,0x7F,0xC8,0x01,0xAF,0x7F,
  10. 0x6E,0xFF,0xEC,0x07,0xEF,0xF7,0xEE,0xEF,0xEF,0x5F,0xEF,0xBF,0xEF,0xDF,0xEF,0xDF}////2//
  11. };

도트 매트릭스 디스플레이

  1. if(mode_n != mode){
  2. mode_n = mode;
  3. for(int i = 0; i<34;i++){
  4. //printf("afgsbgafdffag");
  5. HAL_I2C_Master_Transmit(&hi2c1, 0xA0 , (uint8_t*)&DZP_data[mode][i], 1, 300);
  6. HAL_Delay(2);
  7. }
  8. }

(3) 알람시계 코드 작성

1. 기본변수

         메인.c

  1. //数码管闹钟基础变量
  2. extern int buf[8];
  3. extern int shi_shi;
  4. extern int shi_ge ;
  5. extern int fen_shi;
  6. extern int fen_ge ;
  7. extern int miao_shi ;
  8. extern int miao_ge ;
  9. extern int miao ;
  10. extern int shi ;
  11. extern int fen;
  12. //闹钟保存数组
  13. extern int alarm_clock_array[20][4];
  14. extern int alarm_clock_array_cnt;

        stm32mp1xx_it.c 기본 변수

  1. //数码管闹钟基础设置
  2. int smg_number[10] = {0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xE0,0xFE,0xF6};
  3. int buf[8] = {0};
  4. //闹钟保存数组
  5. int alarm_clock_array[20][4] = {0};
  6. int alarm_clock_array_cnt = 0;
  7. //实时时钟信息
  8. int shi_shi = 0;
  9. int shi_ge = 0;
  10. int fen_shi = 0;
  11. int fen_ge = 0;
  12. int miao_shi = 0;
  13. int miao_ge = 0;
  14. int miao = 0;
  15. int shi = 0;
  16. int fen = 0;
  17. int EN_clock = 0;//闹钟设置使能
  18. extern int en_clock;//用于控制闹钟响铃
  19. //闹钟设置信息
  20. int shi_shi_clock = 0;
  21. int shi_ge_clock = 0;
  22. int fen_shi_clock = 0;
  23. int fen_ge_clock = 0;
  24. int miao_shi_clock = 0;
  25. int miao_ge_clock = 0;
  26. int miao_clock = 0, shi_clock = 0, fen_clock = 0;

2. TIM2 타이머

  1. void TIM2_IRQHandler(void)
  2. {
  3. /* USER CODE BEGIN TIM2_IRQn 0 */
  4. if(EN_music == 1)
  5. time_100ms_cnt++;
  6. else
  7. time_100ms_cnt = time_100ms_cnt; //其余状�?�不计数
  8. if(time_100ms_cnt >= Beat_speed_n * Beat_num){ //这个音节结束
  9. time_100ms_cnt = 0;
  10. flag = 1; //发�?�音节结束信�???????
  11. }
  12. //数码�????
  13. static int smg_time_100ms = 0;
  14. smg_time_100ms++;
  15. if(smg_time_100ms>=10){
  16. miao++;
  17. smg_time_100ms = 0;
  18. }
  19. if (miao>=60)
  20. {
  21. miao=0;
  22. fen++;
  23. if(fen>=60)
  24. {
  25. fen=0;
  26. shi++;
  27. if(shi>=24)
  28. {
  29. shi=0;
  30. }
  31. }
  32. }
  33. if(miao >= 60){
  34. miao = miao-60;
  35. fen++;
  36. }
  37. if(fen>=60){
  38. fen = fen-60;
  39. shi ++;
  40. }
  41. if(shi>= 24){
  42. shi = shi -24;
  43. }
  44. miao_shi=miao/10;
  45. miao_ge=miao%10;
  46. fen_shi=fen/10;
  47. fen_ge=fen%10;
  48. shi_shi=shi/10;
  49. shi_ge=shi%10;
  50. if(EN_clock == 0){
  51. buf[0]=smg_number[shi_shi];
  52. buf[1]=smg_number[shi_ge];
  53. buf[3]=smg_number[fen_shi];
  54. buf[4]=smg_number[fen_ge];
  55. buf[6]=smg_number[miao_shi];
  56. buf[7]=smg_number[miao_ge];
  57. HAL_GPIO_WritePin(GPIOF, GPIO_PIN_1, GPIO_PIN_RESET);
  58. //HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_RESET);
  59. //HAL_GPIO_WritePin(GPIOI, GPIO_PIN_11|GPIO_PIN_10, GPIO_PIN_RESET);
  60. }
  61. else{
  62. HAL_GPIO_WritePin(GPIOF, GPIO_PIN_1, GPIO_PIN_SET);
  63. //HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_SET);
  64. //HAL_GPIO_WritePin(GPIOI, GPIO_PIN_11|GPIO_PIN_10, GPIO_PIN_SET);
  65. }
  66. /* USER CODE END TIM2_IRQn 0 */
  67. HAL_TIM_IRQHandler(&htim2);
  68. /* USER CODE BEGIN TIM2_IRQn 1 */
  69. /* USER CODE END TIM2_IRQn 1 */
  70. }

3. 알람 시계를 설정하고 알람 시계를 저장하는 버튼 제어

  1. void EXTI9_IRQHandler(void)
  2. {
  3. /* USER CODE BEGIN EXTI9_IRQn 0 */
  4. if(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_9) == 0 && mode == 0){//确保数据稳定
  5. EN_music = !EN_music;
  6. }
  7. if(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_9) == 0 && mode == 1 ){//确保数据稳定
  8. if(EN_clock == 1){
  9. //闹钟设置成功
  10. alarm_clock_array[alarm_clock_array_cnt][0] = shi_clock;
  11. alarm_clock_array[alarm_clock_array_cnt][1] = fen_clock;
  12. alarm_clock_array[alarm_clock_array_cnt][2] = miao_clock;
  13. alarm_clock_array[alarm_clock_array_cnt][3] = 3; //默认播放第三首音�????
  14. alarm_clock_array_cnt++;
  15. if(alarm_clock_array_cnt >= 20) alarm_clock_array_cnt = 0;
  16. EN_clock = 0;
  17. }
  18. else if(EN_clock == 0){
  19. //设置闹钟
  20. shi_shi_clock = shi_shi;
  21. shi_ge_clock = shi_ge;
  22. fen_shi_clock = fen_shi;
  23. fen_ge_clock = fen_ge;
  24. miao_shi_clock = 0;
  25. miao_ge_clock = 0;
  26. miao_clock = 0;
  27. shi_clock = shi;
  28. fen_clock = fen;
  29. EN_clock = 1;
  30. }
  31. }
  32. /* USER CODE END EXTI9_IRQn 0 */
  33. HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_9);
  34. /* USER CODE BEGIN EXTI9_IRQn 1 */
  35. /* USER CODE END EXTI9_IRQn 1 */
  36. }

4. 시, 분 버튼 +

  1. void EXTI0_IRQHandler(void)
  2. {
  3. /* USER CODE BEGIN EXTI0_IRQn 0 */
  4. if(HAL_GPIO_ReadPin(GPIOG, GPIO_PIN_0) == 0 && mode == 0)//确保数据稳定
  5. {
  6. //每次按下解决 音量�??????? Low_volume_cnt
  7. Low_volume = Low_volume + Low_volume_cnt;
  8. if(Low_volume >= 10)
  9. Low_volume = 0;
  10. }
  11. if(HAL_GPIO_ReadPin(GPIOG,GPIO_PIN_0)==GPIO_PIN_RESET && mode == 1) {
  12. shi_clock++;
  13. fen_shi_clock=fen_clock/10;
  14. fen_ge_clock=fen_clock%10;
  15. shi_shi_clock=shi_clock/10;
  16. shi_ge_clock=shi_clock%10;
  17. if(shi_clock>=24)
  18. {
  19. shi_clock=0;
  20. }
  21. miao_shi_clock=miao_clock/10;
  22. miao_ge_clock=miao_clock%10;
  23. fen_shi_clock=fen_clock/10;
  24. fen_ge_clock=fen_clock%10;
  25. shi_shi_clock=shi_clock/10;
  26. shi_ge_clock=shi_clock%10;
  27. buf[0]=smg_number[shi_shi_clock];
  28. buf[1]=smg_number[shi_ge_clock];
  29. buf[3]=smg_number[fen_shi_clock];
  30. buf[4]=smg_number[fen_ge_clock];
  31. buf[6]=smg_number[miao_shi_clock];
  32. buf[7]=smg_number[miao_ge_clock];
  33. }
  34. /* USER CODE END EXTI0_IRQn 0 */
  35. HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
  36. /* USER CODE BEGIN EXTI0_IRQn 1 */
  37. /* USER CODE END EXTI0_IRQn 1 */
  38. }
  39. /**
  40. * @brief This function handles EXTI line1 interrupt.
  41. */
  42. void EXTI1_IRQHandler(void)
  43. {
  44. /* USER CODE BEGIN EXTI1_IRQn 0 */
  45. if(HAL_GPIO_ReadPin(GPIOG, GPIO_PIN_1) == 0 && mode == 0)//确保数据稳定
  46. {
  47. music_speed_i++;
  48. music_speed_i = music_speed_kz(music_speed_i);
  49. }
  50. if(HAL_GPIO_ReadPin(GPIOG,GPIO_PIN_1)==GPIO_PIN_RESET && mode == 1) {
  51. fen_clock++;
  52. fen_shi_clock=fen_clock/10;
  53. fen_ge_clock=fen_clock%10;
  54. if(fen_clock>=60)
  55. {
  56. fen_clock=0;
  57. shi_clock++;
  58. fen_shi_clock=fen_clock/10;
  59. fen_ge_clock=fen_clock%10;
  60. shi_shi_clock=shi_clock/10;
  61. shi_ge_clock=shi_clock%10;
  62. if(shi_clock>=24)
  63. {
  64. shi_clock=0;
  65. }
  66. }
  67. miao_shi_clock=miao_clock/10;
  68. miao_ge_clock=miao_clock%10;
  69. fen_shi_clock=fen_clock/10;
  70. fen_ge_clock=fen_clock%10;
  71. shi_shi_clock=shi_clock/10;
  72. shi_ge_clock=shi_clock%10;
  73. buf[0]=smg_number[shi_shi_clock];
  74. buf[1]=smg_number[shi_ge_clock];
  75. buf[3]=smg_number[fen_shi_clock];
  76. buf[4]=smg_number[fen_ge_clock];
  77. buf[6]=smg_number[miao_shi_clock];
  78. buf[7]=smg_number[miao_ge_clock];
  79. }
  80. /* USER CODE END EXTI1_IRQn 0 */
  81. HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_1);
  82. /* USER CODE BEGIN EXTI1_IRQn 1 */
  83. /* USER CODE END EXTI1_IRQn 1 */
  84. }
  85. /**
  86. * @brief This function handles EXTI line2 interrupt.
  87. */
  88. void EXTI2_IRQHandler(void)
  89. {
  90. /* USER CODE BEGIN EXTI2_IRQn 0 */
  91. if(HAL_GPIO_ReadPin(GPIOG, GPIO_PIN_2) == 0 && mode == 0)//确保数据稳定
  92. {
  93. list++;
  94. if(list > list_max){
  95. list = 0;
  96. }
  97. }
  98. if(HAL_GPIO_ReadPin(GPIOG,GPIO_PIN_2)==GPIO_PIN_RESET && mode == 1) {
  99. //在此处关闭闹�????
  100. en_clock = 0;
  101. }
  102. /* USER CODE END EXTI2_IRQn 0 */
  103. HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_2);
  104. /* USER CODE BEGIN EXTI2_IRQn 1 */
  105. /* USER CODE END EXTI2_IRQn 1 */
  106. }

5. 시계 추가 기능(왼쪽 1/3의 해당 시, 분, 초에 마지막 3시간, 분, 초를 추가)

  1. //通过输入不同的n,返回shi fen miao
  2. int clock_compute(int time_shi,int time_fen,int time_miao,int add_shi,int add_fen,int add_miao,int n){
  3. time_miao = time_miao + add_miao;
  4. time_fen = time_fen + time_miao/60;
  5. time_miao = time_miao % 60;
  6. time_fen = time_fen + add_fen;
  7. time_shi = time_shi + time_fen / 60;
  8. time_fen = time_fen%60;
  9. time_shi = time_shi + add_shi;
  10. time_shi = time_shi%24;
  11. if(n == 0) return time_shi;
  12. if(n == 1) return time_fen;
  13. if(n == 2) return time_miao;
  14. return -1;
  15. }

6. 해당 문자열의 마지막 두 자리 추출

  1. // 函数定义:从字符串中提取两位数字
  2. int extract_two_digits(const char *str, const char *prefix, int *value) {
  3. char *pos = strstr(str, prefix); // 查找前缀的位�?????
  4. if (pos == NULL) return 0; // 如果没找到前�?????,返�?????0表示失败
  5. // 跳过前缀的长度,找到数字�?????始的位置
  6. pos += strlen(prefix);
  7. // �?????查接下来的两个字符是否是数字
  8. if (pos[0] >= '0' && pos[0] <= '9' && pos[1] >= '0' && pos[1] <= '9') {
  9. // 转换字符为数�?????
  10. *value = (pos[0] - '0') * 10 + (pos[1] - '0');
  11. return 1; // 成功提取,返�?????1
  12. }
  13. return 0; // 提取失败,返�?????0
  14. }

7. 직렬 포트는 현재 시계, 예약된 알람 시계 및 지연된 알람 시계를 설정합니다.

  1. //判断是否到底闹钟
  2. int en_clock = 0;//用于控制闹钟响铃
  3. int en_clock_cnt = 0;
  4. int clock_end[3] = {0};//记录闹钟无人时关闭的时间
  5. //串口设置闹钟
  6. void uart_clock(){
  7. int ci = 0;
  8. int ci_n = 0;
  9. //ci = number_char_come(uart4_data,(uint8_t *)"clock shi = ",2);
  10. ci = extract_two_digits((char *)uart4_data, (char *)"clock shi = ", &ci_n);
  11. if(ci == 1){
  12. uart4_data[0] = '1';
  13. shi = ci_n;
  14. }
  15. //ci = number_char_come(uart4_data,(uint8_t *)"clock fen = ",2);
  16. ci = extract_two_digits((char *)uart4_data, (char *)"clock fen = ", &ci_n);
  17. if(ci == 1){
  18. uart4_data[0] = '1';
  19. fen = ci_n;
  20. }
  21. //ci = number_char_come(uart4_data,(uint8_t *)"clock miao = ",2);
  22. ci = extract_two_digits((char *)uart4_data, (char *)"clock miao = ", &ci_n);
  23. if(ci == 1){
  24. uart4_data[0] = '1';
  25. miao = ci_n;
  26. }
  27. //设置�?????个多少时间后的闹�?????
  28. //ci = number_char_come(uart4_data,(uint8_t *)"clock delay shi = ",2);
  29. ci = extract_two_digits((char *)uart4_data, "clock delay shi = ", &ci_n);
  30. if(ci == 1){
  31. uart4_data[0] = '1';
  32. alarm_clock_array[alarm_clock_array_cnt][0] = clock_compute(shi,fen,miao,ci_n,0,0,0);
  33. alarm_clock_array[alarm_clock_array_cnt][1] = clock_compute(shi,fen,miao,ci_n,0,0,1);
  34. alarm_clock_array[alarm_clock_array_cnt][2] = clock_compute(shi,fen,miao,ci_n,0,0,2);
  35. alarm_clock_array_cnt++;
  36. }
  37. //ci = number_char_come(uart4_data,(uint8_t *)"clock delay fen = ",2);
  38. ci = extract_two_digits((char *)uart4_data, "clock delay fen = ", &ci_n);
  39. if(ci == 1){
  40. uart4_data[0] = '1';
  41. alarm_clock_array[alarm_clock_array_cnt][0] = clock_compute(shi,fen,miao,0,ci_n,0,0);
  42. alarm_clock_array[alarm_clock_array_cnt][1] = clock_compute(shi,fen,miao,0,ci_n,0,1);
  43. alarm_clock_array[alarm_clock_array_cnt][2] = clock_compute(shi,fen,miao,0,ci_n,0,2);
  44. alarm_clock_array_cnt++;
  45. }
  46. ci = extract_two_digits((char *)uart4_data, "clock delay miao = ", &ci_n);
  47. if(ci == 1){
  48. uart4_data[0] = '1';
  49. alarm_clock_array[alarm_clock_array_cnt][0] = clock_compute(shi,fen,miao,0,0,ci_n,0);
  50. alarm_clock_array[alarm_clock_array_cnt][1] = clock_compute(shi,fen,miao,0,0,ci_n,1);
  51. alarm_clock_array[alarm_clock_array_cnt][2] = clock_compute(shi,fen,miao,0,0,ci_n,2);
  52. alarm_clock_array_cnt++;
  53. }
  54. // time shi = 12;fen = 10;miao = 12;music = 1;
  55. ci = 0;
  56. ci = ci + extract_two_digits((char *)uart4_data, "time shi = ", &alarm_clock_array[alarm_clock_array_cnt][0]);
  57. ci = ci + extract_two_digits((char *)uart4_data, ";fen = ", &alarm_clock_array[alarm_clock_array_cnt][1]);
  58. ci = ci + extract_two_digits((char *)uart4_data, ";miao = ", &alarm_clock_array[alarm_clock_array_cnt][2]);
  59. //ci = ci + extract_two_digits((char *)uart4_data, ";music = ", &alarm_clock_array[alarm_clock_array_cnt][2]);
  60. if(ci == 3){
  61. //完美对应
  62. uart4_data[0] = '1';
  63. ci = extract_two_digits((char *)uart4_data, ";music = ", &alarm_clock_array[alarm_clock_array_cnt][3]);
  64. if(ci > list_max && ci<0) //如果大于音乐总数
  65. alarm_clock_array[alarm_clock_array_cnt][3] = 3;//默认�?????3
  66. alarm_clock_array_cnt++;
  67. }
  68. if(strcmp("clock delay list",(char *)uart4_data)==0){
  69. uart4_data[0] = '0';
  70. for(int i = 0; i< alarm_clock_array_cnt;i++){
  71. if(alarm_clock_array[i][0] != -1 && alarm_clock_array[i][1] != -1 && alarm_clock_array[i][2] != -1)
  72. printf("%d : time -> %d/%d/%d rn",i, alarm_clock_array[i][0],
  73. alarm_clock_array[i][1],
  74. alarm_clock_array[i][2]
  75. );
  76. }
  77. }
  78. //读取关闭第几位闹�?????
  79. //ci = number_char_come(uart4_data,(uint8_t *)"clock stop list = ",2);
  80. ci = extract_two_digits((char *)uart4_data, "clock stop list = ", &ci_n);
  81. if(ci == 1){
  82. alarm_clock_array[ci_n][0] = -1;
  83. alarm_clock_array[ci_n][1] = -1;
  84. alarm_clock_array[ci_n][2] = -1;
  85. }
  86. //关闭闹钟
  87. if(strcmp("clock stop stop",(char *)uart4_data)==0){
  88. en_clock = 0;
  89. }
  90. if(alarm_clock_array_cnt >= 20) alarm_clock_array_cnt = 0;
  91. }

8. 알람시계 구현 및 정지(닉시튜브 디스플레이)

  1. void alarm_clock(){
  2. //时钟显示(数码管)
  3. static int pos = 0;
  4. HAL_I2C_Mem_Write(&hi2c1,0x70,0X10+pos, 1, (uint8_t*)&buf[pos],1,100);
  5. HAL_Delay(1);
  6. pos++;
  7. if(pos == 3 && pos == 6) pos++;
  8. if(pos == 8) pos = 0;
  9. uart_clock();//调用串口控制
  10. for(int j=0;j<alarm_clock_array_cnt && en_clock == 0;j++){
  11. //int cnt_clock = 0;
  12. if(alarm_clock_array[j][0] == shi && alarm_clock_array[j][1] == fen && alarm_clock_array[j][2] == miao) {
  13. en_clock_cnt = j;
  14. en_clock = 1;
  15. clock_end[0] = clock_compute(shi,fen,miao,0,0,30,0);
  16. clock_end[1] = clock_compute(shi,fen,miao,0,0,30,1);
  17. clock_end[2] = clock_compute(shi,fen,miao,0,0,30,2);
  18. break;
  19. }
  20. }
  21. //当闹钟响�?????30S
  22. if(shi == clock_end[0] && fen == clock_end[1] && miao == clock_end[2]){
  23. en_clock = 0;//关闭闹钟
  24. //EN_music = 1;
  25. }
  26. if(en_clock == 1 ){
  27. motor(10);
  28. HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_SET);
  29. }
  30. else{
  31. HAL_GPIO_WritePin(GPIOF, GPIO_PIN_6, GPIO_PIN_RESET);
  32. HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_RESET);
  33. }
  34. }

(4) 온도 및 습도 코드 작성

1. 온도와 습도의 기본변수

  1. uint8_t add1=0xFE,add2=0xE5,add3=0xE3;
  2. //0xFE复位 0xE5启动湿度转换 0xE3启动温度转换
  3. uint16_t RH_Code,RH_Code_low=0,RH_Code_high=0;
  4. uint16_t Temp_Code,Temp_Code_low=0,Temp_Code_high=0;
  5. int humidity_min = 50;//能仍受最低干燥程度
  6. int temperature_max = 50;//能仍受的最高温度
  7. int en_t = 0; //温度使能
  8. int en_r = 0; //湿度使能

2. 온도 및 습도 계산

  1. //计算出温湿度
  2. void Temperature_humidity(){
  3. //湿度
  4. HAL_I2C_Master_Transmit(&hi2c1, 0x80, &add2, 1,100);
  5. //写命�??????? ox40里面写命�??????? 0xe5 启动湿度转换
  6. HAL_I2C_Master_Receive(&hi2c1, 0x81, &RH_Code, 1, 100);
  7. //读命�??????? �???????0x40读取出湿度的数据 存入变量RH_CODE
  8. HAL_Delay(30);
  9. //进行高低字节转换
  10. RH_Code_low=(RH_Code & 0xff);
  11. RH_Code_high=(RH_Code >> 8)& 0xff;
  12. RH_Code=(RH_Code_low << 8)+RH_Code_high;
  13. //温度
  14. HAL_I2C_Master_Transmit(&hi2c1, 0x80, &add3, 1,100);
  15. HAL_I2C_Master_Receive(&hi2c1, 0x81, &Temp_Code, 1, 100);
  16. //读命�??????? �???????0x40读取出温度的数据 存入变量Temp_CODE
  17. HAL_Delay(30);
  18. //进行高低字节转换
  19. Temp_Code_low=(Temp_Code & 0xff);
  20. Temp_Code_high=(Temp_Code >> 8)& 0xff;
  21. Temp_Code=(Temp_Code_low << 8)+Temp_Code_high;
  22. Temp_Code=17572*Temp_Code/65535-4685;//扩大�???????百�??
  23. RH_Code=125*RH_Code/65536-6;//计算出湿度�??
  24. //printf("Temp_Code = r%d.%d RH_Code = %d%%n",Temp_Code/100,Temp_Code%100,RH_Code%100);
  25. //串口输出温湿�???????
  26. HAL_Delay(2);
  27. }

3. 온도 및 습도 직렬 포트 제어

  1. void uart_sensor(){
  2. int tr=0;
  3. int tr_i = 0;
  4. tr = extract_two_digits((char *)uart4_data, "sensor humidity_min = ", &tr_i);
  5. if(tr != 0){
  6. humidity_min = tr_i;
  7. }
  8. tr = extract_two_digits((char *)uart4_data, "sensor temperature_max = ", &tr_i);
  9. if(tr != 0){
  10. temperature_max = tr_i;
  11. }
  12. if(strcmp("sensor temperature start",(char *)uart4_data)==0){
  13. en_t = 1;
  14. }
  15. if(strcmp("sensor humidity start",(char *)uart4_data)==0){
  16. en_r = 1;
  17. }
  18. if(strcmp("sensor temperature stop",(char *)uart4_data)==0){
  19. en_t = 0;
  20. }
  21. if(strcmp("sensor humidity stop",(char *)uart4_data)==0){
  22. en_r = 0;
  23. }
  24. if(strcmp("sensor list",(char *)uart4_data)==0){
  25. uart4_data[0] = '0';
  26. printf("Temp_Code = r%d.%d RH_Code = %d%%rn",Temp_Code/100,Temp_Code%100,RH_Code%100);
  27. printf("sensor en_t : %drn",en_t);
  28. printf("sensor en_r : %drn",en_r);
  29. printf("sensor temperature_max : %drn",temperature_max);
  30. printf("sensor humidity_min : %drn",humidity_min);
  31. }
  32. if(strcmp("sensor Temp_Code RH_Code",(char *)uart4_data)==0){
  33. uart4_data[0] = '0';
  34. printf("Temp_Code = r%d.%d RH_Code = %d%%n",Temp_Code/100,Temp_Code%100,RH_Code%100);
  35. }
  36. }

4. 온도 및 습도 주요 기능

  1. void sensor(){
  2. static int iii = 0;
  3. if(iii == 0){
  4. HAL_I2C_Master_Transmit(&hi2c1, 0x80, &add1, 1, 100);
  5. HAL_Delay(2);
  6. iii++;
  7. }
  8. Temperature_humidity();
  9. uart_sensor();
  10. if(RH_Code < humidity_min && en_r == 1){
  11. //motor(10);
  12. HAL_GPIO_WritePin(GPIOI, GPIO_PIN_11, GPIO_PIN_SET);
  13. }
  14. else{
  15. HAL_GPIO_WritePin(GPIOI, GPIO_PIN_11, GPIO_PIN_RESET);
  16. }
  17. if(Temp_Code/100 >= temperature_max && en_t == 1){
  18. HAL_GPIO_WritePin(GPIOI, GPIO_PIN_10, GPIO_PIN_SET);
  19. }
  20. else{
  21. HAL_GPIO_WritePin(GPIOI, GPIO_PIN_10, GPIO_PIN_RESET);
  22. }
  23. }

(5) 주요 기능

  1. void end_main(){
  2. tone_init(); //初始化音量频�??????
  3. list_max = music_init();//更新乐谱
  4. HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_1); //启动蜂鸣器定时器
  5. HAL_TIM_Base_Start_IT(&htim2); //启动定时�??????2
  6. HAL_TIM_Base_Start_IT(&htim3); //启动定时�??????2
  7. //1 使能串口空闲中断
  8. __HAL_UART_ENABLE_IT(&huart4,UART_IT_IDLE);
  9. //2.使能串口中断接收数据
  10. HAL_UART_Receive_IT(&huart4,rx_buf,sizeof(rx_buf));
  11. int mode_n = 1;
  12. while(1){
  13. music_kz();
  14. alarm_clock();
  15. uart_mode();
  16. sensor();
  17. if(mode_n != mode){
  18. mode_n = mode;
  19. for(int i = 0; i<34;i++){
  20. //printf("afgsbgafdffag");
  21. HAL_I2C_Master_Transmit(&hi2c1, 0xA0 , (uint8_t*)&DZP_data[mode][i], 1, 300);
  22. HAL_Delay(2);
  23. }
  24. }
  25. }
  26. }

5. 일반 코드

메인.c

  1. /* USER CODE BEGIN Header */
  2. /**
  3. ******************************************************************************
  4. * @file : main.c
  5. * @brief : Main program body
  6. ******************************************************************************
  7. * @attention
  8. *
  9. * <h2><center>&copy; Copyright (c) 2024 STMicroelectronics.
  10. * All rights reserved.</center></h2>
  11. *
  12. * This software component is licensed by ST under BSD 3-Clause license,
  13. * the "License"; You may not use this file except in compliance with the
  14. * License. You may obtain a copy of the License at:
  15. * opensource.org/licenses/BSD-3-Clause
  16. *
  17. ******************************************************************************
  18. */
  19. /* USER CODE END Header */
  20. /* Includes ------------------------------------------------------------------*/
  21. #include "main.h"
  22. /* Private includes ----------------------------------------------------------*/
  23. /* USER CODE BEGIN Includes */
  24. #include <string.h>
  25. uint8_t rx_buf[200]={0}; //接收不定长数
  26. uint8_t uart4_data[200] = {0};
  27. extern int mode; //模式
  28. /* USER CODE END Includes */
  29. /* Private typedef -----------------------------------------------------------*/
  30. /* USER CODE BEGIN PTD */
  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. I2C_HandleTypeDef hi2c1;
  40. TIM_HandleTypeDef htim2;
  41. TIM_HandleTypeDef htim3;
  42. TIM_HandleTypeDef htim4;
  43. UART_HandleTypeDef huart4;
  44. /* USER CODE BEGIN PV */
  45. /* USER CODE END PV */
  46. /* Private function prototypes -----------------------------------------------*/
  47. void SystemClock_Config(void);
  48. static void MX_GPIO_Init(void);
  49. static void MX_I2C1_Init(void);
  50. static void MX_TIM2_Init(void);
  51. static void MX_TIM4_Init(void);
  52. static void MX_UART4_Init(void);
  53. static void MX_TIM3_Init(void);
  54. /* USER CODE BEGIN PFP */
  55. /* USER CODE END PFP */
  56. /* Private user code ---------------------------------------------------------*/
  57. /* USER CODE BEGIN 0 */
  58. //重写标准输出函数
  59. int __io_putchar(int ch)
  60. {
  61. HAL_UART_Transmit(&huart4, (uint8_t *)&ch, 1, 10);
  62. return ch;
  63. }
  64. // 自定义空闲中断处理函�????????
  65. void uart4_idle_func(void)
  66. {
  67. int len = 0;
  68. //判定 是否为空闲中�????????
  69. if( __HAL_UART_GET_FLAG(&huart4, UART_FLAG_IDLE) == SET )
  70. {
  71. // 清除空闲中断标志,因为是自己定义的函数 系统不会清标
  72. __HAL_UART_CLEAR_IDLEFLAG(&huart4);
  73. // 计算接收数据的长
  74. len = sizeof(rx_buf) - huart4.RxXferCount;
  75. //第二个参数是 还剩下的空间
  76. // 打印接收到时数据 数据处理
  77. //printf("uart rx len = %d, data: %srn",len, rx_buf);
  78. // 使用strcpy复制字符�????????
  79. strcpy((char *)uart4_data, (char *)rx_buf);
  80. printf("%s instructions successrn", uart4_data);
  81. // 准备接收下一次数�?????????
  82. memset(rx_buf,0,len); // 清理接收容器
  83. //重置接收指针 剩余容器大小
  84. huart4.pRxBuffPtr = rx_buf;
  85. huart4.RxXferCount = sizeof(rx_buf);
  86. }
  87. }
  88. //控制马达
  89. void motor(int d){
  90. HAL_GPIO_TogglePin(GPIOF, GPIO_PIN_6);//
  91. HAL_Delay(d);
  92. }
  93. // 音乐
  94. // 音乐盒基�??????变量
  95. extern int time_100ms_cnt; //0.1s计数�??????
  96. extern int Beat_speed; //节拍速度,代表半个节拍需要多少个0.1s
  97. extern int Beat_speed_n; //实际执行的节拍数
  98. extern int Beat_num; //这个�??????个音�??????要多少个 半拍
  99. extern int flag; //当其等于 1 时,表示�??????个音结束
  100. extern int EN_music ; //使能信号,用于开启整个音乐盒
  101. extern int list ; //音乐列表
  102. extern int list_max ; //音乐总数
  103. extern int Low_volume ; //音量大小
  104. extern int Low_volume_cnt;
  105. extern int music_speed_i; //音乐播放速度模式保存
  106. extern int music_speed_kz(int i);
  107. int tone[3][8];
  108. //初始化高中低音频�??????
  109. void tone_init(){
  110. tone[1][0] = 0; //不执行音�??????
  111. tone[1][1] = 191;
  112. tone[1][2] = 170;
  113. tone[1][3] = 151;
  114. tone[1][4] = 143;
  115. tone[1][5] = 127;
  116. tone[1][6] = 113;
  117. tone[1][7] = 101;
  118. // 低音 (Low)
  119. for (int i = 0; i < 8; i++) {
  120. tone[0][i] = tone[1][i] * 2; // 只是低音 近似的�??
  121. }
  122. // 高音 (High)
  123. for (int i = 0; i < 8; i++) {
  124. tone[2][i] = tone[1][i] / 2; // 只是高音 近似的�??
  125. }
  126. }
  127. #define MAX_unit_num 200 //�????????大乐谱数�????????
  128. //创建结构体保存乐�????????
  129. struct music_unit{
  130. char name[50]; //乐谱名称
  131. int unit[MAX_unit_num]; //发什么音
  132. int unit_HL[MAX_unit_num]; //发高音或者其�????????
  133. int time[MAX_unit_num]; //发音时间
  134. //int time_4[MAX_unit_num]; //判断是否�????????1/4�????????
  135. int num; //记录有多少个
  136. }music[25];
  137. //创建乐谱 返回有多少首音乐
  138. int music_init(){
  139. int cnt = 0;
  140. //第一首音�???????? 生日快乐
  141. strcpy(music[0].name, "生日快乐"); // 使用strcpy复制字符�???????? 给音乐命�????????
  142. int music0_unit[29] = {0,0, 5,5,6,5,1,7, 5,5,6,5,2,1,
  143. 5,5,6,3,1,7, 6,4,4,3,1,2,1,
  144. 0,0}; //基础乐谱
  145. int music0_time[29] = {1,1, 1,1,2,2,2,3, 1,1,2,2,2,3,
  146. 2,2,2,2,2,2, 2,2,2,2,2,2,3,
  147. 1,1}; //乐谱节拍
  148. music[0].num = 29; //乐谱总数
  149. int music0_unit_HL[29] = {1,1,
  150. 0,0,0,0,1,0, 0,0,0,0,1,1,
  151. 0,0,1,1,1,0, 0,1,1,1,1,1,1,
  152. 1,1}; //乐谱全为中音
  153. //第二首音�???????? �????????闪一闪亮晶晶
  154. cnt++;
  155. strcpy(music[1].name, "�????????闪一闪亮晶晶"); // 使用strcpy复制字符�???????? 给音乐命�????????
  156. int music1_unit[44] = {0,
  157. 1,1,5,5,6,6,5, 4,4,3,3,2,2,1,
  158. 5,5,4,4,3,3,2, 5,5,4,4,3,3,2,
  159. 1,1,5,5,6,6,5, 4,4,3,3,2,2,1,
  160. 0}; //基础乐谱
  161. int music1_time[44] = {2,
  162. 2,2,2,2,2,2,3, 2,2,2,2,2,2,3,
  163. 2,2,2,2,2,2,3, 2,2,2,2,2,2,3,
  164. 2,2,2,2,2,2,3, 2,2,2,2,2,2,3,
  165. 2}; //乐谱节拍
  166. int music1_unit_HL[44] =
  167. {1,
  168. 1,1,1,1,1,1,1, 1,1,1,1,1,1,1,
  169. 1,1,1,1,1,1,1, 1,1,1,1,1,1,1,
  170. 1,1,1,1,1,1,1, 1,1,1,1,1,1,1,
  171. 1}; //乐谱全为中音
  172. music[1].num = 44; //乐谱总数
  173. //第三首音�???????? 两只老虎
  174. cnt++;
  175. strcpy(music[2].name, "两只老虎"); // 使用strcpy复制字符�???????? 给音乐命�????????
  176. int music2_unit[38] = {0,
  177. 1,2,3,1, 1,2,3,1, 3,4,5,5, 3,4,5,5,
  178. 5,6,5,4, 3,1,5,6, 5,4,3,1, 1,5,1,1,
  179. 1,5,1,1, 0}; //基础乐谱
  180. int music2_time[38] = {2,
  181. 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1,
  182. 0,0,0,0, 1,1,0,0, 0,0,1,1, 1,1,1,2,
  183. 1,1,1,2, 2}; //乐谱节拍
  184. int music2_unit_HL[38] =
  185. {1,
  186. 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1,
  187. 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,0,1,1,
  188. 1,0,1,1, 1}; //乐谱�???????? 中音
  189. music[2].num = 38; //乐谱总数
  190. //第四首音�???????? 青花瓷片�????????
  191. cnt++;
  192. strcpy(music[3].name, "青花瓷片"); // 使用strcpy复制字符�???????? 给音乐命�????????
  193. int music3_unit[100] = {0,0,0,0, 0,5,5,3, 2,3,6,2, 3,5,3,2, 2,5,5,3,
  194. 2,3,5,2, 3,5,2,1, 1,1,2,3, 5,6,5,4, 5,3,3,2,
  195. 2,2,1,2, 1,1,2,1, 2,3,5,3, 3,3,5,5, 3,2,3,6,
  196. 2,3,5,3, 2,2,5,5, 3,2,3,5, 2,3,5,2, 1,1,1,2,
  197. 3,5,6,5, 4,5,3,3, 2,2,5,3, 2,2,2,1, 1,0,0,0}; //基础乐谱
  198. int music3_time[100] = {0,0,0,0, 0,0,0,0, 0,0,1,0, 0,0,0,2, 0,0,0,0,
  199. 0,0,1,0, 0,0,0,2, 0,0,0,0, 0,0,0,0, 0,0,0,0,
  200. 2,0,0,0, 0,0,0,0, 0,1,0,0, 2,0,0,0, 0,0,0,1,
  201. 0,0,0,0, 2,0,0,0, 0,0,0,1, 0,0,0,0, 2,0,0,0,
  202. 0,0,0,0, 0,0,0,0, 0,2,0,1, 0,0,0,1, 2,1,1,1}; //乐谱节拍
  203. for(int i =0;i<100;i++)
  204. music3_time[i] = music3_time[i]+1;
  205. int music3_unit_HL[100] =
  206. { 1,1,1,1, 1,1,1,1, 1,1,0,1, 1,1,1,1, 1,1,1,1,
  207. 1,1,0,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1,
  208. 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,0,
  209. 1,1,1,1, 1,1,1,1, 1,1,1,0, 1,1,1,1, 1,1,1,1,
  210. 1,1,1,1, 1,1,1,1, 1,1,0,1, 1,1,1,1, 1,1,1,1}; //乐谱�???????? 中音
  211. music[3].num = 100; //乐谱总数
  212. for (int i = 0; i < MAX_unit_num; i++) {
  213. //将乐谱保存进结构�????????
  214. if(i<music[0].num){//确保数据正确
  215. music[0].unit[i] =music0_unit[i];
  216. music[0].unit_HL[i] =music0_unit_HL[i];
  217. music[0].time[i] =music0_time[i];
  218. }
  219. //将乐谱保存进结构�????????
  220. if(i<music[1].num){//确保数据正确
  221. music[1].unit[i] =music1_unit[i];
  222. music[1].unit_HL[i] =music1_unit_HL[i];
  223. music[1].time[i] =music1_time[i];
  224. }
  225. //将乐谱保存进结构�????????
  226. if(i<music[2].num){//确保数据正确
  227. music[2].unit[i] =music2_unit[i];
  228. music[2].unit_HL[i] =music2_unit_HL[i];
  229. music[2].time[i] =music2_time[i];
  230. }
  231. //将乐谱保存进结构�????????
  232. if(i<music[3].num){//确保数据正确
  233. music[3].unit[i] =music3_unit[i];
  234. music[3].unit_HL[i] =music3_unit_HL[i];
  235. music[3].time[i] =music3_time[i];
  236. }
  237. }
  238. return cnt;
  239. }
  240. //播放�???? N首音�???? 音量�???? X 0 - 100
  241. void play_music(int n, int x){
  242. static int ni = 0; //用于判断 是否换了音乐
  243. static int cnt = 0; //记录播放到哪�????�???? 音节
  244. if(ni != n ){//如果音乐换了
  245. ni = n;
  246. cnt = 0;
  247. __HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_1,0);//设置音量
  248. HAL_Delay(1000);//
  249. }
  250. //
  251. int value = tone[music[n].unit_HL[cnt]][music[n].unit[cnt]]; //获取频率
  252. if(flag == 1){ //接受到一个音节结�????
  253. flag = 0; //复位
  254. Beat_num = music[n].time[cnt]; //这个音需要多少个半拍
  255. //LED_BEEP(music[n].unit[cnt]); //LED随音节变动�?�变�????
  256. if(music[n].time[cnt] == 0){//如果�???? 1/4�????
  257. Beat_speed_n = Beat_speed /2;
  258. }
  259. else{//如果没有1/4�????
  260. Beat_speed_n = Beat_speed;
  261. }
  262. //if(value != 0)//如果有频率�?�执行,没有者只更新 时间�????
  263. __HAL_TIM_SET_AUTORELOAD(&htim4,value); //自动加载频率�????
  264. cnt ++; //可进行下�????次音�????
  265. if(cnt >= music[n].num){ //如果�????个音节播放完�????
  266. cnt = 0;//重新播放
  267. //__HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_1,0);//设置音量
  268. //HAL_Delay(500);//
  269. }
  270. }
  271. //__HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_1,x * (value/100));//设置音量
  272. __HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_1,(value/10)*x);//设置音量
  273. }
  274. //串口音乐控制函数
  275. void music_kz(){
  276. if(EN_music == 1)//启动
  277. play_music(list,Low_volume);
  278. else
  279. __HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_1,0);//设置音量
  280. if(strcmp("music volume increase",(char *)uart4_data)==0){
  281. uart4_data[0] = '0';
  282. Low_volume = Low_volume + Low_volume_cnt;
  283. if(Low_volume >= 10)
  284. Low_volume = 10;
  285. }
  286. if(strcmp("music volume reduction",(char *)uart4_data)==0){
  287. Low_volume = Low_volume - Low_volume_cnt;
  288. if(Low_volume <= 0)
  289. Low_volume = 0;
  290. }
  291. if(strcmp("music speed increase",(char *)uart4_data)==0){
  292. uart4_data[0] = '0';
  293. music_speed_i++;
  294. music_speed_i = music_speed_kz(music_speed_i);
  295. }
  296. if(strcmp("music speed reduction",(char *)uart4_data)==0){
  297. uart4_data[0] = '0';
  298. music_speed_i--;
  299. music_speed_i = music_speed_kz(music_speed_i);
  300. }
  301. if(strcmp("music next song",(char *)uart4_data)==0){
  302. uart4_data[0] = '0';
  303. list++;
  304. if(list > list_max){
  305. list = list_max;
  306. }
  307. }
  308. if(strcmp("music previous song",(char *)uart4_data)==0){
  309. list--;
  310. uart4_data[0] = '0';
  311. if(list < 0){
  312. list = 0;
  313. }
  314. }
  315. if(strcmp("music start",(char *)uart4_data)==0){
  316. EN_music = 1;
  317. }
  318. if(strcmp("music stop",(char *)uart4_data)==0){
  319. EN_music = 0;
  320. }
  321. }
  322. //数码管闹�?????
  323. extern int buf[8];
  324. extern int shi_shi;
  325. extern int shi_ge ;
  326. extern int fen_shi;
  327. extern int fen_ge ;
  328. extern int miao_shi ;
  329. extern int miao_ge ;
  330. extern int miao ;
  331. extern int shi ;
  332. extern int fen;
  333. //闹钟保存数组
  334. extern int alarm_clock_array[20][4];
  335. extern int alarm_clock_array_cnt;
  336. //通过输入不同的n,返回shi fen miao
  337. int clock_compute(int time_shi,int time_fen,int time_miao,int add_shi,int add_fen,int add_miao,int n){
  338. time_miao = time_miao + add_miao;
  339. time_fen = time_fen + time_miao/60;
  340. time_miao = time_miao % 60;
  341. time_fen = time_fen + add_fen;
  342. time_shi = time_shi + time_fen / 60;
  343. time_fen = time_fen%60;
  344. time_shi = time_shi + add_shi;
  345. time_shi = time_shi%24;
  346. if(n == 0) return time_shi;
  347. if(n == 1) return time_fen;
  348. if(n == 2) return time_miao;
  349. return -1;
  350. }
  351. //将字符解成数�?????
  352. int char_number(uint8_t c){
  353. if(c >= '0' && c <= '9')
  354. return c-'0';
  355. else
  356. return -1;
  357. }
  358. // zfc 为当前传入字符串
  359. // zfc_n为比较字符串
  360. // num为如果两字符串最初相等,则取字符串后面多少位的数�?????
  361. int number_char_come(uint8_t zfc[200], uint8_t zfc_n[200], int num){
  362. size_t len = strlen((char *)zfc_n);//无符号整数类�?????
  363. int cnt = 0;
  364. for(int i = 0;i < len;i++){
  365. if(zfc[i] != zfc_n[i]) return -1; //不相�?????
  366. else cnt++;
  367. }
  368. if(cnt != len) return -1;//两字符串不等
  369. size_t shen_len = strlen((char *)zfc) - len;//剩余字符串长�?????
  370. size_t hig_num = 0;//用以保存实际有效位数
  371. if(shen_len > num) hig_num = num;
  372. else hig_num = shen_len;
  373. //int number[200];
  374. int number1 = 0;
  375. int multiplier = 1; // 用于计算10的幂的变�?????
  376. for(int i = len + hig_num - 1; i >= len;i--){
  377. //number[i-len] = char_number(zfc[i]);
  378. if(char_number(zfc[i])== -1) {
  379. printf("rrr number errorrn");
  380. return -1;
  381. }
  382. multiplier = multiplier*10;
  383. number1 = number1 + char_number(zfc[i])*multiplier;
  384. }
  385. return number1;
  386. }
  387. // 函数定义:从字符串中提取两位数字
  388. int extract_two_digits(const char *str, const char *prefix, int *value) {
  389. char *pos = strstr(str, prefix); // 查找前缀的位�?????
  390. if (pos == NULL) return 0; // 如果没找到前�?????,返�?????0表示失败
  391. // 跳过前缀的长度,找到数字�?????始的位置
  392. pos += strlen(prefix);
  393. // �?????查接下来的两个字符是否是数字
  394. if (pos[0] >= '0' && pos[0] <= '9' && pos[1] >= '0' && pos[1] <= '9') {
  395. // 转换字符为数�?????
  396. *value = (pos[0] - '0') * 10 + (pos[1] - '0');
  397. return 1; // 成功提取,返�?????1
  398. }
  399. return 0; // 提取失败,返�?????0
  400. }
  401. //判断是否到底闹钟
  402. int en_clock = 0;//用于控制闹钟响铃
  403. int en_clock_cnt = 0;
  404. int clock_end[3] = {0};//记录闹钟无人时关闭的时间
  405. //串口设置闹钟
  406. void uart_clock(){
  407. int ci = 0;
  408. int ci_n = 0;
  409. //ci = number_char_come(uart4_data,(uint8_t *)"clock shi = ",2);
  410. ci = extract_two_digits((char *)uart4_data, (char *)"clock shi = ", &ci_n);
  411. if(ci == 1){
  412. uart4_data[0] = '1';
  413. shi = ci_n;
  414. }
  415. //ci = number_char_come(uart4_data,(uint8_t *)"clock fen = ",2);
  416. ci = extract_two_digits((char *)uart4_data, (char *)"clock fen = ", &ci_n);
  417. if(ci == 1){
  418. uart4_data[0] = '1';
  419. fen = ci_n;
  420. }
  421. //ci = number_char_come(uart4_data,(uint8_t *)"clock miao = ",2);
  422. ci = extract_two_digits((char *)uart4_data, (char *)"clock miao = ", &ci_n);
  423. if(ci == 1){
  424. uart4_data[0] = '1';
  425. miao = ci_n;
  426. }
  427. //设置�?????个多少时间后的闹�?????
  428. //ci = number_char_come(uart4_data,(uint8_t *)"clock delay shi = ",2);
  429. ci = extract_two_digits((char *)uart4_data, "clock delay shi = ", &ci_n);
  430. if(ci == 1){
  431. uart4_data[0] = '1';
  432. alarm_clock_array[alarm_clock_array_cnt][0] = clock_compute(shi,fen,miao,ci_n,0,0,0);
  433. alarm_clock_array[alarm_clock_array_cnt][1] = clock_compute(shi,fen,miao,ci_n,0,0,1);
  434. alarm_clock_array[alarm_clock_array_cnt][2] = clock_compute(shi,fen,miao,ci_n,0,0,2);
  435. alarm_clock_array_cnt++;
  436. }
  437. //ci = number_char_come(uart4_data,(uint8_t *)"clock delay fen = ",2);
  438. ci = extract_two_digits((char *)uart4_data, "clock delay fen = ", &ci_n);
  439. if(ci == 1){
  440. uart4_data[0] = '1';
  441. alarm_clock_array[alarm_clock_array_cnt][0] = clock_compute(shi,fen,miao,0,ci_n,0,0);
  442. alarm_clock_array[alarm_clock_array_cnt][1] = clock_compute(shi,fen,miao,0,ci_n,0,1);
  443. alarm_clock_array[alarm_clock_array_cnt][2] = clock_compute(shi,fen,miao,0,ci_n,0,2);
  444. alarm_clock_array_cnt++;
  445. }
  446. ci = extract_two_digits((char *)uart4_data, "clock delay miao = ", &ci_n);
  447. if(ci == 1){
  448. uart4_data[0] = '1';
  449. alarm_clock_array[alarm_clock_array_cnt][0] = clock_compute(shi,fen,miao,0,0,ci_n,0);
  450. alarm_clock_array[alarm_clock_array_cnt][1] = clock_compute(shi,fen,miao,0,0,ci_n,1);
  451. alarm_clock_array[alarm_clock_array_cnt][2] = clock_compute(shi,fen,miao,0,0,ci_n,2);
  452. alarm_clock_array_cnt++;
  453. }
  454. // time shi = 12;fen = 10;miao = 12;music = 1;
  455. ci = 0;
  456. ci = ci + extract_two_digits((char *)uart4_data, "time shi = ", &alarm_clock_array[alarm_clock_array_cnt][0]);
  457. ci = ci + extract_two_digits((char *)uart4_data, ";fen = ", &alarm_clock_array[alarm_clock_array_cnt][1]);
  458. ci = ci + extract_two_digits((char *)uart4_data, ";miao = ", &alarm_clock_array[alarm_clock_array_cnt][2]);
  459. //ci = ci + extract_two_digits((char *)uart4_data, ";music = ", &alarm_clock_array[alarm_clock_array_cnt][2]);
  460. if(ci == 3){
  461. //完美对应
  462. uart4_data[0] = '1';
  463. ci = extract_two_digits((char *)uart4_data, ";music = ", &alarm_clock_array[alarm_clock_array_cnt][3]);
  464. if(ci > list_max && ci<0) //如果大于音乐总数
  465. alarm_clock_array[alarm_clock_array_cnt][3] = 3;//默认�?????3
  466. alarm_clock_array_cnt++;
  467. }
  468. if(strcmp("clock delay list",(char *)uart4_data)==0){
  469. uart4_data[0] = '0';
  470. for(int i = 0; i< alarm_clock_array_cnt;i++){
  471. if(alarm_clock_array[i][0] != -1 && alarm_clock_array[i][1] != -1 && alarm_clock_array[i][2] != -1)
  472. printf("%d : time -> %d/%d/%d rn",i, alarm_clock_array[i][0],
  473. alarm_clock_array[i][1],
  474. alarm_clock_array[i][2]
  475. );
  476. }
  477. }
  478. //读取关闭第几位闹�?????
  479. //ci = number_char_come(uart4_data,(uint8_t *)"clock stop list = ",2);
  480. ci = extract_two_digits((char *)uart4_data, "clock stop list = ", &ci_n);
  481. if(ci == 1){
  482. alarm_clock_array[ci_n][0] = -1;
  483. alarm_clock_array[ci_n][1] = -1;
  484. alarm_clock_array[ci_n][2] = -1;
  485. }
  486. //关闭闹钟
  487. if(strcmp("clock stop stop",(char *)uart4_data)==0){
  488. en_clock = 0;
  489. }
  490. if(alarm_clock_array_cnt >= 20) alarm_clock_array_cnt = 0;
  491. }
  492. void smg_xians(){
  493. }
  494. void alarm_clock(){
  495. static int pos = 0;
  496. HAL_I2C_Mem_Write(&hi2c1,0x70,0X10+pos, 1, (uint8_t*)&buf[pos],1,100);
  497. HAL_Delay(1);
  498. pos++;
  499. if(pos == 3 && pos == 6) pos++;
  500. if(pos == 8) pos = 0;
  501. uart_clock();//调用串口控制
  502. for(int j=0;j<alarm_clock_array_cnt && en_clock == 0;j++){
  503. //int cnt_clock = 0;
  504. if(alarm_clock_array[j][0] == shi && alarm_clock_array[j][1] == fen && alarm_clock_array[j][2] == miao) {
  505. en_clock_cnt = j;
  506. en_clock = 1;
  507. clock_end[0] = clock_compute(shi,fen,miao,0,0,30,0);
  508. clock_end[1] = clock_compute(shi,fen,miao,0,0,30,1);
  509. clock_end[2] = clock_compute(shi,fen,miao,0,0,30,2);
  510. break;
  511. }
  512. }
  513. //当闹钟响�?????30S
  514. if(shi == clock_end[0] && fen == clock_end[1] && miao == clock_end[2]){
  515. en_clock = 0;//关闭闹钟
  516. //EN_music = 1;
  517. }
  518. if(en_clock == 1 ){
  519. motor(10);
  520. HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_SET);
  521. }
  522. else{
  523. HAL_GPIO_WritePin(GPIOF, GPIO_PIN_6, GPIO_PIN_RESET);
  524. HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_RESET);
  525. }
  526. }
  527. uint8_t add1=0xFE,add2=0xE5,add3=0xE3;
  528. //0xFE复位 0xE5启动湿度转换 0xE3启动温度转换
  529. uint16_t RH_Code,RH_Code_low=0,RH_Code_high=0;
  530. uint16_t Temp_Code,Temp_Code_low=0,Temp_Code_high=0;
  531. int humidity_min = 50;//能仍受的�?????低干燥程�?????
  532. int temperature_max = 50;//能仍受的�?????高温�?????
  533. int en_t = 0; //温度使能
  534. int en_r = 0; //湿度使能
  535. //计算出温湿度
  536. void Temperature_humidity(){
  537. //湿度
  538. HAL_I2C_Master_Transmit(&hi2c1, 0x80, &add2, 1,100);
  539. //写命�??????? ox40里面写命�??????? 0xe5 启动湿度转换
  540. HAL_I2C_Master_Receive(&hi2c1, 0x81, &RH_Code, 1, 100);
  541. //读命�??????? �???????0x40读取出湿度的数据 存入变量RH_CODE
  542. HAL_Delay(30);
  543. //进行高低字节转换
  544. RH_Code_low=(RH_Code & 0xff);
  545. RH_Code_high=(RH_Code >> 8)& 0xff;
  546. RH_Code=(RH_Code_low << 8)+RH_Code_high;
  547. //温度
  548. HAL_I2C_Master_Transmit(&hi2c1, 0x80, &add3, 1,100);
  549. HAL_I2C_Master_Receive(&hi2c1, 0x81, &Temp_Code, 1, 100);
  550. //读命�??????? �???????0x40读取出温度的数据 存入变量Temp_CODE
  551. HAL_Delay(30);
  552. //进行高低字节转换
  553. Temp_Code_low=(Temp_Code & 0xff);
  554. Temp_Code_high=(Temp_Code >> 8)& 0xff;
  555. Temp_Code=(Temp_Code_low << 8)+Temp_Code_high;
  556. Temp_Code=17572*Temp_Code/65535-4685;//扩大�???????百�??
  557. RH_Code=125*RH_Code/65536-6;//计算出湿度�??
  558. //printf("Temp_Code = r%d.%d RH_Code = %d%%n",Temp_Code/100,Temp_Code%100,RH_Code%100);
  559. //串口输出温湿�???????
  560. HAL_Delay(2);
  561. }
  562. void uart_sensor(){
  563. int tr=0;
  564. int tr_i = 0;
  565. tr = extract_two_digits((char *)uart4_data, "sensor humidity_min = ", &tr_i);
  566. if(tr != 0){
  567. humidity_min = tr_i;
  568. }
  569. tr = extract_two_digits((char *)uart4_data, "sensor temperature_max = ", &tr_i);
  570. if(tr != 0){
  571. temperature_max = tr_i;
  572. }
  573. if(strcmp("sensor temperature start",(char *)uart4_data)==0){
  574. en_t = 1;
  575. }
  576. if(strcmp("sensor humidity start",(char *)uart4_data)==0){
  577. en_r = 1;
  578. }
  579. if(strcmp("sensor temperature stop",(char *)uart4_data)==0){
  580. en_t = 0;
  581. }
  582. if(strcmp("sensor humidity stop",(char *)uart4_data)==0){
  583. en_r = 0;
  584. }
  585. if(strcmp("sensor list",(char *)uart4_data)==0){
  586. uart4_data[0] = '0';
  587. printf("Temp_Code = r%d.%d RH_Code = %d%%rn",Temp_Code/100,Temp_Code%100,RH_Code%100);
  588. printf("sensor en_t : %drn",en_t);
  589. printf("sensor en_r : %drn",en_r);
  590. printf("sensor temperature_max : %drn",temperature_max);
  591. printf("sensor humidity_min : %drn",humidity_min);
  592. }
  593. if(strcmp("sensor Temp_Code RH_Code",(char *)uart4_data)==0){
  594. uart4_data[0] = '0';
  595. printf("Temp_Code = r%d.%d RH_Code = %d%%n",Temp_Code/100,Temp_Code%100,RH_Code%100);
  596. }
  597. }
  598. void sensor(){
  599. static int iii = 0;
  600. if(iii == 0){
  601. HAL_I2C_Master_Transmit(&hi2c1, 0x80, &add1, 1, 100);
  602. HAL_Delay(2);
  603. iii++;
  604. }
  605. Temperature_humidity();
  606. uart_sensor();
  607. if(RH_Code < humidity_min && en_r == 1){
  608. //motor(10);
  609. HAL_GPIO_WritePin(GPIOI, GPIO_PIN_11, GPIO_PIN_SET);
  610. }
  611. else{
  612. HAL_GPIO_WritePin(GPIOI, GPIO_PIN_11, GPIO_PIN_RESET);
  613. }
  614. if(Temp_Code/100 >= temperature_max && en_t == 1){
  615. HAL_GPIO_WritePin(GPIOI, GPIO_PIN_10, GPIO_PIN_SET);
  616. }
  617. else{
  618. HAL_GPIO_WritePin(GPIOI, GPIO_PIN_10, GPIO_PIN_RESET);
  619. }
  620. }
  621. uint8_t DZP_data[6][34]={
  622. {0xAA,0x55,
  623. 0xFD,0xFF,0xFE,0xFF,0xC0,0x07,0xFF,0xFF,0xF7,0xDF,0xFB,0xBF,0x00,0x01,0xFF,0xFF,
  624. 0xE0,0x0F,0xEF,0xEF,0xEF,0xEF,0xE0,0x0F,0xEF,0xEF,0xEF,0xEF,0xE0,0x0F,0xEF,0xEF},//�?//0//
  625. {0xAA,0x55,
  626. 0xEF,0xDF,0xEF,0xDF,0xC3,0xDF,0xDF,0xDF,0xBE,0x03,0x42,0xDB,0xEE,0xDB,0xEE,0xDB,
  627. 0x02,0xDB,0xEE,0x03,0xEE,0xDB,0xEF,0xDF,0xEB,0xDF,0xE7,0xDF,0xEF,0xDF,0xFF,0xDF},//�?//1//
  628. {0xAA,0x55,
  629. 0xF7,0xBF,0xF7,0xBF,0xF7,0xBF,0xEC,0x07,0xEF,0xBF,0xCF,0x7F,0xC8,0x01,0xAF,0x7F,
  630. 0x6E,0xFF,0xEC,0x07,0xEF,0xF7,0xEE,0xEF,0xEF,0x5F,0xEF,0xBF,0xEF,0xDF,0xEF,0xDF}//�?//2//
  631. };
  632. void uart_mode(){
  633. if(strcmp("mode = music",(char *)uart4_data)==0){
  634. mode = 0;
  635. }
  636. if(strcmp("mode = clock",(char *)uart4_data)==0){
  637. mode = 1;
  638. }
  639. if(strcmp("mode = sensor",(char *)uart4_data)==0){
  640. mode = 2;
  641. }
  642. }
  643. void end_main(){
  644. tone_init(); //初始化音量频�??????
  645. list_max = music_init();//更新乐谱
  646. HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_1); //启动蜂鸣器定时器
  647. HAL_TIM_Base_Start_IT(&htim2); //启动定时�??????2
  648. HAL_TIM_Base_Start_IT(&htim3); //启动定时�??????2
  649. //1 使能串口空闲中断
  650. __HAL_UART_ENABLE_IT(&huart4,UART_IT_IDLE);
  651. //2.使能串口中断接收数据
  652. HAL_UART_Receive_IT(&huart4,rx_buf,sizeof(rx_buf));
  653. int mode_n = 1;
  654. while(1){
  655. music_kz();
  656. alarm_clock();
  657. uart_mode();
  658. sensor();
  659. if(mode_n != mode){
  660. mode_n = mode;
  661. for(int i = 0; i<34;i++){
  662. //printf("afgsbgafdffag");
  663. HAL_I2C_Master_Transmit(&hi2c1, 0xA0 , (uint8_t*)&DZP_data[mode][i], 1, 300);
  664. HAL_Delay(2);
  665. }
  666. }
  667. }
  668. }
  669. /* USER CODE END 0 */
  670. /**
  671. * @brief The application entry point.
  672. * @retval int
  673. */
  674. int main(void)
  675. {
  676. /* USER CODE BEGIN 1 */
  677. /* USER CODE END 1 */
  678. /* MCU Configuration--------------------------------------------------------*/
  679. /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  680. HAL_Init();
  681. /* USER CODE BEGIN Init */
  682. /* USER CODE END Init */
  683. if(IS_ENGINEERING_BOOT_MODE())
  684. {
  685. /* Configure the system clock */
  686. SystemClock_Config();
  687. }
  688. /* USER CODE BEGIN SysInit */
  689. /* USER CODE END SysInit */
  690. /* Initialize all configured peripherals */
  691. MX_GPIO_Init();
  692. MX_I2C1_Init();
  693. MX_TIM2_Init();
  694. MX_TIM4_Init();
  695. MX_UART4_Init();
  696. MX_TIM3_Init();
  697. /* USER CODE BEGIN 2 */
  698. end_main();
  699. /* USER CODE END 2 */
  700. /* Infinite loop */
  701. /* USER CODE BEGIN WHILE */
  702. while (1)
  703. {
  704. /* USER CODE END WHILE */
  705. /* USER CODE BEGIN 3 */
  706. //printf("afsgbhdntn");
  707. //HAL_Delay(500);
  708. }
  709. /* USER CODE END 3 */
  710. }
  711. /**
  712. * @brief System Clock Configuration
  713. * @retval None
  714. */
  715. void SystemClock_Config(void)
  716. {
  717. RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  718. RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  719. /** Initializes the RCC Oscillators according to the specified parameters
  720. * in the RCC_OscInitTypeDef structure.
  721. */
  722. RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_LSI;
  723. RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  724. RCC_OscInitStruct.HSICalibrationValue = 16;
  725. RCC_OscInitStruct.HSIDivValue = RCC_HSI_DIV1;
  726. RCC_OscInitStruct.LSIState = RCC_LSI_ON;
  727. RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  728. RCC_OscInitStruct.PLL2.PLLState = RCC_PLL_NONE;
  729. RCC_OscInitStruct.PLL3.PLLState = RCC_PLL_NONE;
  730. RCC_OscInitStruct.PLL4.PLLState = RCC_PLL_NONE;
  731. if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  732. {
  733. Error_Handler();
  734. }
  735. /** RCC Clock Config
  736. */
  737. RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_ACLK
  738. |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2
  739. |RCC_CLOCKTYPE_PCLK3|RCC_CLOCKTYPE_PCLK4
  740. |RCC_CLOCKTYPE_PCLK5;
  741. RCC_ClkInitStruct.AXISSInit.AXI_Clock = RCC_AXISSOURCE_HSI;
  742. RCC_ClkInitStruct.AXISSInit.AXI_Div = RCC_AXI_DIV1;
  743. RCC_ClkInitStruct.MCUInit.MCU_Clock = RCC_MCUSSOURCE_HSI;
  744. RCC_ClkInitStruct.MCUInit.MCU_Div = RCC_MCU_DIV1;
  745. RCC_ClkInitStruct.APB4_Div = RCC_APB4_DIV1;
  746. RCC_ClkInitStruct.APB5_Div = RCC_APB5_DIV1;
  747. RCC_ClkInitStruct.APB1_Div = RCC_APB1_DIV1;
  748. RCC_ClkInitStruct.APB2_Div = RCC_APB2_DIV1;
  749. RCC_ClkInitStruct.APB3_Div = RCC_APB3_DIV1;
  750. if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct) != HAL_OK)
  751. {
  752. Error_Handler();
  753. }
  754. }
  755. /**
  756. * @brief I2C1 Initialization Function
  757. * @param None
  758. * @retval None
  759. */
  760. static void MX_I2C1_Init(void)
  761. {
  762. /* USER CODE BEGIN I2C1_Init 0 */
  763. /* USER CODE END I2C1_Init 0 */
  764. /* USER CODE BEGIN I2C1_Init 1 */
  765. /* USER CODE END I2C1_Init 1 */
  766. hi2c1.Instance = I2C1;
  767. hi2c1.Init.Timing = 0x10707DBC;
  768. hi2c1.Init.OwnAddress1 = 0;
  769. hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  770. hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  771. hi2c1.Init.OwnAddress2 = 0;
  772. hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
  773. hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  774. hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  775. if (HAL_I2C_Init(&hi2c1) != HAL_OK)
  776. {
  777. Error_Handler();
  778. }
  779. /** Configure Analogue filter
  780. */
  781. if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
  782. {
  783. Error_Handler();
  784. }
  785. /** Configure Digital filter
  786. */
  787. if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK)
  788. {
  789. Error_Handler();
  790. }
  791. /* USER CODE BEGIN I2C1_Init 2 */
  792. /* USER CODE END I2C1_Init 2 */
  793. }
  794. /**
  795. * @brief TIM2 Initialization Function
  796. * @param None
  797. * @retval None
  798. */
  799. static void MX_TIM2_Init(void)
  800. {
  801. /* USER CODE BEGIN TIM2_Init 0 */
  802. /* USER CODE END TIM2_Init 0 */
  803. TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  804. TIM_MasterConfigTypeDef sMasterConfig = {0};
  805. /* USER CODE BEGIN TIM2_Init 1 */
  806. /* USER CODE END TIM2_Init 1 */
  807. htim2.Instance = TIM2;
  808. htim2.Init.Prescaler = 6400-1;
  809. htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
  810. htim2.Init.Period = 1000-1;
  811. htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  812. htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  813. if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
  814. {
  815. Error_Handler();
  816. }
  817. sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  818. if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
  819. {
  820. Error_Handler();
  821. }
  822. sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  823. sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  824. if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
  825. {
  826. Error_Handler();
  827. }
  828. /* USER CODE BEGIN TIM2_Init 2 */
  829. /* USER CODE END TIM2_Init 2 */
  830. }
  831. /**
  832. * @brief TIM3 Initialization Function
  833. * @param None
  834. * @retval None
  835. */
  836. static void MX_TIM3_Init(void)
  837. {
  838. /* USER CODE BEGIN TIM3_Init 0 */
  839. /* USER CODE END TIM3_Init 0 */
  840. TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  841. TIM_MasterConfigTypeDef sMasterConfig = {0};
  842. /* USER CODE BEGIN TIM3_Init 1 */
  843. /* USER CODE END TIM3_Init 1 */
  844. htim3.Instance = TIM3;
  845. htim3.Init.Prescaler = 6399;
  846. htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
  847. htim3.Init.Period = 10000-1;
  848. htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  849. htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  850. if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
  851. {
  852. Error_Handler();
  853. }
  854. sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  855. if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)
  856. {
  857. Error_Handler();
  858. }
  859. sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  860. sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  861. if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
  862. {
  863. Error_Handler();
  864. }
  865. /* USER CODE BEGIN TIM3_Init 2 */
  866. /* USER CODE END TIM3_Init 2 */
  867. }
  868. /**
  869. * @brief TIM4 Initialization Function
  870. * @param None
  871. * @retval None
  872. */
  873. static void MX_TIM4_Init(void)
  874. {
  875. /* USER CODE BEGIN TIM4_Init 0 */
  876. /* USER CODE END TIM4_Init 0 */
  877. TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  878. TIM_MasterConfigTypeDef sMasterConfig = {0};
  879. TIM_OC_InitTypeDef sConfigOC = {0};
  880. /* USER CODE BEGIN TIM4_Init 1 */
  881. /* USER CODE END TIM4_Init 1 */
  882. htim4.Instance = TIM4;
  883. htim4.Init.Prescaler = 639;
  884. htim4.Init.CounterMode = TIM_COUNTERMODE_UP;
  885. htim4.Init.Period = 100-1;
  886. htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  887. htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  888. if (HAL_TIM_Base_Init(&htim4) != HAL_OK)
  889. {
  890. Error_Handler();
  891. }
  892. sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  893. if (HAL_TIM_ConfigClockSource(&htim4, &sClockSourceConfig) != HAL_OK)
  894. {
  895. Error_Handler();
  896. }
  897. if (HAL_TIM_PWM_Init(&htim4) != HAL_OK)
  898. {
  899. Error_Handler();
  900. }
  901. sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  902. sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  903. if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig) != HAL_OK)
  904. {
  905. Error_Handler();
  906. }
  907. sConfigOC.OCMode = TIM_OCMODE_PWM1;
  908. sConfigOC.Pulse = 0;
  909. sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  910. sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  911. if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
  912. {
  913. Error_Handler();
  914. }
  915. /* USER CODE BEGIN TIM4_Init 2 */
  916. /* USER CODE END TIM4_Init 2 */
  917. HAL_TIM_MspPostInit(&htim4);
  918. }
  919. /**
  920. * @brief UART4 Initialization Function
  921. * @param None
  922. * @retval None
  923. */
  924. static void MX_UART4_Init(void)
  925. {
  926. /* USER CODE BEGIN UART4_Init 0 */
  927. /* USER CODE END UART4_Init 0 */
  928. /* USER CODE BEGIN UART4_Init 1 */
  929. /* USER CODE END UART4_Init 1 */
  930. huart4.Instance = UART4;
  931. huart4.Init.BaudRate = 115200;
  932. huart4.Init.WordLength = UART_WORDLENGTH_8B;
  933. huart4.Init.StopBits = UART_STOPBITS_1;
  934. huart4.Init.Parity = UART_PARITY_NONE;
  935. huart4.Init.Mode = UART_MODE_TX_RX;
  936. huart4.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  937. huart4.Init.OverSampling = UART_OVERSAMPLING_16;
  938. huart4.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  939. huart4.Init.ClockPrescaler = UART_PRESCALER_DIV1;
  940. huart4.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  941. if (HAL_UART_Init(&huart4) != HAL_OK)
  942. {
  943. Error_Handler();
  944. }
  945. if (HAL_UARTEx_SetTxFifoThreshold(&huart4, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
  946. {
  947. Error_Handler();
  948. }
  949. if (HAL_UARTEx_SetRxFifoThreshold(&huart4, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
  950. {
  951. Error_Handler();
  952. }
  953. if (HAL_UARTEx_DisableFifoMode(&huart4) != HAL_OK)
  954. {
  955. Error_Handler();
  956. }
  957. /* USER CODE BEGIN UART4_Init 2 */
  958. /* USER CODE END UART4_Init 2 */
  959. }
  960. /**
  961. * @brief GPIO Initialization Function
  962. * @param None
  963. * @retval None
  964. */
  965. static void MX_GPIO_Init(void)
  966. {
  967. GPIO_InitTypeDef GPIO_InitStruct = {0};
  968. /* GPIO Ports Clock Enable */
  969. __HAL_RCC_GPIOF_CLK_ENABLE();
  970. __HAL_RCC_GPIOC_CLK_ENABLE();
  971. __HAL_RCC_GPIOI_CLK_ENABLE();
  972. __HAL_RCC_GPIOG_CLK_ENABLE();
  973. __HAL_RCC_GPIOB_CLK_ENABLE();
  974. __HAL_RCC_GPIOE_CLK_ENABLE();
  975. /*Configure GPIO pin Output Level */
  976. HAL_GPIO_WritePin(GPIOF, GPIO_PIN_1|GPIO_PIN_6, GPIO_PIN_RESET);
  977. /*Configure GPIO pin Output Level */
  978. HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_RESET);
  979. /*Configure GPIO pin Output Level */
  980. HAL_GPIO_WritePin(GPIOI, GPIO_PIN_11|GPIO_PIN_10, GPIO_PIN_RESET);
  981. /*Configure GPIO pins : PF1 PF6 */
  982. GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_6;
  983. GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  984. GPIO_InitStruct.Pull = GPIO_NOPULL;
  985. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  986. HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
  987. /*Configure GPIO pin : PC7 */
  988. GPIO_InitStruct.Pin = GPIO_PIN_7;
  989. GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  990. GPIO_InitStruct.Pull = GPIO_NOPULL;
  991. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  992. HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
  993. /*Configure GPIO pins : PI11 PI10 */
  994. GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_10;
  995. GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  996. GPIO_InitStruct.Pull = GPIO_NOPULL;
  997. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  998. HAL_GPIO_Init(GPIOI, &GPIO_InitStruct);
  999. /*Configure GPIO pins : PG2 PG0 PG1 */
  1000. GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_0|GPIO_PIN_1;
  1001. GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
  1002. GPIO_InitStruct.Pull = GPIO_PULLUP;
  1003. HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
  1004. /*Configure GPIO pin : PE9 */
  1005. GPIO_InitStruct.Pin = GPIO_PIN_9;
  1006. GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
  1007. GPIO_InitStruct.Pull = GPIO_PULLUP;
  1008. HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
  1009. /* EXTI interrupt init*/
  1010. HAL_NVIC_SetPriority(EXTI0_IRQn, 3, 0);
  1011. HAL_NVIC_EnableIRQ(EXTI0_IRQn);
  1012. HAL_NVIC_SetPriority(EXTI1_IRQn, 3, 0);
  1013. HAL_NVIC_EnableIRQ(EXTI1_IRQn);
  1014. HAL_NVIC_SetPriority(EXTI2_IRQn, 3, 0);
  1015. HAL_NVIC_EnableIRQ(EXTI2_IRQn);
  1016. HAL_NVIC_SetPriority(EXTI9_IRQn, 2, 0);
  1017. HAL_NVIC_EnableIRQ(EXTI9_IRQn);
  1018. }
  1019. /* USER CODE BEGIN 4 */
  1020. /* USER CODE END 4 */
  1021. /**
  1022. * @brief This function is executed in case of error occurrence.
  1023. * @retval None
  1024. */
  1025. void Error_Handler(void)
  1026. {
  1027. /* USER CODE BEGIN Error_Handler_Debug */
  1028. /* User can add his own implementation to report the HAL error return state */
  1029. __disable_irq();
  1030. while (1)
  1031. {
  1032. }
  1033. /* USER CODE END Error_Handler_Debug */
  1034. }
  1035. #ifdef USE_FULL_ASSERT
  1036. /**
  1037. * @brief Reports the name of the source file and the source line number
  1038. * where the assert_param error has occurred.
  1039. * @param file: pointer to the source file name
  1040. * @param line: assert_param error line source number
  1041. * @retval None
  1042. */
  1043. void assert_failed(uint8_t *file, uint32_t line)
  1044. {
  1045. /* USER CODE BEGIN 6 */
  1046. /* User can add his own implementation to report the file name and line number,
  1047. ex: printf("Wrong parameters value: file %s on line %drn", file, line) */
  1048. /* USER CODE END 6 */
  1049. }
  1050. #endif /* USE_FULL_ASSERT */
  1051. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

stm32mp1xx_it.c

  1. /* USER CODE BEGIN Header */
  2. /**
  3. ******************************************************************************
  4. * @file stm32mp1xx_it.c
  5. * @brief Interrupt Service Routines.
  6. ******************************************************************************
  7. * @attention
  8. *
  9. * <h2><center>&copy; Copyright (c) 2024 STMicroelectronics.
  10. * All rights reserved.</center></h2>
  11. *
  12. * This software component is licensed by ST under BSD 3-Clause license,
  13. * the "License"; You may not use this file except in compliance with the
  14. * License. You may obtain a copy of the License at:
  15. * opensource.org/licenses/BSD-3-Clause
  16. *
  17. ******************************************************************************
  18. */
  19. /* USER CODE END Header */
  20. /* Includes ------------------------------------------------------------------*/
  21. #include "main.h"
  22. #include "stm32mp1xx_it.h"
  23. /* Private includes ----------------------------------------------------------*/
  24. /* USER CODE BEGIN Includes */
  25. /* USER CODE END Includes */
  26. /* Private typedef -----------------------------------------------------------*/
  27. /* USER CODE BEGIN TD */
  28. int mode = 0; //模式
  29. extern void uart4_idle_func(void);
  30. extern void smg_xians();
  31. // 音乐盒基�?????变量
  32. int time_100ms_cnt = 0; //0.1s计数�?????
  33. int Beat_speed = 5; //节拍速度,代表半个节拍需要多少个0.1s
  34. int Beat_speed_n = 0; //实际执行的节拍数
  35. int Beat_num = 2; //这个�?????个音�?????要多少个 半拍
  36. int flag = 0; //当其等于 1 时,表示�?????个音结束
  37. int EN_music = 0; //使能信号,用于开启整个音乐盒
  38. int list = 0; //音乐列表
  39. int list_max = 0; //音乐总数
  40. int Low_volume = 5; //音量大小
  41. int Low_volume_cnt = 3; //音量大小增加�?????
  42. int music_speed_i = 0; //音乐播放速度模式保存
  43. // 音乐播放速度控制函数
  44. int music_speed_kz(int i){
  45. //倍数计算公式 1 + (1 - (新的节拍速度 / 原来的节拍�?�度))
  46. switch(i){
  47. case 0:{
  48. Beat_speed = 5; //0.5s半个节拍,正�?????+�??????�度
  49. break;
  50. }
  51. case 1:{
  52. Beat_speed = 4; //1.2倍数
  53. break;
  54. }
  55. case 2:{
  56. Beat_speed = 3; //约等�??????? 1.5倍数
  57. break;
  58. }
  59. case 3:{
  60. Beat_speed = 1; //约等�??????? 2 倍数
  61. break;
  62. }
  63. case 4:{
  64. Beat_speed = 6; //约等�??????? 0.8 倍数
  65. break;
  66. }
  67. case 5:{
  68. Beat_speed = 7; //约等�??????? 0.6 倍数
  69. break;
  70. }
  71. default:{
  72. Beat_speed = 5; //0.5s半个节拍,正常�?�度
  73. i=0;
  74. break;
  75. }
  76. }
  77. return i;
  78. }
  79. //数码管闹�????
  80. int smg_number[10] = {0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xE0,0xFE,0xF6};
  81. int buf[8] = {0};
  82. //闹钟保存数组
  83. int alarm_clock_array[20][4] = {0};
  84. int alarm_clock_array_cnt = 0;
  85. //实时时钟信息
  86. int shi_shi = 0;
  87. int shi_ge = 0;
  88. int fen_shi = 0;
  89. int fen_ge = 0;
  90. int miao_shi = 0;
  91. int miao_ge = 0;
  92. int miao = 0;
  93. int shi = 0;
  94. int fen = 0;
  95. int EN_clock = 0;//闹钟设置使能
  96. extern int en_clock;//用于控制闹钟响铃
  97. //闹钟设置信息
  98. int shi_shi_clock = 0;
  99. int shi_ge_clock = 0;
  100. int fen_shi_clock = 0;
  101. int fen_ge_clock = 0;
  102. int miao_shi_clock = 0;
  103. int miao_ge_clock = 0;
  104. int miao_clock = 0, shi_clock = 0, fen_clock = 0;
  105. /* USER CODE END TD */
  106. /* Private define ------------------------------------------------------------*/
  107. /* USER CODE BEGIN PD */
  108. /* USER CODE END PD */
  109. /* Private macro -------------------------------------------------------------*/
  110. /* USER CODE BEGIN PM */
  111. /* USER CODE END PM */
  112. /* Private variables ---------------------------------------------------------*/
  113. /* USER CODE BEGIN PV */
  114. /* USER CODE END PV */
  115. /* Private function prototypes -----------------------------------------------*/
  116. /* USER CODE BEGIN PFP */
  117. /* USER CODE END PFP */
  118. /* Private user code ---------------------------------------------------------*/
  119. /* USER CODE BEGIN 0 */
  120. /* USER CODE END 0 */
  121. /* External variables --------------------------------------------------------*/
  122. extern TIM_HandleTypeDef htim2;
  123. extern TIM_HandleTypeDef htim3;
  124. extern UART_HandleTypeDef huart4;
  125. /* USER CODE BEGIN EV */
  126. /* USER CODE END EV */
  127. /******************************************************************************/
  128. /* Cortex-M4 Processor Interruption and Exception Handlers */
  129. /******************************************************************************/
  130. /**
  131. * @brief This function handles Non maskable interrupt.
  132. */
  133. void NMI_Handler(void)
  134. {
  135. /* USER CODE BEGIN NonMaskableInt_IRQn 0 */
  136. /* USER CODE END NonMaskableInt_IRQn 0 */
  137. /* USER CODE BEGIN NonMaskableInt_IRQn 1 */
  138. while (1)
  139. {
  140. }
  141. /* USER CODE END NonMaskableInt_IRQn 1 */
  142. }
  143. /**
  144. * @brief This function handles Hard fault interrupt.
  145. */
  146. void HardFault_Handler(void)
  147. {
  148. /* USER CODE BEGIN HardFault_IRQn 0 */
  149. /* USER CODE END HardFault_IRQn 0 */
  150. while (1)
  151. {
  152. /* USER CODE BEGIN W1_HardFault_IRQn 0 */
  153. /* USER CODE END W1_HardFault_IRQn 0 */
  154. }
  155. }
  156. /**
  157. * @brief This function handles Memory management fault.
  158. */
  159. void MemManage_Handler(void)
  160. {
  161. /* USER CODE BEGIN MemoryManagement_IRQn 0 */
  162. /* USER CODE END MemoryManagement_IRQn 0 */
  163. while (1)
  164. {
  165. /* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */
  166. /* USER CODE END W1_MemoryManagement_IRQn 0 */
  167. }
  168. }
  169. /**
  170. * @brief This function handles Pre-fetch fault, memory access fault.
  171. */
  172. void BusFault_Handler(void)
  173. {
  174. /* USER CODE BEGIN BusFault_IRQn 0 */
  175. /* USER CODE END BusFault_IRQn 0 */
  176. while (1)
  177. {
  178. /* USER CODE BEGIN W1_BusFault_IRQn 0 */
  179. /* USER CODE END W1_BusFault_IRQn 0 */
  180. }
  181. }
  182. /**
  183. * @brief This function handles Undefined instruction or illegal state.
  184. */
  185. void UsageFault_Handler(void)
  186. {
  187. /* USER CODE BEGIN UsageFault_IRQn 0 */
  188. /* USER CODE END UsageFault_IRQn 0 */
  189. while (1)
  190. {
  191. /* USER CODE BEGIN W1_UsageFault_IRQn 0 */
  192. /* USER CODE END W1_UsageFault_IRQn 0 */
  193. }
  194. }
  195. /**
  196. * @brief This function handles System service call via SWI instruction.
  197. */
  198. void SVC_Handler(void)
  199. {
  200. /* USER CODE BEGIN SVCall_IRQn 0 */
  201. /* USER CODE END SVCall_IRQn 0 */
  202. /* USER CODE BEGIN SVCall_IRQn 1 */
  203. /* USER CODE END SVCall_IRQn 1 */
  204. }
  205. /**
  206. * @brief This function handles Debug monitor.
  207. */
  208. void DebugMon_Handler(void)
  209. {
  210. /* USER CODE BEGIN DebugMonitor_IRQn 0 */
  211. /* USER CODE END DebugMonitor_IRQn 0 */
  212. /* USER CODE BEGIN DebugMonitor_IRQn 1 */
  213. /* USER CODE END DebugMonitor_IRQn 1 */
  214. }
  215. /**
  216. * @brief This function handles Pendable request for system service.
  217. */
  218. void PendSV_Handler(void)
  219. {
  220. /* USER CODE BEGIN PendSV_IRQn 0 */
  221. /* USER CODE END PendSV_IRQn 0 */
  222. /* USER CODE BEGIN PendSV_IRQn 1 */
  223. /* USER CODE END PendSV_IRQn 1 */
  224. }
  225. /**
  226. * @brief This function handles System tick timer.
  227. */
  228. void SysTick_Handler(void)
  229. {
  230. /* USER CODE BEGIN SysTick_IRQn 0 */
  231. /* USER CODE END SysTick_IRQn 0 */
  232. HAL_IncTick();
  233. /* USER CODE BEGIN SysTick_IRQn 1 */
  234. /* USER CODE END SysTick_IRQn 1 */
  235. }
  236. /******************************************************************************/
  237. /* STM32MP1xx Peripheral Interrupt Handlers */
  238. /* Add here the Interrupt Handlers for the used peripherals. */
  239. /* For the available peripheral interrupt handler names, */
  240. /* please refer to the startup file (startup_stm32mp1xx.s). */
  241. /******************************************************************************/
  242. /**
  243. * @brief This function handles EXTI line0 interrupt.
  244. */
  245. void EXTI0_IRQHandler(void)
  246. {
  247. /* USER CODE BEGIN EXTI0_IRQn 0 */
  248. if(HAL_GPIO_ReadPin(GPIOG, GPIO_PIN_0) == 0 && mode == 0)//确保数据稳定
  249. {
  250. //每次按下解决 音量�??????? Low_volume_cnt
  251. Low_volume = Low_volume + Low_volume_cnt;
  252. if(Low_volume >= 10)
  253. Low_volume = 0;
  254. }
  255. if(HAL_GPIO_ReadPin(GPIOG,GPIO_PIN_0)==GPIO_PIN_RESET && mode == 1) {
  256. shi_clock++;
  257. fen_shi_clock=fen_clock/10;
  258. fen_ge_clock=fen_clock%10;
  259. shi_shi_clock=shi_clock/10;
  260. shi_ge_clock=shi_clock%10;
  261. if(shi_clock>=24)
  262. {
  263. shi_clock=0;
  264. }
  265. miao_shi_clock=miao_clock/10;
  266. miao_ge_clock=miao_clock%10;
  267. fen_shi_clock=fen_clock/10;
  268. fen_ge_clock=fen_clock%10;
  269. shi_shi_clock=shi_clock/10;
  270. shi_ge_clock=shi_clock%10;
  271. buf[0]=smg_number[shi_shi_clock];
  272. buf[1]=smg_number[shi_ge_clock];
  273. buf[3]=smg_number[fen_shi_clock];
  274. buf[4]=smg_number[fen_ge_clock];
  275. buf[6]=smg_number[miao_shi_clock];
  276. buf[7]=smg_number[miao_ge_clock];
  277. }
  278. /* USER CODE END EXTI0_IRQn 0 */
  279. HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
  280. /* USER CODE BEGIN EXTI0_IRQn 1 */
  281. /* USER CODE END EXTI0_IRQn 1 */
  282. }
  283. /**
  284. * @brief This function handles EXTI line1 interrupt.
  285. */
  286. void EXTI1_IRQHandler(void)
  287. {
  288. /* USER CODE BEGIN EXTI1_IRQn 0 */
  289. if(HAL_GPIO_ReadPin(GPIOG, GPIO_PIN_1) == 0 && mode == 0)//确保数据稳定
  290. {
  291. music_speed_i++;
  292. music_speed_i = music_speed_kz(music_speed_i);
  293. }
  294. if(HAL_GPIO_ReadPin(GPIOG,GPIO_PIN_1)==GPIO_PIN_RESET && mode == 1) {
  295. fen_clock++;
  296. fen_shi_clock=fen_clock/10;
  297. fen_ge_clock=fen_clock%10;
  298. if(fen_clock>=60)
  299. {
  300. fen_clock=0;
  301. shi_clock++;
  302. fen_shi_clock=fen_clock/10;
  303. fen_ge_clock=fen_clock%10;
  304. shi_shi_clock=shi_clock/10;
  305. shi_ge_clock=shi_clock%10;
  306. if(shi_clock>=24)
  307. {
  308. shi_clock=0;
  309. }
  310. }
  311. miao_shi_clock=miao_clock/10;
  312. miao_ge_clock=miao_clock%10;
  313. fen_shi_clock=fen_clock/10;
  314. fen_ge_clock=fen_clock%10;
  315. shi_shi_clock=shi_clock/10;
  316. shi_ge_clock=shi_clock%10;
  317. buf[0]=smg_number[shi_shi_clock];
  318. buf[1]=smg_number[shi_ge_clock];
  319. buf[3]=smg_number[fen_shi_clock];
  320. buf[4]=smg_number[fen_ge_clock];
  321. buf[6]=smg_number[miao_shi_clock];
  322. buf[7]=smg_number[miao_ge_clock];
  323. }
  324. /* USER CODE END EXTI1_IRQn 0 */
  325. HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_1);
  326. /* USER CODE BEGIN EXTI1_IRQn 1 */
  327. /* USER CODE END EXTI1_IRQn 1 */
  328. }
  329. /**
  330. * @brief This function handles EXTI line2 interrupt.
  331. */
  332. void EXTI2_IRQHandler(void)
  333. {
  334. /* USER CODE BEGIN EXTI2_IRQn 0 */
  335. if(HAL_GPIO_ReadPin(GPIOG, GPIO_PIN_2) == 0 && mode == 0)//确保数据稳定
  336. {
  337. list++;
  338. if(list > list_max){
  339. list = 0;
  340. }
  341. }
  342. if(HAL_GPIO_ReadPin(GPIOG,GPIO_PIN_2)==GPIO_PIN_RESET && mode == 1) {
  343. //在此处关闭闹�????
  344. en_clock = 0;
  345. }
  346. /* USER CODE END EXTI2_IRQn 0 */
  347. HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_2);
  348. /* USER CODE BEGIN EXTI2_IRQn 1 */
  349. /* USER CODE END EXTI2_IRQn 1 */
  350. }
  351. /**
  352. * @brief This function handles TIM2 global interrupt.
  353. */
  354. void TIM2_IRQHandler(void)
  355. {
  356. /* USER CODE BEGIN TIM2_IRQn 0 */
  357. if(EN_music == 1)
  358. time_100ms_cnt++;
  359. else
  360. time_100ms_cnt = time_100ms_cnt; //其余状�?�不计数
  361. if(time_100ms_cnt >= Beat_speed_n * Beat_num){ //这个音节结束
  362. time_100ms_cnt = 0;
  363. flag = 1; //发�?�音节结束信�???????
  364. }
  365. //数码�????
  366. static int smg_time_100ms = 0;
  367. smg_time_100ms++;
  368. if(smg_time_100ms>=10){
  369. miao++;
  370. smg_time_100ms = 0;
  371. }
  372. if (miao>=60)
  373. {
  374. miao=0;
  375. fen++;
  376. if(fen>=60)
  377. {
  378. fen=0;
  379. shi++;
  380. if(shi>=24)
  381. {
  382. shi=0;
  383. }
  384. }
  385. }
  386. if(miao >= 60){
  387. miao = miao-60;
  388. fen++;
  389. }
  390. if(fen>=60){
  391. fen = fen-60;
  392. shi ++;
  393. }
  394. if(shi>= 24){
  395. shi = shi -24;
  396. }
  397. miao_shi=miao/10;
  398. miao_ge=miao%10;
  399. fen_shi=fen/10;
  400. fen_ge=fen%10;
  401. shi_shi=shi/10;
  402. shi_ge=shi%10;
  403. if(EN_clock == 0){
  404. buf[0]=smg_number[shi_shi];
  405. buf[1]=smg_number[shi_ge];
  406. buf[3]=smg_number[fen_shi];
  407. buf[4]=smg_number[fen_ge];
  408. buf[6]=smg_number[miao_shi];
  409. buf[7]=smg_number[miao_ge];
  410. HAL_GPIO_WritePin(GPIOF, GPIO_PIN_1, GPIO_PIN_RESET);
  411. //HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_RESET);
  412. //HAL_GPIO_WritePin(GPIOI, GPIO_PIN_11|GPIO_PIN_10, GPIO_PIN_RESET);
  413. }
  414. else{
  415. HAL_GPIO_WritePin(GPIOF, GPIO_PIN_1, GPIO_PIN_SET);
  416. //HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_SET);
  417. //HAL_GPIO_WritePin(GPIOI, GPIO_PIN_11|GPIO_PIN_10, GPIO_PIN_SET);
  418. }
  419. /* USER CODE END TIM2_IRQn 0 */
  420. HAL_TIM_IRQHandler(&htim2);
  421. /* USER CODE BEGIN TIM2_IRQn 1 */
  422. /* USER CODE END TIM2_IRQn 1 */
  423. }
  424. /**
  425. * @brief This function handles TIM3 global interrupt.
  426. */
  427. void TIM3_IRQHandler(void)
  428. {
  429. /* USER CODE BEGIN TIM3_IRQn 0 */
  430. smg_xians();
  431. /* USER CODE END TIM3_IRQn 0 */
  432. HAL_TIM_IRQHandler(&htim3);
  433. /* USER CODE BEGIN TIM3_IRQn 1 */
  434. /* USER CODE END TIM3_IRQn 1 */
  435. }
  436. /**
  437. * @brief This function handles UART4 global interrupt.
  438. */
  439. void UART4_IRQHandler(void)
  440. {
  441. /* USER CODE BEGIN UART4_IRQn 0 */
  442. uart4_idle_func();
  443. /* USER CODE END UART4_IRQn 0 */
  444. HAL_UART_IRQHandler(&huart4);
  445. /* USER CODE BEGIN UART4_IRQn 1 */
  446. /* USER CODE END UART4_IRQn 1 */
  447. }
  448. /**
  449. * @brief This function handles EXTI line9 interrupt.
  450. */
  451. void EXTI9_IRQHandler(void)
  452. {
  453. /* USER CODE BEGIN EXTI9_IRQn 0 */
  454. if(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_9) == 0 && mode == 0){//确保数据稳定
  455. EN_music = !EN_music;
  456. }
  457. if(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_9) == 0 && mode == 1 ){//确保数据稳定
  458. if(EN_clock == 1){
  459. //闹钟设置成功
  460. alarm_clock_array[alarm_clock_array_cnt][0] = shi_clock;
  461. alarm_clock_array[alarm_clock_array_cnt][1] = fen_clock;
  462. alarm_clock_array[alarm_clock_array_cnt][2] = miao_clock;
  463. alarm_clock_array[alarm_clock_array_cnt][3] = 3; //默认播放第三首音�????
  464. alarm_clock_array_cnt++;
  465. if(alarm_clock_array_cnt >= 20) alarm_clock_array_cnt = 0;
  466. EN_clock = 0;
  467. }
  468. else if(EN_clock == 0){
  469. //设置闹钟
  470. shi_shi_clock = shi_shi;
  471. shi_ge_clock = shi_ge;
  472. fen_shi_clock = fen_shi;
  473. fen_ge_clock = fen_ge;
  474. miao_shi_clock = 0;
  475. miao_ge_clock = 0;
  476. miao_clock = 0;
  477. shi_clock = shi;
  478. fen_clock = fen;
  479. EN_clock = 1;
  480. }
  481. }
  482. /* USER CODE END EXTI9_IRQn 0 */
  483. HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_9);
  484. /* USER CODE BEGIN EXTI9_IRQn 1 */
  485. /* USER CODE END EXTI9_IRQn 1 */
  486. }
  487. /**
  488. * @brief This function handles RCC wake-up interrupt.
  489. */
  490. void RCC_WAKEUP_IRQHandler(void)
  491. {
  492. /* USER CODE BEGIN RCC_WAKEUP_IRQn 0 */
  493. /* USER CODE END RCC_WAKEUP_IRQn 0 */
  494. HAL_RCC_WAKEUP_IRQHandler();
  495. /* USER CODE BEGIN RCC_WAKEUP_IRQn 1 */
  496. /* USER CODE END RCC_WAKEUP_IRQn 1 */
  497. }
  498. /* USER CODE BEGIN 1 */
  499. /* USER CODE END 1 */
  500. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

직렬 명령 세트

  1. mode = music
  2. mode = clock
  3. mode = sensor
  4. music volume increase
  5. music volume reduction
  6. music speed increase
  7. music speed reduction
  8. music next song
  9. music previous song
  10. music start
  11. music stop
  12. clock shi =
  13. clock fen =
  14. clock miao =
  15. clock delay shi =
  16. clock delay fen =
  17. clock delay miao =
  18. time shi = ;fen = ;miao =
  19. clock delay list
  20. clock stop list =
  21. clock stop stop
  22. sensor humidity_min =
  23. sensor temperature_max =
  24. sensor temperature start
  25. sensor humidity start
  26. sensor temperature stop
  27. sensor humidity stop
  28. sensor list
  29. sensor Temp_Code RH_Code

6. 부분 효과 표시

STM32 하이브리드 버전

7. 요약

이 설계는 STM32MP157A 마이크로컨트롤러를 기반으로 하는 고도로 통합된 다기능 시스템으로 버저, 디지털 튜브, 도트 매트릭스 스크린, 온도 및 습도 센서, LED 조명 및 버튼과 같은 여러 모듈을 통합하여 풍부한 상호 작용과 기능을 구현합니다. 이 시스템은 STM32CUBEIDE를 개발 플랫폼으로 사용하여 STM32MP157A 마이크로컨트롤러의 고성능과 유연성을 최대한 활용하여 임베디드 시스템 설계에서 광범위한 응용 가능성을 보여줍니다.

디자인 요약:

  1. 모듈형 디자인: 이 디자인은 모듈식 설계 아이디어를 채택합니다. 알람 시계, 뮤직 박스, 온도 및 습도 모니터링과 같은 다양한 기능 모듈을 독립적으로 설계한 다음 함께 통합합니다. 이는 시스템의 유지 관리성과 확장성을 향상시킬 뿐만 아니라 모듈의 기능적 구현이 더 명확해졌습니다.

  2. 유연한 모드 전환: 직렬 통신을 통해 다양한 모드(알람시계, 뮤직박스, 온도 및 습도 모니터링) 간 유연한 전환이 구현되어 사용자가 필요에 따라 필요한 기능을 쉽게 선택할 수 있어 시스템의 사용자 친화성과 실용성이 향상됩니다.

  3. 다양한 디스플레이와 상호작용 : 도트 매트릭스 화면은 다양한 한자(예: "Zhong", "Yin", "Zhuan")를 다양한 모드로 표시하여 현재 작업 모드를 직관적으로 보여주고 사용자 경험을 향상시킵니다. 동시에 버튼과 직렬 포트 제어의 조합을 통해 사용자는 음악 재생 속도 및 볼륨 조정, 노래 전환, 알람 시간 조정, 다중 알람 설정 등과 같은 다양한 방법으로 시스템을 작동할 수 있습니다. 시스템의 기능을 강화합니다.

  4. 온도 및 습도 모니터링 및 조정: 시스템에는 주변 온도와 습도를 실시간으로 모니터링하고 온도와 습도가 설정 범위를 초과하면 직렬 포트를 통해 온도와 습도의 상한 및 하한을 조정할 수 있는 온도 및 습도 센서가 통합되어 있습니다. LED 조명을 통해 프롬프트가 제공되어 지능형 모니터링 및 환경 조정이 실현됩니다.

  5. 효율적인 개발 플랫폼: STM32CUBEIDE를 개발 플랫폼으로 사용하고 강력한 코드 편집, 컴파일, 디버깅 기능은 물론 풍부한 라이브러리 기능과 샘플 프로젝트를 사용하여 개발 효율성을 크게 향상시키고 개발 난이도를 줄입니다.

  6. 포괄적인 애플리케이션 기능 시연: 이 설계는 임베디드 시스템 설계에서 STM32MP157A 마이크로컨트롤러의 강력한 기능을 보여줄 뿐만 아니라 하드웨어 선택, 회로 설계, 소프트웨어 프로그래밍, 시스템 디버깅 등에 대한 설계자의 포괄적인 애플리케이션 기능을 반영합니다.

요약하자면, 이 디자인은 다기능, 유연성 및 사용자 친화성을 통합한 임베디드 시스템으로, 복잡한 시스템 디자인에서 STM32MP157A 마이크로컨트롤러의 광범위한 애플리케이션 전망과 잠재력을 완벽하게 보여줍니다. 이 설계의 구현을 통해 임베디드 시스템 설계에 대한 이해가 깊어질 뿐만 아니라 실제 문제를 해결하는 능력도 향상됩니다.

참고자료:

        1. STM32 단순 음악 플레이어(HAL 라이브러리)