打印
[技术问答]

UART 为何收不到第9位数据标志 ,请指教 谢谢

[复制链接]
2416|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
LED吴生|  楼主 | 2017-8-7 17:10 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式


SYS_ResetModule(UART0_RST);

UART_SetLine_Config(UART0, 0, UART_WORD_LEN_8,UART_PARITY_MARK, UART_STOP_BIT_2);//数据格式
UART0->FUNCSEL = UART_FUNCSEL_RS485;         
UART0->FIFO |= UART_FIFO_RXOFF_Msk;//0 接收使能 1=接收器禁止  要在模式之前设置
//----------------------------多点模式  和自动地址检测  --------------自动地址匹配值
UART_SelectRS485Mode(UART0, UART_ALTCTL_RS485NMM_Msk|UART_ALTCTL_ADDRDEN_Msk, 0x00);//RS485模式
//| UART_ALTCTL_RS485AUD_Msk自动方向控制
// UART_ALTCTL_ADDRDEN_Msk;//自动地址检测使能
       
UART_ENABLE_INT(UART0, UART_INTEN_RDAIEN_Msk);//中断使能寄存器
//UART_INTEN_RDAIEN_Msk  接收到数据中断
//| UART_INTEN_RLSIEN_Msk Receive中断
//UART_INTEN_RXTOIEN_Msk//超时中断
NVIC_EnableIRQ(UART0_IRQn);//使能中断
UART_Open(UART0,250000);



void UART0_IRQHandler(void)
{
volatile uint32_t addr = 0;       

  if(UART_RS485_GET_ADDR_FLAG(UART0))//收到第9位地址------------------------------------------------------这里进不来-----------------
               {                       
                                     PE3=!PE3;
                         UART_RS485_CLEAR_ADDR_FLAG(UART0);//清第9位地址位标志
               }
  if(UART_GET_INT_FLAG(UART0, UART_INTSTS_RDAINT_Msk))//收到数据中断 ----------------------------------------这里正常中断-------
            {
           PD5=!PD5;

                addr = UART_READ(UART0);        //读数据  清中断
                 //  printf("%d  ",addr );
      }
                       

       
       
}

沙发
LED吴生|  楼主 | 2017-8-7 17:26 | 只看该作者
CLK_EnableModuleClock(UART0_MODULE);
    CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UARTSEL_PLL, CLK_CLKDIV0_UART(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);       

配置是正常的

使用特权

评论回复
板凳
zhuomuniao110| | 2017-8-7 20:45 | 只看该作者
默认的那种应该没问题吧。9BIT的没用过啊。

使用特权

评论回复
地板
LED吴生|  楼主 | 2017-8-7 22:40 | 只看该作者
这是个DMX512 解码程序   测试 老是识别不到第 9位  也就是帧头
255 100 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
255 100 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

使用特权

评论回复
5
LED吴生|  楼主 | 2017-8-8 09:26 | 只看该作者
有人遇到过吗  

第9位中断进不去

使用特权

