使用stm32通过标准库控制DMX512灯带(RGBW四通道)

一、DMX512协议

关于DMX512协议的解释,下面这篇文章写的十分详尽,这里不再赘述。

DMX512协议-CSDN博客文章浏览阅读2.3w次,点赞23次,收藏110次。写在前面:本文章旨在总结备份、方便以后查询,由于是个人总结,如有不对,欢迎指正;另外,内容大部分来自网络、书籍、和各类手册,如若侵权请告知,马上删帖致歉。DMX512(digital multiplex)其实就是主机向从机整包单向广播发送的协议(protocol),从机自取所需。DMX512数据协议是美国舞台灯光协会(USITT)于1990年发布的一种灯光控制器与灯具设备进行..._dmx512协议https://blog.csdn.net/qq_42992084/article/details/98525578

二、配置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);		//帧间间隔,时间可以自定义
}

三、源码获取

感兴趣的可与我私聊获取,非开源。

  • 8
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个基本的 STM32F4 接收标准 DMX512 信号的程序示例: ```c #include "stm32f4xx.h" #define DMX_BUFFER_SIZE 512 uint8_t dmx_buffer[DMX_BUFFER_SIZE]; // 存储 DMX 数据的缓冲区 volatile uint16_t dmx_channel_count = 0; // DMX 通道数量 void DMX_Init(void) { // 1. 配置 GPIO 为 USART 模式 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_USART1); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOB, &GPIO_InitStructure); // 2. 配置 USART1 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); USART_InitTypeDef USART_InitStructure; USART_InitStructure.USART_BaudRate = 250000; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_2; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx; USART_Init(USART1, &USART_InitStructure); // 3. 配置 DMA RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE); DMA_InitTypeDef DMA_InitStructure; DMA_InitStructure.DMA_Channel = DMA_Channel_4; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(USART1->DR); DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&dmx_buffer; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; DMA_InitStructure.DMA_BufferSize = DMX_BUFFER_SIZE; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_Init(DMA2_Stream2, &DMA_InitStructure); // 4. 启动 DMA DMA_Cmd(DMA2_Stream2, ENABLE); // 5. 启动 USART1 接收 USART_Cmd(USART1, ENABLE); } void DMX_IRQHandler(void) { if (USART_GetITStatus(USART1, USART_IT_IDLE) != RESET) { USART_ITConfig(USART1, USART_IT_IDLE, DISABLE); DMA_Cmd(DMA2_Stream2, DISABLE); dmx_channel_count = DMX_BUFFER_SIZE - DMA_GetCurrDataCounter(DMA2_Stream2); DMA_SetCurrDataCounter(DMA2_Stream2, DMX_BUFFER_SIZE); // 准备下一次接收 DMA_Cmd(DMA2_Stream2, ENABLE); USART_ITConfig(USART1, USART_IT_IDLE, ENABLE); } } int main(void) { DMX_Init(); NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); while (1) { // 在这里处理 DMX 数据 } } ``` 在上面的程序中,我们使用了 USART1 和 DMA2 来接收 DMX 数据。当 USART1 接收到一个 IDLE 事件时,中断服务程序会被调用。在中断服务程序中,我们停止 DMA 传输,记录 DMX 数据的数量,然后再次启动 DMA 传输,准备接收下一帧 DMX 数据。在程序的主循环中,我们可以处理收到的 DMX 数据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值