[其他] 多功能小键盘(基于HK32F030M)

[复制链接]
4186|20
 楼主| hehhehee 发表于 2022-11-26 23:46 | 显示全部楼层 |阅读模式
如果看到了这篇文章,请了解此项目非本人制作。只是用开源项目来学习。 项目渲染图:
83459638234b01cce0.png
简介 项目采用航顺芯片设计制造的HK32F030MF4P6
MF4P6有一个ADC、16个外部中断、16个GPIO端口、封装形式为TSSOP20。
HK32F030不支持USB协议数据端口,本项目采用USB-TTL芯片。
HK32F030数据手册、用户手册


评论

你好,请问HK32F030这个芯片的系统时钟怎么看,系统配置是RCC->CFGR &= (uint32_t)0xF8FFB81C; 算出来HCLK = 6 ,PCLK = 1,配置的TIM时钟应该是 48/6 = 8M,但实际不是这个,大约是24M  发表于 2023-5-18 17:12
 楼主| hehhehee 发表于 2022-11-26 23:47 | 显示全部楼层
代码分析

按照程序文件分析代码。具体文件有:
71179638235070f084.png

main.c、usart.c、tim.c、mcu.c、ec11.c、key.c。

咋这么像是正点原子的风格啊。
 楼主| hehhehee 发表于 2022-11-26 23:47 | 显示全部楼层
