白柴的推荐语:
星座图标,出乎意料的图案,意外的好看\(^o^)/
1.前期准备阶段
5.1号就开始准备材料了,用了eepw提供的墙纸。还有自己买的灯罩,32位单片机,杜邦线,蓝牙模块等等。所以,接下来就是等待材料到来时候了!刚开始有些意外,定制的亚克力板子由于没有和老板商量好,导致板子制作出来只有一小部分,所幸板子买的早。于是在5.8时候所有材料就送到我的手中。


所有材料到了就开始我的制作了!
2.制作我的星空灯
首先我使用的是STM32单片机,使用该单片机的原因是因为速度快,更重要的原因是除了这个其他的我不会。从网上仔细的学习了WS2812灯带的使用方法之后。发现他有以下的特性:
1)上电时,WS2812数据IO为低电平保持。
2)空闲时,IO为低电平。
3)数据发送完毕后,保持电平,超过规格书上定义的RESET时间(只有低电平时间超过280us,就可以认为是RESET.)
从而可见它比其他灯带操作还是更难的。接着对代码进行编写和优化。
灯带部分代码:
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{
HAL_TIM_PWM_Stop_DMA(&htim1,TIM_CHANNEL_1);
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(Buffer>='A' && Buffer <='I')
{
Mode_Led = Buffer;
printf("µÆ¹âģʽ£º%c",Mode_Led);
}
if(Buffer == 'J')
{
Mode_wait +=10;
if(Mode_wait==250)
Mode_wait=240;
printf("µÆ¹âËÙ¶È£º%d",300-Mode_wait);
}
if(Buffer == 'K')
{
Mode_wait -=10;
if(Mode_wait==60)
Mode_wait=70;
printf("µÆ¹âËÙ¶È£º%d",300-Mode_wait);
}
HAL_UART_Receive_IT(&huart2,&Buffer, 1);
}
void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin)
{
switch(GPIO_Pin)
{
case GPIO_PIN_13:Mode_Led++;
if(Mode_Led == 'J')
Mode_Led ='A';break;
}
}
void WS281x_SetPixelColor(uint16_t n, uint32_t GRBColor)
{
uint8_t i;
if (n < LED_NUMS)
{
for (i = 0; i < 24; ++i)
RGB_buffur[24 * n + i] = ((GRBColor << i) & 0X800000) ? ONE_PULSE : ZERO_PULSE;
}
}
uint32_t WS281x_Color(uint8_t red, uint8_t green, uint8_t blue)
{
return green << 16 | red << 8 | blue;
}
uint32_t Wheel(uint8_t WheelPos)
{
WheelPos = 255 - WheelPos;
if (WheelPos < 85)
{
return WS281x_Color(255 - WheelPos * 3, 0, WheelPos * 3);
}
if (WheelPos < 170)
{
WheelPos -= 85;
return WS281x_Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
WheelPos -= 170;
return WS281x_Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}
void Mode2_LED(uint8_t wait)
{
uint32_t timestamp = HAL_GetTick();
uint16_t i;
static uint8_t j;
static uint32_t next_time = 0;
uint32_t flag = 0;
if (next_time < wait)
{
if ((uint64_t)timestamp + wait - next_time > 0)
flag = 1;
}
else if (timestamp > next_time)
{
flag = 1;
}
if (flag)
{
j++;
next_time = timestamp + wait;
for (i = 0; i < LED_NUMS; i++)
{
WS281x_SetPixelColor(i, Wheel((i + j) & 255));
}
}
HAL_TIM_PWM_Start_DMA(&htim1,TIM_CHANNEL_1,(uint32_t *)RGB_buffur,RESET_PULSE + WS2812_DATA_LEN);
}
void Mode1_LED(uint8_t wait)
{
uint32_t timestamp = HAL_GetTick();
uint16_t i;
static uint8_t j;
static uint32_t next_time = 0;
static uint8_t loop = 0;
if (loop == 0)
next_time = timestamp;
loop = 1; //Ê״ε÷Óóõʼ»¯
if ((timestamp > next_time)) // && (timestamp - next_time < wait*5))
{
j++;
next_time = timestamp + wait;
for (i = 0; i < LED_NUMS; i++)
{
WS281x_SetPixelColor(i, Wheel(((i * 256 / (LED_NUMS)) + j) & 255));
}
}
HAL_TIM_PWM_Start_DMA(&htim1,TIM_CHANNEL_1,(uint32_t *)RGB_buffur,RESET_PULSE + WS2812_DATA_LEN);
}
void Mode3_LED(void)//È«ºì
{
uint16_t i;
for (i = 0; i < LED_NUMS; i++)
{
WS281x_SetPixelColor(i,0x0ff000);
}
HAL_TIM_PWM_Start_DMA(&htim1,TIM_CHANNEL_1,(uint32_t *)RGB_buffur,RESET_PULSE + WS2812_DATA_LEN);
}
void Mode4_LED(void)//È«À¶
{
uint16_t i;
for (i = 0; i < LED_NUMS; i++)
{
WS281x_SetPixelColor(i,0x000ff0);
}
HAL_TIM_PWM_Start_DMA(&htim1,TIM_CHANNEL_1,(uint32_t *)RGB_buffur,RESET_PULSE + WS2812_DATA_LEN);
}
void Mode5_LED(void)//È«ÂÌ
{
uint16_t i;
for (i = 0; i < LED_NUMS; i++)
{
WS281x_SetPixelColor(i,0xf0000f);
}
HAL_TIM_PWM_Start_DMA(&htim1,TIM_CHANNEL_1,(uint32_t *)RGB_buffur,RESET_PULSE + WS2812_DATA_LEN);
}
void Mode6_LED(uint8_t wait)//È«ºìºôÎü
{
static uint32_t led_init=0x000000;
uint16_t i;static uint8_t temp =0;
uint32_t timestamp = HAL_GetTick();
static uint32_t next_time = 0;
static uint8_t loop = 0;
if (loop == 0)
next_time = timestamp;
loop = 1; //Ê״ε÷Óóõʼ»¯
if ((timestamp > next_time)) // && (timestamp - next_time < wait*5))
{
next_time = timestamp + wait;
if((led_init < 0x02F000) && (temp == 0))
{
led_init +=0x001000;
if(led_init == 0x02F000)
temp=1;
}else{
led_init -=0x001000;
if(led_init == 0x000000)
temp=0;
}
for (i = 0; i < LED_NUMS; i++)
{
WS281x_SetPixelColor(i,led_init);
}
}
HAL_TIM_PWM_Start_DMA(&htim1,TIM_CHANNEL_1,(uint32_t *)RGB_buffur,RESET_PULSE + WS2812_DATA_LEN);
}
void Mode7_LED(uint8_t wait)//È«À¶ºôÎü
{
static uint32_t led_init=0x000000;
uint16_t i;static uint8_t temp =0;
uint32_t timestamp = HAL_GetTick();
static uint32_t next_time = 0;
static uint8_t loop = 0;
if (loop == 0)
next_time = timestamp;
loop = 1; //Ê״ε÷Óóõʼ»¯
if ((timestamp > next_time)) // && (timestamp - next_time < wait*5))
{
next_time = timestamp + wait;
for (i = 0; i < LED_NUMS; i++)
{
WS281x_SetPixelColor(i,led_init);
}
if((led_init <0x0002f0) && (temp == 0))
{
led_init +=0x000010;
if(led_init == 0x0002f0)
temp=1;
}else{
led_init -=0x000010;
if(led_init == 0x000000)
temp=0;
}
}
HAL_TIM_PWM_Start_DMA(&htim1,TIM_CHANNEL_1,(uint32_t *)RGB_buffur,RESET_PULSE + WS2812_DATA_LEN);
}
void Mode8_LED(uint8_t wait)//È«Â̺ôÎü
{
static uint32_t led_init=0x000000;
uint16_t i;static uint8_t temp =0;
uint32_t timestamp = HAL_GetTick();
static uint32_t next_time = 0;
static uint8_t loop = 0;
if (loop == 0)
next_time = timestamp;
loop = 1; //Ê״ε÷Óóõʼ»¯
if ((timestamp > next_time)) // && (timestamp - next_time < wait*5))
{
next_time = timestamp + wait;
for (i = 0; i < LED_NUMS; i++)
{
WS281x_SetPixelColor(i,led_init);
}
if((led_init <0xf00000) && (temp == 0))
{
led_init +=0x100000;
if(led_init == 0xf00000)
temp=1;
}else{
led_init -=0x100000;
if(led_init == 0x000000)
temp=0;
}
}
HAL_TIM_PWM_Start_DMA(&htim1,TIM_CHANNEL_1,(uint32_t *)RGB_buffur,RESET_PULSE + WS2812_DATA_LEN);
}
void Mode9_LED(uint8_t wait)//Ѭ»·
{
static uint8_t temp =0,loop_A = 0;
uint32_t timestamp = HAL_GetTick();
static uint32_t next_time = 0;
static uint8_t loop = 0;
if (loop == 0)
next_time = timestamp;
loop = 1; //Ê״ε÷Óóõʼ»¯
if ((timestamp > next_time)) // && (timestamp - next_time < wait*5))
{
next_time = timestamp + wait;
if(loop_A == 0){
WS281x_SetPixelColor(temp,0xf0000f);
loop_A = 1;
}
else{
WS281x_SetPixelColor(temp,0x000000);
loop_A = 0;
temp++;
if(temp == LED_NUMS)
temp=0;
}
}
HAL_TIM_PWM_Start_DMA(&htim1,TIM_CHANNEL_1,(uint32_t *)RGB_buffur,RESET_PULSE + WS2812_DATA_LEN);
}这时候基本功能已经完成大半了,和手机如何进行连接。有两种方案:1·使用ESp8266利用WIFI连接。优点是速度快。缺点是我不会。2·使用HC-06模块用蓝牙连接,优点是简单,缺点是速度太慢了。但是这里用这个完全就够了。
主机:用于向从机下发指令,能够搜索从机并主动建立连接的一方。
从机:用于接收主机下发的命令,不能主动建立连接,只能等别人连接自己。(HC-06只能工作在从机模式下。)
主从一体:能够在主机和从机模式间切换,即可做主机也可作从机。如:HC-05既可以设置为主机也可以设置为从机。
代码如下:
static void MX_USART2_UART_Init(void)
{
/* USER CODE BEGIN USART2_Init 0 */
/* USER CODE END USART2_Init 0 */
/* USER CODE BEGIN USART2_Init 1 */
/* USER CODE END USART2_Init 1 */
huart2.Instance = USART2;
huart2.Init.BaudRate = 9600;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart2.Init.ClockPrescaler = UART_PRESCALER_DIV1;
huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&huart2) != HAL_OK)
{
Error_Handler();
}
if (HAL_UARTEx_SetTxFifoThreshold(&huart2, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
{
Error_Handler();
}
if (HAL_UARTEx_SetRxFifoThreshold(&huart2, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
{
Error_Handler();
}
if (HAL_UARTEx_DisableFifoMode(&huart2) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USART2_Init 2 */
/* USER CODE END USART2_Init 2 */
}
/**
* Enable DMA controller clock
*/
static void MX_DMA_Init(void)
{
/* DMA controller clock enable */
__HAL_RCC_DMA1_CLK_ENABLE();
/* DMA interrupt init */
/* DMA1_Channel1_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
}接下来就是重头戏,开始灯罩的设计。由于创造能力太差,我就雕刻的不咋好看,不过可以凑合着看:


3.完成
让我们一起看看效果原图吧!



在宿舍,效果不是不很好。但是,谁收到都会感动哭了!

我要赚赏金
