打印
[其他]

多功能小键盘(基于HK32F030M)

[复制链接]
3734|20
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
hehhehee|  楼主 | 2022-11-26 23:46 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
如果看到了这篇文章,请了解此项目非本人制作。只是用开源项目来学习。 项目渲染图:

简介 项目采用航顺芯片设计制造的HK32F030MF4P6
MF4P6有一个ADC、16个外部中断、16个GPIO端口、封装形式为TSSOP20。
HK32F030不支持USB协议数据端口,本项目采用USB-TTL芯片。
HK32F030数据手册、用户手册


使用特权

评论回复
评论
第二位 2023-5-18 17:12 回复TA
你好,请问HK32F030这个芯片的系统时钟怎么看,系统配置是RCC->CFGR &= (uint32_t)0xF8FFB81C; 算出来HCLK = 6 ,PCLK = 1,配置的TIM时钟应该是 48/6 = 8M,但实际不是这个,大约是24M 

相关帖子

沙发
hehhehee|  楼主 | 2022-11-26 23:47 | 只看该作者
代码分析

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


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

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

使用特权

评论回复
板凳
hehhehee|  楼主 | 2022-11-26 23:47 | 只看该作者
main.c
/**
  ******************************************************************************
  * [url=home.php?mod=space&uid=288409]@file[/url]           : main.c
  * [url=home.php?mod=space&uid=247401]@brief[/url]          : Main program body
  ******************************************************************************
  * @attention
  *
  */

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "hk32f030m.h"
#include "hk32f030m_gpio.h"
#include "usart.h"
#include "string.h"

#include "key.h"
#include "EC11.h"

#include "tim.h"

int main(void)
/* Infinite loop */
{
        for(int i=0;i<10;i++)  // 延时 保证正常下载程序
                softWareDelay();
       
        KEY_Configurature();  // 按键初始化
        EC11_Configurature();  // EC11初始化
        USART_Configurature();  // 串口初始化
        softWareDelay();  // 软件延时等待系统稳定
        TIM6_Config();  // 3S定时器初始化
  while (1)
  {
                KEY_Scan();
                switch(EC11_Read_T())
                {
                        case 0x01:
                                printf("Z\r\n");break;  // 旋钮1左转
                        case 0x02:
                                printf("C\r\n");break;  // 旋钮1右转
                        case 0x03:
                                printf("X\r\n");break;  // 旋钮1按下
                        case 0x11:
                                printf("Q\r\n");break;  // 旋钮1按下左转
                        case 0x12:
                                printf("W\r\n");break;  // 旋钮1按下右转
                }
               
                switch(EC11_Read_D())
                {
                        case 0x01:
                                printf("N\r\n");break;  // 旋钮2右转
                        case 0x02:
                                printf("V\r\n");break;  // 旋钮2左转
                        case 0x03:
                                printf("B\r\n");break;  // 旋钮2按下
                        case 0x11:
                                printf("H\r\n");break;  // 旋钮2按下右转
                        case 0x12:
                                printf("G\r\n");break;  // 旋钮2按下左转
                }
               
  }
}
/*时钟配置*/
void RCC_Configuration(void)
{
        RCC_AHBPeriphClockCmd( RCC_AHBPeriph_GPIOA, ENABLE);
        RCC_AHBPeriphClockCmd( RCC_AHBPeriph_GPIOB, ENABLE);
        RCC_AHBPeriphClockCmd( RCC_AHBPeriph_GPIOC, ENABLE);
        RCC_AHBPeriphClockCmd( RCC_AHBPeriph_GPIOD, ENABLE);
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);
}
/*软件延时*/
void softWareDelay(void)
{
        uint16_t i;
        uint16_t j;
       
        for(i=0;i<500;i++)
        {
                for(j=0;j<1000;j++)
                {
                        __NOP();
                }
        }
}

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

使用特权

评论回复
地板
hehhehee|  楼主 | 2022-11-26 23:49 | 只看该作者
main.h
/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.h
  * @brief          : Header for main.c file.
  *                   This file contains the common defines of the application.
  ******************************************************************************
  */
/* USER CODE END Header */

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MAIN_H
#define __MAIN_H

#ifdef __cplusplus
extern "C" {
#endif

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

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


#ifdef __cplusplus
}
#endif

#endif /* __MAIN_H */

使用特权