main.c
  1. /**
  2.   ******************************************************************************
  3.   * [url=home.php?mod=space&uid=288409]@file[/url]           : main.c
  4.   * [url=home.php?mod=space&uid=247401]@brief[/url]          : Main program body
  5.   ******************************************************************************
  6.   * @attention
  7.   *
  8.   */

  9. /* Includes ------------------------------------------------------------------*/
  10. #include "main.h"
  11. #include "hk32f030m.h"
  12. #include "hk32f030m_gpio.h"
  13. #include "usart.h"
  14. #include "string.h"

  15. #include "key.h"
  16. #include "EC11.h"

  17. #include "tim.h"

  18. int main(void)
  19. /* Infinite loop */
  20. {
  21.         for(int i=0;i<10;i++)  // 延时 保证正常下载程序
  22.                 softWareDelay();
  23.        
  24.         KEY_Configurature();  // 按键初始化
  25.         EC11_Configurature();  // EC11初始化
  26.         USART_Configurature();  // 串口初始化
  27.         softWareDelay();  // 软件延时等待系统稳定
  28.         TIM6_Config();  // 3S定时器初始化
  29.   while (1)
  30.   {
  31.                 KEY_Scan();
  32.                 switch(EC11_Read_T())
  33.                 {
  34.                         case 0x01:
  35.                                 printf("Z\r\n");break;  // 旋钮1左转
  36.                         case 0x02:
  37.                                 printf("C\r\n");break;  // 旋钮1右转
  38.                         case 0x03:
  39.                                 printf("X\r\n");break;  // 旋钮1按下
  40.                         case 0x11:
  41.                                 printf("Q\r\n");break;  // 旋钮1按下左转
  42.                         case 0x12:
  43.                                 printf("W\r\n");break;  // 旋钮1按下右转
  44.                 }
  45.                
  46.                 switch(EC11_Read_D())
  47.                 {
  48.                         case 0x01:
  49.                                 printf("N\r\n");break;  // 旋钮2右转
  50.                         case 0x02:
  51.                                 printf("V\r\n");break;  // 旋钮2左转
  52.                         case 0x03:
  53.                                 printf("B\r\n");break;  // 旋钮2按下
  54.                         case 0x11:
  55.                                 printf("H\r\n");break;  // 旋钮2按下右转
  56.                         case 0x12:
  57.                                 printf("G\r\n");break;  // 旋钮2按下左转
  58.                 }
  59.                
  60.   }
  61. }
  62. /*时钟配置*/
  63. void RCC_Configuration(void)
  64. {
  65.         RCC_AHBPeriphClockCmd( RCC_AHBPeriph_GPIOA, ENABLE);
  66.         RCC_AHBPeriphClockCmd( RCC_AHBPeriph_GPIOB, ENABLE);
  67.         RCC_AHBPeriphClockCmd( RCC_AHBPeriph_GPIOC, ENABLE);
  68.         RCC_AHBPeriphClockCmd( RCC_AHBPeriph_GPIOD, ENABLE);
  69.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);
  70. }
  71. /*软件延时*/
  72. void softWareDelay(void)
  73. {
  74.         uint16_t i;
  75.         uint16_t j;
  76.        
  77.         for(i=0;i<500;i++)
  78.         {
  79.                 for(j=0;j<1000;j++)
  80.                 {
  81.                         __NOP();
  82.                 }
  83.         }
  84. }

  85. #ifdef  USE_FULL_ASSERT
  86. /**
  87.   * @brief  Reports the name of the source file and the source line number
  88.   *         where the assert_param error has occurred.
  89.   * @param  file: pointer to the source file name
  90.   * @param  line: assert_param error line source number
  91.   * @retval None
  92.   */
  93. void assert_failed(uint8_t* file, uint32_t line)
  94. {
  95.   /* User can add his own implementation to report the file name and line number,
  96.      tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  97. }
  98. #endif /* USE_FULL_ASSERT */

 楼主| hehhehee 发表于 2022-11-26 23:49 | 显示全部楼层
main.h
  1. /* USER CODE BEGIN Header */
  2. /**
  3.   ******************************************************************************
  4.   * @file           : main.h
  5.   * @brief          : Header for main.c file.
  6.   *                   This file contains the common defines of the application.
  7.   ******************************************************************************
  8.   */
  9. /* USER CODE END Header */

  10. /* Define to prevent recursive inclusion -------------------------------------*/
  11. #ifndef __MAIN_H
  12. #define __MAIN_H

  13. #ifdef __cplusplus
  14. extern "C" {
  15. #endif

  16. //#define DEBUG  // 调试标志位 如果开启 则下载引脚不使用

  17. void RCC_Configuration(void);  // 时钟初始化
  18. void softWareDelay(void);  // 软件延时


  19. #ifdef __cplusplus
  20. }
  21. #endif

  22. #endif /* __MAIN_H */
 楼主| hehhehee 发表于 2022-11-26 23:50 | 显示全部楼层
key.c

由于主函数调用的KEY_Scan()函数,所以从key.c开始看起。
  1. #include "key.h"
  2. /**
  3. * @brief  键盘引脚初始化
  4. * @param  
  5. * [url=home.php?mod=space&uid=144993]@ref[/url]
  6. * [url=home.php?mod=space&uid=266161]@return[/url]
  7. * -
  8. * [url=home.php?mod=space&uid=1543424]@Details[/url]  
  9. * [url=home.php?mod=space&uid=8537]@see[/url]  
  10. */
  11. void KEY_Configurature(void)
  12. {
  13.         GPIO_InitTypeDef GPIO_InitStructure;
  14.     EXTI_InitTypeDef EXTI_InitStructure;
  15.     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD|RCC_AHBPeriph_GPIOC|RCC_AHBPeriph_GPIOA,ENABLE);
  16.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

  17.         // 初始化GPIOA
  18.         GPIO_InitStructure.GPIO_Pin = MKEY1 | MKEY2;
  19.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
  20.         GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  21.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
  22.         GPIO_Init(KEYPortGrou1, &GPIO_InitStructure);

  23.         //机械按键1中断初始化
  24.     EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  25.     EXTI_InitStructure.EXTI_Line = MKEY1_Line;        //EXTI_Line2
  26.     EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
  27.     EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  28.     EXTI_Init(&EXTI_InitStructure);
  29.         SYSCFG_EXTILineConfig(KEYPortGrou1_EXTI,MKEY1_Source);
  30.         EXTI_ClearITPendingBit(MKEY1_Line);

  31.         //机械按键2中断初始化
  32.         EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  33.     EXTI_InitStructure.EXTI_Line = MKEY2_Line;        //EXTI_Line1
  34.     EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
  35.     EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  36.     EXTI_Init(&EXTI_InitStructure);
  37.         SYSCFG_EXTILineConfig(KEYPortGrou1_EXTI,MKEY2_Source);
  38.         EXTI_ClearITPendingBit(MKEY2_Line);

  39.         // 初始化GPIOC
  40.         GPIO_InitStructure.GPIO_Pin = KEYUP;
  41.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
  42.         GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  43.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
  44.         GPIO_Init(KEYPortGroup2, &GPIO_InitStructure);

  45.         // 初始化GPIOD
  46.         GPIO_InitStructure.GPIO_Pin = KEYDOWN | KEYLEFT | KEYRIGHT | KEYSIDE | MKEY3 | MKEY4;
  47.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
  48.         GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  49.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
  50.         GPIO_Init(KEYPortGroup3, &GPIO_InitStructure);

  51.         //机械按键3中断初始化
  52.         EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  53.     EXTI_InitStructure.EXTI_Line = MKEY3_Line ;        //EXTI_Line5
  54.     EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
  55.     EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  56.     EXTI_Init(&EXTI_InitStructure);
  57.         SYSCFG_EXTILineConfig(KEYPortGrou3_EXTI,MKEY3_Source);
  58.         EXTI_ClearITPendingBit(MKEY3_Line);

  59.         //机械按键4中断初始化
  60.         EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  61.     EXTI_InitStructure.EXTI_Line = MKEY4_Line;        //EXTI_Line4
  62.     EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
  63.     EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  64.     EXTI_Init(&EXTI_InitStructure);
  65.         SYSCFG_EXTILineConfig(KEYPortGrou3_EXTI,MKEY4_Source);
  66.         EXTI_ClearITPendingBit(MKEY4_Line);

  67.         //侧边按键中断初始化
  68.         EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  69.     EXTI_InitStructure.EXTI_Line = KEYSIDE_Line;        //EXTI_Line7
  70.     EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
  71.     EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  72.     EXTI_Init(&EXTI_InitStructure);
  73.         SYSCFG_EXTILineConfig(KEYPortGrou3_EXTI,KEYSIDE_Source);
  74.         EXTI_ClearITPendingBit(KEYSIDE_Line);

  75.         NVIC_Configurature();
  76. }
  77. /**
  78. * @brief  键盘引脚NVIC配置初始化
  79. * @param  
  80. * @ref
  81. * @return
  82. * -
  83. * @details  
  84. * @see  
  85. */
  86. void NVIC_Configurature(void)
  87. {
  88.        
  89.     NVIC_InitTypeDef NVIC_InitStructure;
  90.     // 初始化中断函数
  91.         NVIC_InitStructure.NVIC_IRQChannel =EXTI1_IRQn;
  92.     NVIC_InitStructure.NVIC_IRQChannelPriority = 0;
  93.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  94.     NVIC_Init(&NVIC_InitStructure);

  95.         // 初始化中断函数
  96.         NVIC_InitStructure.NVIC_IRQChannel =EXTI2_IRQn;
  97.     NVIC_InitStructure.NVIC_IRQChannelPriority = 0;
  98.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  99.     NVIC_Init(&NVIC_InitStructure);

  100.         // 初始化中断函数
  101.         NVIC_InitStructure.NVIC_IRQChannel =EXTI4_IRQn;
  102.     NVIC_InitStructure.NVIC_IRQChannelPriority = 0;
  103.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  104.     NVIC_Init(&NVIC_InitStructure);

  105.         // 初始化中断函数
  106.         NVIC_InitStructure.NVIC_IRQChannel =EXTI5_IRQn;
  107.     NVIC_InitStructure.NVIC_IRQChannelPriority = 0;
  108.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  109.     NVIC_Init(&NVIC_InitStructure);

  110.         // 初始化中断函数
  111.         NVIC_InitStructure.NVIC_IRQChannel =EXTI7_IRQn;
  112.     NVIC_InitStructure.NVIC_IRQChannelPriority = 0;
  113.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  114.     NVIC_Init(&NVIC_InitStructure);
  115. }
  116. /**
  117. * @brief  静音按键扫描函数
  118. * @param  
  119. * @ref
  120. * @return
  121. * -
  122. * @details  
  123. * @see  
  124. */
  125. //方向键。这一部分低电平有效
  126. void KEY_Scan(void)
  127. {
  128.         if(!GPIO_ReadInputDataBit(KEYPortGroup2,KEYUP))
  129.         {
  130.                 printf("U\r\n");
  131.                 while(!GPIO_ReadInputDataBit(KEYPortGroup2,KEYUP));
  132.         }
  133.        
  134.         if(!GPIO_ReadInputDataBit(KEYPortGroup3,KEYDOWN))
  135.         {
  136.                 printf("D\r\n");
  137.                 while(!GPIO_ReadInputDataBit(KEYPortGroup3,KEYDOWN));
  138.         }
  139.        
  140.         if(!GPIO_ReadInputDataBit(KEYPortGroup3,KEYLEFT))
  141.         {
  142.                 printf("L\r\n");
  143.                 while(!GPIO_ReadInputDataBit(KEYPortGroup3,KEYLEFT));
  144.         }
  145.        
  146.         if(!GPIO_ReadInputDataBit(KEYPortGroup3,KEYRIGHT))
  147.         {
  148.                 printf("R\r\n");
  149.                 while(!GPIO_ReadInputDataBit(KEYPortGroup3,KEYRIGHT));
  150.         }
  151.        
  152.        
  153. }
  154. // 按键测试函数
  155. void KEY_Test(void)
  156. {
  157.     GPIO_InitTypeDef GPIO_InitStructure;
  158.     EXTI_InitTypeDef EXTI_InitStructure;
  159.     NVIC_InitTypeDef NVIC_InitStructure;
  160.        
  161.     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD|RCC_AHBPeriph_GPIOC|RCC_AHBPeriph_GPIOB|RCC_AHBPeriph_GPIOA,ENABLE);
  162.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

  163.         GPIO_InitStructure.GPIO_Pin = MKEY2;  
  164.   
  165.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
  166.         GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  167.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
  168.     GPIO_Init(KEYPortGrou1, &GPIO_InitStructure);

  169.     EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  170.     EXTI_InitStructure.EXTI_Line = MKEY2_Line;
  171.     EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
  172.     EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  173.     EXTI_Init(&EXTI_InitStructure);

  174.     SYSCFG_EXTILineConfig(KEYPortGrou1_EXTI,MKEY2_Source);
  175.         EXTI_ClearITPendingBit(MKEY2_Line);

  176.     NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;
  177.     NVIC_InitStructure.NVIC_IRQChannelPriority = 0;
  178.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  179.     NVIC_Init(&NVIC_InitStructure);
  180. }
 楼主| hehhehee 发表于 2022-11-26 23:51 | 显示全部楼层
