打印
[DemoCode下载]

M051 UART的RS485模式

[复制链接]
2953|14
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主


主机模式
/****************************************************************************
* [url=home.php?mod=space&uid=288409]@file[/url]     main.c
* [url=home.php?mod=space&uid=895143]@version[/url]  V1.00
* $Revision: 7 $
* $Date: 14/01/28 11:45a $
* [url=home.php?mod=space&uid=247401]@brief[/url]    M051 Series UART Interface Controller Driver Sample Code
*
* @note
* Copyright (C) 2011 Nuvoton Technology Corp. All rights reserved.
*
******************************************************************************/
#include <stdio.h>
#include "M051Series.h"


#define PLL_CLOCK           50000000


#define MATCH_ADDRSS1     0xC0
#define MATCH_ADDRSS2     0xA2
#define UNMATCH_ADDRSS1   0xB1
#define UNMATCH_ADDRSS2   0xD3


/*---------------------------------------------------------------------------------------------------------*/
/* Define functions prototype                                                                              */
/*---------------------------------------------------------------------------------------------------------*/
extern char GetChar(void);
int32_t main(void);
void RS485_SendAddressByte(uint8_t u8data);
void RS485_SendDataByte(uint8_t *pu8TxBuf, uint32_t u32WriteBytes);
void RS485_9bitModeMaster(void);


/*---------------------------------------------------------------------------------------------------------*/
/*  RS485 Transmit Control  (Address Byte: Parity Bit =1 , Data Byte:Parity Bit =0)                        */
/*---------------------------------------------------------------------------------------------------------*/
void RS485_SendAddressByte(uint8_t u8data)
{
    /* Set UART parity as MARK and ship baud rate setting */
    UART_SetLine_Config(UART1, 0, UART_WORD_LEN_8, UART_PARITY_MARK, UART_STOP_BIT_1);

    /* Send data */
    UART_WRITE(UART1, u8data);
}

void RS485_SendDataByte(uint8_t *pu8TxBuf, uint32_t u32WriteBytes)
{
    /* Set UART parity as SPACE and ship baud rate setting */
    UART_SetLine_Config(UART1, 0, UART_WORD_LEN_8, UART_PARITY_SPACE, UART_STOP_BIT_1);

    /* Send data */
    UART_Write(UART1, pu8TxBuf, u32WriteBytes);
}