评论回复
5
hehhehee|  楼主 | 2022-11-26 23:50 | 只看该作者
key.c

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

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

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

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

        // 初始化GPIOC
        GPIO_InitStructure.GPIO_Pin = KEYUP;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
        GPIO_Init(KEYPortGroup2, &GPIO_InitStructure);

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

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

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

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

        NVIC_Configurature();
}
/**
* @brief  键盘引脚NVIC配置初始化
* @param  
* @ref
* @return
* -
* @details  
* @see  
*/
void NVIC_Configurature(void)
{
       
    NVIC_InitTypeDef NVIC_InitStructure;
    // 初始化中断函数
        NVIC_InitStructure.NVIC_IRQChannel =EXTI1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

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

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

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

        // 初始化中断函数
        NVIC_InitStructure.NVIC_IRQChannel =EXTI7_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}
/**
* @brief  静音按键扫描函数
* @param  
* @ref
* @return
* -
* @details  
* @see  
*/
//方向键。这一部分低电平有效
void KEY_Scan(void)
{
        if(!GPIO_ReadInputDataBit(KEYPortGroup2,KEYUP))
        {
                printf("U\r\n");
                while(!GPIO_ReadInputDataBit(KEYPortGroup2,KEYUP));
        }
       
        if(!GPIO_ReadInputDataBit(KEYPortGroup3,KEYDOWN))
        {
                printf("D\r\n");
                while(!GPIO_ReadInputDataBit(KEYPortGroup3,KEYDOWN));
        }
       
        if(!GPIO_ReadInputDataBit(KEYPortGroup3,KEYLEFT))
        {
                printf("L\r\n");
                while(!GPIO_ReadInputDataBit(KEYPortGroup3,KEYLEFT));
        }
       
        if(!GPIO_ReadInputDataBit(KEYPortGroup3,KEYRIGHT))
        {
                printf("R\r\n");
                while(!GPIO_ReadInputDataBit(KEYPortGroup3,KEYRIGHT));
        }
       
       
}
// 按键测试函数
void KEY_Test(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    EXTI_InitTypeDef EXTI_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
       
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD|RCC_AHBPeriph_GPIOC|RCC_AHBPeriph_GPIOB|RCC_AHBPeriph_GPIOA,ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

        GPIO_InitStructure.GPIO_Pin = MKEY2;  
  
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
    GPIO_Init(KEYPortGrou1, &GPIO_InitStructure);

    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Line = MKEY2_Line;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);

    SYSCFG_EXTILineConfig(KEYPortGrou1_EXTI,MKEY2_Source);
        EXTI_ClearITPendingBit(MKEY2_Line);

    NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}

使用特权

评论回复
6
hehhehee|  楼主 | 2022-11-26 23:51 | 只看该作者
key.h
#ifndef _key_h
#define _key_h

#ifdef __cplusplus
extern "C" {
#endif
#include "hk32f030m.h"
#include "hk32f030m_gpio.h"
#include "main.h"

// GPIOA引脚**********************************
#define KEYPortGrou1 GPIOA
#define KEYPortGrou1_EXTI EXTI_PortSourceGPIOA
// 机械按键1
#define MKEY1 GPIO_Pin_2
#define MKEY1_Line EXTI_Line2
#define MKEY1_Source EXTI_PinSource2
// 机械按键2
#define MKEY2 GPIO_Pin_1
#define MKEY2_Line EXTI_Line1
#define MKEY2_Source EXTI_PinSource1


// GPIOC引脚**********************************
#define KEYPortGroup2 GPIOC
#define KEYPortGrou2_EXTI EXTI_PortSourceGPIOC
// 静音按键
#define KEYUP GPIO_Pin_7


// GPIOD引脚**********************************
#define KEYPortGroup3 GPIOD
#define KEYPortGrou3_EXTI EXTI_PortSourceGPIOD
// 静音按键
#define KEYRIGHT         GPIO_Pin_3
#define KEYDOWN GPIO_Pin_2
#define KEYLEFT GPIO_Pin_1
// 侧边按键
#define KEYSIDE GPIO_Pin_7
#define KEYSIDE_Line EXTI_Line7
#define KEYSIDE_Source EXTI_PinSource7
//机械按键3  注意此引脚为下载引脚
#ifdef DEBUG
#define MKEY3 GPIO_Pin_7
#define MKEY3_Line EXTI_Line7
#define MKEY3_Source EXTI_PinSource7
#else
#define MKEY3 GPIO_Pin_5
#define MKEY3_Line EXTI_Line5
#define MKEY3_Source EXTI_PinSource5
#endif
//机械按键4
#define MKEY4 GPIO_Pin_4
#define MKEY4_Line EXTI_Line4
#define MKEY4_Source EXTI_PinSource4

void KEY_Configurature(void);   // 按键引脚初始化
void EXIT_Configurature(void);  // 按键EXIT初始化
void NVIC_Configurature(void);  // 按键NVIC初始化
void KEY_Scan(void);  // 静音按键扫描函数
void KEY_Test(void);  // 按键测试函数
#ifdef __cplusplus
}
#endif /* __cplusplus */


