提交全部资料
This commit is contained in:
265
1.主程序源代码/User/src/bsp_bat.c
Normal file
265
1.主程序源代码/User/src/bsp_bat.c
Normal file
@@ -0,0 +1,265 @@
|
||||
/*
|
||||
* @Date: 2025-06-26 16:58:50
|
||||
* @LastEditors: 路怀帅
|
||||
* @LastEditTime: 2025-07-04 17:07:40
|
||||
* @FilePath: \RVMDK(uv5)e:\个人项目\零距电子\安灯遥控器\Andon_Remote_Control\Andon_RTOS\User\src\bsp_bat.c
|
||||
*/
|
||||
#include "main.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "semphr.h"
|
||||
#include "task.h"
|
||||
static void BAT_Init(void);
|
||||
static uint8_t BAT_State_Read(void);
|
||||
|
||||
BATClassStruct BATClass = {
|
||||
.Init = BAT_Init,
|
||||
.Read_State = BAT_State_Read};
|
||||
|
||||
static void BAT_Init()
|
||||
{
|
||||
/*电池检测IO初始化*/
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
|
||||
GPIO_Init(GPIOA, &GPIO_InitStructure);
|
||||
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
|
||||
GPIO_Init(GPIOB, &GPIO_InitStructure);
|
||||
}
|
||||
|
||||
int cont = 0;
|
||||
static uint8_t BAT_State_Read()
|
||||
{
|
||||
cont++;
|
||||
uint8_t isCharging, batteryLevel;
|
||||
batteryLevel = GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_2);
|
||||
isCharging = GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_4);
|
||||
|
||||
if ((isCharging == 0) && (batteryLevel == 1))
|
||||
{
|
||||
if (cont >= 30)
|
||||
{
|
||||
GPIOB->BSRR = ((GPIOB->ODR & GPIO_Pin_0) << 16) | (~GPIOB->ODR & GPIO_Pin_0);
|
||||
cont = 0;
|
||||
}
|
||||
}
|
||||
else if ((isCharging == 1) && (batteryLevel == 0))
|
||||
{
|
||||
GPIO_ResetBits(GPIOB, GPIO_Pin_0);
|
||||
}
|
||||
else
|
||||
{
|
||||
GPIO_SetBits(GPIOB, GPIO_Pin_0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Power_button_init()
|
||||
{
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
|
||||
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
|
||||
GPIO_Init(GPIOA, &GPIO_InitStructure);
|
||||
}
|
||||
|
||||
uint8_t Check_Power_buttun()
|
||||
{
|
||||
|
||||
if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == 0)
|
||||
{
|
||||
delay_ms(30);
|
||||
if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == 0)
|
||||
return 0;
|
||||
}
|
||||
else if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == 1)
|
||||
{
|
||||
delay_ms(30);
|
||||
if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == 1)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ADC1_Init(void);
|
||||
static uint16_t getADC1Value(uint8_t ADC_channelx);
|
||||
|
||||
ADC1ClassStruct ADC1Class = {
|
||||
.Init = ADC1_Init,
|
||||
.GetValue = getADC1Value};
|
||||
|
||||
#define ADC1_DMA_CHANNEL DMA1_Channel1
|
||||
#define ADC1_DMA_CLK RCC_AHBPeriph_DMA1
|
||||
|
||||
#define ADC1_CLK RCC_APB2Periph_ADC1
|
||||
|
||||
#define ADC1_A0_A7_GPIO_PORT GPIOA
|
||||
#define ADC1_A0_A7_GPIO_CLK RCC_APB2Periph_GPIOA
|
||||
#define ADC1_A0_GPIO_PIN GPIO_Pin_0
|
||||
#define ADC1_A1_GPIO_PIN GPIO_Pin_1
|
||||
#define ADC1_A2_GPIO_PIN GPIO_Pin_2
|
||||
#define ADC1_A3_GPIO_PIN GPIO_Pin_3
|
||||
#define ADC1_A4_GPIO_PIN GPIO_Pin_4
|
||||
#define ADC1_A5_GPIO_PIN GPIO_Pin_5
|
||||
#define ADC1_A6_GPIO_PIN GPIO_Pin_6
|
||||
#define ADC1_A7_GPIO_PIN GPIO_Pin_7
|
||||
#define ADC1_B0_B1_GPIO_PORT GPIOB
|
||||
#define ADC1_B0_B1_GPIO_CLK RCC_APB2Periph_GPIOB
|
||||
#define ADC1_B0_GPIO_PIN GPIO_Pin_0
|
||||
#define ADC1_B1_GPIO_PIN GPIO_Pin_1
|
||||
|
||||
#define ADC1_A0_CHANNEL ADC_Channel_0
|
||||
#define ADC1_A1_CHANNEL ADC_Channel_1
|
||||
#define ADC1_A2_CHANNEL ADC_Channel_2
|
||||
#define ADC1_A3_CHANNEL ADC_Channel_3
|
||||
#define ADC1_A4_CHANNEL ADC_Channel_4
|
||||
#define ADC1_A5_CHANNEL ADC_Channel_5
|
||||
#define ADC1_A6_CHANNEL ADC_Channel_6
|
||||
#define ADC1_A7_CHANNEL ADC_Channel_7
|
||||
#define ADC1_B0_CHANNEL ADC_Channel_8
|
||||
#define ADC1_B1_CHANNEL ADC_Channel_9
|
||||
|
||||
__IO uint16_t ADC_ConvertedValue[10] = {0};
|
||||
|
||||
/**
|
||||
* @brief ADC1初始化
|
||||
* @param None
|
||||
* @retval None
|
||||
* @note None
|
||||
*/
|
||||
static void ADC1_Init(void)
|
||||
{
|
||||
/*定义一个GPIO_InitTypeDef类型的结构体*/
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
ADC_InitTypeDef ADC_InitStructure;
|
||||
DMA_InitTypeDef DMA_InitStructure;
|
||||
|
||||
RCC_APB2PeriphClockCmd(ADC1_A0_A7_GPIO_CLK, ENABLE);
|
||||
/***************************************************************/
|
||||
// 1. 修改为所使用的引脚
|
||||
GPIO_InitStructure.GPIO_Pin = ADC1_A5_GPIO_PIN;
|
||||
/***************************************************************/
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
|
||||
GPIO_Init(ADC1_A0_A7_GPIO_PORT, &GPIO_InitStructure);
|
||||
|
||||
// 打开DMA时钟
|
||||
RCC_AHBPeriphClockCmd(ADC1_DMA_CLK, ENABLE);
|
||||
// 打开ADC时钟
|
||||
RCC_APB2PeriphClockCmd(ADC1_CLK, ENABLE);
|
||||
// 复位DMA控制器
|
||||
DMA_DeInit(ADC1_DMA_CHANNEL);
|
||||
// 配置 DMA 初始化结构体
|
||||
// 外设基址为:ADC 数据寄存器地址
|
||||
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&(ADC1->DR));
|
||||
// 存储器地址
|
||||
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADC_ConvertedValue;
|
||||
// 数据源来自外设
|
||||
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
|
||||
/***************************************************************/
|
||||
// 2.缓存数量 使用1个ADC引脚就是1 使用2个ADC引脚就是2
|
||||
DMA_InitStructure.DMA_BufferSize = 1;
|
||||
/***************************************************************/
|
||||
// 外设寄存器只有一个,地址不用递增
|
||||
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
|
||||
// 存储器地址递增
|
||||
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
|
||||
// 外设数据大小为半字,即两个字节
|
||||
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
|
||||
// 内存数据大小也为半字,跟外设数据大小相同
|
||||
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
|
||||
// 循环传输模式
|
||||
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
|
||||
// DMA 传输通道优先级为高,当使用一个DMA通道时,优先级设置不影响
|
||||
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
|
||||
// 禁止存储器到存储器模式,因为是从外设到存储器
|
||||
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
|
||||
// 初始化DMA
|
||||
DMA_Init(ADC1_DMA_CHANNEL, &DMA_InitStructure);
|
||||
// 使能 DMA 通道
|
||||
DMA_Cmd(ADC1_DMA_CHANNEL, ENABLE);
|
||||
|
||||
// ADC 模式配置
|
||||
// 只使用一个ADC,属于单模式
|
||||
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
|
||||
// 扫描模式
|
||||
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
|
||||
// 连续转换模式
|
||||
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
|
||||
// 不用外部触发转换,软件开启即可
|
||||
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
|
||||
// 转换结果右对齐
|
||||
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
|
||||
/***************************************************************/
|
||||
// 3.转换通道个数 使用1个ADC引脚就是1 使用2个ADC引脚就是2
|
||||
ADC_InitStructure.ADC_NbrOfChannel = 1;
|
||||
/***************************************************************/
|
||||
// 初始化ADC
|
||||
ADC_Init(ADC1, &ADC_InitStructure);
|
||||
// 配置ADC时钟N狿CLK2的8分频,即9MHz
|
||||
RCC_ADCCLKConfig(RCC_PCLK2_Div8);
|
||||
/***************************************************************/
|
||||
// 4.配置ADC通道的转换顺序和采样时间 将所使用的所有引脚按自定义顺序填写
|
||||
ADC_RegularChannelConfig(ADC1, ADC1_A5_CHANNEL, 1, ADC_SampleTime_55Cycles5);
|
||||
// ADC_RegularChannelConfig(ADC1, ADC1_A2_CHANNEL, 2, ADC_SampleTime_55Cycles5);
|
||||
/***************************************************************/
|
||||
// 使能ADC DMA 请求
|
||||
ADC_DMACmd(ADC1, ENABLE);
|
||||
// 开启ADC ,并开始转换
|
||||
ADC_Cmd(ADC1, ENABLE);
|
||||
// 初始化ADC 校准寄存器
|
||||
ADC_ResetCalibration(ADC1);
|
||||
// 等待校准寄存器初始化完成
|
||||
while (ADC_GetResetCalibrationStatus(ADC1))
|
||||
;
|
||||
// ADC开始校准
|
||||
ADC_StartCalibration(ADC1);
|
||||
// 等待校准完成
|
||||
while (ADC_GetCalibrationStatus(ADC1))
|
||||
;
|
||||
// 由于没有采用外部触发,所以使用软件触发ADC转换
|
||||
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
|
||||
}
|
||||
/* 0-9对应第四步中的ADC引脚通道顺序 例如顺序为ADC1_A3 ADC1_A4 则A3引脚对应0 A4引脚对应1*/
|
||||
static uint16_t getADC1Value(uint8_t ADC_channelx)
|
||||
{
|
||||
uint16_t ADCTemp = 0;
|
||||
switch (ADC_channelx)
|
||||
{
|
||||
case 0:
|
||||
ADCTemp = (float)ADC_ConvertedValue[0] * 3.3 * 100 / 4096;
|
||||
break;
|
||||
case 1:
|
||||
ADCTemp = (float)ADC_ConvertedValue[1] / 4096 * 3.3 * 100;
|
||||
break;
|
||||
case 2:
|
||||
ADCTemp = (float)ADC_ConvertedValue[2] / 4096 * 3.3 * 100;
|
||||
break;
|
||||
case 3:
|
||||
ADCTemp = (float)ADC_ConvertedValue[3] / 4096 * 3.3 * 100;
|
||||
break;
|
||||
case 4:
|
||||
ADCTemp = (float)ADC_ConvertedValue[4] / 4096 * 3.3 * 100;
|
||||
break;
|
||||
case 5:
|
||||
ADCTemp = (float)ADC_ConvertedValue[5] / 4096 * 3.3 * 100;
|
||||
break;
|
||||
case 6:
|
||||
ADCTemp = (float)ADC_ConvertedValue[6] / 4096 * 3.3 * 100;
|
||||
break;
|
||||
case 7:
|
||||
ADCTemp = (float)ADC_ConvertedValue[7] / 4096 * 3.3 * 100;
|
||||
break;
|
||||
case 8:
|
||||
ADCTemp = (float)ADC_ConvertedValue[8] / 4096 * 3.3 * 100;
|
||||
break;
|
||||
case 9:
|
||||
ADCTemp = (float)ADC_ConvertedValue[9] / 4096 * 3.3 * 100;
|
||||
break;
|
||||
}
|
||||
return ADCTemp;
|
||||
}
|
||||
459
1.主程序源代码/User/src/bsp_button.c
Normal file
459
1.主程序源代码/User/src/bsp_button.c
Normal file
@@ -0,0 +1,459 @@
|
||||
#include "FreeRTOS.h"
|
||||
#include "semphr.h"
|
||||
#include "task.h"
|
||||
#include "main.h"
|
||||
|
||||
#define KEY_ENABLED(bit) ((rc_data()->Kv_get.key_en_table & (1 << (bit - 1))) != 0)
|
||||
|
||||
typedef enum
|
||||
{
|
||||
S1_BUTTON = 0,
|
||||
S2_BUTTON,
|
||||
S3_BUTTON,
|
||||
S4_BUTTON,
|
||||
S5_BUTTON,
|
||||
S6_BUTTON,
|
||||
S7_BUTTON,
|
||||
S8_BUTTON,
|
||||
S9_BUTTON,
|
||||
S10_BUTTON,
|
||||
S11_BUTTON,
|
||||
S12_BUTTON,
|
||||
BUTTON_MAX
|
||||
} user_button_t;
|
||||
|
||||
static flex_button_t user_button[BUTTON_MAX];
|
||||
|
||||
/**
|
||||
*@brief 按键1回调函数
|
||||
*@param *btn 按键结构体
|
||||
*@retval None
|
||||
*/
|
||||
static void btn_1_cb(flex_button_t *btn)
|
||||
{
|
||||
switch (btn->event)
|
||||
{
|
||||
case FLEX_BTN_PRESS_DOWN:
|
||||
|
||||
break;
|
||||
case FLEX_BTN_PRESS_CLICK:
|
||||
rc_data()->Lock_state = !rc_data()->Lock_state;
|
||||
rc_data()->Lock_time_tick = 0;
|
||||
LEDClass.Set(BLACK);
|
||||
rc_data()->isLEDTog = DISABLE;
|
||||
rc_data()->isSend = DISABLE;
|
||||
ASR_Power_OFF;
|
||||
rc_data()->Asr_state = LOCK;
|
||||
|
||||
break;
|
||||
case FLEX_BTN_PRESS_LONG_START:
|
||||
BOARD_Power_OFF;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*@brief 按键2回调函数
|
||||
*@param *btn 按键结构体
|
||||
*@retval None
|
||||
*/
|
||||
static void btn_2_cb(flex_button_t *btn)
|
||||
{
|
||||
switch (btn->event)
|
||||
{
|
||||
case FLEX_BTN_PRESS_DOWN:
|
||||
break;
|
||||
case FLEX_BTN_PRESS_CLICK:
|
||||
if (KEY_ENABLED(2))
|
||||
{
|
||||
rc_data()->Lock_time_tick = 0;
|
||||
rc_data()->Key_data[1] = 1;
|
||||
rc_data()->isLEDTog = ENABLE;
|
||||
}
|
||||
|
||||
break;
|
||||
case FLEX_BTN_PRESS_LONG_START:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*@brief 按键3回调函数
|
||||
*@param *btn 按键结构体
|
||||
*@retval None
|
||||
*/
|
||||
static void btn_3_cb(flex_button_t *btn)
|
||||
{
|
||||
switch (btn->event)
|
||||
{
|
||||
case FLEX_BTN_PRESS_DOWN:
|
||||
break;
|
||||
case FLEX_BTN_PRESS_CLICK:
|
||||
if (KEY_ENABLED(3))
|
||||
{
|
||||
rc_data()->Lock_time_tick = 0;
|
||||
rc_data()->isLEDTog = ENABLE;
|
||||
rc_data()->Key_data[0] = 3;
|
||||
}
|
||||
break;
|
||||
case FLEX_BTN_PRESS_LONG_START:
|
||||
break;
|
||||
}
|
||||
}
|
||||
/**
|
||||
*@brief 按键4回调函数
|
||||
*@param *btn 按键结构体
|
||||
*@retval None
|
||||
*/
|
||||
static void btn_4_cb(flex_button_t *btn)
|
||||
{
|
||||
switch (btn->event)
|
||||
{
|
||||
case FLEX_BTN_PRESS_DOWN:
|
||||
break;
|
||||
case FLEX_BTN_PRESS_CLICK:
|
||||
if (KEY_ENABLED(4))
|
||||
{
|
||||
rc_data()->Lock_time_tick = 0;
|
||||
rc_data()->isLEDTog = ENABLE;
|
||||
rc_data()->Key_data[0] = 4;
|
||||
}
|
||||
break;
|
||||
case FLEX_BTN_PRESS_LONG_START:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*@brief 按键5回调函数
|
||||
*@param *btn 按键结构体
|
||||
*@retval None
|
||||
*/
|
||||
static void btn_5_cb(flex_button_t *btn)
|
||||
{
|
||||
switch (btn->event)
|
||||
{
|
||||
case FLEX_BTN_PRESS_DOWN:
|
||||
break;
|
||||
case FLEX_BTN_PRESS_CLICK:
|
||||
if (KEY_ENABLED(5))
|
||||
{
|
||||
rc_data()->Lock_time_tick = 0;
|
||||
rc_data()->isLEDTog = ENABLE;
|
||||
rc_data()->Key_data[0] = 5;
|
||||
}
|
||||
break;
|
||||
case FLEX_BTN_PRESS_LONG_START:
|
||||
break;
|
||||
}
|
||||
}
|
||||
/**
|
||||
*@brief 按键6回调函数
|
||||
*@param *btn 按键结构体
|
||||
*@retval None
|
||||
*/
|
||||
static void btn_6_cb(flex_button_t *btn)
|
||||
{
|
||||
switch (btn->event)
|
||||
{
|
||||
case FLEX_BTN_PRESS_DOWN:
|
||||
break;
|
||||
case FLEX_BTN_PRESS_CLICK:
|
||||
if (KEY_ENABLED(6))
|
||||
{
|
||||
rc_data()->Lock_time_tick = 0;
|
||||
rc_data()->isLEDTog = ENABLE;
|
||||
rc_data()->Key_data[0] = 6;
|
||||
}
|
||||
break;
|
||||
case FLEX_BTN_PRESS_LONG_START:
|
||||
break;
|
||||
}
|
||||
}
|
||||
/**
|
||||
*@brief 按键7回调函数
|
||||
*@param *btn 按键结构体
|
||||
*@retval None
|
||||
*/
|
||||
static void btn_7_cb(flex_button_t *btn)
|
||||
{
|
||||
switch (btn->event)
|
||||
{
|
||||
case FLEX_BTN_PRESS_DOWN:
|
||||
break;
|
||||
case FLEX_BTN_PRESS_CLICK:
|
||||
if (KEY_ENABLED(7))
|
||||
{
|
||||
rc_data()->Lock_time_tick = 0;
|
||||
rc_data()->isLEDTog = ENABLE;
|
||||
rc_data()->Key_data[0] = 7;
|
||||
}
|
||||
break;
|
||||
case FLEX_BTN_PRESS_LONG_START:
|
||||
break;
|
||||
}
|
||||
}
|
||||
/**
|
||||
*@brief 按键8回调函数
|
||||
*@param *btn 按键结构体
|
||||
*@retval None
|
||||
*/
|
||||
static void btn_8_cb(flex_button_t *btn)
|
||||
{
|
||||
switch (btn->event)
|
||||
{
|
||||
case FLEX_BTN_PRESS_DOWN:
|
||||
break;
|
||||
case FLEX_BTN_PRESS_CLICK:
|
||||
if (KEY_ENABLED(8))
|
||||
{
|
||||
rc_data()->Lock_time_tick = 0;
|
||||
rc_data()->isLEDTog = ENABLE;
|
||||
rc_data()->Key_data[0] = 8;
|
||||
}
|
||||
break;
|
||||
case FLEX_BTN_PRESS_LONG_START:
|
||||
break;
|
||||
}
|
||||
}
|
||||
/**
|
||||
*@brief 按键9回调函数
|
||||
*@param *btn 按键结构体
|
||||
*@retval None
|
||||
*/
|
||||
static void btn_9_cb(flex_button_t *btn)
|
||||
{
|
||||
switch (btn->event)
|
||||
{
|
||||
case FLEX_BTN_PRESS_DOWN:
|
||||
break;
|
||||
case FLEX_BTN_PRESS_CLICK:
|
||||
if (KEY_ENABLED(9))
|
||||
{
|
||||
rc_data()->Lock_time_tick = 0;
|
||||
rc_data()->isLEDTog = ENABLE;
|
||||
rc_data()->Key_data[2] = 1;
|
||||
rc_data()->Key_data[3] = 0;
|
||||
}
|
||||
break;
|
||||
case FLEX_BTN_PRESS_LONG_START:
|
||||
break;
|
||||
}
|
||||
}
|
||||
/**
|
||||
*@brief 按键10回调函数
|
||||
*@param *btn 按键结构体
|
||||
*@retval None
|
||||
*/
|
||||
static void btn_10_cb(flex_button_t *btn)
|
||||
{
|
||||
switch (btn->event)
|
||||
{
|
||||
case FLEX_BTN_PRESS_DOWN:
|
||||
break;
|
||||
case FLEX_BTN_PRESS_CLICK:
|
||||
if (KEY_ENABLED(10))
|
||||
{
|
||||
rc_data()->Lock_time_tick = 0;
|
||||
rc_data()->isLEDTog = ENABLE;
|
||||
rc_data()->Key_data[2] = 0;
|
||||
rc_data()->Key_data[3] = 1;
|
||||
}
|
||||
break;
|
||||
case FLEX_BTN_PRESS_LONG_START:
|
||||
break;
|
||||
}
|
||||
}
|
||||
/**
|
||||
*@brief 按键11回调函数
|
||||
*@param *btn 按键结构体
|
||||
*@retval None
|
||||
*/
|
||||
static void btn_11_cb(flex_button_t *btn)
|
||||
{
|
||||
switch (btn->event)
|
||||
{
|
||||
case FLEX_BTN_PRESS_DOWN:
|
||||
break;
|
||||
case FLEX_BTN_PRESS_CLICK:
|
||||
if (KEY_ENABLED(11))
|
||||
{
|
||||
rc_data()->Lock_time_tick = 0;
|
||||
if (rc_data()->Asr_state == UNLOCK && rc_data()->Lock_state == UNLOCK)
|
||||
{
|
||||
ASR_Power_OFF;
|
||||
LEDClass.Set(BLACK);
|
||||
rc_data()->Asr_state = LOCK;
|
||||
}
|
||||
else if (rc_data()->Asr_state == LOCK && rc_data()->Lock_state == UNLOCK)
|
||||
{
|
||||
ASR_Power_ON;
|
||||
LEDClass.Set(BLACK);
|
||||
rc_data()->Asr_state = UNLOCK;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case FLEX_BTN_PRESS_LONG_START:
|
||||
break;
|
||||
}
|
||||
}
|
||||
/**
|
||||
*@brief 按键12回调函数
|
||||
*@param *btn 按键结构体
|
||||
*@retval None
|
||||
*/
|
||||
static void btn_12_cb(flex_button_t *btn)
|
||||
{
|
||||
switch (btn->event)
|
||||
{
|
||||
case FLEX_BTN_PRESS_DOWN:
|
||||
break;
|
||||
case FLEX_BTN_PRESS_CLICK:
|
||||
rc_data()->Lock_time_tick = 0;
|
||||
rc_data()->isSend = ENABLE;
|
||||
break;
|
||||
case FLEX_BTN_PRESS_LONG_START:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 按键001平读取接口
|
||||
static uint8_t button_s1_read(void)
|
||||
{
|
||||
return GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0);
|
||||
}
|
||||
|
||||
// 按键02电平读取接口
|
||||
static uint8_t button_s2_read(void)
|
||||
{
|
||||
return GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_11);
|
||||
}
|
||||
|
||||
// 按键03平读取接口
|
||||
static uint8_t button_s3_read(void)
|
||||
{
|
||||
return GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_12);
|
||||
}
|
||||
|
||||
// 按键04电平读取接口
|
||||
static uint8_t button_s4_read(void)
|
||||
{
|
||||
return GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_7);
|
||||
}
|
||||
// 按键05电平读取接口
|
||||
static uint8_t button_s5_read(void)
|
||||
{
|
||||
return GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14);
|
||||
}
|
||||
// 按键06电平读取接口
|
||||
static uint8_t button_s6_read(void)
|
||||
{
|
||||
return GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_6);
|
||||
}
|
||||
// 按键07电平读取接口
|
||||
static uint8_t button_s7_read(void)
|
||||
{
|
||||
return GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_13);
|
||||
}
|
||||
// 按键08电平读取接口
|
||||
static uint8_t button_s8_read(void)
|
||||
{
|
||||
return GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_5);
|
||||
}
|
||||
// 按键09电平读取接口
|
||||
static uint8_t button_s9_read(void)
|
||||
{
|
||||
return GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_15);
|
||||
}
|
||||
// 按键10电平读取接口
|
||||
static uint8_t button_s10_read(void)
|
||||
{
|
||||
return GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_3);
|
||||
}
|
||||
// 按键11电平读取接口
|
||||
static uint8_t button_s11_read(void)
|
||||
{
|
||||
return GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1);
|
||||
}
|
||||
// 按键12电平读取接口
|
||||
static uint8_t button_s12_read(void)
|
||||
{
|
||||
return GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_12);
|
||||
}
|
||||
|
||||
/**
|
||||
*@brief 按键初始化
|
||||
*@param None
|
||||
*@retval None
|
||||
*/
|
||||
void user_button_init(void)
|
||||
{
|
||||
/*注册按键Callback函数*/
|
||||
memset(&user_button[0], 0x0, sizeof(user_button));
|
||||
|
||||
user_button[S1_BUTTON].usr_button_read = button_s1_read;
|
||||
user_button[S1_BUTTON].cb = (flex_button_response_callback)btn_1_cb;
|
||||
|
||||
user_button[S2_BUTTON].usr_button_read = button_s2_read;
|
||||
user_button[S2_BUTTON].cb = (flex_button_response_callback)btn_2_cb;
|
||||
|
||||
user_button[S3_BUTTON].usr_button_read = button_s3_read;
|
||||
user_button[S3_BUTTON].cb = (flex_button_response_callback)btn_3_cb;
|
||||
|
||||
user_button[S4_BUTTON].usr_button_read = button_s4_read;
|
||||
user_button[S4_BUTTON].cb = (flex_button_response_callback)btn_4_cb;
|
||||
|
||||
user_button[S5_BUTTON].usr_button_read = button_s5_read;
|
||||
user_button[S5_BUTTON].cb = (flex_button_response_callback)btn_5_cb;
|
||||
|
||||
user_button[S6_BUTTON].usr_button_read = button_s6_read;
|
||||
user_button[S6_BUTTON].cb = (flex_button_response_callback)btn_6_cb;
|
||||
|
||||
user_button[S7_BUTTON].usr_button_read = button_s7_read;
|
||||
user_button[S7_BUTTON].cb = (flex_button_response_callback)btn_7_cb;
|
||||
|
||||
user_button[S8_BUTTON].usr_button_read = button_s8_read;
|
||||
user_button[S8_BUTTON].cb = (flex_button_response_callback)btn_8_cb;
|
||||
|
||||
user_button[S9_BUTTON].usr_button_read = button_s9_read;
|
||||
user_button[S9_BUTTON].cb = (flex_button_response_callback)btn_9_cb;
|
||||
|
||||
user_button[S10_BUTTON].usr_button_read = button_s10_read;
|
||||
user_button[S10_BUTTON].cb = (flex_button_response_callback)btn_10_cb;
|
||||
|
||||
user_button[S11_BUTTON].usr_button_read = button_s11_read;
|
||||
user_button[S11_BUTTON].cb = (flex_button_response_callback)btn_11_cb;
|
||||
|
||||
user_button[S12_BUTTON].usr_button_read = button_s12_read;
|
||||
user_button[S12_BUTTON].cb = (flex_button_response_callback)btn_12_cb;
|
||||
|
||||
/*按键检测IO初始化*/
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
|
||||
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_13 | GPIO_Pin_6 | GPIO_Pin_14 | GPIO_Pin_7 | GPIO_Pin_12 | GPIO_Pin_1 | GPIO_Pin_15 | GPIO_Pin_5;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
|
||||
GPIO_Init(GPIOB, &GPIO_InitStructure);
|
||||
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_12 | GPIO_Pin_11;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
|
||||
GPIO_Init(GPIOA, &GPIO_InitStructure);
|
||||
|
||||
user_button[0].pressed_logic_level = 1;
|
||||
user_button[0].click_start_tick = 20;
|
||||
user_button[0].short_press_start_tick = 80;
|
||||
user_button[0].long_press_start_tick = 200;
|
||||
user_button[0].long_hold_start_tick = 300;
|
||||
flex_button_register(&user_button[0]);
|
||||
|
||||
for (uint8_t i = 1; i < BUTTON_MAX; i++)
|
||||
{
|
||||
user_button[i].pressed_logic_level = 0;
|
||||
user_button[i].click_start_tick = 20;
|
||||
user_button[i].short_press_start_tick = 80;
|
||||
user_button[i].long_press_start_tick = 200;
|
||||
user_button[i].long_hold_start_tick = 300;
|
||||
flex_button_register(&user_button[i]);
|
||||
}
|
||||
}
|
||||
30
1.主程序源代码/User/src/bsp_chipid.c
Normal file
30
1.主程序源代码/User/src/bsp_chipid.c
Normal file
@@ -0,0 +1,30 @@
|
||||
#include "bsp_chipid.h"
|
||||
|
||||
uint32_t ChipUniqueID[3];
|
||||
|
||||
/*
|
||||
* 函数名:Get_ChipID
|
||||
* 描述 :获取芯片ID
|
||||
* 输入 :无
|
||||
* 输出 :无
|
||||
*/
|
||||
void Get_ChipID(void)
|
||||
{
|
||||
ChipUniqueID[0] = *(__IO u32 *)(0X1FFFF7F0); // 高字节
|
||||
ChipUniqueID[1] = *(__IO u32 *)(0X1FFFF7EC); //
|
||||
ChipUniqueID[2] = *(__IO u32 *)(0X1FFFF7E8); // 低字节
|
||||
}
|
||||
|
||||
void WDOG_Init()
|
||||
{
|
||||
// 使能 预分频寄存器PR和重装载寄存器RLR可写
|
||||
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
|
||||
// 设置预分频器值
|
||||
IWDG_SetPrescaler(IWDG_Prescaler_16); // IWDG 1s 超时溢出40k/16/2500= 1s
|
||||
// 设置重装载寄存器值
|
||||
IWDG_SetReload(0xfff);
|
||||
// 把重装载寄存器的值放到计数器中
|
||||
IWDG_ReloadCounter();
|
||||
// 使能 IWDG
|
||||
IWDG_Enable();
|
||||
}
|
||||
117
1.主程序源代码/User/src/bsp_led.c
Normal file
117
1.主程序源代码/User/src/bsp_led.c
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* @Date: 2025-06-26 09:38:27
|
||||
* @LastEditors: 路怀帅
|
||||
* @LastEditTime: 2025-06-26 15:04:35
|
||||
* @FilePath: \Andon_Remote_Control\MDK_PROJECT\Drive\Led.c
|
||||
*/
|
||||
#include "main.h"
|
||||
|
||||
static void LED_Init(void);
|
||||
static void LED_Set(uint8_t led_x);
|
||||
static void Green_Toggle_Fun(void);
|
||||
static void Red_Toggle_Fun(void);
|
||||
static void Blue_Toggle_Fun(void);
|
||||
static void Yellow_Toggle_Fun(void);
|
||||
|
||||
typedef LED_Color_Enum Led_Color;
|
||||
|
||||
LEDClassStruct LEDClass = {
|
||||
.Init = LED_Init,
|
||||
.Set = LED_Set,
|
||||
.GREEN_Toggle = Green_Toggle_Fun,
|
||||
.RED_Toggle = Red_Toggle_Fun,
|
||||
.BLUE_Toggle = Blue_Toggle_Fun,
|
||||
.YELLOW_Toggle = Yellow_Toggle_Fun};
|
||||
|
||||
static void LED_Set(uint8_t led_x)
|
||||
{
|
||||
switch (led_x)
|
||||
{
|
||||
case BLACK:
|
||||
LED_ALL_OFF;
|
||||
break;
|
||||
case BLUE:
|
||||
BLUE_ON;
|
||||
break;
|
||||
case GREEN:
|
||||
GREEN_ON;
|
||||
break;
|
||||
case RED:
|
||||
RED_ON;
|
||||
break;
|
||||
case YELLOW:
|
||||
RED_ON;
|
||||
GREEN_ON;
|
||||
break;
|
||||
case WHITE:
|
||||
RED_ON;
|
||||
GREEN_ON;
|
||||
BLUE_ON;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void Green_Toggle_Fun()
|
||||
{
|
||||
GREEN_TOG;
|
||||
}
|
||||
static void Blue_Toggle_Fun()
|
||||
{
|
||||
BLUE_TOG;
|
||||
}
|
||||
static void Red_Toggle_Fun()
|
||||
{
|
||||
RED_TOG;
|
||||
}
|
||||
static void Yellow_Toggle_Fun()
|
||||
{
|
||||
RED_TOG;
|
||||
GREEN_TOG;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief LED初始化
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void LED_Init()
|
||||
{
|
||||
/*初始化LED引脚*/
|
||||
GPIO_InitTypeDef GPIO_InitStruct;
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);
|
||||
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
|
||||
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
|
||||
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
|
||||
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
|
||||
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
GPIO_SetBits(GPIOA, GPIO_Pin_6 | GPIO_Pin_7);
|
||||
GPIO_SetBits(GPIOB, GPIO_Pin_0);
|
||||
}
|
||||
|
||||
void ASR_Power_Init()
|
||||
{
|
||||
/*初始化LED引脚*/
|
||||
GPIO_InitTypeDef GPIO_InitStruct;
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
|
||||
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8;
|
||||
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
|
||||
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
}
|
||||
|
||||
void BOARD_Power_Init()
|
||||
{
|
||||
/*初始化LED引脚*/
|
||||
GPIO_InitTypeDef GPIO_InitStruct;
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
|
||||
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_1;
|
||||
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
|
||||
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
BOARD_Power_ON;
|
||||
}
|
||||
40
1.主程序源代码/User/src/bsp_mod.c
Normal file
40
1.主程序源代码/User/src/bsp_mod.c
Normal file
@@ -0,0 +1,40 @@
|
||||
#include "main.h"
|
||||
|
||||
typedef void (*ToggleFunc)(void);
|
||||
typedef void (*DelayFunc)(uint32_t);
|
||||
|
||||
static void toggleLoop(ToggleFunc toggle, DelayFunc delayFunc, uint8_t iterations, uint32_t delayTime);
|
||||
|
||||
MODClassStruct MODClass = {
|
||||
.Loop = toggleLoop,
|
||||
};
|
||||
|
||||
static void toggleLoop(ToggleFunc toggle, DelayFunc delayFunc, uint8_t iterations, uint32_t delayTime)
|
||||
{
|
||||
for (uint8_t i = 0; i < iterations; i++)
|
||||
{
|
||||
toggle();
|
||||
delayFunc(delayTime);
|
||||
}
|
||||
}
|
||||
|
||||
LoraCommandParams cmd_params[] = {
|
||||
{"6", "1", "0", "0"},
|
||||
{"3", "1", "0", "0"},
|
||||
{"7", "1", "0", "0"},
|
||||
{"5", "1", "0", "0"},
|
||||
{"4", "1", "0", "0"},
|
||||
{"6", "0", "0", "0"},
|
||||
{"3", "0", "0", "0"},
|
||||
{"7", "0", "0", "0"},
|
||||
{"5", "0", "0", "0"},
|
||||
{"4", "0", "0", "0"},
|
||||
{"0", "0", "1", "0"},
|
||||
{"0", "0", "0", "1"},
|
||||
};
|
||||
|
||||
rc_data_t *rc_data(void)
|
||||
{
|
||||
static rc_data_t instance = {0};
|
||||
return &instance;
|
||||
}
|
||||
0
1.主程序源代码/User/src/bsp_sleep.c
Normal file
0
1.主程序源代码/User/src/bsp_sleep.c
Normal file
370
1.主程序源代码/User/src/bsp_usart.c
Normal file
370
1.主程序源代码/User/src/bsp_usart.c
Normal file
@@ -0,0 +1,370 @@
|
||||
#include "main.h"
|
||||
|
||||
static void USART1_Init(uint32_t baudRate);
|
||||
static void USART2_Init(uint32_t baudRate);
|
||||
static void USART3_Init(uint32_t baudRate);
|
||||
static void USART_SendString1(USART_TypeDef *USARTx, uint8_t *str, uint16_t len);
|
||||
static void USART_SendString2(USART_TypeDef *USARTx, uint8_t *str);
|
||||
|
||||
USARTClassStruct USARTClass = {
|
||||
.USART1_Init = USART1_Init,
|
||||
.USART2_Init = USART2_Init,
|
||||
.USART3_Init = USART3_Init,
|
||||
.USART_SendString1 = USART_SendString1,
|
||||
.USART_SendString2 = USART_SendString2};
|
||||
|
||||
#define use_USART1
|
||||
#define use_USART2
|
||||
#define use_USART3
|
||||
#define DEBUG_USART USART1
|
||||
|
||||
/* 在别的地方复现此函数 串口1中断函数
|
||||
void USART1_IRQHandler(void)
|
||||
{
|
||||
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) {
|
||||
USART_ClearITPendingBit(USART1, USART_IT_RXNE);
|
||||
}
|
||||
}
|
||||
*/
|
||||
/* 在别的地方复现此函数 串口2中断函数
|
||||
void USART2_IRQHandler(void)
|
||||
{
|
||||
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) {
|
||||
USART_ClearITPendingBit(USART2, USART_IT_RXNE);
|
||||
}
|
||||
}
|
||||
*/
|
||||
/* 在别的地方复现此函数 串口3中断函数
|
||||
void USART3_IRQHandler(void)
|
||||
{
|
||||
if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) {
|
||||
USART_ClearITPendingBit(USART3, USART_IT_RXNE);
|
||||
}
|
||||
}
|
||||
*/
|
||||
#define DEBUG_REVDATA_SIZE 500
|
||||
uint8_t g_debugRxFlag = 0;
|
||||
uint8_t g_debugRxBuf[DEBUG_REVDATA_SIZE];
|
||||
uint16_t g_debugRxLen = 0;
|
||||
uint8_t Lora_sendbuf[DEBUG_REVDATA_SIZE];
|
||||
void USART1_IRQHandler(void)
|
||||
{
|
||||
if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
|
||||
{
|
||||
USART_ClearITPendingBit(USART1, USART_IT_RXNE);
|
||||
g_debugRxBuf[g_debugRxLen] = USART_ReceiveData(USART1);
|
||||
g_debugRxLen++;
|
||||
}
|
||||
else if (USART_GetFlagStatus(USART1, USART_FLAG_IDLE) != RESET)
|
||||
{
|
||||
USART1->SR;
|
||||
USART1->DR;
|
||||
// memcpy(Lora_sendbuf,g_debugRxBuf,g_debugRxLen);
|
||||
|
||||
// printf("send data:%s\r\n",g_debugRxBuf);
|
||||
// USARTClass.USART_SendString1(USART3,g_debugRxBuf,g_debugRxLen);
|
||||
// memset(g_debugRxBuf,0x00,DEBUG_REVDATA_SIZE);
|
||||
// g_debugRxLen = 0;
|
||||
g_debugRxFlag = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USART1初始化
|
||||
* @param baudRate: 波特率
|
||||
* @retval None
|
||||
*/
|
||||
static void USART1_Init(uint32_t baudRate)
|
||||
{
|
||||
#ifdef use_USART1
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
USART_InitTypeDef USART_InitStructure;
|
||||
NVIC_InitTypeDef NVIC_InitStructure;
|
||||
|
||||
// 打开串口GPIO的时钟
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
|
||||
// 打开串口外设的时钟
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
|
||||
|
||||
// 将USART Tx的GPIO配置为推挽复用模式
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_Init(GPIOA, &GPIO_InitStructure);
|
||||
// 将USART Rx的GPIO配置为浮空输入模式
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
|
||||
GPIO_Init(GPIOA, &GPIO_InitStructure);
|
||||
|
||||
// 配置波特率
|
||||
USART_InitStructure.USART_BaudRate = baudRate;
|
||||
// 配置 针数据字长
|
||||
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
|
||||
// 配置停止位
|
||||
USART_InitStructure.USART_StopBits = USART_StopBits_1;
|
||||
// 配置校验位
|
||||
USART_InitStructure.USART_Parity = USART_Parity_No;
|
||||
// 配置硬件流控制
|
||||
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
|
||||
// 配置工作模式,收发一起
|
||||
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
|
||||
// 完成串口的初始化配置
|
||||
USART_Init(USART1, &USART_InitStructure);
|
||||
// 使能串口
|
||||
USART_Cmd(USART1, ENABLE);
|
||||
// 使能接收中断
|
||||
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
|
||||
|
||||
USART_ITConfig(USART1, USART_IT_IDLE, ENABLE); // 使能串口空闲中断
|
||||
|
||||
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); // 中断控制器分组设置
|
||||
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
|
||||
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
||||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 4;
|
||||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
|
||||
NVIC_Init(&NVIC_InitStructure);
|
||||
#endif
|
||||
}
|
||||
|
||||
#define ASR_REVDATA_SIZE 20
|
||||
uint8_t g_asrRxFlag = 0;
|
||||
uint8_t Asr_recbuff[ASR_REVDATA_SIZE];
|
||||
uint16_t g_asrRxLen = 0;
|
||||
|
||||
void USART2_IRQHandler(void)
|
||||
{
|
||||
if (USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
|
||||
{
|
||||
USART_ClearITPendingBit(USART2, USART_IT_RXNE);
|
||||
Asr_recbuff[g_asrRxLen] = USART_ReceiveData(USART2);
|
||||
g_asrRxLen++;
|
||||
}
|
||||
else if (USART_GetFlagStatus(USART2, USART_FLAG_IDLE) != RESET)
|
||||
{
|
||||
USART2->SR;
|
||||
USART2->DR;
|
||||
g_asrRxLen = 0;
|
||||
// printf("asr data:");
|
||||
// for(int i = 0;i<=2;i++)
|
||||
// {
|
||||
// printf("%02X",Asr_recbuff[i]);
|
||||
|
||||
// }
|
||||
// printf("\r\n");
|
||||
g_asrRxFlag = 1;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @brief USART2初始化
|
||||
* @param baudRate: 波特率
|
||||
* @retval None
|
||||
*/
|
||||
static void USART2_Init(uint32_t baudRate)
|
||||
{
|
||||
#ifdef use_USART2
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
USART_InitTypeDef USART_InitStructure;
|
||||
NVIC_InitTypeDef NVIC_InitStructure;
|
||||
|
||||
// 打开串口GPIO的时钟
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
|
||||
// 打开串口外设的时钟
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
|
||||
|
||||
// 将USART Tx的GPIO配置为推挽复用模式
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_Init(GPIOA, &GPIO_InitStructure);
|
||||
// 将USART Rx的GPIO配置为浮空输入模式
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
|
||||
GPIO_Init(GPIOA, &GPIO_InitStructure);
|
||||
|
||||
// 配置波特率
|
||||
USART_InitStructure.USART_BaudRate = baudRate;
|
||||
// 配置 针数据字长
|
||||
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
|
||||
// 配置停止位
|
||||
USART_InitStructure.USART_StopBits = USART_StopBits_1;
|
||||
// 配置校验位
|
||||
USART_InitStructure.USART_Parity = USART_Parity_No;
|
||||
// 配置硬件流控制
|
||||
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
|
||||
// 配置工作模式,收发一起
|
||||
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
|
||||
// 完成串口的初始化配置
|
||||
USART_Init(USART2, &USART_InitStructure);
|
||||
// 使能串口
|
||||
USART_Cmd(USART2, ENABLE);
|
||||
// 使能接收中断
|
||||
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
|
||||
|
||||
USART_ITConfig(USART2, USART_IT_IDLE, ENABLE); // 使能串口空闲中断
|
||||
|
||||
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); // 中断控制器分组设置
|
||||
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
|
||||
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
||||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
|
||||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
|
||||
NVIC_Init(&NVIC_InitStructure);
|
||||
#endif
|
||||
}
|
||||
|
||||
#define LORA_REVDATA_SIZE 400
|
||||
uint8_t g_loraRxFlag = 0;
|
||||
uint8_t Lora_recbuff[LORA_REVDATA_SIZE];
|
||||
uint16_t g_loraRxLen = 0;
|
||||
|
||||
void USART3_IRQHandler(void)
|
||||
{
|
||||
if (USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)
|
||||
{
|
||||
USART_ClearITPendingBit(USART3, USART_IT_RXNE);
|
||||
Lora_recbuff[g_loraRxLen] = USART_ReceiveData(USART3);
|
||||
g_loraRxLen++;
|
||||
}
|
||||
else if (USART_GetFlagStatus(USART3, USART_FLAG_IDLE) != RESET)
|
||||
{
|
||||
USART3->SR;
|
||||
USART3->DR;
|
||||
g_loraRxLen = 0;
|
||||
printf("%s", Lora_recbuff);
|
||||
memset(Lora_recbuff, 0x00, LORA_REVDATA_SIZE);
|
||||
g_loraRxFlag = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USART3初始化
|
||||
* @param baudRate: 波特率
|
||||
* @retval None
|
||||
*/
|
||||
static void USART3_Init(uint32_t baudRate)
|
||||
{
|
||||
#ifdef use_USART3
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
USART_InitTypeDef USART_InitStructure;
|
||||
NVIC_InitTypeDef NVIC_InitStructure;
|
||||
|
||||
// 打开串口GPIO的时钟
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
|
||||
// 打开串口外设的时钟
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
|
||||
|
||||
// 将USART Tx的GPIO配置为推挽复用模式
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_Init(GPIOB, &GPIO_InitStructure);
|
||||
// 将USART Rx的GPIO配置为浮空输入模式
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
|
||||
GPIO_Init(GPIOB, &GPIO_InitStructure);
|
||||
|
||||
// 配置波特率
|
||||
USART_InitStructure.USART_BaudRate = baudRate;
|
||||
// 配置 针数据字长
|
||||
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
|
||||
// 配置停止位
|
||||
USART_InitStructure.USART_StopBits = USART_StopBits_1;
|
||||
// 配置校验位
|
||||
USART_InitStructure.USART_Parity = USART_Parity_No;
|
||||
// 配置硬件流控制
|
||||
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
|
||||
// 配置工作模式,收发一起
|
||||
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
|
||||
// 完成串口的初始化配置
|
||||
USART_Init(USART3, &USART_InitStructure);
|
||||
// 使能串口
|
||||
USART_Cmd(USART3, ENABLE);
|
||||
// 使能接收中断
|
||||
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
|
||||
USART_ITConfig(USART3, USART_IT_IDLE, ENABLE); // 使能串口空闲中断
|
||||
|
||||
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); // 中断控制器分组设置
|
||||
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
|
||||
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
||||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
|
||||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
|
||||
NVIC_Init(&NVIC_InitStructure);
|
||||
#endif
|
||||
}
|
||||
/**
|
||||
* @brief USART发送定长字符串
|
||||
* @param USARTx: 串口几发送
|
||||
* @param str: 发送的内容
|
||||
* @param len: 长度
|
||||
* @retval None
|
||||
*/
|
||||
static void USART_SendString1(USART_TypeDef *USARTx, uint8_t *str, uint16_t len)
|
||||
{
|
||||
|
||||
unsigned short count = 0;
|
||||
|
||||
for (; count < len; count++)
|
||||
{
|
||||
USART_SendData(USARTx, *str++); // 发送数据
|
||||
while (USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET)
|
||||
; // 等待发送完成
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @brief USART发送不定长字符串
|
||||
* @param USARTx: 串口几发送
|
||||
* @param str: 发送的内容
|
||||
* @retval None
|
||||
*/
|
||||
static void USART_SendString2(USART_TypeDef *USARTx, uint8_t *str)
|
||||
{
|
||||
unsigned int k = 0;
|
||||
do
|
||||
{
|
||||
USART_SendData(USARTx, *(str + k));
|
||||
/* 等待发送数据寄存器为空 */
|
||||
while (USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET)
|
||||
{
|
||||
}
|
||||
k++;
|
||||
} while (*(str + k) != '\0');
|
||||
/* 等待发送完成 */
|
||||
while (USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// 重定向c库函数printf到串口,重定向后可使用printf函数
|
||||
int fputc(int ch, FILE *f)
|
||||
{
|
||||
/* 发送一个字节数据到串口 */
|
||||
USART_SendData(DEBUG_USART, (uint8_t)ch);
|
||||
/* 等待发送完毕 */
|
||||
while (USART_GetFlagStatus(DEBUG_USART, USART_FLAG_TXE) == RESET)
|
||||
;
|
||||
return (ch);
|
||||
}
|
||||
|
||||
void Usart_SendByte(USART_TypeDef *pUSARTx, uint8_t ch)
|
||||
{
|
||||
/* 发送一个字节数据到USART */
|
||||
USART_SendData(pUSARTx, ch);
|
||||
|
||||
/* 等待发送数据寄存器为空 */
|
||||
while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET)
|
||||
;
|
||||
}
|
||||
|
||||
void Usart_SendString(USART_TypeDef *pUSARTx, char *str)
|
||||
{
|
||||
unsigned int k = 0;
|
||||
do
|
||||
{
|
||||
Usart_SendByte(pUSARTx, *(str + k));
|
||||
k++;
|
||||
} while (*(str + k) != '\0');
|
||||
|
||||
/* 等待发送完成 */
|
||||
while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TC) == RESET)
|
||||
{
|
||||
}
|
||||
}
|
||||
153
1.主程序源代码/User/src/delay.c
Normal file
153
1.主程序源代码/User/src/delay.c
Normal file
@@ -0,0 +1,153 @@
|
||||
#include "delay.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
//如果使用ucos,则包括下面的头文件即可.
|
||||
#if SYSTEM_SUPPORT_UCOS
|
||||
#include "includes.h" //ucos 使用
|
||||
#endif
|
||||
|
||||
static u8 fac_us=0;//us延时倍乘数
|
||||
static u16 fac_ms=0;//ms延时倍乘数
|
||||
#ifdef OS_CRITICAL_METHOD //如果OS_CRITICAL_METHOD定义了,说明使用ucosII了.
|
||||
//systick中断服务函数,使用ucos时用到
|
||||
void SysTick_Handler(void)
|
||||
{
|
||||
OSIntEnter(); //进入中断
|
||||
OSTimeTick(); //调用ucos的时钟服务程序
|
||||
OSIntExit(); //触发任务切换软中断
|
||||
}
|
||||
#endif
|
||||
|
||||
//初始化延迟函数
|
||||
//当使用ucos的时候,此函数会初始化ucos的时钟节拍
|
||||
//SYSTICK的时钟固定为HCLK时钟的1/8
|
||||
//SYSCLK:系统时钟
|
||||
void delay_init()
|
||||
{
|
||||
|
||||
#ifdef OS_CRITICAL_METHOD //如果OS_CRITICAL_METHOD定义了,说明使用ucosII了.
|
||||
u32 reload;
|
||||
#endif
|
||||
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //选择外部时钟 HCLK/8
|
||||
fac_us=SystemCoreClock/8000000; //为系统时钟的1/8
|
||||
|
||||
#ifdef OS_CRITICAL_METHOD //如果OS_CRITICAL_METHOD定义了,说明使用ucosII了.
|
||||
reload=SystemCoreClock/8000000; //每秒钟的计数次数 单位为K
|
||||
reload*=1000000/OS_TICKS_PER_SEC;//根据OS_TICKS_PER_SEC设定溢出时间
|
||||
//reload为24位寄存器,最大值:16777216,在72M下,约合1.86s左右
|
||||
fac_ms=1000/OS_TICKS_PER_SEC;//代表ucos可以延时的最少单位
|
||||
SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk; //开启SYSTICK中断
|
||||
SysTick->LOAD=reload; //每1/OS_TICKS_PER_SEC秒中断一次
|
||||
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk; //开启SYSTICK
|
||||
#else
|
||||
fac_ms=(u16)fac_us*1000;//非ucos下,代表每个ms需要的systick时钟数
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef OS_CRITICAL_METHOD //使用了ucos
|
||||
//延时nus
|
||||
//nus为要延时的us数.
|
||||
void delay_us(u32 nus)
|
||||
{
|
||||
u32 ticks;
|
||||
u32 told,tnow,tcnt=0;
|
||||
u32 reload=SysTick->LOAD; //LOAD的值
|
||||
ticks=nus*fac_us; //需要的节拍数
|
||||
tcnt=0;
|
||||
told=SysTick->VAL; //刚进入时的计数器值
|
||||
while(1)
|
||||
{
|
||||
tnow=SysTick->VAL;
|
||||
if(tnow!=told)
|
||||
{
|
||||
if(tnow<told)tcnt+=told-tnow;//这里注意一下SYSTICK是一个递减的计数器就可以了.
|
||||
else tcnt+=reload-tnow+told;
|
||||
told=tnow;
|
||||
if(tcnt>=ticks)break;//时间超过/等于要延迟的时间,则退出.
|
||||
}
|
||||
};
|
||||
}
|
||||
//延时nms
|
||||
//nms:要延时的ms数
|
||||
void delay_ms(u16 nms)
|
||||
{
|
||||
if(OSRunning==TRUE)//如果os已经在跑了
|
||||
{
|
||||
if(nms>=fac_ms)//延时的时间大于ucos的最少时间周期
|
||||
{
|
||||
OSTimeDly(nms/fac_ms);//ucos延时
|
||||
}
|
||||
nms%=fac_ms; //ucos已经无法提供这么小的延时了,采用普通方式延时
|
||||
}
|
||||
delay_us((u32)(nms*1000)); //普通方式延时,此时ucos无法启动调度.
|
||||
}
|
||||
#else//不用ucos时
|
||||
//延时nus
|
||||
//nus为要延时的us数.
|
||||
void delay_us(u32 nus)
|
||||
{
|
||||
u32 temp;
|
||||
SysTick->LOAD=nus*fac_us; //时间加载
|
||||
SysTick->VAL=0x00; //清空计数器
|
||||
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //开始倒数
|
||||
do
|
||||
{
|
||||
temp=SysTick->CTRL;
|
||||
}
|
||||
while(temp&0x01&&!(temp&(1<<16)));//等待时间到达
|
||||
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器
|
||||
SysTick->VAL =0X00; //清空计数器
|
||||
}
|
||||
//延时nms
|
||||
//注意nms的范围
|
||||
//SysTick->LOAD为24位寄存器,所以,最大延时为:
|
||||
//nms<=0xffffff*8*1000/SYSCLK
|
||||
//SYSCLK单位为Hz,nms单位为ms
|
||||
//对72M条件下,nms<=1864
|
||||
void delay_ms(u16 nms)
|
||||
{
|
||||
u32 temp;
|
||||
SysTick->LOAD=(u32)nms*fac_ms;//时间加载(SysTick->LOAD为24bit)
|
||||
SysTick->VAL =0x00; //清空计数器
|
||||
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //开始倒数
|
||||
do
|
||||
{
|
||||
temp=SysTick->CTRL;
|
||||
}
|
||||
while(temp&0x01&&!(temp&(1<<16)));//等待时间到达
|
||||
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器
|
||||
SysTick->VAL =0X00; //清空计数器
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
293
1.主程序源代码/User/src/flexible_button.c
Normal file
293
1.主程序源代码/User/src/flexible_button.c
Normal file
@@ -0,0 +1,293 @@
|
||||
/*
|
||||
* @Date: 2025-06-26 10:58:20
|
||||
* @LastEditors: 路怀帅
|
||||
* @LastEditTime: 2025-06-26 14:47:21
|
||||
* @FilePath: \Andon_Remote_Control\MDK_PROJECT\Drive\flexible_button.c
|
||||
*/
|
||||
/**
|
||||
* @File: flexible_button.c
|
||||
* @Author: MurphyZhao
|
||||
* @Date: 2018-09-29
|
||||
*
|
||||
* Copyright (c) 2018-2019 MurphyZhao <d2014zjt@163.com>
|
||||
* https://github.com/murphyzhao
|
||||
* All rights reserved.
|
||||
* License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Change logs:
|
||||
* Date Author Notes
|
||||
* 2018-09-29 MurphyZhao First add
|
||||
* 2019-08-02 MurphyZhao 迁移代码到 murphyzhao 仓库
|
||||
*
|
||||
*/
|
||||
|
||||
#include "flexible_button.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static flex_button_t *btn_head = NULL;
|
||||
|
||||
#define EVENT_CB_EXECUTOR(button) if(button->cb) button->cb((flex_button_t*)button)
|
||||
#define MAX_BUTTON_CNT 16
|
||||
|
||||
static uint16_t trg = 0;
|
||||
static uint16_t cont = 0;
|
||||
static uint16_t keydata = 0xFFFF;
|
||||
static uint16_t key_rst_data = 0xFFFF;
|
||||
static uint8_t button_cnt = 0;
|
||||
|
||||
/**
|
||||
* @brief Register a user button
|
||||
*
|
||||
* @param button: button structure instance
|
||||
* @return Number of keys that have been registered
|
||||
*/
|
||||
int8_t flex_button_register(flex_button_t *button)
|
||||
{
|
||||
flex_button_t *curr = btn_head;
|
||||
|
||||
if (!button || (button_cnt > MAX_BUTTON_CNT))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (curr)
|
||||
{
|
||||
if(curr == button)
|
||||
{
|
||||
return -1; //already exist.
|
||||
}
|
||||
curr = curr->next;
|
||||
}
|
||||
|
||||
button->next = btn_head;
|
||||
button->status = 0;
|
||||
button->event = FLEX_BTN_PRESS_NONE;
|
||||
button->scan_cnt = 0;
|
||||
button->click_cnt = 0;
|
||||
btn_head = button;
|
||||
key_rst_data = key_rst_data << 1;
|
||||
button_cnt ++;
|
||||
return button_cnt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read all key values in one scan cycle
|
||||
*
|
||||
* @param void
|
||||
* @return none
|
||||
*/
|
||||
static void flex_button_read(void)
|
||||
{
|
||||
flex_button_t* target;
|
||||
uint16_t read_data = 0;
|
||||
keydata = key_rst_data;
|
||||
int8_t i = 0;
|
||||
|
||||
for(target = btn_head, i = 0;
|
||||
(target != NULL) && (target->usr_button_read != NULL);
|
||||
target = target->next, i ++)
|
||||
{
|
||||
keydata = keydata |
|
||||
(target->pressed_logic_level == 1 ?
|
||||
((!(target->usr_button_read)()) << i) :
|
||||
((target->usr_button_read)() << i));
|
||||
}
|
||||
|
||||
read_data = keydata^0xFFFF;
|
||||
trg = read_data & (read_data ^ cont);
|
||||
cont = read_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handle all key events in one scan cycle.
|
||||
* Must be used after 'flex_button_read' API
|
||||
*
|
||||
* @param void
|
||||
* @return none
|
||||
*/
|
||||
static void flex_button_process(void)
|
||||
{
|
||||
int8_t i = 0;
|
||||
flex_button_t* target;
|
||||
|
||||
for (target = btn_head, i = 0; target != NULL; target = target->next, i ++)
|
||||
{
|
||||
if (target->status > 0)
|
||||
{
|
||||
target->scan_cnt ++;
|
||||
}
|
||||
|
||||
switch (target->status)
|
||||
{
|
||||
case 0: /* is default */
|
||||
if (trg & (1 << i)) /* is pressed */
|
||||
{
|
||||
target->scan_cnt = 0;
|
||||
target->click_cnt = 0;
|
||||
target->status = 1;
|
||||
target->event = FLEX_BTN_PRESS_DOWN;
|
||||
EVENT_CB_EXECUTOR(target);
|
||||
}
|
||||
else
|
||||
{
|
||||
target->event = FLEX_BTN_PRESS_NONE;
|
||||
}
|
||||
break;
|
||||
|
||||
case 1: /* is pressed */
|
||||
if (!(cont & (1 << i))) /* is up */
|
||||
{
|
||||
target->status = 2;
|
||||
}
|
||||
else if ((target->scan_cnt >= target->short_press_start_tick) &&
|
||||
(target->scan_cnt < target->long_press_start_tick))
|
||||
{
|
||||
target->status = 4;
|
||||
target->event = FLEX_BTN_PRESS_SHORT_START;
|
||||
EVENT_CB_EXECUTOR(target);
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: /* is up */
|
||||
if ((target->scan_cnt < target->click_start_tick))
|
||||
{
|
||||
target->click_cnt++; // 1
|
||||
|
||||
if (target->click_cnt == 1)
|
||||
{
|
||||
target->status = 3; /* double click check */
|
||||
}
|
||||
else
|
||||
{
|
||||
target->click_cnt = 0;
|
||||
target->status = 0;
|
||||
target->event = FLEX_BTN_PRESS_DOUBLE_CLICK;
|
||||
EVENT_CB_EXECUTOR(target);
|
||||
}
|
||||
}
|
||||
else if ((target->scan_cnt >= target->click_start_tick) &&
|
||||
(target->scan_cnt < target->short_press_start_tick))
|
||||
{
|
||||
target->click_cnt = 0;
|
||||
target->status = 0;
|
||||
target->event = FLEX_BTN_PRESS_CLICK;
|
||||
EVENT_CB_EXECUTOR(target);
|
||||
}
|
||||
else if ((target->scan_cnt >= target->short_press_start_tick) &&
|
||||
(target->scan_cnt < target->long_press_start_tick))
|
||||
{
|
||||
target->click_cnt = 0;
|
||||
target->status = 0;
|
||||
target->event = FLEX_BTN_PRESS_SHORT_UP;
|
||||
EVENT_CB_EXECUTOR(target);
|
||||
}
|
||||
else if ((target->scan_cnt >= target->long_press_start_tick) &&
|
||||
(target->scan_cnt < target->long_hold_start_tick))
|
||||
{
|
||||
target->click_cnt = 0;
|
||||
target->status = 0;
|
||||
target->event = FLEX_BTN_PRESS_LONG_UP;
|
||||
EVENT_CB_EXECUTOR(target);
|
||||
}
|
||||
else if (target->scan_cnt >= target->long_hold_start_tick)
|
||||
{
|
||||
/* long press hold up, not deal */
|
||||
target->click_cnt = 0;
|
||||
target->status = 0;
|
||||
target->event = FLEX_BTN_PRESS_LONG_HOLD_UP;
|
||||
EVENT_CB_EXECUTOR(target);
|
||||
}
|
||||
break;
|
||||
|
||||
case 3: /* double click check */
|
||||
if (trg & (1 << i))
|
||||
{
|
||||
target->click_cnt++;
|
||||
target->status = 2;
|
||||
target->scan_cnt --;
|
||||
}
|
||||
else if (target->scan_cnt >= target->click_start_tick)
|
||||
{
|
||||
target->status = 2;
|
||||
}
|
||||
break;
|
||||
|
||||
case 4: /* is short pressed */
|
||||
if (!(cont & (1 << i))) /* is up */
|
||||
{
|
||||
target->status = 2;
|
||||
}
|
||||
else if ((target->scan_cnt >= target->long_press_start_tick) &&
|
||||
(target->scan_cnt < target->long_hold_start_tick))
|
||||
{
|
||||
target->status = 5;
|
||||
target->event = FLEX_BTN_PRESS_LONG_START;
|
||||
EVENT_CB_EXECUTOR(target);
|
||||
}
|
||||
break;
|
||||
|
||||
case 5: /* is long pressed */
|
||||
if (!(cont & (1 << i))) /* is up */
|
||||
{
|
||||
target->status = 2;
|
||||
}
|
||||
else if (target->scan_cnt >= target->long_hold_start_tick)
|
||||
{
|
||||
target->status = 6;
|
||||
target->event = FLEX_BTN_PRESS_LONG_HOLD;
|
||||
EVENT_CB_EXECUTOR(target);
|
||||
}
|
||||
break;
|
||||
|
||||
case 6: /* is long pressed */
|
||||
if (!(cont & (1 << i))) /* is up */
|
||||
{
|
||||
target->status = 2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* flex_button_event_read
|
||||
*
|
||||
* @brief Get the button event of the specified button.
|
||||
*
|
||||
* @param button: button structure instance
|
||||
* @return button event
|
||||
*/
|
||||
flex_button_event_t flex_button_event_read(flex_button_t* button)
|
||||
{
|
||||
return (flex_button_event_t)(button->event);
|
||||
}
|
||||
|
||||
/**
|
||||
* flex_button_scan
|
||||
*
|
||||
* @brief Start key scan.
|
||||
* Need to be called cyclically within the specified period.
|
||||
* Sample cycle: 5 - 20ms
|
||||
*
|
||||
* @param void
|
||||
* @return none
|
||||
*/
|
||||
void flex_button_scan(void)
|
||||
{
|
||||
flex_button_read();
|
||||
flex_button_process();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user