/*---------------------------------------------------------------------------------------------------------*/
/*  RS485 Transmit Test                                                                                    */
/*---------------------------------------------------------------------------------------------------------*/
void RS485_9bitModeMaster()
{
    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");
    printf("+-----------------------------------------------------------+\n");
    printf("|     Pin Configure                                         |\n");
    printf("+-----------------------------------------------------------+\n");
    printf("|    _______                                    _______     |\n");
    printf("|   |       |                                  |       |    |\n");
    printf("|   |Master |---TXD1(P1.3) <====> RXD1(P1.2)---| Slave |    |\n");
    printf("|   |       |---RTS1(P0.1) <====> RTS1(P0.1)---|       |    |\n");
    printf("|   |_______|                                  |_______|    |\n");
    printf("|                                                           |\n");
    printf("+-----------------------------------------------------------+\n");

    /*
        The sample code is used to test RS485 9-bit mode and needs
        two Module test board to complete the test.
        Master:
            1.Set AUD mode and HW will control RTS pin. LEV_RTS is set to '0'.
            2.Master will send four different address with 10 bytes data to test Slave.
            3.Address bytes : the parity bit should be '1'. (Set UA_LCR = 0x2B)
            4.Data bytes : the parity bit should be '0'. (Set UA_LCR = 0x3B)
            5.RTS pin is low in idle state. When master is sending,
              RTS pin will be pull high.

        Slave:
            1.Set AAD and AUD mode firstly. LEV_RTS is set to '0'.
            2.The received byte, parity bit is '1' , is considered "ADDRESS".
            3.The received byte, parity bit is '0' , is considered "DATA".  (Default)
            4.AAD: The slave will ignore any data until ADDRESS match ADDR_MATCH value.
              When RLS and RDA interrupt is happened,it means the ADDRESS is received.
              Check if RS485_ADD_DETF is set and read UA_RBR to clear ADDRESS stored in rx_fifo.

              NMM: The slave will ignore data byte until disable RX_DIS.
              When RLS and RDA interrupt is happened,it means the ADDRESS is received.
              Check the ADDRESS is match or not by user in UART_IRQHandler.
              If the ADDRESS is match,clear RX_DIS bit to receive data byte.
              If the ADDRESS is not match,set RX_DIS bit to avoid data byte stored in FIFO.
    */

    printf("\n");
    printf("+-----------------------------------------------------------+\n");
    printf("|           RS485  Function Test (9-bit Master)             |\n");
    printf("+-----------------------------------------------------------+\n");
    printf("| The function will send different address with 10 data bytes|\n");
    printf("| to test RS485 9-bit mode. Please connect TX/RX to another |\n");
    printf("| 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 low level active */
    UART1->MCR &= ~UART_MCR_LEV_RTS_Msk;
    UART1->MCR |= UART_RTS_IS_LOW_LEV_ACTIVE;

    /* 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 For 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("\nTransfer Done\n");

}

void SYS_Init(void)
{
    /*---------------------------------------------------------------------------------------------------------*/
    /* Init System Clock                                                                                       */
    /*---------------------------------------------------------------------------------------------------------*/

    /* Enable Internal RC 22.1184MHz clock */
    CLK_EnableXtalRC(CLK_PWRCON_OSC22M_EN_Msk);

    /* Waiting for Internal RC clock ready */
    CLK_WaitClockReady(CLK_CLKSTATUS_OSC22M_STB_Msk);

    /* Switch HCLK clock source to Internal RC and HCLK source divide 1 */
    CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_HIRC, CLK_CLKDIV_HCLK(1));

    /* Enable external XTAL 12MHz clock */
    CLK_EnableXtalRC(CLK_PWRCON_XTL12M_EN_Msk);

    /* Waiting for external XTAL clock ready */
    CLK_WaitClockReady(CLK_CLKSTATUS_XTL12M_STB_Msk);

    /* Set core clock as PLL_CLOCK from PLL */
    CLK_SetCoreClock(PLL_CLOCK);

    /* Enable UART module clock */
    CLK_EnableModuleClock(UART0_MODULE);
    CLK_EnableModuleClock(UART1_MODULE);

    /* Select UART module clock source */
    CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART_S_HXT, CLK_CLKDIV_UART(1));
    CLK_SetModuleClock(UART1_MODULE, CLK_CLKSEL1_UART_S_HXT, CLK_CLKDIV_UART(1));

    /*---------------------------------------------------------------------------------------------------------*/
    /* Init I/O Multi-function                                                                                 */
    /*---------------------------------------------------------------------------------------------------------*/

    /* Set P3 multi-function pins for UART0 RXD and TXD */
    SYS->P3_MFP &= ~(SYS_MFP_P30_Msk | SYS_MFP_P31_Msk);
    SYS->P3_MFP |= (SYS_MFP_P30_RXD0 | SYS_MFP_P31_TXD0);

    /* Set P1 multi-function pins for UART1 RXD and TXD */
    SYS->P1_MFP &= ~(SYS_MFP_P12_Msk | SYS_MFP_P13_Msk);
    SYS->P1_MFP |= (SYS_MFP_P12_RXD1 | SYS_MFP_P13_TXD1);

    /* Set P0 multi-function pins for UART1 RTS */
    SYS->P0_MFP = SYS->P0_MFP & (~SYS_MFP_P01_Msk) | SYS_MFP_P01_RTS1;


}

void UART0_Init()
{
    /*---------------------------------------------------------------------------------------------------------*/
    /* Init UART                                                                                               */
    /*---------------------------------------------------------------------------------------------------------*/
    /* Reset UART0 module */
    SYS_ResetModule(UART0_RST);

    /* Configure UART0 and set UART0 Baudrate */
    UART_Open(UART0, 115200);
}

void UART1_Init()
{
    /*---------------------------------------------------------------------------------------------------------*/
    /* Init UART                                                                                               */
    /*---------------------------------------------------------------------------------------------------------*/
    /* Reset UART1 module */
    SYS_ResetModule(UART1_RST);

    /* Configure UART1 and set UART1 Baudrate */
    UART_Open(UART1, 115200);
}

