通过板卡的485接口模拟dmx512协议进行控制sm16512ps灯带,通过以下方式初始化串口的引脚:
void dmx512_uart1_init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_USART1_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**USART2 GPIO Configuration
PD5 ------> USART2_TX
PD6 ------> USART2_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
// PA9 PA10
huart1.Instance = USART1;
huart1.Init.BaudRate = 250000;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_2;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16; //设置接收端使用16倍采样
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();
}
}
void dmx512_io_init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOA_CLK_ENABLE();
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9|GPIO_PIN_10, GPIO_PIN_SET);
GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
通过复用串口TX引脚来输出dmx512协议的高低电平:
void dmx512_pin_mode(uint8_t mode)
{
if(mode) //mode=1,当串口发送用,在dmx512发送中主要用于发送数据帧
{
dmx512_uart1_init();
}
else if(mode == 0)//mode=0,当普通io用,在dmx512发送中主要用来形成break和mab信号
{
dmx512_io_init();
}
}
int dmx512_uart1_send(uint8_t *buf,uint16_t size,uint32_t timeout)
{
uint8_t value;
value = HAL_UART_Transmit(&huart1, buf, size, timeout);
return value;
}
void dmx512_task(void *para)
{
uint8_t tx_data[4] = {0};
uint8_t start_code= 0;
dmx512_pin_mode(0);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, GPIO_PIN_RESET);
rt_us_delay(100);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, GPIO_PIN_SET);
rt_us_delay(10);
dmx512_pin_mode(1);
dmx512_uart1_send(&start_code, sizeof(start_code), 0xFFFF);
rt_thread_mdelay(1000);
while(1)
{
tx_data[0] = 1;
tx_data[1] = 0;
tx_data[2] = 0;
tx_data[3] = 0;
dmx512_uart1_send(tx_data, sizeof(tx_data), 0xFFFF);
rt_thread_mdelay(1000);
}
}
因为灯带是RGBW灯带,所以我以为是四个通道控制红、绿、蓝、白四种颜色,但是程序控制的灯带并没有亮起红色灯光,而是几个光的颜色切换一下后就再也不亮了。
有大佬能指点指点吗?
不管有用没用,先接上逻辑分析仪🙂
假設你的DMX512 正確的話 改成下面這樣試試
void dmx512_task(void *para)
{
uint8_t tx_data[5] = {0};
tx_data[0] = 0; /* start code */
tx_data[1] = 255;
tx_data[2] = 0;
tx_data[3] = 0;
tx_data[4] = 0;
while(1)
{
dmx512_pin_mode(0);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, GPIO_PIN_RESET);
rt_us_delay(100);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, GPIO_PIN_SET);
rt_us_delay(10);
dmx512_pin_mode(1);
dmx512_uart1_send(tx_data, sizeof(tx_data), 0xFFFF);
rt_thread_mdelay(1000);
}
}
————————————————
没有逻辑分析仪这种高端设备
调DMX512用这种就够了 https://item.taobao.com/item.htm?id=671664119953
@aozima
okok 感谢回复