打印
[应用方案]

基于新唐M451的串口FIFO中断状态机接收的DMX512的方案

[复制链接]
6671|25
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
缥缈九哥|  楼主 | 2014-10-7 00:15 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 缥缈九哥 于 2014-10-7 00:18 编辑

利用国庆假期,写了一个简单方案。用了串口FIFO中断和状态机,详情请看源码:
#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_UARTSEL_HXT, CLK_CLKDIV0_UART(1));
       
    /*---------------------------------------------------------------------------------------------------------*/
    /* Init I/O Multi-function                                                                                 */
    /*---------------------------------------------------------------------------------------------------------*/
    /* Set PD multi-function pins for UART0 RXD(PD.0) and TXD(PD.1) */
//    SYS->GPD_MFPL &= ~(SYS_GPD_MFPL_PD0MFP_Msk | SYS_GPD_MFPL_PD1MFP_Msk);
//  SYS->GPD_MFPL |= (SYS_GPD_MFPL_PD0MFP_UART0_RXD | SYS_GPD_MFPL_PD1MFP_UART0_TXD);
        /* Set PD multi-function pins for UART0 RXD(PD.6) and TXD(PD.1) */
        SYS->GPD_MFPL &= ~(SYS_GPD_MFPL_PD6MFP_Msk | SYS_GPD_MFPL_PD1MFP_Msk);
        SYS->GPD_MFPL |= (SYS_GPD_MFPL_PD6MFP_UART0_RXD | SYS_GPD_MFPL_PD1MFP_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 = 14 */
        UART0->FIFO = (UART0->FIFO & (~ UART_FIFO_RFITL_Msk)) | UART_FIFO_RFITL_14BYTES;
               
        /* Set Timeout time 16 bit-time */
        UART_SetTimeoutCnt(UART0,16);
#if 0               
        /* Set RTS Trigger Level */
        UART0->MODEM |= UART_RTS_IS_HIGH_LEV_TRG;
        UART0->FIFO = (UART0->FIFO &~ UART_FIFO_RTSTRGLV_Msk) | UART_FIFO_RTSTRGLV_14BYTES;

    /* Enable RTS and CTS autoflow control */
        UART0->INTEN |= UART_INTEN_ATORTSEN_Msk | UART_INTEN_ATOCTSEN_Msk;
#endif
        /* Enable RDA\RLS\RTO Interrupt  */
        UART_EnableInt(UART0, (UART_INTEN_RDAIEN_Msk | UART_INTEN_RLSIEN_Msk | UART_INTEN_RXTOIEN_Msk));
    /* Disable Interrupt */
//        UART_DisableInt(UART0, (UART_INTEN_RDAIEN_Msk | UART_INTEN_RLSIEN_Msk | UART_INTEN_RXTOIEN_Msk));

        dmxRx.status=dmxIDLE;dmxRx.length=dmxRx.index=0;
        /* Lock protected registers */
    SYS_LockReg();
}

/*---------------------------------------------------------------------------------------------------------*/
/* ISR to handle UART Channel 0 interrupt event                                                            */
/*---------------------------------------------------------------------------------------------------------*/
void UART0_IRQHandler(void)
{
        uint32_t u32IntSts=UART0->INTSTS;
        if(dmxRx.index>=DMXBUFMAX){dmxRx.index=0;}

        if(u32IntSts & UART_INTSTS_RLSINT_Msk) // UART_INTSTS_RLSIF_Msk
        {
                if(dmxRx.status==dmxIDLE){dmxRx.status=dmxBREAK;}
                UART0->FIFOSTS |= UART_FIFOSTS_ADDRDETF_Msk | UART_FIFOSTS_PEF_Msk | UART_FIFOSTS_FEF_Msk | UART_FIFOSTS_BIF_Msk;
                uint8_t tmp = UART_READ(UART0);
                if(dmxRx.status==dmxBREAK){dmxRx.status=dmxSLOT;dmxRx.length=dmxRx.index=0;}
        }
    if(u32IntSts & UART_INTSTS_RDAINT_Msk) //UART_INTSTS_RDAIF_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_INTSTS_RXTOINT_Msk) //UART_INTSTS_RXTOIF_Msk
        {
                if(dmxRx.status==dmxSLOT){dmxRx.status=dmxTOUT;}
                while(UART0->FIFOSTS & UART_FIFOSTS_RXPTR_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_INTSTS_THREINT_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
        UART0->FUNCSEL = UART_FUNCSEL_LIN;
        UART0->ALTCTL |= UART_ALTCTL_LINTXEN_Msk;
//        UART0->LINCTL &= UART_LINCTL_HSEL_Msk;
//        UART0->LINCTL |= (UART_LINCTL_HSEL_Msk & 0x01);
        UART0->ALTCTL &= ~UART_ALTCTL_BRKFL_Msk;
        UART0->ALTCTL |= (UART_ALTCTL_BRKFL_Msk & 0x0f);
#else
        /* DMX512 “SPACE” for BREAK                          88us         */
        UART0->LINE |= UART_LINE_BCB_Msk;
        CLK_SysTickDelay(88);
        /* DMX512 “MARK” After BREAK (MAB)          8us         */
        UART0->LINE &= ~UART_LINE_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);
}

/*---------------------------------------------------------------------------------------------------------*/
/* MAIN function                                                                                           */
/*---------------------------------------------------------------------------------------------------------*/

int dmx512_test(void)
{
        uint32_t delay=0;
    /* Init System, IP clock and multi-function I/O */
    DMX_Init();
       
        DBG_PRINTF("\n\r\n\r");
        DBG_PRINTF("*** 9G-NUC451 V3.00 Build by yuanxihua@21cn.com on ("__DATE__ " - " __TIME__ ")\n\r");
        DBG_PRINTF("*** 9G-NUC451 V3.00 Rebooting ...\n\r\n\r");
       
    /*---------------------------------------------------------------------------------------------------------*/
    /* SAMPLE CODE                                                                                             */
    /*---------------------------------------------------------------------------------------------------------*/
        uint8_t buf[512];for(uint32_t i=0;i<sizeof(buf);i++){buf=i>>1;}
//        printf("Transmission Test:\n\r");
//        while(1) {UART_Write(UART0,buf,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++;
        }
}
沙发
缥缈九哥|  楼主 | 2014-10-7 00:15 | 只看该作者
顶起

