85 lines
1.8 KiB
C
85 lines
1.8 KiB
C
#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; // 开中断
|
|
}
|