/*---------------------------------------------------------------------------------------------------------*/
/* MAIN function                                                                                           */
/*---------------------------------------------------------------------------------------------------------*/
int main(void)
{
    /* Unlock protected registers */
    SYS_UnlockReg();

    /* Init System, IP clock and multi-function I/O */
    SYS_Init();

    /* Lock protected registers */
    SYS_LockReg();

    /* Init UART0 for printf */
    UART0_Init();

    /* Init UART1 for testing */
    UART1_Init();

    /*---------------------------------------------------------------------------------------------------------*/
    /* SAMPLE CODE                                                                                             */
    /*---------------------------------------------------------------------------------------------------------*/

    printf("\n\nCPU [url=home.php?mod=space&uid=72445]@[/url] %dHz\n", SystemCoreClock);

    printf("\n\nUART Sample Program\n");

    /* UART RS485 sample master function */
    RS485_9bitModeMaster();

    while(1);

}


沙发
捉虫天师|  楼主 | 2016-7-28 19:32 | 只看该作者
从机模式
/****************************************************************************
* @file     main.c
* @version  V1.00
* $Revision: 7 $
* $Date: 14/01/29 2:05p $
* @brief    M051 Series UART Interface Controller Driver Sample Code
*
* @note
* Copyright (C) 2011 Nuvoton Technology Corp. All rights reserved.
*
******************************************************************************/
#include <stdio.h>
#include "M051Series.h"


#define PLL_CLOCK           50000000


#define IS_USE_RS485NMM   0      //1:Select NMM_Mode , 0:Select AAD_Mode
#define MATCH_ADDRSS1     0xC0
#define MATCH_ADDRSS2     0xA2
#define UNMATCH_ADDRSS1   0xB1
#define UNMATCH_ADDRSS2   0xD3


/*---------------------------------------------------------------------------------------------------------*/
/* Define functions prototype                                                                              */
/*---------------------------------------------------------------------------------------------------------*/
extern char GetChar(void);
int32_t main(void);
void RS485_HANDLE(void);
void RS485_9bitModeSlave(void);


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