key.h
  1. #ifndef _key_h
  2. #define _key_h

  3. #ifdef __cplusplus
  4. extern "C" {
  5. #endif
  6. #include "hk32f030m.h"
  7. #include "hk32f030m_gpio.h"
  8. #include "main.h"

  9. // GPIOA引脚**********************************
  10. #define KEYPortGrou1 GPIOA
  11. #define KEYPortGrou1_EXTI EXTI_PortSourceGPIOA
  12. // 机械按键1
  13. #define MKEY1 GPIO_Pin_2
  14. #define MKEY1_Line EXTI_Line2
  15. #define MKEY1_Source EXTI_PinSource2
  16. // 机械按键2
  17. #define MKEY2 GPIO_Pin_1
  18. #define MKEY2_Line EXTI_Line1
  19. #define MKEY2_Source EXTI_PinSource1


  20. // GPIOC引脚**********************************
  21. #define KEYPortGroup2 GPIOC
  22. #define KEYPortGrou2_EXTI EXTI_PortSourceGPIOC
  23. // 静音按键
  24. #define KEYUP GPIO_Pin_7


  25. // GPIOD引脚**********************************
  26. #define KEYPortGroup3 GPIOD
  27. #define KEYPortGrou3_EXTI EXTI_PortSourceGPIOD
  28. // 静音按键
  29. #define KEYRIGHT         GPIO_Pin_3
  30. #define KEYDOWN GPIO_Pin_2
  31. #define KEYLEFT GPIO_Pin_1
  32. // 侧边按键
  33. #define KEYSIDE GPIO_Pin_7
  34. #define KEYSIDE_Line EXTI_Line7
  35. #define KEYSIDE_Source EXTI_PinSource7
  36. //机械按键3  注意此引脚为下载引脚
  37. #ifdef DEBUG
  38. #define MKEY3 GPIO_Pin_7
  39. #define MKEY3_Line EXTI_Line7
  40. #define MKEY3_Source EXTI_PinSource7
  41. #else
  42. #define MKEY3 GPIO_Pin_5
  43. #define MKEY3_Line EXTI_Line5
  44. #define MKEY3_Source EXTI_PinSource5
  45. #endif
  46. //机械按键4
  47. #define MKEY4 GPIO_Pin_4
  48. #define MKEY4_Line EXTI_Line4
  49. #define MKEY4_Source EXTI_PinSource4

  50. void KEY_Configurature(void);   // 按键引脚初始化
  51. void EXIT_Configurature(void);  // 按键EXIT初始化
  52. void NVIC_Configurature(void);  // 按键NVIC初始化
  53. void KEY_Scan(void);  // 静音按键扫描函数
  54. void KEY_Test(void);  // 按键测试函数
  55. #ifdef __cplusplus
  56. }
  57. #endif /* __cplusplus */


  58. #endif /*KEY.H*/
 楼主| hehhehee 发表于 2022-11-26 23:52 | 显示全部楼层
