LEDC代码驱动

针对CH585的LEDC接口驱动ws2812点灯测试

#include "CH58x_common.h"
#include "ch58x_drv_ledc.h"

#define  led_num        3*1
#define  breadthe       1
#if !breadthe
__attribute__((__aligned__(4))) uint8_t SPI_Tx_Buffer[] = {
        0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,  // G - 0x01
        0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,  // R - 0x00
        0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,  // B - 0x00

        0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,  // G - 0x00
        0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,  // R - 0x01
        0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,  // B - 0x00

        0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,  // G - 0x00
        0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,  // R - 0x00
        0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,  // B - 0x01
};
#endif
#define  LSB_HSB         0           // LED串行数据位序, 1:高位在前;  0:低位在前
#define  POLAR           0           // LED数据输出极性, 0:直通,数据0输出0,数据1输出1; 1为反相

#define WS2812_BUFFER_SIZE 24  // R/G/B各8字节
uint8_t ws2812_buffer[WS2812_BUFFER_SIZE];  // 总缓冲区:R[0-7], G[8-15], B[16-23]
void gray_to_red_array(uint8_t gray) {
    for (int i = 0; i < 8; i++) {
        ws2812_buffer[i] = (gray & (0x80 >> i)) ? 0x0f : 0x03;
    }
}

__HIGH_CODE
void ch58x_led_controller_send_TEST(uint32_t *data, uint16_t length)
{
    R32_LED_DMA_BEG = ((uint32_t)(data) & RB_LED_DMA_BEG);
    R16_LED_DMA_LEN = length;
    R8_LED_CTRL_MOD |= RB_LED_DMA_EN;
}

void DebugInit(void)
{
    GPIOA_SetBits(GPIO_Pin_14);
    GPIOPinRemap(ENABLE, RB_PIN_UART0);
    GPIOA_ModeCfg(GPIO_Pin_15, GPIO_ModeIN_PU);
    GPIOA_ModeCfg(GPIO_Pin_14, GPIO_ModeOut_PP_5mA);
    UART0_DefInit();
}

int main()
{
    uint32_t breath_counter = 0;

    HSECFG_Capacitance(HSECap_18p);
    SetSysClock(CLK_SOURCE_HSE_PLL_78MHz);
    /* 配置串口调试 */
    DebugInit();
    PRINT( "Start @ChipID=%02X\n", R8_CHIP_ID );
    {
        GPIOB_ResetBits(GPIO_Pin_0|GPIO_Pin_1);
        GPIOB_ModeCfg( GPIO_Pin_0|GPIO_Pin_1, GPIO_ModeOut_PP_5mA );
    }
    //led clk
    GPIOA_ResetBits(GPIO_Pin_4);
    GPIOA_ModeCfg( GPIO_Pin_4, GPIO_ModeOut_PP_5mA );
    //led data  //LED 0-7
    GPIOA_ResetBits(GPIO_Pin_0);
    GPIOA_ModeCfg(GPIO_Pin_0, GPIO_ModeOut_PP_5mA );
//    GPIOA_ModeCfg(GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8, GPIO_ModeOut_PP_5mA );
    //配置分频和模式选择
    ch58x_led_controller_init(CH58X_LED_OUT_MODE_SINGLE, 12);//128);

    //开始发送,后面再发送就在中断里面发送了
//    R32_LED_DMA_BEG = ((uint32_t)(SPI_Tx_Buffer)& RB_LED_DMA_BEG);
//    R16_LED_DMA_LEN = 2*led_num;
//    R8_LED_CTRL_MOD |= RB_LED_DMA_EN;

#if LSB_HSB   //LSB HSB
    R8_LED_CTRL_MOD ^= RB_LED_BIT_ORDER;
#endif

#if POLAR     //极性
    R8_LED_CTRL_MOD ^= RB_LED_OUT_POLAR;
#endif

    LED_ENABLE();
    PFIC_EnableIRQ(LED_IRQn);

#if !breadthe
    while(1){
        ch58x_led_controller_send_TEST((uint32_t*)SPI_Tx_Buffer, 2*9);//定义u8,强转为u32,因此数组从8个元素变成了2个元素,所以长度传入2。
        mDelaymS(100);
    }
#else
    while(1){
        uint16_t pos = breath_counter % 512;
        if (pos > 255) pos = 511 - pos;
        uint8_t gray = (pos * pos) >> 8;
        gray_to_red_array(gray);
        ch58x_led_controller_send_TEST((uint32_t*)ws2812_buffer, 2*led_num);
        breath_counter++;
        DelayMs(10);  // 调整延时控制呼吸速度
    }
#endif
    while(1);
}

__INTERRUPT
__HIGH_CODE
void LED_IRQHandler(void){
    if((R16_LED_STATUS & RB_LED_LOAD_FAIL)){
        LED_ClearITFlag(RB_LED_IF_DMA_END); // 清除中断标志
#if 0
        GPIOB_SetBits(GPIO_Pin_1);
        uint16_t LED_status;
        LED_status = R16_LED_STATUS;
        R16_LED_STATUS = LED_status;
        R8_LED_CTRL_MOD &= ~RB_LED_DMA_EN;
        R8_LED_CTRL_MOD &= ~RB_LED_OUT_EN;
        GPIOA_ResetBits(GPIO_Pin_0);//手动拉低数据线,作为reset信号
        GPIOB_ResetBits(GPIO_Pin_1);
#endif
    }
}

 

posted @ 2025-03-01 09:56  SweetTea_lllpc  阅读(262)  评论(0)    收藏  举报