当前位置:   article > 正文

【开源项目学习】多功能小键盘(基于HK32F030M)_hk32f0301mf4p7c

hk32f0301mf4p7c

并不是真正意义上的键盘!!!需谨慎看!!

并不是真正意义上的键盘!!!需谨慎看!!

并不是真正意义上的键盘!!!需谨慎看!!

并不是真正意义上的键盘!!!需谨慎看!!

项目原地址:【航顺训练营】多功能小键盘 - 立创EDA开源硬件平台

说明:如果看到了这篇文章,请了解此项目非本人制作。只是用开源项目来学习。

项目渲染图:

7a04240ea662400b952d792cc2b19918.png

 


目录

简介

代码分析

main.c

main.h

key.c

key.h

中断服务函数:

ec11.c

ec11.h

其它函数不重要了,不分析了。

蓝牙模块

硬件部分

EC11部分

按键部分

type-C接口

USB-TTL

电池充电电路

MCU


 

 

 

简介

项目采用航顺芯片设计制造的HK32F030MF4P6

MF4P6有一个ADC、16个外部中断、16个GPIO端口、封装形式为TSSOP20。

HK32F030不支持USB协议数据端口,本项目采用USB-TTL芯片。

HK32F030数据手册、用户手册:HK32F030M_技术支持_深圳市航顺芯片技术研发有限公司

代码分析

按照程序文件分析代码。具体文件有:

c5f9e2b072bc45dc85c7d516cba5020c.png

330cdcc1541146e4b859f11419ecafbc.png

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

咋这么像是正点原子的风格啊。

main.c

  1. /**
  2. ******************************************************************************
  3. * @file : main.c
  4. * @brief : 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. KEY_Configurature(); // 按键初始化
  24. EC11_Configurature(); // EC11初始化
  25. USART_Configurature(); // 串口初始化
  26. softWareDelay(); // 软件延时等待系统稳定
  27. TIM6_Config(); // 3S定时器初始化
  28. while (1)
  29. {
  30. KEY_Scan();
  31. switch(EC11_Read_T())
  32. {
  33. case 0x01:
  34. printf("Z\r\n");break; // 旋钮1左转
  35. case 0x02:
  36. printf("C\r\n");break; // 旋钮1右转
  37. case 0x03:
  38. printf("X\r\n");break; // 旋钮1按下
  39. case 0x11:
  40. printf("Q\r\n");break; // 旋钮1按下左转
  41. case 0x12:
  42. printf("W\r\n");break; // 旋钮1按下右转
  43. }
  44. switch(EC11_Read_D())
  45. {
  46. case 0x01:
  47. printf("N\r\n");break; // 旋钮2右转
  48. case 0x02:
  49. printf("V\r\n");break; // 旋钮2左转
  50. case 0x03:
  51. printf("B\r\n");break; // 旋钮2按下
  52. case 0x11:
  53. printf("H\r\n");break; // 旋钮2按下右转
  54. case 0x12:
  55. printf("G\r\n");break; // 旋钮2按下左转
  56. }
  57. }
  58. }
  59. /*时钟配置*/
  60. void RCC_Configuration(void)
  61. {
  62. RCC_AHBPeriphClockCmd( RCC_AHBPeriph_GPIOA, ENABLE);
  63. RCC_AHBPeriphClockCmd( RCC_AHBPeriph_GPIOB, ENABLE);
  64. RCC_AHBPeriphClockCmd( RCC_AHBPeriph_GPIOC, ENABLE);
  65. RCC_AHBPeriphClockCmd( RCC_AHBPeriph_GPIOD, ENABLE);
  66. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);
  67. }
  68. /*软件延时*/
  69. void softWareDelay(void)
  70. {
  71. uint16_t i;
  72. uint16_t j;
  73. for(i=0;i<500;i++)
  74. {
  75. for(j=0;j<1000;j++)
  76. {
  77. __NOP();
  78. }
  79. }
  80. }
  81. #ifdef USE_FULL_ASSERT
  82. /**
  83. * @brief Reports the name of the source file and the source line number
  84. * where the assert_param error has occurred.
  85. * @param file: pointer to the source file name
  86. * @param line: assert_param error line source number
  87. * @retval None
  88. */
  89. void assert_failed(uint8_t* file, uint32_t line)
  90. {
  91. /* User can add his own implementation to report the file name and line number,
  92. tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  93. }
  94. #endif /* USE_FULL_ASSERT */

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 */

key.c

由于主函数调用的KEY_Scan()函数,所以从key.c开始看起。

  1. #include "key.h"
  2. /**
  3. * @brief 键盘引脚初始化
  4. * @param
  5. * @ref
  6. * @return
  7. * -
  8. * @details
  9. * @see
  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. NVIC_InitTypeDef NVIC_InitStructure;
  89. // 初始化中断函数
  90. NVIC_InitStructure.NVIC_IRQChannel =EXTI1_IRQn;
  91. NVIC_InitStructure.NVIC_IRQChannelPriority = 0;
  92. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  93. NVIC_Init(&NVIC_InitStructure);
  94. // 初始化中断函数
  95. NVIC_InitStructure.NVIC_IRQChannel =EXTI2_IRQn;
  96. NVIC_InitStructure.NVIC_IRQChannelPriority = 0;
  97. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  98. NVIC_Init(&NVIC_InitStructure);
  99. // 初始化中断函数
  100. NVIC_InitStructure.NVIC_IRQChannel =EXTI4_IRQn;
  101. NVIC_InitStructure.NVIC_IRQChannelPriority = 0;
  102. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  103. NVIC_Init(&NVIC_InitStructure);
  104. // 初始化中断函数
  105. NVIC_InitStructure.NVIC_IRQChannel =EXTI5_IRQn;
  106. NVIC_InitStructure.NVIC_IRQChannelPriority = 0;
  107. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  108. NVIC_Init(&NVIC_InitStructure);
  109. // 初始化中断函数
  110. NVIC_InitStructure.NVIC_IRQChannel =EXTI7_IRQn;
  111. NVIC_InitStructure.NVIC_IRQChannelPriority = 0;
  112. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  113. NVIC_Init(&NVIC_InitStructure);
  114. }
  115. /**
  116. * @brief 静音按键扫描函数
  117. * @param
  118. * @ref
  119. * @return
  120. * -
  121. * @details
  122. * @see
  123. */
  124. //方向键。这一部分低电平有效
  125. void KEY_Scan(void)
  126. {
  127. if(!GPIO_ReadInputDataBit(KEYPortGroup2,KEYUP))
  128. {
  129. printf("U\r\n");
  130. while(!GPIO_ReadInputDataBit(KEYPortGroup2,KEYUP));
  131. }
  132. if(!GPIO_ReadInputDataBit(KEYPortGroup3,KEYDOWN))
  133. {
  134. printf("D\r\n");
  135. while(!GPIO_ReadInputDataBit(KEYPortGroup3,KEYDOWN));
  136. }
  137. if(!GPIO_ReadInputDataBit(KEYPortGroup3,KEYLEFT))
  138. {
  139. printf("L\r\n");
  140. while(!GPIO_ReadInputDataBit(KEYPortGroup3,KEYLEFT));
  141. }
  142. if(!GPIO_ReadInputDataBit(KEYPortGroup3,KEYRIGHT))
  143. {
  144. printf("R\r\n");
  145. while(!GPIO_ReadInputDataBit(KEYPortGroup3,KEYRIGHT));
  146. }
  147. }
  148. // 按键测试函数
  149. void KEY_Test(void)
  150. {
  151. GPIO_InitTypeDef GPIO_InitStructure;
  152. EXTI_InitTypeDef EXTI_InitStructure;
  153. NVIC_InitTypeDef NVIC_InitStructure;
  154. RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD|RCC_AHBPeriph_GPIOC|RCC_AHBPeriph_GPIOB|RCC_AHBPeriph_GPIOA,ENABLE);
  155. RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
  156. GPIO_InitStructure.GPIO_Pin = MKEY2;
  157. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
  158. GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  159. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
  160. GPIO_Init(KEYPortGrou1, &GPIO_InitStructure);
  161. EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  162. EXTI_InitStructure.EXTI_Line = MKEY2_Line;
  163. EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
  164. EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  165. EXTI_Init(&EXTI_InitStructure);
  166. SYSCFG_EXTILineConfig(KEYPortGrou1_EXTI,MKEY2_Source);
  167. EXTI_ClearITPendingBit(MKEY2_Line);
  168. NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;
  169. NVIC_InitStructure.NVIC_IRQChannelPriority = 0;
  170. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  171. NVIC_Init(&NVIC_InitStructure);
  172. }

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*/