中断服务函数:

在文件hk32f030m_it.c中。
  1. /******************************************************************************/
  2. /* hk32f0301m Peripheral Interrupt Handlers                                    */
  3. /* Add here the Interrupt Handlers for the used peripherals.                  */
  4. /* For the available peripheral interrupt handler names,                      */
  5. /* please refer to the startup file (startup_hk32f0301m.s).                    */
  6. /******************************************************************************/

  7. /* USER CODE BEGIN 1 */
  8. /**
  9.   * @brief  This function handles machine key 2 global interrupt request.
  10.   * @param  None
  11.   * @retval None
  12.   */
  13. void EXTI1_IRQHandler(void)    //按键2
  14. {
  15.   if (EXTI_GetFlagStatus(EXTI_Line1) != RESET)
  16.   {
  17.     printf("2\r\n");
  18.                 EXTI_ClearITPendingBit(EXTI_Line1);
  19.   }
  20. }
  21. /**
  22.   * @brief  This function handles machine key 1 global interrupt request.
  23.   * @param  None
  24.   * @retval None
  25.   */
  26. void EXTI2_IRQHandler(void)    //按键1
  27. {
  28.   if (EXTI_GetFlagStatus(EXTI_Line2) != RESET)
  29.   {
  30.     printf("1\r\n");
  31.                 EXTI_ClearITPendingBit(EXTI_Line2);
  32.   }
  33. }
  34. /**
  35.   * @brief  This function handles machine key 4 global interrupt request.
  36.   * @param  None
  37.   * @retval None
  38.   */
  39. void EXTI4_IRQHandler(void)    //按键4
  40. {
  41.   if (EXTI_GetFlagStatus(EXTI_Line4) != RESET)
  42.   {
  43.     printf("4\r\n");
  44.                 EXTI_ClearITPendingBit(EXTI_Line4);
  45.   }
  46. }
  47. /**
  48.   * @brief  This function handles machine key 3 global interrupt request.
  49.   * @param  None
  50.   * @retval None
  51.   */
  52. void EXTI5_IRQHandler(void)    //按键3
  53. {
  54.   if (EXTI_GetFlagStatus(EXTI_Line5) != RESET)
  55.   {
  56.     printf("3\r\n");
  57.                 EXTI_ClearITPendingBit(EXTI_Line5);
  58.   }
  59. }
  60. /**
  61.   * @brief  This function handles side key global interrupt request.
  62.   * @param  None
  63.   * @retval None
  64.   */
  65. void EXTI7_IRQHandler(void)    //侧边按键
  66. {
  67.   if (EXTI_GetFlagStatus(EXTI_Line7) != RESET)
  68.   {
  69.     printf("S\r\n");
  70.                 EXTI_ClearITPendingBit(EXTI_Line7);
  71.   }
  72. }
  73. /**
  74.   * @brief  This function handles TIM1 global interrupt request.
  75.   * @param  None
  76.   * @retval None
  77.   */
  78. void TIM1_UP_TRG_COM_IRQnHandler()
  79. {
  80.        
  81. }
  82. void TIM1_IRQHandler(void)
  83. {
  84.         if(TIM_GetITStatus(TIM1, TIM_IT_Update) != RESET)
  85.   {
  86.     TIM_ClearITPendingBit(TIM1, TIM_IT_Update);
  87.                 printf("toggle\r\n");
  88.   }
  89. }
  90. /**
  91.   * @brief  This function handles TIM2 global interrupt request.
  92.   * @param  None
  93.   * @retval None
  94.   */
  95. void TIM2_IRQHandler(void)
  96. {
  97. if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
  98.   {
  99.     TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
  100.                 printf("toggle\r\n");
  101.   }
  102. }
  103. /**
  104.   * @brief  This function handles TIM6 global interrupt request.
  105.   * @param  None
  106.   * @retval None
  107.   */
  108. void TIM6_IRQHandler(void)
  109. {
  110.         TIM_ClearITPendingBit(TIM6, TIM_IT_Update);
  111.         //printf("time\r\n");
  112.         //低功耗计数器
  113. }

  114. /* USER CODE END 1 */
  115. /************************ (C) COPYRIGHT HKMicroChip *****END OF FILE****/
 楼主| hehhehee 发表于 2022-11-26 23:53 | 显示全部楼层
