PHY6222(6252)通过SPI控制WS2812

 定义灯珠数量、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];
    }
}

控制一个灯是可以的,多个灯没有测试。

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值