#endif /*KEY.H*/

使用特权

评论回复
7
hehhehee|  楼主 | 2022-11-26 23:52 | 只看该作者
中断服务函数:

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

/* USER CODE BEGIN 1 */
/**
  * @brief  This function handles machine key 2 global interrupt request.
  * @param  None
  * @retval None
  */
void EXTI1_IRQHandler(void)    //按键2
{
  if (EXTI_GetFlagStatus(EXTI_Line1) != RESET)
  {
    printf("2\r\n");
                EXTI_ClearITPendingBit(EXTI_Line1);
  }
}
/**
  * @brief  This function handles machine key 1 global interrupt request.
  * @param  None
  * @retval None
  */
void EXTI2_IRQHandler(void)    //按键1
{
  if (EXTI_GetFlagStatus(EXTI_Line2) != RESET)
  {
    printf("1\r\n");
                EXTI_ClearITPendingBit(EXTI_Line2);
  }
}
/**
  * @brief  This function handles machine key 4 global interrupt request.
  * @param  None
  * @retval None
  */
void EXTI4_IRQHandler(void)    //按键4
{
  if (EXTI_GetFlagStatus(EXTI_Line4) != RESET)
  {
    printf("4\r\n");
                EXTI_ClearITPendingBit(EXTI_Line4);
  }
}
/**
  * @brief  This function handles machine key 3 global interrupt request.
  * @param  None
  * @retval None
  */
void EXTI5_IRQHandler(void)    //按键3
{
  if (EXTI_GetFlagStatus(EXTI_Line5) != RESET)
  {
    printf("3\r\n");
                EXTI_ClearITPendingBit(EXTI_Line5);
  }
}
/**
  * @brief  This function handles side key global interrupt request.
  * @param  None
  * @retval None
  */
void EXTI7_IRQHandler(void)    //侧边按键
{
  if (EXTI_GetFlagStatus(EXTI_Line7) != RESET)
  {
    printf("S\r\n");
                EXTI_ClearITPendingBit(EXTI_Line7);
  }
}
/**
  * @brief  This function handles TIM1 global interrupt request.
  * @param  None
  * @retval None
  */
void TIM1_UP_TRG_COM_IRQnHandler()
{
       
}
void TIM1_IRQHandler(void)
{
        if(TIM_GetITStatus(TIM1, TIM_IT_Update) != RESET)
  {
    TIM_ClearITPendingBit(TIM1, TIM_IT_Update);
                printf("toggle\r\n");
  }
}
/**
  * @brief  This function handles TIM2 global interrupt request.
  * @param  None
  * @retval None
  */
void TIM2_IRQHandler(void)
{
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
  {
    TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
                printf("toggle\r\n");
  }
}
/**
  * @brief  This function handles TIM6 global interrupt request.
  * @param  None
  * @retval None
  */
void TIM6_IRQHandler(void)
{
        TIM_ClearITPendingBit(TIM6, TIM_IT_Update);
        //printf("time\r\n");
        //低功耗计数器
}

/* USER CODE END 1 */
/************************ (C) COPYRIGHT HKMicroChip *****END OF FILE****/

使用特权

评论回复
8
hehhehee|  楼主 | 2022-11-26 23:53 | 只看该作者
就这个代码,太清晰了。没啥好分析的都! 哈哈哈哈
ec11.c

ec11相关知识!!!:

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

AB之间的电平状态关系

使用特权

评论回复
9
hehhehee|  楼主 | 2022-11-26 23:53 | 只看该作者

使用特权

评论回复
10
hehhehee|  楼主 | 2022-11-26 23:54 | 只看该作者
判断方法:

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

同理:

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

#include "ec11.h"