就这个代码,太清晰了。没啥好分析的都! 哈哈哈哈
ec11.c

ec11相关知识!!!:

左转:逆时针。右转:顺时针

AB之间的电平状态关系
 楼主| hehhehee 发表于 2022-11-26 23:53 | 显示全部楼层
 楼主| hehhehee 发表于 2022-11-26 23:54 | 显示全部楼层
判断方法:

A信号位于下降沿时,B是高电平,表示顺时针。B是低电平,表示逆时针。

同理:

B信号位于下降沿时,A是高电平,表示顺时针。A是低电平,表示逆时针。

  1. #include "ec11.h"

  2. uint8_t Encoder[2]={0, 0};  // 存放按键的值
  3. uint8_t flag[2]={0, 0};  // 按下旋钮标志位
  4. /**
  5. * @brief EC11旋转编码器初始化
  6. * @param  
  7. * @ref none
  8. * @return none
  9. * @details  
  10. * @see  
  11. */
  12. void EC11_Configurature(void)
  13. {
  14.         RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB,ENABLE);
  15.         GPIO_InitTypeDef GPIO_InitStructure;
  16.         //旋转编码器1
  17.         GPIO_InitStructure.GPIO_Pin = TBUT_R | TBUT_D;
  18.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;  // 输入模式
  19.         GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;  // 上拉输入
  20.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
  21.         GPIO_Init(EC11_1_Port,&GPIO_InitStructure);
  22.         // 旋转编码器2
  23.         GPIO_InitStructure.GPIO_Pin = TBUT_L | BBUT_L | BBUT_R | BBUT_D;
  24.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;  // 输入模式
  25.         GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;  // 上拉输入
  26.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
  27.         GPIO_Init(EC11_2_Port,&GPIO_InitStructure);
  28. }
  29. /**
  30. * @brief  读取EC11旋转状态 第一个EC11 上方
  31. * @param  
  32. * @ref
  33. * @return
  34. * -
  35. * @details  
  36. * @see  
  37. */
  38. //首先,应该是低电平有效
  39. //TBUT_L接的B、TBUT_R接的A
  40. uint8_t EC11_Read_T()
  41. {
  42.         static uint16_t cou0;  // 锁死计时器
  43.         static uint8_t KUP0;  // 锁死标志位
  44.         uint8_t kt;  // 状态记录标志位

  45.         Encoder[0] = 0;

  46.         if(GPIO_ReadInputDataBit(EC11_2_Port,TBUT_L))   
  47.                 KUP0=0;        //判断旋钮是否解除锁死
  48.        
  49.         if(!GPIO_ReadInputDataBit(EC11_2_Port,TBUT_L)&&KUP0==0)//判断是否旋转旋钮,同时判断是否有旋钮锁死
  50.     //这里B是下降沿了,判断A的电平。
  51.     {
  52.                 // softWareDelay();  // 延时
  53.                 kt=GPIO_ReadInputDataBit(EC11_1_Port,TBUT_R);        //把旋钮另一端电平状态记录
  54.                 // softWareDelay(); //延时
  55.                 if(!GPIO_ReadInputDataBit(EC11_2_Port,TBUT_L))//去抖
  56.         {
  57.                         if(kt==0)//用另一端判断左或右旋转
  58.             //A是低电平,逆时针
  59.             {
  60.                                 Encoder[0] = 1;  // 右转 //作者写错了,这里应该是左转
  61.                         }
  62.             else
  63.             //A是高电平,顺时针
  64.             {
  65.                                 Encoder[0] = 2;  // 左转 //作者写错了,这里应该是右转
  66.                         }
  67.                         cou0=0; //初始锁死判断计数器
  68.                         while(!GPIO_ReadInputDataBit(EC11_2_Port,TBUT_L)&&cou0<1200)
  69.             { //等待放开旋钮,同时累加判断锁死
  70.                                 cou0++;KUP0=1;softWareDelay(); //
  71.                         }
  72.                 }
  73.         }
  74.        
  75.         if(GPIO_ReadInputDataBit(EC11_1_Port,TBUT_D))  
  76.                 flag[0]=0;
  77.        
  78.         if(flag[0]!=1)
  79.         {
  80.                 if(!GPIO_ReadInputDataBit(EC11_1_Port,TBUT_D)&&KUP0==0)
  81.         { // 判断旋钮是否按下  
  82.                         //softWareDelay();
  83.                         if(!GPIO_ReadInputDataBit(EC11_1_Port,TBUT_D))
  84.             { // 去抖动
  85.                                 softWareDelay();
  86.                                 if(GPIO_ReadInputDataBit(EC11_1_Port,TBUT_D))
  87.                 {  // 判断是否放开
  88.                                         Encoder[0] = 3;  // 按下
  89.                                         flag[0]=0;
  90.                                 }
  91.                 else{
  92.                                         Encoder[0] |= 0x10;
  93.                                         flag[0]=1;
  94.                                 }
  95.                         }
  96.                 }
  97.         }
  98.     else
  99.     {
  100.                 Encoder[0] |= 0x10;
  101.         }
  102.        
  103.         if(Encoder[0] == 0x10)
  104.                 Encoder[0]=0;
  105.        
  106.         return Encoder[0];
  107. }
  108. /**
  109. * @brief  读取EC11旋转状态 第二个EC11 下方
  110. * @param  
  111. * @ref
  112. * @return
  113. * -
  114. * @details  
  115. * @see  
  116. */
  117. uint8_t EC11_Read_D()
  118. {
  119.         static uint16_t cou;  // 锁死计时器
  120.         static uint8_t KUP;  // 锁死标志位
  121.         uint8_t kt;  // 状态记录标志位
  122.         Encoder[1] = 0;
  123.         if(GPIO_ReadInputDataBit(EC11_2_Port,BBUT_L))
  124.                 KUP=0;        //判断旋钮是否解除锁死
  125.        
  126.         if(!GPIO_ReadInputDataBit(EC11_2_Port,BBUT_L)&&KUP==0){ //判断是否旋转旋钮,同时判断是否有旋钮锁死
  127.                 // softWareDelay();  // 延时
  128.                 kt=GPIO_ReadInputDataBit(EC11_2_Port,BBUT_R);        //把旋钮另一端电平状态记录
  129.                 // softWareDelay(); //延时
  130.                 if(!GPIO_ReadInputDataBit(EC11_2_Port,BBUT_L)){ //去抖
  131.                         if(kt==0){ //用另一端判断左或右旋转
  132.                                 Encoder[1] = 1;  // 右转
  133.                         }else{
  134.                                 Encoder[1] = 2;  // 左转
  135.                         }
  136.                         cou=0; //初始锁死判断计数器
  137.                         while(!GPIO_ReadInputDataBit(EC11_2_Port,BBUT_L)&&cou<1200){ //等待放开旋钮,同时累加判断锁死
  138.                                 cou++;KUP=1;softWareDelay(); //
  139.                         }
  140.                 }
  141.         }
  142.        
  143.         if(GPIO_ReadInputDataBit(EC11_2_Port,BBUT_D))  
  144.                 flag[1]=0;
  145.        
  146.         if(flag[1]!=1)
  147.         {
  148.                 if(!GPIO_ReadInputDataBit(EC11_2_Port,BBUT_D)&&KUP==0){ // 判断旋钮是否按下  
  149.                         //softWareDelay();
  150.                         if(!GPIO_ReadInputDataBit(EC11_2_Port,BBUT_D)){ // 去抖动
  151.                                 softWareDelay();
  152.                                 if(GPIO_ReadInputDataBit(EC11_2_Port,BBUT_D)){  // 判断是否放开
  153.                                         Encoder[1] = 3;  // 按下
  154.                                         flag[1]=0;
  155.                                 }else{
  156.                                         Encoder[1] |= 0x10;
  157.                                         flag[1]=1;
  158.                                 }
  159.                         }
  160.                 }
  161.         }else{
  162.                 Encoder[1] |= 0x10;
  163.         }
  164.        
  165.         if(Encoder[1] == 0x10)
  166.                 Encoder[1]=0;
  167.        
  168.         return Encoder[1];
  169. }
 楼主| hehhehee 发表于 2022-11-26 23:55 | 显示全部楼层
