K1Guitar/device/TM1617/Drv_TM1617_RGB.c

299 lines
7.6 KiB
C
Raw Normal View History

/*
* @Author: CTW
* @Date: 2025-11-07 14:37:55
* @FilePath: \PhoenixSMGT_Testproject\Drivers\TM1617\Drv_TM1617_RGB.c
* @note: STM32 HAL AT32F403AGPIO
* - HAL_GPIO_WritePin/ReadPin/Init -> at32f403a_407 GPIO
* - Delay_us / Delay_ms / HAL_Delay ->
*/
#include "Drv_TM1617_RGB.h"
uint8_t rgb_color_seq[] = {COLOR_R, COLOR_G, COLOR_B, COLOR_YEL, COLOR_CYA, COLOR_PUR, COLOR_WHT}; // 颜色流转序列
uint8_t color_idx = 0; // 颜色索引
/* ================= 底层原语AT32 GPIO ================= */
#define TM1617_DIO_H() gpio_bits_set(DIO_PORT, DIO_PIN)
#define TM1617_DIO_L() gpio_bits_reset(DIO_PORT, DIO_PIN)
#define TM1617_CLK_H() gpio_bits_set(CLK_PORT, CLK_PIN)
#define TM1617_CLK_L() gpio_bits_reset(CLK_PORT, CLK_PIN)
#define TM1617_STB_H() gpio_bits_set(STB_PORT, STB_PIN)
#define TM1617_STB_L() gpio_bits_reset(STB_PORT, STB_PIN)
/* 忙等延时:约 1usNOP 循环,不依赖 SysTick/RTOS */
static void TM1617_Delay1us(void)
{
volatile uint32_t i = 24; /* 240MHz 下约 1us可实测微调 */
while (i--) __NOP();
}
/* 忙等延时:约 1msNOP 循环) */
static void TM1617_Delay1ms(void)
{
volatile uint32_t i = 24000; /* 240MHz 下约 1ms */
while (i--) __NOP();
}
/* DIO 引脚切换为输出模式(推挽) */
static void TM1617_DIO_Output(void)
{
gpio_init_type g;
gpio_default_para_init(&g);
g.gpio_mode = GPIO_MODE_OUTPUT;
g.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
g.gpio_pull = GPIO_PULL_NONE;
g.gpio_pins = DIO_PIN;
gpio_init(DIO_PORT, &g);
}
/* DIO 引脚切换为输入模式(读按键) */
static void TM1617_DIO_Input(void)
{
gpio_init_type g;
gpio_default_para_init(&g);
g.gpio_mode = GPIO_MODE_INPUT;
g.gpio_pull = GPIO_PULL_NONE;
g.gpio_pins = DIO_PIN;
gpio_init(DIO_PORT, &g);
}
/* GPIO初始化 */
void TM1617_GPIO_Init(void)
{
gpio_init_type g;
/* 使能 GPIOB / GPIOC 时钟 */
crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);
crm_periph_clock_enable(CRM_GPIOC_PERIPH_CLOCK, TRUE);
/* CLK(PB0)、STB(PC15)、DIO(PC4):推挽输出,初始拉高 */
gpio_default_para_init(&g);
g.gpio_mode = GPIO_MODE_OUTPUT;
g.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
g.gpio_pull = GPIO_PULL_NONE;
g.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE;
g.gpio_pins = CLK_PIN;
gpio_init(CLK_PORT, &g);
g.gpio_pins = STB_PIN;
gpio_init(STB_PORT, &g);
g.gpio_pins = DIO_PIN;
gpio_init(DIO_PORT, &g);
TM1617_CLK_H();
TM1617_STB_H();
TM1617_DIO_H();
}
/* 读取1字节数据STB已拉低CLK上升沿读 */
uint8_t TM1617_ReadByte(void)
{
uint8_t i, data = 0;
TM1617_DIO_Input();
for (i = 0; i < 8; i++)
{
data >>= 1; // 低位先收,右移占位
TM1617_CLK_L();
TM1617_Delay1us();
// 时钟上升沿读数据
TM1617_CLK_H();
if (gpio_input_data_bit_read(DIO_PORT, DIO_PIN) == SET)
{
data |= 0x80; // 最高位置1
}
TM1617_Delay1us();
}
TM1617_DIO_Output();
return data;
}
/* TM1617写1字节数据低位先行CLK上升沿锁存 */
void TM1617_WriteByte(uint8_t data)
{
uint8_t i;
for (i = 0; i < 8; i++)
{
TM1617_CLK_L();
TM1617_Delay1us();
// DIO写当前bit低位先行
if (data & 0x01) TM1617_DIO_H();
else TM1617_DIO_L();
TM1617_Delay1us();
// CLK拉高锁存数据
TM1617_CLK_H();
TM1617_Delay1us();
data >>= 1;
}
}
/* TM1617上电清零避免显示乱码必须执行 */
void TM1617_Clear(void)
{
TM1617_STB_L();
TM1617_Delay1us();
TM1617_WriteByte(0x40); // 写数据+地址自动增加
TM1617_WriteByte(0xC0); // 起始地址 C0H
for (uint8_t i = 0; i < 6; i++)
{
TM1617_WriteByte(0x00); // 6个显存地址清零
}
TM1617_STB_H();
TM1617_Delay1us();
}
/* TM1617初始化设置显示模式+初始辉度) */
void TM1617_Init(void)
{
TM1617_GPIO_Init(); /* 必须先配引脚/时钟,否则 CLK/STB/DIO 浮空,灯不亮 */
TM1617_Clear();
TM1617_Delay1ms();
// 配置显示模式3位7段指令0x03
TM1617_STB_L();
TM1617_Delay1us();
TM1617_WriteByte(0x03);
TM1617_STB_H();
TM1617_Delay1us();
// 配置初始辉度最高0x8F
TM1617_STB_L();
TM1617_Delay1us();
TM1617_WriteByte(0x8F);
TM1617_STB_H();
TM1617_Delay1us();
}
/* 设置RGB颜色+辉度brightness0~7对应8级PWM */
void TM1617_SetRGB(uint8_t color, uint8_t brightness)
{
if (brightness > 7) brightness = 7;
// 写颜色数据(地址自动增加模式)
TM1617_STB_L();
TM1617_Delay1us();
TM1617_WriteByte(0x40); // 数据命令:写数据+地址自增
TM1617_WriteByte(0xC0); // 起始地址 C0H
TM1617_WriteByte(color); // RGB颜色数据
TM1617_STB_H();
TM1617_Delay1us();
// 写辉度命令
TM1617_STB_L();
TM1617_Delay1us();
TM1617_WriteByte(0x88 + brightness); // 辉度指令 0x88~0x8F
TM1617_STB_H();
TM1617_Delay1us();
}
/* 按键扫描函数返回SEG5~SEG8对应按键状态 */
KeyStatusTypeDef TM1617_ScanFkey(void)
{
uint8_t keyData[5] = {0};
KeyStatusTypeDef keyState = KEY_NULL;
TM1617_STB_L();
TM1617_Delay1us();
TM1617_WriteByte(0x42); // 读键数据命令
TM1617_Delay1us();
// 按顺序读取5字节数据
keyData[0] = TM1617_ReadByte(); // BYTE1
keyData[1] = TM1617_ReadByte(); // BYTE2
keyData[2] = TM1617_ReadByte(); // BYTE3SEG5、SEG6
keyData[3] = TM1617_ReadByte(); // BYTE4SEG7、SEG8
keyData[4] = TM1617_ReadByte(); // BYTE5
TM1617_STB_H();
TM1617_Delay1us();
// 解析SEG5~SEG8对应按键按下为1
if (keyData[2] & 0x01)
{
keyState = KEY_MAIN_A;
}
else if (keyData[2] & 0x08)
{
keyState = KEY_MAIN_B;
}
else if (keyData[3] & 0x01)
{
keyState = KEY_MAIN_C;
}
else if (keyData[3] & 0x08)
{
keyState = KEY_MAIN_D;
}
return keyState;
}
/* RGB呼吸流转 */
void RGB_Breath_Flow(void)
{
static uint8_t brightness;
// 吸气:暗→亮
for (brightness = 0; brightness < 8; brightness++)
{
TM1617_SetRGB(rgb_color_seq[color_idx], brightness);
TM1617_Delay1ms();
// 近似 100ms
for (volatile uint32_t k = 0; k < 100; k++) TM1617_Delay1ms();
}
// 呼气:亮→暗
for (brightness = 7; brightness > 0; brightness--)
{
TM1617_SetRGB(rgb_color_seq[color_idx], brightness);
TM1617_Delay1ms();
for (volatile uint32_t k = 0; k < 100; k++) TM1617_Delay1ms();
}
// 切换下一种颜色
color_idx = (color_idx + 1) % 7;
}
/* 最小化测试让RGB灯常亮白色最高辉度 */
void RGB_Test_On(uint8_t u8Color)
{
TM1617_Clear();
TM1617_Delay1ms();
// 配置显示模式
TM1617_STB_L();
TM1617_Delay1us();
TM1617_WriteByte(0x03);
TM1617_STB_H();
TM1617_Delay1us();
// 写颜色数据到 C0H
TM1617_STB_L();
TM1617_Delay1us();
TM1617_WriteByte(0x40);
TM1617_WriteByte(0xC0);
TM1617_WriteByte(u8Color);
TM1617_STB_H();
TM1617_Delay1us();
// 配置最高辉度
TM1617_STB_L();
TM1617_Delay1us();
TM1617_WriteByte(0x8F);
TM1617_STB_H();
TM1617_Delay1us();
// 保持
for (volatile uint32_t k = 0; k < 500; k++) TM1617_Delay1ms();
}