uint8_t Encoder[2]={0, 0};  // 存放按键的值
uint8_t flag[2]={0, 0};  // 按下旋钮标志位
/**
* @brief EC11旋转编码器初始化
* @param  
* @ref none
* @return none
* @details  
* @see  
*/
void EC11_Configurature(void)
{
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB,ENABLE);
        GPIO_InitTypeDef GPIO_InitStructure;
        //旋转编码器1
        GPIO_InitStructure.GPIO_Pin = TBUT_R | TBUT_D;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;  // 输入模式
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;  // 上拉输入
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
        GPIO_Init(EC11_1_Port,&GPIO_InitStructure);
        // 旋转编码器2
        GPIO_InitStructure.GPIO_Pin = TBUT_L | BBUT_L | BBUT_R | BBUT_D;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;  // 输入模式
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;  // 上拉输入
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
        GPIO_Init(EC11_2_Port,&GPIO_InitStructure);
}
/**
* @brief  读取EC11旋转状态 第一个EC11 上方
* @param  
* @ref
* @return
* -
* @details  
* @see  
*/
//首先,应该是低电平有效
//TBUT_L接的B、TBUT_R接的A
uint8_t EC11_Read_T()
{
        static uint16_t cou0;  // 锁死计时器
        static uint8_t KUP0;  // 锁死标志位
        uint8_t kt;  // 状态记录标志位

        Encoder[0] = 0;

        if(GPIO_ReadInputDataBit(EC11_2_Port,TBUT_L))   
                KUP0=0;        //判断旋钮是否解除锁死
       
        if(!GPIO_ReadInputDataBit(EC11_2_Port,TBUT_L)&&KUP0==0)//判断是否旋转旋钮,同时判断是否有旋钮锁死
    //这里B是下降沿了,判断A的电平。
    {
                // softWareDelay();  // 延时
                kt=GPIO_ReadInputDataBit(EC11_1_Port,TBUT_R);        //把旋钮另一端电平状态记录
                // softWareDelay(); //延时
                if(!GPIO_ReadInputDataBit(EC11_2_Port,TBUT_L))//去抖
        {
                        if(kt==0)//用另一端判断左或右旋转
            //A是低电平,逆时针
            {
                                Encoder[0] = 1;  // 右转 //作者写错了,这里应该是左转
                        }
            else
            //A是高电平,顺时针
            {
                                Encoder[0] = 2;  // 左转 //作者写错了,这里应该是右转
                        }
                        cou0=0; //初始锁死判断计数器
                        while(!GPIO_ReadInputDataBit(EC11_2_Port,TBUT_L)&&cou0<1200)
            { //等待放开旋钮,同时累加判断锁死
                                cou0++;KUP0=1;softWareDelay(); //
                        }
                }
        }
       
        if(GPIO_ReadInputDataBit(EC11_1_Port,TBUT_D))  
                flag[0]=0;
       
        if(flag[0]!=1)
        {
                if(!GPIO_ReadInputDataBit(EC11_1_Port,TBUT_D)&&KUP0==0)
        { // 判断旋钮是否按下  
                        //softWareDelay();
                        if(!GPIO_ReadInputDataBit(EC11_1_Port,TBUT_D))
            { // 去抖动
                                softWareDelay();
                                if(GPIO_ReadInputDataBit(EC11_1_Port,TBUT_D))
                {  // 判断是否放开
                                        Encoder[0] = 3;  // 按下
                                        flag[0]=0;
                                }
                else{
                                        Encoder[0] |= 0x10;
                                        flag[0]=1;
                                }
                        }
                }
        }
    else
    {
                Encoder[0] |= 0x10;
        }
       
        if(Encoder[0] == 0x10)
                Encoder[0]=0;
       
        return Encoder[0];
}
/**
* @brief  读取EC11旋转状态 第二个EC11 下方
* @param  
* @ref
* @return
* -
* @details  
* @see  
*/
uint8_t EC11_Read_D()
{
        static uint16_t cou;  // 锁死计时器
        static uint8_t KUP;  // 锁死标志位
        uint8_t kt;  // 状态记录标志位
        Encoder[1] = 0;
        if(GPIO_ReadInputDataBit(EC11_2_Port,BBUT_L))
                KUP=0;        //判断旋钮是否解除锁死
       
        if(!GPIO_ReadInputDataBit(EC11_2_Port,BBUT_L)&&KUP==0){ //判断是否旋转旋钮,同时判断是否有旋钮锁死
                // softWareDelay();  // 延时
                kt=GPIO_ReadInputDataBit(EC11_2_Port,BBUT_R);        //把旋钮另一端电平状态记录
                // softWareDelay(); //延时
                if(!GPIO_ReadInputDataBit(EC11_2_Port,BBUT_L)){ //去抖
                        if(kt==0){ //用另一端判断左或右旋转
                                Encoder[1] = 1;  // 右转
                        }else{
                                Encoder[1] = 2;  // 左转
                        }
                        cou=0; //初始锁死判断计数器
                        while(!GPIO_ReadInputDataBit(EC11_2_Port,BBUT_L)&&cou<1200){ //等待放开旋钮,同时累加判断锁死
                                cou++;KUP=1;softWareDelay(); //
                        }
                }
        }
       
        if(GPIO_ReadInputDataBit(EC11_2_Port,BBUT_D))  
                flag[1]=0;
       
        if(flag[1]!=1)
        {
                if(!GPIO_ReadInputDataBit(EC11_2_Port,BBUT_D)&&KUP==0){ // 判断旋钮是否按下  
                        //softWareDelay();
                        if(!GPIO_ReadInputDataBit(EC11_2_Port,BBUT_D)){ // 去抖动
                                softWareDelay();
                                if(GPIO_ReadInputDataBit(EC11_2_Port,BBUT_D)){  // 判断是否放开
                                        Encoder[1] = 3;  // 按下
                                        flag[1]=0;
                                }else{
                                        Encoder[1] |= 0x10;
                                        flag[1]=1;
                                }
                        }
                }
        }else{
                Encoder[1] |= 0x10;
        }
       
        if(Encoder[1] == 0x10)
                Encoder[1]=0;
       
        return Encoder[1];
}