ec11.h
  1. #ifndef _ec11_h
  2. #define _ec11_h

  3. #ifdef __cplusplus
  4. extern "C" {
  5. #endif
  6. #include "hk32f030m.h"
  7. #include "hk32f030m_gpio.h"
  8. #include "usart.h"
  9. #include "main.h"

  10. #define EC11_1_Port GPIOB  // 按下和右转在B引脚
  11. #define TBUT_R GPIO_Pin_4  // 1右转
  12. // 注意 此引脚为下载引脚
  13. #ifdef DEBUG
  14. #define TBUT_D GPIO_Pin_7  // 1按下
  15. #else
  16. #define TBUT_D GPIO_Pin_5  // 1按下
  17. #endif

  18. #define EC11_2_Port GPIOC  // EC11 2 和EC11 1的左转
  19. #define TBUT_L GPIO_Pin_3  // 1左转
  20. #define BBUT_L GPIO_Pin_4  // 2左转
  21. #define BBUT_R GPIO_Pin_5  // 2右转
  22. #define BBUT_D GPIO_Pin_6  // 2按下

  23. void EC11_Configurature(void);  // EC11初始化
  24. uint8_t EC11_Read_T();  // EC11 TOP读取
  25. uint8_t EC11_Read_D();  // EC11 DOWN读取
  26. #ifdef __cplusplus
  27. }
  28. #endif /* __cplusplus */


  29. #endif /*EC11.H*/
 楼主| hehhehee 发表于 2022-11-26 23:55 | 显示全部楼层