评论回复
6
a_ziliu| | 2017-8-8 09:31 | 只看该作者
//master send
void RS485_9bitModeMaster()
{
    volatile int32_t i32;
    uint8_t g_u8SendDataGroup1[10] = {0};
    uint8_t g_u8SendDataGroup2[10] = {0};
    uint8_t g_u8SendDataGroup3[10] = {0};
    uint8_t g_u8SendDataGroup4[10] = {0};

    printf("\n\n");
    printf("+-----------------------------------------------------------+\n");
    printf("|               RS485 9-bit Master Test                     |\n");
    printf("+-----------------------------------------------------------+\n");
    printf("| The function will send different address with 10 data     |\n");
    printf("| bytes to test RS485 9-bit mode. Please connect TX/RX to   |\n");
    printf("| another board and wait its ready to receive.              |\n");
    printf("| Press any key to start...                                 |\n");
    printf("+-----------------------------------------------------------+\n\n");
    GetChar();

    /* Set RS485-Master as AUD mode */
    /* Enable AUD mode to HW control RTS pin automatically */
    /* You also can use GPIO to control RTS pin for replacing AUD mode*/
    UART_SelectRS485Mode(UART1, UART_ALT_CSR_RS485_AUD_Msk, 0);

    /* Set RTS pin active level as high level active */
    UART1->MCR &= ~UART_MCR_LEV_RTS_Msk;
    UART1->MCR |= UART_RTS_IS_HIGH_LEV_ACTIVE;

    /* Set TX delay time */
    UART1->TOR = 0x2000;

    /* Prepare Data to transmit*/
    for(i32 = 0; i32 < 10; i32++)
    {
        g_u8SendDataGroup1[i32] = i32;
        g_u8SendDataGroup2[i32] = i32 + 10;
        g_u8SendDataGroup3[i32] = i32 + 20;
        g_u8SendDataGroup4[i32] = i32 + 30;
    }

    /* Send different address and data for test */
    printf("Send Address %x and data 0~9\n", MATCH_ADDRSS1);
    RS485_SendAddressByte(MATCH_ADDRSS1);
    RS485_SendDataByte(g_u8SendDataGroup1, 10);

    printf("Send Address %x and data 10~19\n", UNMATCH_ADDRSS1);
    RS485_SendAddressByte(UNMATCH_ADDRSS1);
    RS485_SendDataByte(g_u8SendDataGroup2, 10);

    printf("Send Address %x and data 20~29\n", MATCH_ADDRSS2);
    RS485_SendAddressByte(MATCH_ADDRSS2);
    RS485_SendDataByte(g_u8SendDataGroup3, 10);

    printf("Send Address %x and data 30~39\n", UNMATCH_ADDRSS2);
    RS485_SendAddressByte(UNMATCH_ADDRSS2);
    RS485_SendDataByte(g_u8SendDataGroup4, 10);

    printf("Transfer Done\n");
}

//slave
void RS485_9bitModeSlave()
{
    /* Set Data Format, only need parity enable whatever parity ODD/EVEN */
    UART_SetLine_Config(UART1, 0, UART_WORD_LEN_8, UART_PARITY_EVEN, UART_STOP_BIT_1);

    /* Set RTS pin active level as high level active */
    UART1->MCR &= ~UART_MCR_LEV_RTS_Msk;
    UART1->MCR |= UART_RTS_IS_HIGH_LEV_ACTIVE;

#if(IS_USE_RS485NMM == 1)
    printf("+-----------------------------------------------------------+\n");
    printf("|    Normal Multidrop Operation Mode                        |\n");
    printf("+-----------------------------------------------------------+\n");
    printf("| The function is used to test 9-bit slave mode.            |\n");
    printf("| Only Address %x and %x,data can receive                   |\n", MATCH_ADDRSS1, MATCH_ADDRSS2);
    printf("+-----------------------------------------------------------+\n");

    /* Set RX_DIS enable before set RS485-NMM mode */
    UART1->FCR |= UART_FCR_RX_DIS_Msk;

    /* Set RS485-NMM Mode */
    UART_SelectRS485Mode(UART1, UART_ALT_CSR_RS485_NMM_Msk | UART_ALT_CSR_RS485_AUD_Msk, 0);

    /* Set RS485 address detection enable */
    UART1->ALT_CSR |= UART_ALT_CSR_RS485_ADD_EN_Msk;

#else
    printf("Auto Address Match Operation Mode\n");
    printf("+-----------------------------------------------------------+\n");
    printf("| The function is used to test 9-bit slave mode.            |\n");
    printf("|    Auto Address Match Operation Mode                      |\n");
    printf("+-----------------------------------------------------------+\n");
    printf("|Only Address %x,data can receive                          |\n", MATCH_ADDRSS1);
    printf("+-----------------------------------------------------------+\n");

    /* Set RS485-AAD Mode and address match is 0xC0 */
    UART_SelectRS485Mode(UART1, UART_ALT_CSR_RS485_AAD_Msk | UART_ALT_CSR_RS485_AUD_Msk, MATCH_ADDRSS1);

    /* Set RS485 address detection enable */
    UART1->ALT_CSR |= UART_ALT_CSR_RS485_ADD_EN_Msk;

#endif

    /* Enable RDA\RLS\Time-out Interrupt */
    UART_ENABLE_INT(UART1, (UART_IER_RDA_IEN_Msk | UART_IER_RLS_IEN_Msk | UART_IER_RTO_IEN_Msk));

    /* Enable UART1 interrupt */
    NVIC_EnableIRQ(UART1_IRQn);

    printf("Ready to receive data...(Press any key to stop test)\n");
    GetChar();

    /* Flush Rx FIFO */
    UART1->FCR |= UART_FCR_RFR_Msk;

    /* Disable RDA/RLS/RTO interrupt */
    UART_DISABLE_INT(UART1, (UART_IER_RDA_IEN_Msk | UART_IER_RLS_IEN_Msk | UART_IER_RTO_IEN_Msk));

    /* Set UART Function */
    UART_Open(UART1, 115200);

    printf("\nEnd test\n");
}

