日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

dmx512如何帧同步_stm32实现DMX512协议发送与接收(非标)

發(fā)布時間:2023/12/14 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 dmx512如何帧同步_stm32实现DMX512协议发送与接收(非标) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

最近把玩了一下485,期間也接觸了dmx512通信協(xié)議,該協(xié)議主要用于各種舞臺燈光的控制當(dāng)中,進而實現(xiàn)各種光效以及色彩變化。根據(jù)標(biāo)準(zhǔn)的512協(xié)議,其物理連接與傳統(tǒng)上的RS485是完全一致的,并沒有什么差別,差別只是在協(xié)議上的不同,工業(yè)上應(yīng)用的主要是modbus協(xié)議,而這里是用512通信協(xié)議。

DMX512數(shù)據(jù)協(xié)議是美國舞臺燈光協(xié)會(USITT)于1990年發(fā)布的一種燈光控制器與燈具設(shè)備進行數(shù)據(jù)傳輸?shù)臉?biāo)準(zhǔn)。它包括電氣特性,數(shù)據(jù)協(xié)議,數(shù)據(jù)格式等方面的內(nèi)容。

512協(xié)議規(guī)定使用的波特率是250Kbps,但是stm32可以支持shangMbps的波特率,所以說這不是什么大問題。

該協(xié)議發(fā)送的數(shù)據(jù)幀一共11位,1位開始位,8位數(shù)據(jù),2個停止位,無校驗位。

根據(jù)波特率可以知道,位時間是4us,11位數(shù)據(jù)供需要44us的時間。當(dāng)然對于標(biāo)準(zhǔn)的512協(xié)議是需要break和mark after break 幀的,break是一個92us的低電平,而mark after break是一個12us的高電平,如下圖所示

根據(jù)上面的圖片(缺失了起始碼,下圖補上),512協(xié)議必須有break和mark,但是在我們通常的非標(biāo)準(zhǔn)收發(fā)中,檢測break和mark相對比較困難,如果非要做,耗費的資源也比較多,比如定時器計時,中斷等等。如果不是做標(biāo)準(zhǔn)控制器的,完全可以另辟蹊徑。

根據(jù)512 協(xié)議,每一串?dāng)?shù)據(jù)的開始都要有一個起始碼,也稱復(fù)位碼,其數(shù)據(jù)為0,但是從開始位數(shù)至第十位是0,用來聲明數(shù)據(jù)傳輸開始,隨后包含1-512個數(shù)據(jù),也稱調(diào)光數(shù)據(jù),其是標(biāo)準(zhǔn)的數(shù)據(jù)幀,所以第十位是1,所以我們可以根據(jù)這個第十位來進行做文章。大家都知道,一般的單片機,像51,avr等都是支持8-9位數(shù)據(jù)發(fā)送的,所以我們就是用9位數(shù)據(jù),1位停止位,無校驗位,通過檢測檢測第十位,也就是所謂的RB8來進行數(shù)據(jù)的接收與傳輸,不需要發(fā)送break和mark。

1、發(fā)送端

串口設(shè)為 9位數(shù)據(jù),1停止位,無校驗位,波特率250000

void USART1_Configuration(void)

{

USART_InitTypeDef USART_InitStructure;

USART_InitStructure.USART_BaudRate = 250000;

USART_InitStructure.USART_WordLength = USART_WordLength_9b;

USART_InitStructure.USART_StopBits = USART_StopBits_1;

USART_InitStructure.USART_Parity = USART_Parity_No;

USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

/* Configure USART1 */

USART_Init(USART1, &USART_InitStructure);

/* Enable USART1 Receive and Transmit interrupts */

USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

//USART_ITConfig(USART1, USART_IT_TC, ENABLE);

/* Enable the USART1 */

USART_Cmd(USART1, ENABLE);

}

注意在初始化串口的時候別忘了485芯片設(shè)為發(fā)送狀態(tài)

