由STM32F103C8T6和ISD1820,LCD1602,按键模块组成的录音设备,三个按键分别控制语音的录入、播放、循环播放,按键模块的软件代码怎么写,详细解释
时间: 2023-12-16 10:04:21 浏览: 97
首先,我们需要了解 STM32F103C8T6 和 ISD1820 的硬件连接方式。
- 将 ISD1820 的记录模式设置为 Latch,然后将其 VCC 和 GND 分别连接到 STM32F103C8T6 的 5V 和 GND 引脚。
- 将 ISD1820 的 PlayE 引脚连接到 STM32F103C8T6 的 PB12 引脚,将其 REC 引脚连接到 STM32F103C8T6 的 PB13 引脚。
- 将 LCD1602 的 VSS 和 VDD 引脚分别连接到 STM32F103C8T6 的 GND 和 5V 引脚。
- 将 LCD1602 的 RS,RW,E 引脚分别连接到 STM32F103C8T6 的 PA2,PA3,PA4 引脚。
- 将 LCD1602 的 D4~D7 引脚分别连接到 STM32F103C8T6 的 PA5~PA8 引脚。
- 将按键模块的 K1,K2,K3 引脚分别连接到 STM32F103C8T6 的 PA9,PA10,PA11 引脚。
接下来是按键模块的软件代码实现,我们使用 GPIO 输入模式来读取按键信号,并通过状态机来控制录音和播放功能。
首先定义状态机的状态:
```c
typedef enum
{
IDLE_STATE = 0,
RECORD_STATE,
PLAY_STATE,
LOOP_STATE
} State_t;
```
然后定义按键的状态:
```c
typedef enum
{
KEY_IDLE = 0,
KEY_DOWN,
KEY_HOLD,
KEY_UP
} KeyState_t;
```
接着定义按键的结构体:
```c
typedef struct
{
GPIO_TypeDef* GPIOx; // 按键所在的GPIO端口
uint16_t GPIO_Pin; // 按键所在的GPIO引脚
uint32_t keyDownTime; // 按键按下的时间
uint32_t keyUpTime; // 按键松开的时间
KeyState_t keyState; // 按键的状态
} Key_t;
```
定义录音设备的变量:
```c
// 定义按键数组
Key_t keys[] = {
{GPIOA, GPIO_Pin_9, 0, 0, KEY_IDLE},
{GPIOA, GPIO_Pin_10, 0, 0, KEY_IDLE},
{GPIOA, GPIO_Pin_11, 0, 0, KEY_IDLE}
};
// 定义状态机的初始状态
State_t state = IDLE_STATE;
```
接着实现按键扫描函数,通过读取 GPIO 输入来判断按键的状态:
```c
void scanKeys(void)
{
for (int i = 0; i < 3; i++)
{
// 判断按键是否按下
if (GPIO_ReadInputDataBit(keys[i].GPIOx, keys[i].GPIO_Pin) == 0)
{
// 记录按键按下的时间
if (keys[i].keyState == KEY_IDLE)
{
keys[i].keyDownTime = HAL_GetTick();
keys[i].keyState = KEY_DOWN;
}
else if (keys[i].keyState == KEY_DOWN)
{
// 判断按键是否保持按下状态
if (HAL_GetTick() - keys[i].keyDownTime > 500)
{
keys[i].keyState = KEY_HOLD;
}
}
}
else
{
// 记录按键松开的时间
if (keys[i].keyState == KEY_HOLD || keys[i].keyState == KEY_DOWN)
{
keys[i].keyUpTime = HAL_GetTick();
keys[i].keyState = KEY_UP;
}
}
}
}
```
接着实现状态机的转移函数,根据按键的状态来判断状态机的转移:
```c
void transitionState(void)
{
switch (state)
{
case IDLE_STATE:
// 判断是否按下录音键
if (keys[0].keyState == KEY_UP)
{
state = RECORD_STATE;
}
// 判断是否按下播放键
else if (keys[1].keyState == KEY_UP)
{
state = PLAY_STATE;
}
break;
case RECORD_STATE:
// 判断是否按下松开录音键
if (keys[0].keyState == KEY_UP)
{
// 发送记录命令到 ISD1820
HAL_GPIO_WritePin(GPIOB, GPIO_Pin_13, GPIO_PIN_SET);
HAL_Delay(100);
HAL_GPIO_WritePin(GPIOB, GPIO_Pin_13, GPIO_PIN_RESET);
state = IDLE_STATE;
}
break;
case PLAY_STATE:
// 判断是否按下松开播放键
if (keys[1].keyState == KEY_UP)
{
// 发送播放命令到 ISD1820
HAL_GPIO_WritePin(GPIOB, GPIO_Pin_12, GPIO_PIN_SET);
HAL_Delay(100);
HAL_GPIO_WritePin(GPIOB, GPIO_Pin_12, GPIO_PIN_RESET);
state = IDLE_STATE;
}
break;
case LOOP_STATE:
// 判断是否按下松开循环播放键
if (keys[2].keyState == KEY_UP)
{
// 发送循环播放命令到 ISD1820
HAL_GPIO_WritePin(GPIOB, GPIO_Pin_12, GPIO_PIN_SET);
HAL_Delay(100);
HAL_GPIO_WritePin(GPIOB, GPIO_Pin_12, GPIO_PIN_RESET);
state = LOOP_STATE;
}
break;
default:
break;
}
}
```
最后在主函数中调用按键扫描和状态机转移函数:
```c
int main(void)
{
// ...
while (1)
{
scanKeys();
transitionState();
}
}
```
以上就是 STM32F103C8T6 和 ISD1820,LCD1602,按键模块组成的录音设备的按键模块的软件代码实现。
阅读全文