/* * @Author: CTW * @Date: 2025-11-07 14:37:55 * @FilePath: \PhoenixSMGT_Testproject\Drivers\TM1617\Drv_TM1617_RGB.c * @note: 从 STM32 HAL 库移植到 AT32F403A,软件模拟时序(GPIO 位翻转) * - 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) /* 忙等延时:约 1us(NOP 循环,不依赖 SysTick/RTOS) */ static void TM1617_Delay1us(void) { volatile uint32_t i = 24; /* 240MHz 下约 1us,可实测微调 */ while (i--) __NOP(); } /* 忙等延时:约 1ms(NOP 循环) */ 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颜色+辉度(brightness:0~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(); // BYTE3(SEG5、SEG6) keyData[3] = TM1617_ReadByte(); // BYTE4(SEG7、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(); }