打印
[DemoCode下载]

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

[复制链接]
9800|26
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
缥缈九哥|  楼主 | 2014-10-30 01:11 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
不说别的了,请看源码:
#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++;
        }
}

沙发
缥缈九哥|  楼主 | 2014-11-3 14:24 | 只看该作者
竟然没有人看到?伤心。

使用特权

评论回复
板凳
handengpan| | 2014-11-4 23:13 | 只看该作者
比较渣,没看懂,请问你有M0518详细资料吗

使用特权

评论回复
地板
华邦掌门人| | 2014-11-9 22:04 | 只看该作者
M0518系列特色:主频为50MHz,
1.宽电压工作范围2.5V至5.5V, 工作温度: -40℃至105℃, 内建22.1184MHz高精度晶振(1%准确度)。
2.内建16位PWM产生器,可输出24路PWM,或4组互补配对PWM。
3.8路12bit ADC,可达1 MSPS (每秒采样率),±1℃ 准确度温感计。
4.一组SPI (可达36 MHz),两组 I²C (可达 400 kHz),6路 UART (可达1 Mbps)
非常适宜用于舞台灯光,欢迎索取样品和开发工具。

使用特权

评论回复
5
缥缈九哥|  楼主 | 2014-11-10 11:55 | 只看该作者
详细手册我有。但是好像我不能上传附件,不知道是不是我WIN81和IE11的原因 。QQ14131338上联系我。

使用特权

评论回复
6
wuhaiduo| | 2015-1-8 19:02 | 只看该作者
没参考价值

使用特权

评论回复
7
缥缈九哥|  楼主 | 2015-1-17 23:54 | 只看该作者
wuhaiduo 发表于 2015-1-8 19:02
没参考价值

为什么没有参考价值呢?

使用特权

评论回复
8
gaoyang9992006| | 2015-1-18 13:29 | 只看该作者
我看懂了,那个串口波特率设置的真高大上。

使用特权

评论回复
9
gaoyang9992006| | 2015-1-18 13:29 | 只看该作者
那么高的串口波特率,收发误码率会不会多?

使用特权

评论回复
10
wishu| | 2015-1-19 11:09 | 只看该作者
本帖最后由 wishu 于 2015-1-19 11:13 编辑

不知下面的程序是否有参考价值,反正我是用得好好的。