中断服务函数:

在文件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. void TIM1_IRQHandler(void)
  82. {
  83. if(TIM_GetITStatus(TIM1, TIM_IT_Update) != RESET)
  84. {
  85. TIM_ClearITPendingBit(TIM1, TIM_IT_Update);
  86. printf("toggle\r\n");
  87. }
  88. }
  89. /**
  90. * @brief This function handles TIM2 global interrupt request.
  91. * @param None
  92. * @retval None
  93. */
  94. void TIM2_IRQHandler(void)
  95. {
  96. if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
  97. {
  98. TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
  99. printf("toggle\r\n");
  100. }
  101. }
  102. /**
  103. * @brief This function handles TIM6 global interrupt request.
  104. * @param None
  105. * @retval None
  106. */
  107. void TIM6_IRQHandler(void)
  108. {
  109. TIM_ClearITPendingBit(TIM6, TIM_IT_Update);
  110. //printf("time\r\n");
  111. //低功耗计数器
  112. }
  113. /* USER CODE END 1 */
  114. /************************ (C) COPYRIGHT HKMicroChip *****END OF FILE****/

就这个代码,太清晰了。没啥好分析的都! 哈哈哈哈

ec11.c

ec11相关知识!!!:

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

AB之间的电平状态关系

逆时针(左转)11、01、00、10
顺时针(右转)11、10、00、01

 判断方法:

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

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*/

其它函数不重要了,不分析了。

蓝牙模块

HC-05即可。

b10ed5bbb4e64b48be3093718352ea9b.png

 没啥代码要求,比较简单的。

项目使用的jdy-33

硬件部分

1d1e305b09e844878b9eb17ab9133a01.png

EC11部分

17d876ff115e406b93fc440efa41f545.png

按键部分

机械按键

89b407ce68544094b61bb5b4a251ee20.png

方向键

86063801e5c04f2fa6ba01e72ff3e511.png

侧边键

9316fb18ace543e29bb8f59cd1e56aca.png

type-C接口

024dca8ce84649089fcf209e5b1f69bd.png

USB-TTL

66d755518499417f8812d457648e9fb5.png

电池充电电路

1b7e02fe268d4236bf66b91040ae70cf.png

MCU

d883278bf8fe4f8587e531d5c8eb4124.png

 

 

 

啊~还有上位机,作者没分享,假如有了再更新吧~~

OK,算是比较简单的项目~

学习啦~

学习了EC11的使用方法~ 有所收获!不错

 

 

f248813ad806489f945ad2d41aab4ceb.png

 

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/酷酷是懒虫/article/detail/754322
推荐阅读
相关标签
  

闽ICP备14008679号