利用stm32f103c8t6实现对WS2812的控制(从硬件出发)

发布于:2022-11-01 ⋅ 阅读:(1175) ⋅ 点赞:(0)

代码思路(IO翻转模拟时序方法)

目录

所用IO资源 电路图

STM32CUBEMX配置

延时函数思路

代码部分


所用IO资源 电路图

调试所用开发板开源平台链接(含原理图,PCB)icon-default.png?t=M85Bhttps://oshwhub.com/jhx275816/stm32f103c8t6-zui-xiao-xi-tong-ban

PB8 为串行数据线(连WS2812)

 

PB9 为三极管基极(连蜂鸣器)

 

PC13为调试指示灯(低电平有效)

 

STM32CUBEMX配置

GPIO设置(基于开头所述 电路图)

时钟树配置(系统时钟72mhz)

 

 WS2812数据手册部分

数据传输时间(TH+TL=1.25μs±600ns)

T0H 0码高电平时间 0.35μs ± 150ns
T0L 0码低电平时间 0.8μs ± 150ns
T1H 1码高电平时间 0.7μs ± 150ns
T1L 1码低电平时间 0.6μs ± 150ns
RES帧单位 低电平时间 50μs以上

 一定时间的高电平 + 一定时间的低电平 = WS2812承认的一位信号

延时函数思路

在keil的C代码里,可以用__NOP()【两个下划线】产生一个有nop效果的指令

因为系统时钟72mhz,所以一个__nop()=1/72 us。(实测波形中第二个高电平持续时间和理论趋于一致)

接下来仍需要构建一个函数,实测N=1时,延时330-360ns之间(第一个高电平时间为N=2,延时约750ns)

void delay_ns(u32 nus)//n=1 330-360ns
	{
	for(int i=0;i<nus;i++)
		__nop();
}

代码部分

要使用单片机控制一个WS2812b灯珠要给它发送24bit的数据,这24bit的数据就是灯珠的RGB值,不过发送的时候要按照GRB的顺序来发送。

24bit数据格式:

G7 G6 G5 G4 G3 G2 G1 G0 R7 R6 R5 R4 R3 R2 R1 R0 B7 B6 B5 B4 B3 B2 B1 B0

我们把24bit数据分为三次发送 先构建一个发 8bit 函数

void RGB_WriteByte(u8 in_data){
	uint8_t n = 0;
	uint8_t y = 0,z = 0;
		n = in_data;
		for(y = 0;y < 8;y++){
			z = ((n<<y)&0x80);
			if(z){
				HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_SET);
				delay_ns(2);
				HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_RESET);
				__nop();// 1码

			}else{    
				HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_SET);
				__nop();    //
				HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_RESET);
				delay_ns(2);// 0码 
			}
		}
}

分三次发送(注意是RGB,该函数改变了GRB这个难受的发送方式)

// 设置一个灯的颜色
void RGB_ColorSet(u8 red,u8 green,u8 blue)
{
	// 灯的实际写入颜色是GRB
	RGB_WriteByte(green);  // 写入绿色
	RGB_WriteByte(red); // 写入红色
	RGB_WriteByte(blue); // 写入蓝色
}

放在while里

        RGB_ColorSet(0x00,0x00,0xff);	
		RGB_ColorSet(0xff,0x00,0xff);
		RGB_ColorSet(0x00,0xff,0x00);
		RGB_ColorSet(0xff,0xff,0x00);	
		
		HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_RESET);
		delay_ns(500);// 大于280us的低电平过来,然后才会将刚刚发送过来的24bit数据应用到灯上 
		
		HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_SET);//关闭
		
		HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_RESET);
		HAL_Delay(500);//作为送数据结束标志
		HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_SET);
		HAL_Delay(500);

最后效果图

 

Tip:2020 RGB颜色查询大全 #000000 【颜色列表】 (改变灯的颜色需要用到的)

        【STM32】晶振,主时钟,外设频率介绍

         STM32驱动WS2812B-2020 RGB彩灯(一)

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到