void DMX_Init(void)
{
SYS->IPRSTC2 |=  SYS_IPRSTC2_UART0_RST_Msk;
SYS->IPRSTC2 &= ~SYS_IPRSTC2_UART0_RST_Msk;
  UART0->FUN_SEL = UART_FUNC_SEL_RS485;                           //使能RS485
UART0->BAUD = UART_BAUD_MODE2 | UART_BAUD_MODE2_DIVIDER(__HXT, 250000);
//UART0->BAUD = UART_BAUD_MODE2 | UART_BAUD_MODE2_DIVIDER(__HIRC, 250000);

  UART0->LCR  = UART_WORD_LEN_8 | UART_PARITY_NONE | UART_STOP_BIT_1;// 8位数据, 2-stop, no parity
  UART0->LCR &= ~UART_PARITY_MARK;                             //校验位禁止

//  UART0->FCR    = (UART0->FCR & (~UART_FCR_RFITL_Msk)) | UART_FCR_RFITL_14BYTES;// 收1字节以上中断

  UART0->IER    = 0 ;                                                               // 中断, 这里没使能
  UART0->IER |= UART_IER_RDA_IEN_Msk | UART_IER_RLS_IEN_Msk | UART_IER_TOUT_IEN_Msk;//使能中断

  NVIC_SetPriority(UART02_IRQn, 1) ;                  
  NVIC->ISER[0] = 1 << UART02_IRQn ;                       // 打开中断向量
  UART0->ALT_CSR= UART_ALT_CSR_RS485_NMM_Msk;              //使能 RS-485 普通操作模式 (NMM)
}
/*---------------------------------------------------------------------------------------------------------*/
/* ISR to handle UART Channel 0 interrupt event                                                            */
/*---------------------------------------------------------------------------------------------------------*/
void UART02_IRQHandler(void)
{
   static uint16_t Counter = 0;  //  DMX地址
  static uint8_t slaveCount = 0;
  static uint8_t rece_temp_tick = 0;
  uint8_t rece_data;
   uint32_t u32IntSts = UART0->ISR;

    if((u32IntSts & UART_ISR_RLS_INT_Msk) && (u32IntSts & UART_ISR_RDA_INT_Msk))           /* RLS INT & RDA INT */ //For RS485 Detect Address
    {
   if(UART0->FSR & UART_FSR_BIF_Msk)   /* ADD_IF, RS485 mode */
   {
    rece_data = UART0->RBR;   
    if(rece_data==0)
    {
     Counter=0;
     rece_flag|=DMX_start;
     if(rece_temp_tick>2)rece_temp_tick=0;
    }
   }
    }
    else if(u32IntSts & UART_ISR_RDA_INT_Msk)
    {
      rece_data = UART0->RBR;
   rece_flag |= RS485_sig;
   if(rece_flag&DMX_start)
   {   
    if((++Counter)>DMX_addr)
    {
     if((Counter-DMX_addr) <= chanmax){DMX_rece_temp[rece_temp_tick][Counter-DMX_addr-1] = rece_data;}
     else{rece_flag|=DMX_end;rece_flag&=~DMX_start;rece_temp_tick++;}
    }
   }
    }
  else if(u32IntSts & UART_ISR_TOUT_INT_Msk) //UART_ISR_TOUT_IF_Msk
  {
  }
    else if(u32IntSts & UART_ISR_BUF_ERR_INT_Msk)     /* Buffer Error INT */
    {
        UART0->FSR |= (UART_FSR_RX_OVER_IF_Msk | UART_FSR_TX_OVER_IF_Msk);
    }
  UART0->FSR |= UART_FSR_PEF_Msk | UART_FSR_FEF_Msk | UART_FSR_BIF_Msk;
}

使用特权

评论回复
11
youxin2004| | 2015-6-6 15:51 | 只看该作者
你好请问一下:
1.你程序里使用了UART_FSR_RS485_ADD_DETF_Msk,是否只能用于UART0,1;
2.接收可用数据中断的处理中,为什么用for(uint32_t i=0;i<13;i++),设置的FIFO深度不是14byte吗?

使用特权

评论回复
12
Messi1999| | 2015-6-6 21:29 | 只看该作者
看到了,谢谢九哥

使用特权

评论回复
13
gaoyang9992006| | 2015-6-11 17:49 | 只看该作者
我经常来看九哥的帖子,每次看每次有新的收获,。

使用特权

评论回复
14
mintspring| | 2015-6-14 11:55 | 只看该作者
不知道九哥最近忙啥呢,今年还在推广新唐啊?

使用特权

评论回复
15
734774645| | 2015-6-14 18:13 | 只看该作者
那个详细手册你可以上传百度云盘,然后分享来。

使用特权

评论回复
16
yinzhihong| | 2015-7-2 09:36 | 只看该作者
wishu 发表于 2015-1-19 11:09
不知下面的程序是否有参考价值,反正我是用得好好的。

void DMX_Init(void)

使用特权

评论回复
17
ccw1986| | 2015-7-3 10:49 | 只看该作者
在汽车之家也有个九哥

使用特权

评论回复
18
Luis德华| | 2015-7-5 21:25 | 只看该作者
谢谢九个的蚊香,我也不用倒车了

使用特权

评论回复
19
oahzhao| | 2015-8-15 16:55 | 只看该作者
不错的讨论贴!

使用特权

评论回复
20
声艺舞美| | 2016-7-4 11:11 | 只看该作者
这对舞台DMX512信号控台的单片机开发有大用啊,联系我

使用特权

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

本版积分规则

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

67

主题

1868

帖子

271

粉丝