使用特权

评论回复
板凳
gaoyang9992006| | 2014-10-8 16:28 | 只看该作者
这程序写的出神入化,我差点没看懂。顶起。

使用特权

评论回复
地板
598330983| | 2014-10-15 19:49 | 只看该作者
九哥的这种精神值得学习,顶起

使用特权

评论回复
5
gxliu08| | 2014-10-15 20:20 | 只看该作者
学习学习,谢谢分享

使用特权

评论回复
6
从小木丁丁| | 2014-10-15 21:24 | 只看该作者
缥缈九哥 发表于 2014-10-7 00:15
顶起

九哥果然厉害,赞一个

使用特权

评论回复
7
从小木丁丁| | 2014-10-15 21:24 | 只看该作者
gaoyang9992006 发表于 2014-10-8 16:28
这程序写的出神入化,我差点没看懂。顶起。

你这是拍马屁呢还是拍马屁呢

使用特权

评论回复
8
从小木丁丁| | 2014-10-15 21:25 | 只看该作者
598330983 发表于 2014-10-15 19:49
九哥的这种精神值得学习,顶起

值得学习,值得鼓励

使用特权

评论回复
9
从小木丁丁| | 2014-10-15 21:25 | 只看该作者
gxliu08 发表于 2014-10-15 20:20
学习学习,谢谢分享

我们要好好跟九哥学习

使用特权

评论回复
10
bobde163| | 2014-10-15 22:42 | 只看该作者
得好好看一下

使用特权

评论回复
11
缥缈九哥|  楼主 | 2014-10-30 01:08 | 只看该作者
顶起。

使用特权

评论回复
12
缥缈九哥|  楼主 | 2014-11-3 14:24 | 只看该作者
又沉下去了。

使用特权

评论回复
13
kulas| | 2016-1-19 20:31 | 只看该作者
为九哥顶起

使用特权

评论回复
14
天灵灵地灵灵| | 2016-1-20 21:48 | 只看该作者
UART_Open(UART0, 250000);
250000是什么?波特率还是主频?

使用特权

评论回复
15
598330983| | 2016-1-20 22:22 | 只看该作者
typedef enum {dmxIDLE=1,dmxBREAK,dmxSTART,dmxSLOT,dmxTOUT,dmxEND} status_t;
这个类型好复杂的说。

使用特权

评论回复
16
Tennasi| | 2016-1-21 08:53 | 只看该作者
波特率最高能设为多少呢?

使用特权

评论回复
17
huangcunxiake| | 2016-1-25 22:39 | 只看该作者
FIFO( First In First Out)简单说就是指先进先出。由于微电子技术的飞速发展,新一代FIFO芯片容量越来越大,体积越来越小,价格越来越便宜。

使用特权

评论回复
18
598330983| | 2016-1-26 09:54 | 只看该作者
如果程序能分块写就好了,就想那个Labview一样,但是还是C,只不过可以封装到一个图形里,然后提供接口。。。

使用特权

评论回复
19
稳稳の幸福| | 2016-1-26 20:56 | 只看该作者
是25MH的晶振使用吗?

使用特权

评论回复
20
zhuotuzi| | 2016-1-27 14:10 | 只看该作者
这程序写的出神入化,我差点没看懂。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:童时不懂世事艰,笑谈学成锦衣还。岁月无声已先过,男儿有泪空自弹。    莫待沾霜愁上发,须嬴吐气喜开颜。拼搏半年誓如愿,不到长城心不甘。

67

主题

1868

帖子

271

粉丝