使用特权

评论回复
11
hehhehee|  楼主 | 2022-11-26 23:55 | 只看该作者
ec11.h
#ifndef _ec11_h
#define _ec11_h

#ifdef __cplusplus
extern "C" {
#endif
#include "hk32f030m.h"
#include "hk32f030m_gpio.h"
#include "usart.h"
#include "main.h"

#define EC11_1_Port GPIOB  // 按下和右转在B引脚
#define TBUT_R GPIO_Pin_4  // 1右转
// 注意 此引脚为下载引脚
#ifdef DEBUG
#define TBUT_D GPIO_Pin_7  // 1按下
#else
#define TBUT_D GPIO_Pin_5  // 1按下
#endif

#define EC11_2_Port GPIOC  // EC11 2 和EC11 1的左转
#define TBUT_L GPIO_Pin_3  // 1左转
#define BBUT_L GPIO_Pin_4  // 2左转
#define BBUT_R GPIO_Pin_5  // 2右转
#define BBUT_D GPIO_Pin_6  // 2按下

void EC11_Configurature(void);  // EC11初始化
uint8_t EC11_Read_T();  // EC11 TOP读取
uint8_t EC11_Read_D();  // EC11 DOWN读取
#ifdef __cplusplus
}
#endif /* __cplusplus */


#endif /*EC11.H*/

使用特权

评论回复
12
hehhehee|  楼主 | 2022-11-26 23:55 | 只看该作者
其它函数不重要了,不分析了。
蓝牙模块

HC-05即可。

使用特权

评论回复
13
hehhehee|  楼主 | 2022-11-26 23:56 | 只看该作者
没啥代码要求,比较简单的。

项目使用的jdy-33
硬件部分

使用特权

评论回复
14
hehhehee|  楼主 | 2022-11-26 23:56 | 只看该作者
EC11部分

使用特权

评论回复
15
hehhehee|  楼主 | 2022-11-26 23:57 | 只看该作者
按键部分

机械按键

使用特权

评论回复
16
hehhehee|  楼主 | 2022-11-26 23:57 | 只看该作者
方向键

侧边键

使用特权

评论回复
17
hehhehee|  楼主 | 2022-11-26 23:58 | 只看该作者
type-C接口

使用特权

评论回复
18
hehhehee|  楼主 | 2022-11-26 23:59 | 只看该作者
USB-TTL

使用特权

评论回复
19
hehhehee|  楼主 | 2022-11-26 23:59 | 只看该作者
电池充电电路


使用特权

评论回复
20
微信13267226716| | 2022-11-29 11:54 | 只看该作者
这个好

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

80

主题

945

帖子

0

粉丝