STM32系列基于專為要求高性能、低成本、低功耗的嵌入式應用專門設(shè)計的ARM Cortex-M3內(nèi)核,其中STM32F系列有:STM32F103“增強型”系列STM32F101“基本型”系列STM32F105、STM32F107“互聯(lián)型”系列,增強型系列時鐘頻率達到72MHz,是同類產(chǎn)品中性能最高的產(chǎn)品;基本型時鐘頻率為36MHz,以16位產(chǎn)品的價格得到比16位產(chǎn)品大幅提升的性能,是32位產(chǎn)品用戶的最佳選擇。兩個系列都內(nèi)置32K到128K的閃存,不同的是SRAM的最大容量和外設(shè)接口的組合。時鐘頻率72MHz時,從閃存執(zhí)行代碼,STM32功耗36mA,相當于0.5mA/MHz。
基于stm32實現(xiàn)DMX512協(xié)議發(fā)送與接收
DMX512數(shù)據(jù)協(xié)議是美國舞臺燈光協(xié)會(USITT)于1990年發(fā)布的一種燈光控制器與燈具設(shè)備進行數(shù)據(jù)傳輸?shù)臉藴省K?a href="http://m.1cnz.cn/v/tag/2364/" target="_blank">電氣特性,數(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的時間。當然對于標準的512協(xié)議是需要break和mark after break 幀的,break是一個92us的低電平,而mark after break是一個12us的高電平,如下圖所示
根據(jù)上面的圖片(缺失了起始碼,下圖補上),512協(xié)議必須有break和mark,但是在我們通常的非標準收發(fā)中,檢測break和mark相對比較困難,如果非要做,耗費的資源也比較多,比如定時器計時,中斷等等。如果不是做標準控制器的,完全可以另辟蹊徑。
根據(jù)512 協(xié)議,每一串數(shù)據(jù)的開始都要有一個起始碼,也稱復位碼,其數(shù)據(jù)為0,但是從開始位數(shù)至第十位是0,用來聲明數(shù)據(jù)傳輸開始,隨后包含1-512個數(shù)據(jù),也稱調(diào)光數(shù)據(jù),其是標準的數(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) //復位信號
{
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ù)
}
}
}
}
}
評論
查看更多