不说别的了,请看源码:
#include <string.h>
#include "main.h"
#include "uart.h"
/*---------------------------------------------------------------------------------------------------------*/
/* Global variables */
/*---------------------------------------------------------------------------------------------------------*/
#define DMXBUFMAX 513
typedef enum {dmxIDLE=1,dmxBREAK,dmxSTART,dmxSLOT,dmxTOUT,dmxEND} status_t;
typedef struct
{
status_t status;
uint32_t index;
uint32_t length;
uint8_t slot[DMXBUFMAX];
}dmx_t; dmx_t dmxRx,dmxTx;
/*---------------------------------------------------------------------------------------------------------*/
/* Define functions prototype */
/*---------------------------------------------------------------------------------------------------------*/
void DMX512_Transmit(const uint8_t slot0, const uint32_t address, const uint32_t length);
void DMX_Init(void)
{
/*---------------------------------------------------------------------------------------------------------*/
/* Init System Clock */
/*---------------------------------------------------------------------------------------------------------*/
/* Unlock protected registers */
SYS_UnlockReg();
/* Reset IP */
SYS_ResetModule(UART0_RST);
/* Enable UART module clock */
CLK_EnableModuleClock(UART0_MODULE);
/* Select UART module clock source */
CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART_S_HXT, CLK_CLKDIV_UART(1));
/*---------------------------------------------------------------------------------------------------------*/
/* Init I/O Multi-function */
/*---------------------------------------------------------------------------------------------------------*/
/* Set GPB multi-function pins for UART0 RXD(PB.0) and TXD(PB.1) */
SYS->GPB_MFP &= ~(SYS_GPB_MFP_PB0_Msk | SYS_GPB_MFP_PB1_Msk);
SYS->GPB_MFP |= SYS_GPB_MFP_PB0_UART0_RXD | SYS_GPB_MFP_PB1_UART0_TXD;
/*---------------------------------------------------------------------------------------------------------*/
/* Init UART */
/*---------------------------------------------------------------------------------------------------------*/
UART_Open(UART0, 250000);
/* Set Data Format*/ /* Only need 8 M 2 */
UART_SetLine_Config(UART0, 0, UART_WORD_LEN_8, UART_PARITY_MARK, UART_STOP_BIT_2);
/* Set RX Trigger Level as 14 bytes */
UART0->FCR = (UART0->FCR & (~UART_FCR_RFITL_Msk)) | UART_FCR_RFITL_14BYTES;
/* Set Timeout time 16 bit-time */
UART_SetTimeoutCnt(UART0,16);
#if 0
/* Enable RTS and CTS autoflow control */
UART_EnableFlowCtrl(UART0);
/* Set RTS Trigger Level as 8 bytes */
UART0->FCR &= ~UART_FCR_RTS_TRI_LEV_Msk;
UART0->FCR |= UART_FCR_RTS_TRI_LEV_8BYTES;
/* Set RTS pin active level as low level active */
UART0->MCR &= ~UART_MCR_LEV_RTS_Msk;
UART0->MCR |= UART_RTS_IS_LOW_LEV_ACTIVE;
#endif
/* Enable RDA\RLS\RTO Interrupt */
UART_EnableInt(UART0, (UART_IER_RDA_IEN_Msk | UART_IER_RLS_IEN_Msk | UART_IER_TOUT_IEN_Msk));
/* Disable Interrupt */
// UART_DisableInt(UART0, (UART_IER_RDA_IEN_Msk | UART_IER_THRE_IEN_Msk | UART_IER_TOUT_IEN_Msk));
dmxRx.status=dmxIDLE;dmxRx.length=dmxRx.index=0;
/* Lock protected registers */
SYS_LockReg();
}
/*---------------------------------------------------------------------------------------------------------*/
/* ISR to handle UART Channel 0 interrupt event */
/*---------------------------------------------------------------------------------------------------------*/
void UART02_IRQHandler(void)
{
uint32_t u32IntSts = UART0->ISR;
if(dmxRx.index>=DMXBUFMAX){dmxRx.index=0;}
if(u32IntSts & UART_ISR_RLS_INT_Msk) // UART_ISR_RLS_IF_Msk
{
if(dmxRx.status==dmxIDLE){dmxRx.status=dmxBREAK;}
UART0->FSR |= UART_FSR_RS485_ADD_DETF_Msk | UART_FSR_PEF_Msk | UART_FSR_FEF_Msk | UART_FSR_BIF_Msk;
uint8_t tmp = UART_READ(UART0);
if(dmxRx.status==dmxBREAK){dmxRx.status=dmxSLOT;dmxRx.length=dmxRx.index=0;}
}
if(u32IntSts & UART_ISR_RDA_INT_Msk)
{
for(uint32_t i=0;i<13;i++)
{
uint8_t tmp=UART_READ(UART0);
if(dmxRx.status==dmxSLOT){dmxRx.slot[dmxRx.index++]=tmp;}
}
}
if(u32IntSts & UART_ISR_TOUT_INT_Msk) //UART_ISR_TOUT_IF_Msk
{
if(dmxRx.status==dmxSLOT){dmxRx.status=dmxTOUT;}
while(UART0->FSR & UART_FSR_RX_POINTER_Msk)
{
uint8_t tmp=UART_READ(UART0);
if(dmxRx.status==dmxTOUT){dmxRx.slot[dmxRx.index++]=tmp;}
}
}
if((dmxRx.status==dmxTOUT)||(dmxRx.index>=DMXBUFMAX))
{dmxRx.length=dmxRx.index;dmxRx.status=dmxEND;dmxRx.index=0;}
if(u32IntSts & UART_ISR_THRE_INT_Msk) // UART_INTSTS_THREIF_Msk
{printf("THRE\n\r");}
}
/*---------------------------------------------------------------------------------------------------------*/
/* DMX512 Transmit */
/*---------------------------------------------------------------------------------------------------------*/
void DMX512_Transmit(const uint8_t slot0, const uint32_t address, const uint32_t length)
{
uint8_t *buf=(uint8_t *)address;uint32_t len=length;
#if 0
/* Switch back to LIN Function */
UART0->FUN_SEL = UART_FUNC_SEL_LIN;
/* Set LIN 1. Header select as includes "break field".[UART_LIN_CTL_LIN_HEAD_SEL_BREAK]
2. Break/Sync Delimiter Length as 1 bit time [UART_LIN_CTL_LIN_BS_LEN(1)]
3. Break Field Length as 16 bit time [UART_LIN_CTL_LIN_BKFL(16)]
*/
UART0->LIN_CTL = UART_LIN_CTL_LIN_HEAD_SEL_BREAK | UART_LIN_CTL_LIN_BS_LEN(1) | UART_LIN_CTL_LIN_BKFL(16);
/* LIN TX Send Header Enable */
UART0->LIN_CTL |= UART_LIN_CTL_LIN_SHD_Msk;
/* Wait until break field transfer completed */
while((UART0->LIN_CTL & UART_LIN_CTL_LIN_SHD_Msk) == UART_LIN_CTL_LIN_SHD_Msk);
#else
/* DMX512 “SPACE” for BREAK 88us */
UART0->LCR |= UART_LCR_BCB_Msk;
CLK_SysTickDelay(88);
/* DMX512 “MARK” After BREAK (MAB) 8us */
UART0->LCR &= ~UART_LCR_BCB_Msk;
CLK_SysTickDelay(8);
#endif
/* DMX512 START CODE (Slot 0 Data) 1byte */
UART_WRITE(UART0,slot0);
/* DMX512 SLOT 1-512 DATA (Maximum 512) 512 bytes */
UART_Write(UART0,buf,len);
}
void TMR0_Init(void)
{
/* Unlock protected registers */
SYS_UnlockReg();
/* Enable peripheral clock */
CLK_EnableModuleClock(TMR0_MODULE);
/* Peripheral clock source */
CLK_SetModuleClock(TMR0_MODULE, CLK_CLKSEL1_TMR0_S_HXT, 0);
/* Lock protected registers */
SYS_LockReg();
/* Open Timer0 in periodic mode, enable interrupt and 1 interrupt tick per second */
TIMER_Open(TIMER0, TIMER_PERIODIC_MODE, 1);
TIMER_EnableInt(TIMER0);
/* Enable Timer0 NVIC */
NVIC_EnableIRQ(TMR0_IRQn);
/* Start Timer0 counting */
TIMER_Start(TIMER0);
}
void TMR0_IRQHandler(void)
{
if(TIMER_GetIntFlag(TIMER0) == 1)
{
/* Clear Timer0 time-out interrupt flag */
TIMER_ClearIntFlag(TIMER0);
// PB13 = !PB13;
}
}
/*---------------------------------------------------------------------------------------------------------*/
/* MAIN function */
/*---------------------------------------------------------------------------------------------------------*/
int dmx512_test(void)
{
uint32_t delay=0;
/* Init System, IP clock and multi-function I/O */
DMX_Init();
TMR0_Init();
printf("\n\r\n\r");
printf("*** 9G-M0518 V3.00 Build by yuanxihua@21cn.com on ("__DATE__ " - " __TIME__ ")\n\r");
printf("*** 9G-M0518 V3.00 Rebooting ...\n\r\n\r");
/*---------------------------------------------------------------------------------------------------------*/
/* SAMPLE CODE */
/*---------------------------------------------------------------------------------------------------------*/
uint8_t buf[512];for(uint32_t i=0;i<sizeof(buf);i++){buf=255-(i>>1);}
// printf("Transmission Test:\n\r");
// while(1) {UART_Write(UART0,(uint32_t)&buf[0],sizeof(buf));CLK_SysTickDelay(500000);}
while(1)
{
if(delay>10000)
{
DMX512_Transmit(0,(uint32_t)&buf[0],sizeof(buf));
delay=0;
}
if(dmxRx.status==dmxEND)
{
// printf("DMX:");for(uint32_t i=0;i<dmxRx.length;i++){if(i%16==0){printf("\n\r");}printf("%02x ",dmxRx.slot);}
DMX512_Transmit(dmxRx.slot[0],(uint32_t)&dmxRx.slot[1],dmxRx.length-1);
dmxRx.status=dmxIDLE;dmxRx.length=0;
}
CLK_SysTickDelay(100);delay++;
}
}
|