/*---------------------------------------------------------------------------------------------------------*/
/* ISR to handle UART Channel 1 interrupt event                                                            */
/*---------------------------------------------------------------------------------------------------------*/
void UART1_IRQHandler(void)
{
    RS485_HANDLE();
}


void RS485_HANDLE()
{
    volatile uint32_t addr = 0;
    volatile uint32_t regRX = 0xFF;
    volatile uint32_t u32IntSts = UART1->ISR;;

    if(UART_GET_INT_FLAG(UART1, UART_ISR_RLS_INT_Msk) && UART_GET_INT_FLAG(UART1, UART_ISR_RDA_INT_Msk))      /* RLS INT & RDA INT */
    {
        //if(UART1->FSR & UART_FSR_RS485_ADD_DETF_Msk)  /* ADD_IF, RS485 mode */
        if(UART_RS485_GET_ADDR_FLAG(UART1))
        {
            //addr = UART1->DATA;
            addr = UART_READ(UART1);
            UART_RS485_CLEAR_ADDR_FLAG(UART1);         /* clear ADD_IF flag */
            printf("\nAddr=0x%x,Get:", addr);

#if (IS_USE_RS485NMM ==1) //RS485_NMM
            /* if address match, enable RX to receive data, otherwise to disable RX. */
            /* In NMM mode,user can decide multi-address filter. In AAD mode,only one address can set */
            if((addr == MATCH_ADDRSS1) || (addr == MATCH_ADDRSS2))
            {
                UART1->FCR &= ~ UART_FCR_RX_DIS_Msk;  /* Enable RS485 RX */
            }
            else
            {
                printf("\n");
                UART1->FCR |= UART_FCR_RX_DIS_Msk;    /* Disable RS485 RX */
                UART1->FCR |= UART_FCR_RFR_Msk;       /* Clear data from RX FIFO */
            }
#endif
        }
    }
    else if(UART_GET_INT_FLAG(UART1, UART_ISR_RDA_INT_Msk) || UART_GET_INT_FLAG(UART1, UART_ISR_TOUT_INT_Msk))       /* Rx Ready or Time-out INT*/
    {
        /* Handle received data */
        printf("%d,", UART1->RBR);
    }

    else if(UART_GET_INT_FLAG(UART1, UART_ISR_BUF_ERR_INT_Msk))       /* Buffer Error INT */
    {
        printf("\nBuffer Error...\n");
        UART_ClearIntFlag(UART1, UART_ISR_BUF_ERR_INT_Msk);
    }
}

使用特权

