先看效果:
下载安装e2后安装FSP后即可新建项目:
选择匹配的芯片类型:RA4E2
选择默认选项
选择无RTOS模式:
选择默认即可:
新建文件夹:放ws2812驱动底层代码
文件夹分别是C文件和H文件
bsp_ws2812LED.c代码
/*
* ws2812.c
*
* Created on: 2023年10月31日
* Author: Administrator
*/
#include"bsp_ws2812LED.h"
#include"hal_data.h"
externfsp_err_t err ;
externvolatile bool g_transfer_complete ;
//灯条显存SPI数据缓存
uint8_t gWs2812bDat_SPI[WS2812B_AMOUNT *24+88]={0};
//灯条显存
tWs2812bCache_TypeDef gWs2812bDat[WS2812B_AMOUNT]={
//R G B
0XFF,0X00,0X00,//0
0X00,0XFF,0X00,//1
0X00,0X00,0XFF,//2
0X00,0XFF,0XFF,//3
0XFF,0X00,0XFF,//4
0XFF,0XFF,0X00,//5
0XFF,0XFF,0XFF,//6
0X0F,0X0F,0X0F,//7
0XFF,0X00,0X00,//0
0X00,0XFF,0X00,//1
0X00,0X00,0XFF,//2
0X00,0XFF,0XFF,//3
0XFF,0X00,0XFF,//4
0XFF,0XFF,0X00,//5
0XFF,0XFF,0XFF,//6
0X0F,0X0F,0X0F,//7
};
voidWS2812b_Set(uint16_tWs2b812b_NUM,uint8_tr,uint8_tg,uint8_tb)
{
uint8_t*pR=&gWs2812bDat_SPI[88+(Ws2b812b_NUM)*24+8];
uint8_t*pG=&gWs2812bDat_SPI[88+(Ws2b812b_NUM)*24];
uint8_t*pB=&gWs2812bDat_SPI[88+(Ws2b812b_NUM)*24+16];
for(uint8_ti=0;i<8;i++){
if(g&0x80){
*pG= CODE_1;
}
else{
*pG= CODE_0;
}
if(r&0x80){
*pR= CODE_1;
}
else{
*pR= CODE_0;
}
if(b&0x80){
*pB= CODE_1;
}
else{
*pB= CODE_0;
}
r<<=1;
g<<=1;
b<<=1;
pR++;
pG++;
pB++;
}
}
voidWS2812B_Task(void)
{
uint8_tdat=0;
for(inti=0;i<88;i++)
{
gWs2812bDat_SPI[i]=0;
}
//将gWs2812bDat数据解析成SPI数据
for(uint8_tiLED=0;iLED< WS2812B_AMOUNT;iLED++)
{
WS2812b_Set(iLED, gWs2812bDat[iLED].R, gWs2812bDat[iLED].G, gWs2812bDat[iLED].B);
}
//总线输出数据
/* Send the reset command */
g_transfer_complete = false;
err =R_SCI_SPI_Write(&g_spi0_ctrl, gWs2812bDat_SPI,sizeof(gWs2812bDat_SPI),SPI_BIT_WIDTH_8_BITS);
assert(FSP_SUCCESS== err);
/* Wait for SPI_EVENT_TRANSFER_COMPLETE callback event. */
while( g_transfer_complete==false)
{
;
}
// //使总线输出低电平
// g_transfer_complete = false;
// err = R_SCI_SPI_Write(&g_spi0_ctrl, dat, 1, SPI_BIT_WIDTH_8_BITS);
// assert(FSP_SUCCESS == err);
// /* Wait for SPI_EVENT_TRANSFER_COMPLETE callback event. */
// while ( g_transfer_complete==false)
// {
// ;
// }
//帧信号:一个大于50us的低电平
R_BSP_SoftwareDelay(1,BSP_DELAY_UNITS_MILLISECONDS);
}
bsp_ws2812LED.h代码
#ifndef BSP_WS2812LED_H_
#defineBSP_WS2812LED_H_
#include<stdint.h>
// 编码 0 : 11000000
#defineCODE_0 0xc0
// 编码 1 : 11111000
#defineCODE_1 0xF8
/*ws2812b灯珠数量*/
#defineWS2812B_AMOUNT 16
typedefstruct
{
uint8_tR;
uint8_tG;
uint8_tB;
}tWs2812bCache_TypeDef;
externtWs2812bCache_TypeDef gWs2812bDat[WS2812B_AMOUNT];
voidWS2812b_Set(uint16_tWs2b812b_NUM,uint8_tr,uint8_tg,uint8_tb);
voidWS2812B_Task(void);
#endif/* WS2812_H_ */
hal.entry.c文件
#include"hal_data.h"
#include"ws2812LED/bsp_ws2812LED.h"
FSP_CPP_HEADER
voidR_BSP_WarmStart(bsp_warm_start_event_tevent);
FSP_CPP_FOOTER
fsp_err_t err =FSP_SUCCESS;
volatile bool g_transfer_complete = false;
voidsci_spi_callback(spi_callback_args_t*p_args)
{
if(SPI_EVENT_TRANSFER_COMPLETE==p_args->event)
{
g_transfer_complete = true;
}
}
externtWs2812bCache_TypeDef gWs2812bDat[WS2812B_AMOUNT];
voidmove_Front()
{
uint8_ti;
uint8_ttemp[3];
temp[0]= gWs2812bDat[0].R;
temp[1]= gWs2812bDat[0].G;
temp[2]= gWs2812bDat[0].B;
for(i=0;i< WS2812B_AMOUNT-1;i++)
{
gWs2812bDat[i].R= gWs2812bDat[i+1].R;
gWs2812bDat[i].G= gWs2812bDat[i+1].G;
gWs2812bDat[i].B= gWs2812bDat[i+1].B;
}
gWs2812bDat[15].R=temp[0];
gWs2812bDat[15].G=temp[1];
gWs2812bDat[15].B=temp[2];
}
/*******************************************************************************************************************//**
* main() is generated by the RA Configuration editor and is used to generate threads if an RTOS is used. This function
* is called by main() when no RTOS is used.
**********************************************************************************************************************/
voidhal_entry(void)
{
/* TODO: add your own code here */
err =R_SCI_SPI_Open(&g_spi0_ctrl,&g_spi0_cfg);
assert(FSP_SUCCESS== err);
sci_spi_extended_cfg_tsci_spi_extended_cfg_t1;
WS2812B_Task();
R_BSP_SoftwareDelay(1,BSP_DELAY_UNITS_MILLISECONDS);
while(1)
{
WS2812B_Task();
move_Front();
R_BSP_SoftwareDelay(100,BSP_DELAY_UNITS_MILLISECONDS);
}
#if BSP_TZ_SECURE_BUILD
/* Enter non-secure code */
R_BSP_NonSecureEnter();
#endif
}
/*******************************************************************************************************************//**
* This function is called at various points during the startup process. This implementation uses the event that is
* called right before main() to set up the pins.
*
* @param[in] event Where at in the start up process the code is currently at
**********************************************************************************************************************/
voidR_BSP_WarmStart(bsp_warm_start_event_tevent)
{
if(BSP_WARM_START_RESET==event)
{
#if BSP_FEATURE_FLASH_LP_VERSION != 0
/* Enable reading from data flash. */
R_FACI_LP->DFLCTL =1U;
/* Would normally have to wait tDSTOP(6us) for data flash recovery. Placing the enable here, before clock and
* C runtime initialization, should negate the need for a delay since the initialization will typically take more than 6us. */
#endif
}
if(BSP_WARM_START_POST_C==event)
{
/* C runtime environment and system clocks are setup. */
/* Configure pins. */
R_IOPORT_Open(&g_ioport_ctrl, g_ioport.p_cfg);
}
}
#if BSP_TZ_SECURE_BUILD
FSP_CPP_HEADER
BSP_CMSE_NONSECURE_ENTRY void template_nonsecure_callable ();
/* Trustzone Secure Projects require at least one nonsecurecallable function in order to build (Remove this if it is not required to build). */
BSP_CMSE_NONSECURE_ENTRY void template_nonsecure_callable ()
{
}
FSP_CPP_FOOTER
#endif
新建SPI配置参数:
配置相关参数与引脚;
配置引脚参数:
采用内置时钟配置:
点击生成相关代码:
编译生成代码:
效果演示:
参考来源:
1.https://blog.csdn.net/qq_24312945/article/details/134152211
更多回帖