一、DMX512协议
关于DMX512协议的解释,下面这篇文章写的十分详尽,这里不再赘述。
二、配置stm32
2.1 使用器件
stm32F103C8T6,RGBW四通道DMX512灯带
2.2 初始化串口
DMX512协议一帧一共有11位,分别是1位开始位、8位数据位,2位停止位。故可将stm32串口设置为1位开始位、8位数据位、2位停止位。
//初始化 PA2 为串口2模式 用于发送DMX512数据格式
void USART2_Init(u32 Baud)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = Baud; //波特率设置为250000
USART_InitStructure.USART_HardwareFlowControl =USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Tx;
USART_InitStructure.USART_Parity =USART_Parity_No ;
USART_InitStructure.USART_StopBits = USART_StopBits_2; //2位停止位
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//8位数据位
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel =USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&NVIC_InitStructure);
USART_ITConfig(USART2,USART_IT_IDLE,ENABLE);
USART_Init (USART2,&USART_InitStructure);
USART_Cmd(USART2,ENABLE);
}
2.3 复位信号
每次发送完整的DMX512协议帧均需要BREAK和MAB信号,作为复位信号。而串口模式下,
PA2无法通过 GPIO_ResetBits(); 让引脚拉输出低电平88us以上,所以需要重新初始化为普通IO模式。
//初始化 PA2 普通GPIO模式 因定义成串口模式下,
//PA2无法通过 GPIO_ResetBits(); 让引脚拉输出低电平88us以上
//所以需要重新初始化为普通IO模式
void GPIOA_PIN2_Iint(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_SetBits(GPIOA,GPIO_Pin_2);
}
有了以上代码,就可以发送复位信号了,如下:
//复位信号
void Reset(void)
{
GPIOA_PIN2_Iint();
GPIO_ResetBits(GPIOA,GPIO_Pin_2);
Delay_us(300);
GPIO_SetBits(GPIOA,GPIO_Pin_2);
Delay_us(100);
USART2_Init(250000);
}
2.4 发送DMX数据
接下来就可以编写函数,发送DMX512数据了。
void DMX512_SendData(uint8_t R,uint8_t G,uint8_t B,uint8_t W,uint16_t led_num)
{
Reset(); //复位
Send_8bits(0x00); //起始字节
while(led_num--)
{
Send_8bits(R); //R
Send_8bits(G); //G
Send_8bits(B); //B
Send_8bits(W); //w
}
Delay_ms(1); //帧间间隔,时间可以自定义
}
三、源码获取
感兴趣的可与我私聊获取,非开源。