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

目录

所用IO资源 电路图

STM32CUBEMX配置

延时函数思路

代码部分


所用IO资源 电路图

调试所用开发板开源平台链接(含原理图,PCB)https://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);

IO翻转时序法代码链接https://download.csdn.net/download/qq_44125275/86875749

最后效果图

2022.11.9更新(完善代码架构)

test-stm32-ws2812-IO-2022.11.9.7z

/* USER CODE BEGIN PV */
uint8_t rgb_data[24] = {0x00,0x00,0x00,0x00,0xFF,0x00,0xFF,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0xFF,0xFF,0X00,0XFF,0XFF};
/* USER CODE END PV */
/* USER CODE BEGIN PFP */
	
//IO模拟时序延时
void delay_ns(u32 nus)//n=1 330ns
	{
	while(nus--);
}
//RGB解算并发送
void send_code(u8 * sdata){    //
	uint8_t n = 0,j=0;
	uint8_t x = 0,y = 0,z = 0;
	for(j = 0;j < led_number;j++)
	{
		for(x = 0;x < 3;x++)
		{        //
			n = sdata[x];
				for(y = 0;y < 8;y++)
				{
					z = ((n<<y)&0x80);
					if(z)
						{
						HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_SET);
						delay_ns(7);        
						HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_RESET);
						delay_ns(1);    //
						}
					else
						{
						HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_SET);
						delay_ns(1);
						HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_RESET);
						delay_ns(7);
						}
				}
		}
  }
}
//自定义颜色
void colorset(u8 i)
{
	switch(i)
	{
		case 0:
				 send_code(&rgb_data[0]);//所有灯清零
					break;
		case 1:
					send_code(&rgb_data[3]);//所有灯变红灯
					break;
		case 2:
					send_code(&rgb_data[6]);//所有灯变绿灯
					break;
		case 3:
					send_code(&rgb_data[9]);//所有灯变蓝灯
					break;
		case 4:
					send_code(&rgb_data[13]);//所有灯变红灯//所有灯变绿灯
					break;
		case 5:
					send_code(&rgb_data[22]);//所有灯变红灯//所有灯变蓝灯
					break;
		case 6:
					send_code(&rgb_data[19]);//所有灯变红灯//所有灯变绿灯//所有灯变蓝灯
					break;
		case 7:
		      send_code(&rgb_data[16]);//所有灯变绿灯//所有灯变蓝灯
					break;
		
	}

}

	// 循环显示各种彩色
void circular_led_show()
{
u8 i=0,j=0;
	for(i=0;i<8;i++)
	{
	colorset(i);
	HAL_Delay(300);
	
	}

}
/* USER CODE END PFP */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		circular_led_show();
		
//reset信号
		HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_RESET); 
		HAL_Delay(500);
  }

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

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

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

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