接下來主要就是數(shù)據(jù)包的發(fā)送,發(fā)送的時候注意起始碼的數(shù)據(jù)第九位設(shè)為0,調(diào)光數(shù)據(jù)第九位設(shè)為1.

void DMX_SendPacket(void)

{

pDMX_buf = 0;

while (pDMX_buf <= 512) //1-512

{

/* send data packet to slaves*/

if(USART1->SR & (1<<6))

{

/*發(fā)送起始碼 00*/

if (0 == pDMX_buf)

{

USART1->DR = ((USART1->DR) & 0xfe00); ? //第九位置0

}

else

{

USART1->DR = 0x0100 | DMX_buf[pDMX_buf]; ??//第九位置1

}

pDMX_buf++;

}

}

}

以上函數(shù)相比大家都可以看懂,接下來就是在main函數(shù)中進行循環(huán)數(shù)據(jù)的發(fā)送了,比如每200ms發(fā)送一次,由于發(fā)送快,偶爾的錯誤也不是很明顯。

2,、接收端

接收端得工作就是接收的信息進行解碼(廢話),關(guān)鍵是對RB8的處理,接收用到了中斷接收,所以需要使能接收中斷。

void USART1_Configuration(void)

{

USART_InitTypeDef USART_InitStructure;

USART_InitStructure.USART_BaudRate = 250000;

USART_InitStructure.USART_WordLength = USART_WordLength_9b;

USART_InitStructure.USART_StopBits = USART_StopBits_1;

USART_InitStructure.USART_Parity = USART_Parity_No;

USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

/* Configure USART1 */

USART_Init(USART1, &USART_InitStructure);

/* Enable USART1 Receive and Transmit interrupts */

USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//使能接收中斷

//USART_ITConfig(USART1, USART_IT_TC, ENABLE);

/* Enable the USART1 */

USART_Cmd(USART1, ENABLE);

}

void NVIC_Configuration(void)

{

NVIC_InitTypeDef NVIC_InitStructure;

#ifdef ?VECT_TAB_RAM

/* Set the Vector Table base location at 0x20000000 */

NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);

#else ?/* VECT_TAB_FLASH ?*/

/* Set the Vector Table base location at 0x08000000 */

NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);

#endif

//設(shè)置優(yōu)先級分組:先占優(yōu)先級和從優(yōu)先級 ,先占優(yōu)先級0位,從優(yōu)先級4位

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);

/* Enable the USART1 Interrupt */

NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

}

void USART1_IRQHandler(void)

{

uint16_t UDR;

static uint16_t RXB8;

static uint16_t pDMX_buf = 0; //數(shù)據(jù)指針

static uint8_t fDMX_buf_right = 0;

//接收數(shù)據(jù)

if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)//USART_FLAG_RXNE

{

//USART_ClearITPendingBit(USART1,USART_FLAG_RXNE);

UDR = USART_ReceiveData(USART1);

RXB8 = (UDR & 0x0100);

if (RXB8 == 0) //復(fù)位信號

{

if (!UDR)

{

fDMX_buf_right = 1;//接收數(shù)據(jù)正確

pDMX_buf = 1; //直接接收第一個數(shù)據(jù) ?不保存第0個數(shù)據(jù)。

}

}

else //rb8 =1 ?pDMX_buf=1 調(diào)光數(shù)據(jù)

{

if (1 == fDMX_buf_right)

{

DMX_buf[pDMX_buf++] = (u8)UDR;

//接收到512個數(shù)據(jù)

if (pDMX_buf > 512)

{

fDMX_buf_right = 0;

tim_update = SET; //更新調(diào)光數(shù)據(jù)

}

}

}

}

}

————————————————

版權(quán)聲明:本文為CSDN博主「愛飛的小兵」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明。

原文鏈接:https://blog.csdn.net/cunlingwang/java/article/details/6712187

總結(jié)

以上是生活随笔為你收集整理的dmx512如何帧同步_stm32实现DMX512协议发送与接收(非标)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。