其它函数不重要了,不分析了。
蓝牙模块

HC-05即可。

37426638236fa8ba2b.png
 楼主| hehhehee 发表于 2022-11-26 23:56 | 显示全部楼层
没啥代码要求,比较简单的。

项目使用的jdy-33
硬件部分
38083638237258ec81.png
 楼主| hehhehee 发表于 2022-11-26 23:56 | 显示全部楼层
EC11部分
68576382373b52a13.png
 楼主| hehhehee 发表于 2022-11-26 23:57 | 显示全部楼层
按键部分

机械按键
653926382375693eec.png
 楼主| hehhehee 发表于 2022-11-26 23:57 | 显示全部楼层
方向键
857796382377610078.png
侧边键
7738763823784760f9.png
 楼主| hehhehee 发表于 2022-11-26 23:58 | 显示全部楼层
type-C接口
9267663823793cef42.png
 楼主| hehhehee 发表于 2022-11-26 23:59 | 显示全部楼层
 楼主| hehhehee 发表于 2022-11-26 23:59 | 显示全部楼层
电池充电电路
83431638237d521aa0.png

99932638237e605122.png
微信13267226716 发表于 2022-11-29 11:54 | 显示全部楼层
这个好
您需要登录后才可以回帖 登录 | 注册

本版积分规则

89

主题

1252

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部