/*---------------------------------------------------------------------------------------------------------*/
/* RS485 Callback function                                                                                 */
/*---------------------------------------------------------------------------------------------------------*/
void RS485_HANDLE()
{
    volatile uint32_t addr = 0;
    volatile uint32_t u32IntSts = UART1->ISR;

    /* RLS INT & RDA INT */  //For RS485 Detect Address
    if((u32IntSts & UART_ISR_RLS_INT_Msk) && (u32IntSts & UART_ISR_RDA_INT_Msk))
    {
        if(UART1->FSR & UART_FSR_RS485_ADD_DETF_Msk)    /* ADD_IF, RS485 mode */
        {
            addr = UART1->RBR;
            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((u32IntSts & UART_ISR_RDA_INT_Msk) || (u32IntSts & UART_ISR_TOUT_INT_Msk))  /* Rx Ready or Time-out INT*/
    {
        /* Handle received data */
        printf("%d,", UART1->RBR);
    }

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

/*---------------------------------------------------------------------------------------------------------*/
/*  RS485 Receive Test  (IS_USE_RS485NMM: 0:AAD  1:NMM)                                                    */
/*---------------------------------------------------------------------------------------------------------*/
void RS485_9bitModeSlave()
{

    printf("\n");
    printf("+-----------------------------------------------------------+\n");
    printf("|     Pin Configure                                         |\n");
    printf("+-----------------------------------------------------------+\n");
    printf("|    _______                                    _______     |\n");
    printf("|   |       |                                  |       |    |\n");
    printf("|   |Master |---TXD1(P1.3) <====> RXD1(P1.2)---| Slave |    |\n");
    printf("|   |       |---RTS1(P0.1) <====> RTS1(P0.1)---|       |    |\n");
    printf("|   |_______|                                  |_______|    |\n");
    printf("|                                                           |\n");
    printf("+-----------------------------------------------------------+\n");
    printf("|           RS485  Function Test (9-bit Slave)              |\n");
    printf("+-----------------------------------------------------------+\n");

    /*
        The sample code is used to test RS485 9-bit mode and needs
        two Module test board to complete the test.
        Master:
            1.Set AUD mode and HW will control RTS pin. LEV_RTS is set to '0'.
            2.Master will send four different address with 10 bytes data to test Slave.
            3.Address bytes : the parity bit should be '1'. (Set UA_LCR = 0x2B)
            4.Data bytes : the parity bit should be '0'. (Set UA_LCR = 0x3B)
            5.RTS pin is low in idle state. When master is sending,
              RTS pin will be pull high.

        Slave:
            1.Set AAD and AUD mode firstly. LEV_RTS is set to '0'.
            2.The received byte, parity bit is '1' , is considered "ADDRESS".
            3.The received byte, parity bit is '0' , is considered "DATA".  (Default)
            4.AAD: The slave will ignore any data until ADDRESS match ADDR_MATCH value.
              When RLS and RDA interrupt is happened,it means the ADDRESS is received.
              Check if RS485_ADD_DETF is set and read UA_RBR to clear ADDRESS stored in rx_fifo.

              NMM: The slave will ignore data byte until disable RX_DIS.
              When RLS and RDA interrupt is happened,it means the ADDRESS is received.
              Check the ADDRESS is match or not by user in UART_IRQHandler.
              If the ADDRESS is match,clear RX_DIS bit to receive data byte.
              If the ADDRESS is not match,set RX_DIS bit to avoid data byte stored in FIFO.
    */

    /* Set Data Format, Only need parity enable whenever 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 low level active */
    UART1->MCR &= ~UART_MCR_LEV_RTS_Msk;
    UART1->MCR |= UART_RTS_IS_LOW_LEV_ACTIVE;

#if(IS_USE_RS485NMM == 1)

    printf("\n");
    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 IRQ */
    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\Time-out Interrupt */
    UART_DISABLE_INT(UART1, (UART_IER_RDA_IEN_Msk | UART_IER_RLS_IEN_Msk | UART_IER_RTO_IEN_Msk));

    printf("\nEnd test\n");

}


void SYS_Init(void)
{
    /*---------------------------------------------------------------------------------------------------------*/
    /* Init System Clock                                                                                       */
    /*---------------------------------------------------------------------------------------------------------*/

    /* Enable Internal RC 22.1184MHz clock */
    CLK_EnableXtalRC(CLK_PWRCON_OSC22M_EN_Msk);

    /* Waiting for Internal RC clock ready */
    CLK_WaitClockReady(CLK_CLKSTATUS_OSC22M_STB_Msk);

    /* Switch HCLK clock source to Internal RC and HCLK source divide 1 */
    CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_HIRC, CLK_CLKDIV_HCLK(1));

    /* Enable external XTAL 12MHz clock */
    CLK_EnableXtalRC(CLK_PWRCON_XTL12M_EN_Msk);

    /* Waiting for external XTAL clock ready */
    CLK_WaitClockReady(CLK_CLKSTATUS_XTL12M_STB_Msk);

    /* Set core clock as PLL_CLOCK from PLL */
    CLK_SetCoreClock(PLL_CLOCK);

    /* Enable UART module clock */
    CLK_EnableModuleClock(UART0_MODULE);
    CLK_EnableModuleClock(UART1_MODULE);

    /* Select UART module clock source */
    CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART_S_HXT, CLK_CLKDIV_UART(1));
    CLK_SetModuleClock(UART1_MODULE, CLK_CLKSEL1_UART_S_HXT, CLK_CLKDIV_UART(1));

    /*---------------------------------------------------------------------------------------------------------*/
    /* Init I/O Multi-function                                                                                 */
    /*---------------------------------------------------------------------------------------------------------*/

    /* Set P3 multi-function pins for UART0 RXD and TXD */
    SYS->P3_MFP &= ~(SYS_MFP_P30_Msk | SYS_MFP_P31_Msk);
    SYS->P3_MFP |= (SYS_MFP_P30_RXD0 | SYS_MFP_P31_TXD0);

    /* Set P1 multi-function pins for UART1 RXD and TXD */
    SYS->P1_MFP &= ~(SYS_MFP_P12_Msk | SYS_MFP_P13_Msk);
    SYS->P1_MFP |= (SYS_MFP_P12_RXD1 | SYS_MFP_P13_TXD1);

    /* Set P0 multi-function pins for UART1 RTS */
    SYS->P0_MFP = SYS->P0_MFP & (~SYS_MFP_P01_Msk) | SYS_MFP_P01_RTS1;


}

void UART0_Init()
{
    /*---------------------------------------------------------------------------------------------------------*/
    /* Init UART                                                                                               */
    /*---------------------------------------------------------------------------------------------------------*/
    /* Reset UART0 module */
    SYS_ResetModule(UART0_RST);

    /* Configure UART0 and set UART0 Baudrate */
    UART_Open(UART0, 115200);
}

void UART1_Init()
{
    /*---------------------------------------------------------------------------------------------------------*/
    /* Init UART                                                                                               */
    /*---------------------------------------------------------------------------------------------------------*/
    /* Reset UART1 module */
    SYS_ResetModule(UART1_RST);

    /* Configure UART1 and set UART1 Baudrate */
    UART_Open(UART1, 115200);
}

/*---------------------------------------------------------------------------------------------------------*/
/* MAIN function                                                                                           */
/*---------------------------------------------------------------------------------------------------------*/
int32_t main(void)
{

    /* Unlock protected registers */
    SYS_UnlockReg();

    /* Init System, IP clock and multi-function I/O */
    SYS_Init();

    /* Lock protected registers */
    SYS_LockReg();

    /* Init UART0 for printf */
    UART0_Init();

    /* Init UART1 for testing */
    UART1_Init();

    /*---------------------------------------------------------------------------------------------------------*/
    /* SAMPLE CODE                                                                                             */
    /*---------------------------------------------------------------------------------------------------------*/

    printf("\n\nCPU @ %dHz\n", SystemCoreClock);

    printf("\n\nUART Sample Program\n");

    /* UART RS485 sample slave function */
    RS485_9bitModeSlave();

}


使用特权

评论回复
板凳
捉虫天师|  楼主 | 2016-7-28 19:46 | 只看该作者
RS-485 模式
UART 支持RS-485 9位模式. RS-485模式通过设置UA_FUN_SEL寄存器选择RS-485功能设定。使用来
自异步串行口的RTS控制信号来使能RS-485驱动器,执行RS-485驱动器控制。在RS-485模式下, RX
与TX的许多特性与UART相同。
RS-485 模式下,控制器可以配置成可寻址的RS-485从机, RS-485主机发送器将通过设置校验位 (第9
位)为1来识别一个地址字符。对于数据字符,校验位设置为0. 软件可通过设置寄存器UA_LCR 控制第9
位 (PBE , EPE 和 SPE置位, 第9位发送0 , PBE 和 SPE 置位, EPE清零, 第9位发送1). 该控制器支持三
种操作模式: RS-485 普通多点模式(NMM), RS-485 自动地址识别模式 (AAD) 和RS-485 自动方向控制
模式(AUD), 可通过编程UA_RS-485_CSR寄存器选择其中一种工作模式, 通过设置UA_TOR [DLY] 可以
设置上一个停止位与下一个开始位之间的延迟时间

使用特权

评论回复
地板
捉虫天师|  楼主 | 2016-7-28 19:48 | 只看该作者
RS-485 普通多点模式 (NMM)
RS-485 普通多点模式, 首先必须软件配置在地址位之前检测到的数据是否存储于RX-FIFO中。如果想软
件忽略地址位之前检测到的所有数据,则接下来是设置UART_FCR[RS485_RX_DIS]和使能UA_RS-
485[RS485_NMM],这样,接收器忽略所有数据直至检测到地址字节( bit9=1)并将地址字节数据存储
于 RX-FIFO 中 。 如 果 想 软 件 接 收 检 测 到 地 址 位 之 前 的 所 有 数 据 , 接 下 来 就 是 禁 止 UART_FCR
[RS485_RX_DIS]和使能UA_RS-485[RS485_NMM],这样,接收器就会接收所有数据。如果检测到地
址位, RS-485控制器会向CPU产生一个中断,软件可通过设定UA_RS-485_FCR [RX_DIS]来决定是否
使能接收器来接收接下来的数据字节。如果使能接收器接收,所有接收的数据都将被接收并存储于RXFIFO中,如果禁用接收器,则接收到的所有数据都将被忽略直至下一个地址位被检测到。若软件设置
UA_RS-485禁用接收器, 当检测到下一个地址字节,控制器清UA_RS-485_FCR [RX_DIS]位,地址字节
数据存储到RX-FIFO.

使用特权

评论回复
5
捉虫天师|  楼主 | 2016-7-28 19:51 | 只看该作者
RS-485 自动地址识别模式 (AAD)
RS-485自动地址识别模式下, 接收器在检测到地址字节( bit9=1)并且地址字节数据与UA_ALT_CSR
[ADDR_MATCH]的值相匹配之前,忽略所有数据. 地址字节数据将被存储在RX-FIFO. 所有接收字节数
据将被接受,并存储于RX-FIFO 直到地址字节不匹配UA_ALT_CSR [ADDR_MATCH] 的值为止.
RS-485 自动方向模式 (AUD)
RS-485控制器的另一个功能是自动方向控制. 使用来自异步串行口的RTS控制信号来使能RS-485驱动
器,执行RS-485驱动器控制. RTS线被连接到RS-485驱动器使能,以便设置RTS线为高(逻辑1)使能
RS-485 驱动器. 设置RTS为低(逻辑0),使驱动器进入tri-state状态. 用户通过设置寄存器UA_MCR 中
的LEV_RTS位改变 RTS 驱动电平.

使用特权

评论回复
6
捉虫天师|  楼主 | 2016-7-28 20:00 | 只看该作者
编程流程示例:
1. 设置寄存器UA_FUN_SEL中的FUN_SEL位选择RS-485功能.
2. 设置寄存器UA_FCR 中的RX_DIS 位使能或禁用RS-485 接收器
3. 设置RS-485_NMM 或 RS-485_AAD 模式.
4. 如果选择RS-485_AAD 模式, ADDR_MATCH设置成自动地址匹配值.
5. 设置RS-485_AUD选择自动方向控制

使用特权

评论回复
7
捉虫天师|  楼主 | 2016-7-28 20:01 | 只看该作者

使用特权

评论回复
8
zhuomuniao110| | 2016-7-29 00:10 | 只看该作者

1、通讯距离

RS232口最大通讯距离是15米,而RS422/485最大通讯距离是1200米。

2、所连接设备个数

RS232只能连接一个设备,而RS485可以连接多个设备。

3、端口的定义

RS232是标准接口,为D形9针头,所连接设备的接口的信号定义是一样的,其信号定义如下:


    而RS422/RS485为非标准接口,一般为15针串行接口(也有使用9针接口的),每个设备的引脚定义也不一样。另外还需要说明的是,RS422和RS485也有区别:RS422为4线制,全双工模式;RS485为两线制,半双工模式。



使用特权

评论回复
9
zhuomuniao110| | 2016-7-29 00:13 | 只看该作者

1、通讯距离

RS232口最大通讯距离是15米,而RS422/485最大通讯距离是1200米。

2、所连接设备个数

RS232只能连接一个设备,而RS485可以连接多个设备。

3、端口的定义

RS232是标准接口,为D形9针头,所连接设备的接口的信号定义是一样的,其信号定义如下:


    而RS422/RS485为非标准接口,一般为15针串行接口(也有使用9针接口的),每个设备的引脚定义也不一样。另外还需要说明的是,RS422和RS485也有区别:RS422为4线制,全双工模式;RS485为两线制,半双工模式。



使用特权

评论回复
10
捉虫天师|  楼主 | 2016-7-30 16:21 | 只看该作者
这个DB9的接口没找到VCC供电,还要单独搞个供电的,要不可以给外挂省了个电源了

使用特权

评论回复
11
稳稳の幸福| | 2016-7-30 17:06 | 只看该作者
通信距离决定了使用场合,比如同一个设备内的通信是可以用232的,一般是TTL232,如果是一两米内通信就是用RS232.
如果是2米以上,1000米内,那就是用485通信了。

使用特权

评论回复
12
捉虫天师|  楼主 | 2016-8-4 08:22 | 只看该作者
我们用外场设备传输,几十米的都使用485,性能很稳定。

使用特权

评论回复
13
quray1985| | 2016-8-8 16:44 | 只看该作者
串口怎么控制485器件呢?

使用特权

评论回复
14
gejigeji521| | 2016-8-8 22:35 | 只看该作者
RS422/RS485为非标准接口,一般为15针串行接口(也有使用9针接口的)

使用特权

评论回复
15
捉虫天师|  楼主 | 2016-8-14 15:24 | 只看该作者
至于怎么用,还看具体使用环境。

使用特权

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

本版积分规则

195

主题

3117

帖子

7

粉丝