gd32e230c8t6 驱动ws2812
单片机PA8口接ws2812的DI
keil工程
main.c代码
#include "gd32e23x.h"
#include "systick.h"
#include <stdio.h>
#define ws2812_led_quantity 8//ws2812数量
#define WS2812_GPIO GPIOA //ws2812 gpiox
#define WS2812_GPIO_PIN GPIO_PIN_8 //ws2812 gpio pin/* bit[23:16] Green 绿色,bit[15:8]Red 红色, bit[7:0]Blue 蓝色*/
// 颜色常量定义(按bit[23:16]=Green, bit[15:8]=Red, bit[7:0]=Blue)
#define white 0xFFFFFF // 白色 = 绿255 + 红255 + 蓝255
#define red 0x00FF00 // 红色 = 绿0 + 红255 + 蓝0
#define green 0xFF0000 // 绿色 = 绿255 + 红0 + 蓝0
#define blue 0x0000FF // 蓝色 = 绿0 + 红0 + 蓝255
#define yellow 0xFFFF00 // 黄色 = 绿255 + 红255 + 蓝0
#define purple 0x00FFFF // 紫色 = 绿0 + 红255 + 蓝255
#define cyan 0xFF00FF // 青色 = 绿255 + 红0 + 蓝255#define gray 0x808080 // 灰色(50%亮度)
#define silver 0xC0C0C0 // 银色(75%亮度)
#define darkgray 0x404040 // 深灰色(25%亮度)// 彩虹色系
#define orange 0xFD7F00 // 橙色
#define lime 0x80FF00 // 酸橙绿
#define skyblue 0x007FFF // 天蓝色
#define pink 0x00FFAF // 粉色
#define magenta 0x00FFFF // 洋红色
#define indigo 0x004080 // 靛蓝色
#define violet 0x400080 // 紫罗兰色// 金属色系
#define gold 0xFD9F00 // 金色
#define bronze 0x805500 // 青铜色
#define copper 0x996633 // 铜色
#define platinum 0xE5E4E2 // 铂金色
#define steelblue 0x4682B4 // 钢蓝色// 自然色系
#define forest 0x228B22 // 森林绿
#define ocean 0x0066CC // 海洋蓝
#define sunset 0xFF3300 // 日落橙
#define lavender 0xB57EDC // 薰衣草紫
#define chocolate 0xD2691E // 巧克力棕
#define maroon 0x800000 // 栗色
#define olive 0x808000 // 橄榄绿// 特殊效果
#define dimwhite 0x333333 // 暗白色(10%亮度)
#define flashgreen 0xAAFFAA // 闪烁绿(脉冲效果)
#define pulseblue 0x0055FF // 脉冲蓝(呼吸灯效果)void led_config(){rcu_periph_clock_enable(RCU_GPIOC);gpio_mode_set(GPIOC, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_13);gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, GPIO_PIN_13);gpio_bit_set(GPIOC,GPIO_PIN_13);}void nopdelay50ns(uint32_t n){//延时不准
while(n--){
__NOP();
}}void ws2812_io_init(uint32_t gpio_periph,uint32_t pin){switch(gpio_periph) {case GPIOA:rcu_periph_clock_enable(RCU_GPIOA);break;case GPIOB:rcu_periph_clock_enable(RCU_GPIOB);break;case GPIOC:rcu_periph_clock_enable(RCU_GPIOC);break;case GPIOF:rcu_periph_clock_enable(RCU_GPIOF);break;default:/* 处理无效参数 */break;}gpio_mode_set(gpio_periph, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE,pin);gpio_output_options_set(gpio_periph, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,pin);gpio_bit_reset(gpio_periph,pin);}void ws2812_11(){//延时不准,弃用
gpio_bit_set(WS2812_GPIO,WS2812_GPIO_PIN);nopdelay50ns(12);//约600nsgpio_bit_reset(WS2812_GPIO,WS2812_GPIO_PIN);nopdelay50ns(6);//约300ns}
void ws2812_00(){//延时不准,弃用gpio_bit_set(WS2812_GPIO,WS2812_GPIO_PIN);nopdelay50ns(6);//约300nsgpio_bit_reset(WS2812_GPIO,WS2812_GPIO_PIN);nopdelay50ns(12);//约600ns}void ws2812_1(){
gpio_bit_set(WS2812_GPIO,WS2812_GPIO_PIN);__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();gpio_bit_reset(WS2812_GPIO,WS2812_GPIO_PIN);__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();}
void ws2812_0(){gpio_bit_set(WS2812_GPIO,WS2812_GPIO_PIN);__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();gpio_bit_reset(WS2812_GPIO,WS2812_GPIO_PIN);__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();}void ws2812_res(){
gpio_bit_reset(WS2812_GPIO,WS2812_GPIO_PIN);nopdelay50ns(6000);//约400us}void ws2812_write(uint32_t data[ws2812_led_quantity]) {uint32_t d;uint8_t b;for (int a = 0; a < ws2812_led_quantity; a++) {d = data[a];// 从最高位(第23位)开始发送,到最低位(第0位)for (b = 24; b > 0; b--) {if (d & 0x800000) { // 检查最高位是否为1ws2812_1();} else {ws2812_0();}d <<= 1; // 左移一位,准备发送下一位}}ws2812_res(); // 发送完所有数据后,发送复位信号
}uint32_t data1[ws2812_led_quantity],data2[ws2812_led_quantity],data3[ws2812_led_quantity];
uint32_t data4[ws2812_led_quantity]={red,blue,white,0x00ffaf,0xfd7f00,violet,0xe5e4e2,0x808000};
int main(void){led_config();systick_config();for(int i = 0; i < ws2812_led_quantity; i++) {data1[i] =blue;data2[i] =white;data3[i] =green;
}ws2812_io_init(WS2812_GPIO,WS2812_GPIO_PIN);//初始化ws2812 io口while(1){ws2812_write(data1);delay_1ms(500);gpio_bit_toggle(GPIOC,GPIO_PIN_13);ws2812_write(data2);delay_1ms(500);gpio_bit_toggle(GPIOC,GPIO_PIN_13);ws2812_write(data3);delay_1ms(500);gpio_bit_toggle(GPIOC,GPIO_PIN_13);ws2812_write(data4);delay_1ms(500);gpio_bit_toggle(GPIOC,GPIO_PIN_13);}}