Files
stc32g128k/App/rgb.c

85 lines
1.8 KiB
C
Raw Normal View History

#include "rgb.h"
/* ====== SPI 寄存器定义 (如果 stc32g.h 没定义) ====== */
#ifndef P_SW1
sfr P_SW1 = 0xA2;
sfr SPCTL = 0xCE;
sfr SPSTAT = 0xCD;
sfr SPDAT = 0xCF;
#endif
void SPI_Init(void)
{
P_SW1 = (P_SW1 & ~0x0C) | 0x04; // 映射 SPI 至第二组 (P2.2~P2.5)
SPCTL = 0xD1; // SSIG=1, SPEN=1, MSTR=1, SPR0=1 (3.0 MHz)
SPSTAT = 0xC0; // 清除标志
}
void Encode_Byte(u8 val, u8 *out)
{
u32 spi_val = 0;
u8 i;
for (i = 0; i < 8; i++)
{
spi_val <<= 3;
if (val & (0x80 >> i))
{
spi_val |= 6; // 1码 -> 110
}
else
{
spi_val |= 4; // 0码 -> 100
}
}
out[0] = (u8)(spi_val >> 16);
out[1] = (u8)(spi_val >> 8);
out[2] = (u8)spi_val;
}
void RGB_Send(u8 g1, u8 r1, u8 b1, u8 g2, u8 r2, u8 b2)
{
u8 idata spi_buf[18];
u8 i;
// 转码 3-bit 编码
Encode_Byte(g1, &spi_buf[0]);
Encode_Byte(r1, &spi_buf[3]);
Encode_Byte(b1, &spi_buf[6]);
Encode_Byte(g2, &spi_buf[9]);
Encode_Byte(r2, &spi_buf[12]);
Encode_Byte(b2, &spi_buf[15]);
EA = 0; // 关中断
// 临时将 P2.5 (MOTOR) 配置为高阻输入以隔离时钟信号
P2M1 |= (1 << 5);
P2M0 &= ~(1 << 5);
SPI_Init(); // 启动 SPI
for (i = 0; i < 18; i++)
{
SPDAT = spi_buf[i];
while (!(SPSTAT & 0x80)); // 等待发送完毕
SPSTAT = 0xC0;
}
SPCTL = 0; // 关闭 SPI
// 配置 P2.3 (RGB_DIN) 为推挽输出并拉低 100us 做 Reset
P2M1 &= ~(1 << 3);
P2M0 |= (1 << 3);
RGB_DIN = 0;
for (i = 0; i < 200; i++)
{
_nop_(); _nop_(); _nop_();
}
// 恢复 P2.5 (MOTOR) 为推挽输出以进行振动控制
P2M1 &= ~(1 << 5);
P2M0 |= (1 << 5);
MOTOR = 0;
EA = 1; // 开中断
}