杰理-701-单线灯-ws2812-驱动
LED_gradual_open(); //调用后 呼吸灯
set_led_colour(R,G,B);//具体颜色
spi_dma_set_addr_for_isr //spi 配置dma 后灯才亮
#define LED_H 0x7c
#define LED_L 0x40
发送高位和地位的字节,具体使用逻辑分析仪配合灯的时序调试
spi 时钟修改
开机初始化spi
makefile添加led_spi.c
IO口高低电平输出,若没有led电源没有控制,则忽略
void user_set_gpio(u32 gpio, bool level)
{gpio_set_pull_down(gpio, 0);gpio_set_pull_up(gpio, 0);gpio_set_die(gpio, 1);gpio_set_hd(gpio, 0);//看需求是否需要开启强推,会导致芯片功耗大gpio_set_hd0(gpio, 0);gpio_set_direction(gpio, 0);gpio_set_output_value(gpio, level); //1高0低
}
#include "system/includes.h"
#include "app_config.h"
#include "asm/spi.h"#if G_log_total#if 1#define G_log(format, ...) printf("->>>--- GZH ---<<<-" format "\r\n", ## __VA_ARGS__)#else#define G_log(...)#endif
#else#define G_log(...)
#endif#if SINGLE_LEDstatic const u8 SPI1_DO[2] = {IO_PORTB_01,//'A'IO_PORTC_05 //'B'
};
static const u8 SPI2_DO[2] = {IO_PORTB_10,//'A'IO_PORT_DM //'B'
};
#define LED_SPI JL_SPI2
#define LED_SPI_PORT 'A'
#define LED_SPI_DAT_BAUD 8000000
#define LED_SPI_REST_BAUD 1000000
#define LED_SPI_CLOCK_BASE clk_get("lsb")static OS_SEM led_spi_sem;
static u32 spi_do = 0;
static u8 led_spi_busy = 0;
static u8 led_spi_sus = 0;void user_led_spi_test(void);___interrupt
void led_spi_isr()
{LED_SPI->CON &= ~BIT(13); //关闭中断LED_SPI->CON |= BIT(14); //清pndingos_sem_post(&led_spi_sem);led_spi_busy = 0;
}void led_spi_init(void)
{if ((u32)LED_SPI == (u32)JL_SPI1) {// spi_do = SPI1_DO[LED_SPI_PORT - 'A'];SFR(JL_IOMAP->OCH_CON1, 4, 1, LED_SPI_PORT - 'A');request_irq(IRQ_SPI1_IDX, 0, led_spi_isr, 0);} else {// spi_do = SPI2_DO[LED_SPI_PORT - 'A'];SFR(JL_IOMAP->OCH_CON1, 5, 1, LED_SPI_PORT - 'A');request_irq(IRQ_SPI2_IDX, 0, led_spi_isr, 0);}gpio_set_die(TCFG_HW_SPI2_PORT_DO, 1);gpio_set_direction(TCFG_HW_SPI2_PORT_DO, 0);gpio_set_pull_up(TCFG_HW_SPI2_PORT_DO, 0);gpio_set_pull_down(TCFG_HW_SPI2_PORT_DO, 0);gpio_write(TCFG_HW_SPI2_PORT_DO, 0);os_sem_create(&led_spi_sem, 1);LED_SPI->CON = 0x4021;
}void led_spi_rgb_to_24byte(u8 r, u8 g, u8 b, u8 *buf, int idx)
{buf = buf + idx * 24;u32 dat = ((g << 16) | (r << 8) | b);for (u8 i = 0; i < 24; i ++) {if (dat & BIT(23 - i)) {*(buf + i) = 0x7c;} else {*(buf + i) = 0x60;}}
}void led_spi_rest()
{u8 tmp_buf[16] = {0};LED_SPI->BAUD = LED_SPI_CLOCK_BASE / LED_SPI_REST_BAUD - 1;LED_SPI->CON |= BIT(14);LED_SPI->ADR = (u32)tmp_buf;LED_SPI->CNT = 16;while (!(LED_SPI->CON & BIT(15)));LED_SPI->CON |= BIT(14);
}void led_spi_send_rgbbuf(u8 *rgb_buf, u16 led_num) //rgb_buf的大小 至少要等于 led_num * 24
{if (!led_num) {return;}while (led_spi_sus) {os_time_dly(1);}led_spi_busy = 1;// led_spi_rest();LED_SPI->BAUD = LED_SPI_CLOCK_BASE / LED_SPI_DAT_BAUD - 1;LED_SPI->CON |= BIT(14);LED_SPI->ADR = (u32)rgb_buf;LED_SPI->CNT = led_num * 24;while (!(LED_SPI->CON & BIT(15)));LED_SPI->CON |= BIT(14);led_spi_busy = 0;
}void led_spi_send_rgbbuf_isr(u8 *rgb_buf, u16 led_num) //rgb_buf的大小 至少要等于 led_num * 24
{if (!led_num) {return;}while (led_spi_sus) {os_time_dly(1);}led_spi_busy = 1;os_sem_pend(&led_spi_sem, 0);led_spi_rest();LED_SPI->BAUD = LED_SPI_CLOCK_BASE / LED_SPI_DAT_BAUD - 1;LED_SPI->CON |= BIT(14);LED_SPI->ADR = (u32)rgb_buf;LED_SPI->CNT = led_num * 24;LED_SPI->CON |= BIT(13);//打开中断
}u8 led_spi_suspend(void)
{if (led_spi_sus) {return 1;}if (led_spi_busy) {return 1;}LED_SPI->CON |= BIT(14);LED_SPI->CON &= ~BIT(0);led_spi_sus = 1;return 0;
}u8 led_spi_resume(void)
{if (!led_spi_sus) {return 0;}gpio_set_die(TCFG_HW_SPI2_PORT_DO, 1);gpio_set_direction(TCFG_HW_SPI2_PORT_DO, 0);gpio_set_pull_up(TCFG_HW_SPI2_PORT_DO, 0);gpio_set_pull_down(TCFG_HW_SPI2_PORT_DO, 0);gpio_write(TCFG_HW_SPI2_PORT_DO, 0);LED_SPI->CON = 0x4021;led_spi_sus = 0;return 0;
}// static u8 spi_dat_buf[24 * 20] __attribute__((aligned(4)));#define LED_NUM 12
#define LED_H 0x7c
#define LED_L 0x40u8 spi_dat_buf[24*LED_NUM] = {0};//设置全部灯的颜色
void set_led_colour(u8 red, u8 green, u8 blue)
{printf(" red = %d green = %d blue = %d ",red,green,blue);
#if 1for(u8 i=0;i<LED_NUM;i++){for(u8 j=0;j<8;j++){spi_dat_buf[(i*24)+j] = (green & BIT(7-j)) ? LED_H : LED_L;}for(u8 j=0;j<8;j++){spi_dat_buf[(i*24)+j+8] = (red & BIT(7-j)) ? LED_H : LED_L;}for(u8 j=0;j<8;j++){spi_dat_buf[(i*24)+j+16] = (blue & BIT(7-j)) ? LED_H : LED_L;}}
#endif// put_buf(spi_dat_buf,sizeof(spi_dat_buf));
}extern void wdt_clear();void user_led_spi_test(void)
{printf("****************** led spi test *******************\n");u8 spi_pro=SPI2;spi_open(spi_pro);u8 cnt = 0;u8 pulse = 0;// local_irq_disable();// memset(spi_dat_buf,LED_L,sizeof(spi_dat_buf));// while (1) {// cnt ++;// led_spi_rgb_to_24byte(cnt, 255 - cnt, 0, spi_dat_buf, 0);// led_spi_rgb_to_24byte(0, 0, cnt, spi_dat_buf, 1);
#if 0spi_dma_send(spi_pro,spi_dat_buf, sizeof(spi_dat_buf)); //等待的方式,建议用在发的数据量小的场合
#elsespi_dma_set_addr_for_isr(spi_pro,spi_dat_buf, 24*LED_NUM,0); //中断的方式,建议用在发的数据量大的场合
#endifprintf(" ----- ");os_time_dly(50);wdt_clear();}
}void led_spi_test(void)
{user_led_spi_test();printf("****************** led spi test *******************\n");led_spi_init();u8 cnt = 0;u8 pulse = 0;// local_irq_disable();while (1) {// cnt ++;// led_spi_rgb_to_24byte(cnt, 255 - cnt, 0, spi_dat_buf, 0);// led_spi_rgb_to_24byte(0, 0, cnt, spi_dat_buf, 1);
#if 0led_spi_send_rgbbuf(spi_dat_buf, sizeof(spi_dat_buf)); //等待的方式,建议用在发的数据量小的场合
#elseled_spi_send_rgbbuf_isr(spi_dat_buf, sizeof(spi_dat_buf)); //中断的方式,建议用在发的数据量大的场合
#endifprintf(" +++++ ");os_time_dly(50);wdt_clear();}
}#define HIGT_BRIGHT 150
#define LOW_BRIGHT 0
#define HIGT_STEP 10static u16 gradual_timer = 0;
static int colour[3] = {0};
static u8 type = 0;void gradual_timer_func(void)
{ // G_log(" 0 type = %d R = %d G = %d B = %d ",type,colour[0],colour[2],colour[2]);user_set_gpio(IO_PORTB_06,0);switch(type){case 0:colour[0] += HIGT_STEP;colour[1] = 0;colour[2] = 0;if(colour[0] >= HIGT_BRIGHT ){type = 1;colour[0] = HIGT_BRIGHT;}break;case 1:colour[0] -= HIGT_STEP;colour[1] = 0;colour[2] = 0;if(colour[0] <= LOW_BRIGHT ){type = 2;}break;case 2:colour[0] = 0;colour[1] += HIGT_STEP;colour[2] = 0;if(colour[1] >= HIGT_BRIGHT ){type = 3;colour[1] = HIGT_BRIGHT;}break;case 3:colour[0] = 0;colour[1] -= HIGT_STEP;colour[2] = 0;if(colour[1] <= LOW_BRIGHT ){type = 4;}break;case 4:colour[0] = 0;colour[1] = 0;colour[2] += HIGT_STEP;if(colour[2] >= HIGT_BRIGHT ){colour[2] = HIGT_BRIGHT;type = 5;}break;case 5:colour[0] = 0;colour[1] = 0;colour[2] -= HIGT_STEP;if(colour[2] <= LOW_BRIGHT ){type = 0;}break;}// G_log(" 1 type = %d R = %d G = %d B = %d ",type,colour[0],colour[2],colour[2]);set_led_colour(colour[0],colour[1],colour[2]);// user_led_spi_test();spi_dma_set_addr_for_isr(SPI2,spi_dat_buf, 24*LED_NUM,0);
}void LED_gradual_close(void)
{user_set_gpio(IO_PORTB_06,1);if(gradual_timer){sys_timer_del(gradual_timer);gradual_timer = 0;}set_led_colour(0,0,0);spi_dma_set_addr_for_isr(SPI2,spi_dat_buf, 24*LED_NUM,0);memset(colour,0,sizeof(colour));type = 0;
}void LED_gradual_open(void)
{LED_gradual_close();if(!gradual_timer){gradual_timer = sys_timer_add(NULL,gradual_timer_func,50);}}#endif