定义灯珠数量、0码、1码
#define Pixel_S1_NUM 1 //灯珠 RGB数量
#define CODE0 0xC0 // 0码, 发送的时间 1100 0000 根据不同的SCK适当调整
#define CODE1 0xFC // 1码, 发送的时间 1111 1100
typedef struct
{
uint8 R;
uint8 G;
uint8 B;
} RGBColor_TypeDef;
初始化SPI
void spi_cb(spi_evt_t* evt)
{
}
spi_Cfg_t spi_cfg =
{
.sclk_pin = GPIO_DUMMY,//CLK引脚配置
.ssn_pin = GPIO_DUMMY,//cs引脚配置
.MOSI = GPIO_P24,//MOSI引脚配置
.MISO = GPIO_DUMMY,//MISO引脚配置
.baudrate = 8000000,//设置波特率
// .baudrate = 4571429,//设置波特率 感觉这个设置没有啥用 低于4571429这个值才有点作用,而且会跳变
.spi_tmod = SPI_TXD,//SPI 使用场景
.spi_scmod = SPI_MODE0,//SPI 工作模式。
.spi_dfsmod = SPI_1BYTE,
.int_mode = false,
.force_cs = true,
.evt_handler = spi_cb,
};
void WS2812b_Configuration(void)
{
uint8_t retval = PPlus_SUCCESS;
retval = hal_spi_bus_init(&spiflash_spi,spi_cfg);
if(retval != PPlus_SUCCESS)
{
LOG("spi init err!please check it!\n");
return ;
}
}
设置灯的颜色
void rgb_SetColor(uint8 LedId, RGBColor_TypeDef Color){
uint8 i;
if( LedId > ( Pixel_S1_NUM ) ){
LOG("Error:Out of Range!\r\n");
return; //to avoid overflow
}
for(i=0;i<=7;i++){
pixelBuffer[LedId][i]= ( (Color.G & (1 << (7 -i)) )? (CODE1):CODE0 );
pixelBuffer[LedId][i+8]= ( (Color.R & (1 << (7-i)) )? (CODE1):CODE0 );
pixelBuffer[LedId][i+16]= ( (Color.B & (1 << (7-i)) )? (CODE1):CODE0 );
}
}
发送数据
void spi_tx_buf(hal_spi_t* spi_ptr,uint8_t* tx_buf,uint16_t tx_len)
{
AP_SSI_TypeDef* Ssix = NULL;
Ssix = (spi_ptr->spi_index == SPI0) ? AP_SPI0 : AP_SPI1;
for(uint16_t i=0;i<tx_len;i++)
{
Ssix->DataReg = tx_buf[i];
}
}
void rgb_SendArray(void){
spi_tx_buf(&spiflash_spi,pixelBuffer[0],24);
}
1、遇到的问题,有时候灯的颜色不对,逻辑分析仪抓取波形发现每发送8个字节会有一个延时,因为刚开始直接采用官方封装的函数。
#define spiflash_cmd_tx_and_rx(mode,tx_buf,rx_buf,tx_len,rx_len) \
hal_spi_transmit(&spiflash_spi,mode,tx_buf,rx_buf,tx_len,rx_len)
换成下面的函数就可以了
void spi_tx_buf(hal_spi_t* spi_ptr,uint8_t* tx_buf,uint16_t tx_len)
{
AP_SSI_TypeDef* Ssix = NULL;
Ssix = (spi_ptr->spi_index == SPI0) ? AP_SPI0 : AP_SPI1;
for(uint16_t i=0;i<tx_len;i++)
{
Ssix->DataReg = tx_buf[i];
}
}
控制一个灯是可以的,多个灯没有测试。