评论回复
7
LED吴生|  楼主 | 2017-8-8 09:42 | 只看该作者
a_ziliu 发表于 2017-8-8 09:31
//master send
void RS485_9bitModeMaster()
{

这个是M0的   现在是M451  M451默认会用到fifo

使用特权

评论回复
8
LED吴生|  楼主 | 2017-8-8 11:25 | 只看该作者

ART_RS485_GET_ADDR_FLAG(UART0)
改成
(UART0->FIFOSTS &(1<<3))

还是一样检测不到第9位

使用特权

评论回复
9
LED吴生|  楼主 | 2017-8-8 14:41 | 只看该作者
10000010000000000000100000000

这是读
UART0->FIFOSTS ;
的值
可以看到是没有中断标志产生

使用特权

评论回复
10
LED吴生|  楼主 | 2017-8-8 15:36 | 只看该作者
LED吴生 发表于 2017-8-8 14:41
10000010000000000000100000000

这是读

只有 BIF和FEF不断的中断

使用特权

评论回复
11
天灵灵地灵灵| | 2017-8-8 19:50 | 只看该作者
M451的没用过,看看那个谁的书。

使用特权

评论回复
12
LED吴生|  楼主 | 2017-8-11 09:49 | 只看该作者
数据中断 正确  数据也正确   

就是 读不到地址的标志位  

分开检测 也是一样  有 帧错误和 break中断
if(u32IntSts & UART_INTSTS_RLSINT_Msk) //接收线中断
{
         
//          if(u32IntSts & UART_INTSTS_RLSIF_Msk) //接收线中断标志
//                {
//      PE3=!PE3;
//                       
//     }
                 if(u32fifioSts&UART_FIFOSTS_BIF_Msk)//BIF break中断标志 6
                 {
       PD2=!PD2;
                                 // printf("*");
     }

                 if(u32fifioSts&UART_FIFOSTS_FEF_Msk)//FEF 帧错误标志 5
                 {
        PD3=!PD3;
              //printf("#");                        
     }
         
                 if(u32fifioSts&UART_FIFOSTS_PEF_Msk)//PEF 奇偶错误标志 4
                 {
        PD4=!PD4;
     }
                           
                if(u32fifioSts&UART_FIFOSTS_ADDRDETF_Msk)//RS485地址位标记   3
                {
          PD5=!PD5;
                                       
     }       
               
                UART0->FIFOSTS |= UART_FIFOSTS_ADDRDETF_Msk | UART_FIFOSTS_PEF_Msk | UART_FIFOSTS_FEF_Msk | UART_FIFOSTS_BIF_Msk;//清标志  4种线中断
               

  }

使用特权

评论回复
13
LED吴生|  楼主 | 2017-8-12 10:27 | 只看该作者
void RS_485_9bit(void)
{
    volatile uint32_t addr = 0;
  //  volatile uint32_t regRX = 0xFF;
    volatile uint32_t u32IntSts = UART0->INTSTS;
    volatile uint32_t u32fifioSts = UART0->FIFOSTS;
          


//这里可以进入  但还是没有区分第9位 地址与数据位      是不是有BUG 啊  



   if((u32IntSts & UART_INTSTS_RDAINT_Msk)&&(u32fifioSts&UART_FIFOSTS_ADDRDETF_Msk))
    {

          addr = UART_READ(UART0); printf("%d ",addr);
                                       
                                        UART0->FIFOSTS |= UART_FIFOSTS_ADDRDETF_Msk | UART_FIFOSTS_PEF_Msk | UART_FIFOSTS_FEF_Msk | UART_FIFOSTS_BIF_Msk;//清标志  4种线中断

                }


}
/*---------------------------------------------------------------------------------------------------------*/
/* ISR to handle UART Channel 1 interrupt event                                                            */
/*---------------------------------------------------------------------------------------------------------*/
void UART0_IRQHandler(void)
{
                  
                RS_485_9bit();
}

使用特权

评论回复
14
lei_chn| | 2017-8-22 10:26 | 只看该作者
本帖最后由 lei_chn 于 2017-8-22 10:29 编辑

我用的是NUC240,也是进不去第九位。后来我每次在中断里都会重新打开第九位侦测模式,这样每次来地址都能侦测到了。
也不知道合不合理,至少功能算是实现了。
我把 中断 里打开第九位侦测的代码贴出来,大家讨论一下。
void UART1_IRQHandler(void)
{            前面的中断代码省略
    /* Set RX_DIS enable before set RS485-NMM mode */
    UART1->FCR |= UART_FCR_RX_DIS_Msk;
        
    if(UART_RS485_GET_ADDR_FLAG(UART1))
    {
        addr = UART_READ(UART1);
        UART_RS485_CLEAR_ADDR_FLAG(UART1);         /* clear ADD_IF flag */
    }

    /* Set RS485-NMM Mode */
    UART_SelectRS485Mode(UART1, UART_ALT_CSR_RS485_NMM_Msk, 0);

    /* Set RS485 address detection enable */
    UART1->ALT_CSR |= UART_ALT_CSR_RS485_ADD_EN_Msk;
   后面的中断代码省略
}

使用特权

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

本版积分规则

8

主题

84

帖子

1

粉丝