[DemoCode下载] M058S的从机模式485模式

[复制链接]
1894|7
 楼主| zhuotuzi 发表于 2017-1-28 10:03 | 显示全部楼层 |阅读模式
  1. /****************************************************************************
  2. * [url=home.php?mod=space&uid=288409]@file[/url]     main.c
  3. * [url=home.php?mod=space&uid=895143]@version[/url]  V3.00
  4. * $Revision: 4 $
  5. * $Date: 15/02/06 10:22a $
  6. * @brief
  7. *           Transmit and receive data in UART RS485 mode.
  8. *           This sample code needs to work with UART_RS485_Master.
  9. * @note
  10. * Copyright (C) 2011 Nuvoton Technology Corp. All rights reserved.
  11. *
  12. ******************************************************************************/
  13. #include <stdio.h>
  14. #include "M058S.h"


  15. #define PLL_CLOCK           50000000

  16. #define RXBUFSIZE           128

  17. #define IS_USE_RS485NMM     1      //1:Select NMM_Mode , 0:Select AAD_Mode
  18. #define MATCH_ADDRSS        0xC0


  19. /*---------------------------------------------------------------------------------------------------------*/
  20. /* Define functions prototype                                                                              */
  21. /*---------------------------------------------------------------------------------------------------------*/
  22. extern char GetChar(void);
  23. int32_t main(void);
  24. void RS485_HANDLE(void);
  25. void RS485_9bitModeSlave(void);

  26. volatile int32_t r_pointer = 0;
  27. uint8_t g_u8RecData[RXBUFSIZE] = {0};


  28. /*---------------------------------------------------------------------------------------------------------*/
  29. /* ISR to handle UART Channel 0 interrupt event                                                            */
  30. /*---------------------------------------------------------------------------------------------------------*/
  31. void UART0_IRQHandler(void)
  32. {
  33.     RS485_HANDLE();
  34. }

  35. /*---------------------------------------------------------------------------------------------------------*/
  36. /* RS485 Callback function                                                                                 */
  37. /*---------------------------------------------------------------------------------------------------------*/
  38. void RS485_HANDLE()
  39. {
  40.     volatile uint32_t addr = 0;
  41.     volatile uint32_t u32IntSts = UART0->ISR;

  42.     /* RLS INT & RDA INT */  //For RS485 Detect Address
  43.     if((u32IntSts & UART_ISR_RLS_INT_Msk) && (u32IntSts & UART_ISR_RDA_INT_Msk))
  44.     {
  45.         if(UART0->FSR & UART_FSR_RS485_ADD_DETF_Msk)    /* ADD_IF, RS485 mode */
  46.         {
  47.             addr = UART0->RBR;
  48.             UART_RS485_CLEAR_ADDR_FLAG(UART0);          /* clear ADD_IF flag */

  49. #if (IS_USE_RS485NMM ==1) //RS485_NMM

  50.             /* if address match, enable RX to receive data, otherwise to disable RX */
  51.             /* In NMM mode, user can decide multi-address filter */
  52.             /* In AAD mode, only one address can set */
  53.             if(addr == MATCH_ADDRSS)
  54.             {
  55.                 UART0->FCR &= ~ UART_FCR_RX_DIS_Msk;  /* Enable RS485 RX */
  56.             }
  57.             else
  58.             {
  59.                 UART0->FCR |= UART_FCR_RX_DIS_Msk;    /* Disable RS485 RX */
  60.                 UART0->FCR |= UART_FCR_RFR_Msk;       /* Clear data from RX FIFO */
  61.             }
  62. #endif
  63.         }
  64.     }
  65.     else if((u32IntSts & UART_ISR_RDA_INT_Msk) || (u32IntSts & UART_ISR_TOUT_INT_Msk))  /* Rx Ready or Time-out INT*/
  66.     {
  67.         /* Handle received data */
  68.         g_u8RecData[r_pointer++] = UART0->RBR;
  69.     }

  70.     else if(u32IntSts & UART_ISR_BUF_ERR_INT_Msk)     /* Buffer Error INT */
  71.     {
  72.         printf("\nBuffer Error...\n");
  73.         UART_ClearIntFlag(UART0, UART_ISR_BUF_ERR_INT_Msk);
  74.     }
  75. }

  76. /*---------------------------------------------------------------------------------------------------------*/
  77. /*  RS485 Receive Test  (IS_USE_RS485NMM: 0:AAD  1:NMM)                                                    */
  78. /*---------------------------------------------------------------------------------------------------------*/
  79. void RS485_9bitModeSlave()
  80. {
  81.     uint32_t i;

  82.     printf("\n");
  83.     printf("+-------------------------------------------------------------+\n");
  84.     printf("|     Pin Configure                                           |\n");
  85.     printf("+-------------------------------------------------------------+\n");
  86.     printf("|     _______                                    _______      |\n");
  87.     printf("|    |       |                                  |       |     |\n");
  88.     printf("|    |Master |--- TXD(P3.1) <====> RXD(P3.0) ---| Slave |     |\n");
  89.     printf("|    |       |--- RTS(P0.3) <====> RTS(P0.3) ---|       |     |\n");
  90.     printf("|    |_______|                                  |_______|     |\n");
  91.     printf("|                                                             |\n");
  92.     printf("+-------------------------------------------------------------+\n");
  93.     printf("|  Please enable semihosted to show messages on debug session.|\n");
  94.     printf("|  Keil users must define DEBUG_ENABLE_SEMIHOST in both C/C++ |\n");
  95.     printf("|  and Asm preprocessor symbols.                              |\n");
  96.     printf("|  IAR users must define DEBUG_ENABLE_SEMIHOST in both C/C++  |\n");
  97.     printf("|  Compiler and Assembler preprocessor symbols.               |\n");
  98.     printf("+-------------------------------------------------------------+\n");
  99.     printf("|            RS485  Function Test (9-bit Slave)               |\n");
  100.     printf("+-------------------------------------------------------------+\n");

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

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

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

  124.     /* Set Data Format, Only need parity enable whenever parity ODD/EVEN */
  125.     UART_SetLine_Config(UART0, 0, UART_WORD_LEN_8, UART_PARITY_EVEN, UART_STOP_BIT_1);

  126.     /* Set RTS pin active level as high level active */
  127.     UART0->MCR &= ~UART_MCR_LEV_RTS_Msk;
  128.     UART0->MCR |= UART_RTS_IS_HIGH_LEV_ACTIVE;

  129. #if(IS_USE_RS485NMM == 1)

  130.     printf("\n");
  131.     printf("+-------------------------------------------------------------+\n");
  132.     printf("|    Normal Multidrop Operation Mode                          |\n");
  133.     printf("+-------------------------------------------------------------+\n");
  134.     printf("| The function is used to test 9-bit slave mode.              |\n");
  135.     printf("| Only Address %x data can receive                            |\n", MATCH_ADDRSS);
  136.     printf("+-------------------------------------------------------------+\n");

  137.     /* Set RX_DIS enable before set RS485-NMM mode */
  138.     UART0->FCR |= UART_FCR_RX_DIS_Msk;

  139.     /* Set RS485-NMM Mode */
  140.     UART_SelectRS485Mode(UART0, UART_ALT_CSR_RS485_NMM_Msk | UART_ALT_CSR_RS485_AUD_Msk, 0);

  141.     /* Set RS485 address detection enable */
  142.     UART0->ALT_CSR |= UART_ALT_CSR_RS485_ADD_EN_Msk;

  143. #else
  144.     printf("+-------------------------------------------------------------+\n");
  145.     printf("| The function is used to test 9-bit slave mode.              |\n");
  146.     printf("|    Auto Address Match Operation Mode                        |\n");
  147.     printf("+-------------------------------------------------------------+\n");
  148.     printf("|Only Address %x, data can receive                            |\n", MATCH_ADDRSS);
  149.     printf("+-------------------------------------------------------------+\n");

  150.     /* Set RS485-AAD Mode and address match is 0xC0 */
  151.     UART_SelectRS485Mode(UART0, UART_ALT_CSR_RS485_AAD_Msk | UART_ALT_CSR_RS485_AUD_Msk, MATCH_ADDRSS);

  152.     /* Set RS485 address detection enable */
  153.     UART0->ALT_CSR |= UART_ALT_CSR_RS485_ADD_EN_Msk;

  154. #endif

  155.     /* Enable RDA\RLS\Time-out Interrupt */
  156.     UART_EnableInt(UART0, (UART_IER_RDA_IEN_Msk | UART_IER_RLS_IEN_Msk | UART_IER_RTO_IEN_Msk));

  157.     r_pointer = 0;

  158.     /* Check Rx empty, otherwise read Rx */
  159.     printf("Starting to recevice %d bytes data...\n", RXBUFSIZE);

  160.     while(r_pointer < RXBUFSIZE);

  161.     /* Compare Data */
  162.     for(i = 0; i < RXBUFSIZE; i++)
  163.     {
  164.         if(g_u8RecData[i] != (i & 0xFF))
  165.         {
  166.             printf("Compare Data Failed\n");
  167.             while(1);
  168.         }
  169.     }
  170.     printf("\n Receive OK & Check OK\n");

  171.     /* Flush Rx FIFO */
  172.     UART0->FCR |= UART_FCR_RFR_Msk;

  173.     /* Disable RDA\RLS\Time-out Interrupt */
  174.     UART_DisableInt(UART0, (UART_IER_RDA_IEN_Msk | UART_IER_RLS_IEN_Msk | UART_IER_RTO_IEN_Msk));

  175.     printf("\nEnd test\n");

  176. }


  177. void SYS_Init(void)
  178. {
  179.     /*---------------------------------------------------------------------------------------------------------*/
  180.     /* Init System Clock                                                                                       */
  181.     /*---------------------------------------------------------------------------------------------------------*/

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

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

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

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

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

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

  194.     /* Enable UART module clock */
  195.     CLK_EnableModuleClock(UART0_MODULE);

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

  198.     /*---------------------------------------------------------------------------------------------------------*/
  199.     /* Init I/O Multi-function                                                                                 */
  200.     /*---------------------------------------------------------------------------------------------------------*/

  201.     /* Set P3 multi-function pins for UART0 RXD and TXD */
  202.     SYS->P3_MFP &= ~(SYS_MFP_P30_Msk | SYS_MFP_P31_Msk);
  203.     SYS->P3_MFP |= (SYS_MFP_P30_RXD | SYS_MFP_P31_TXD);

  204.     /* Set P0 multi-function pins for UART RTS */
  205.     SYS->P0_MFP = SYS->P0_MFP & (~SYS_MFP_P03_Msk) | SYS_MFP_P03_RTS;

  206. }

  207. void UART0_Init()
  208. {
  209.     /*---------------------------------------------------------------------------------------------------------*/
  210.     /* Init UART                                                                                               */
  211.     /*---------------------------------------------------------------------------------------------------------*/
  212.     /* Reset UART0 */
  213.     SYS_ResetModule(UART0_RST);

  214.     /* Configure UART0 and set UART0 Baudrate */
  215.     UART_Open(UART0, 115200);
  216. }

  217. /*---------------------------------------------------------------------------------------------------------*/
  218. /* MAIN function                                                                                           */
  219. /*---------------------------------------------------------------------------------------------------------*/
  220. int32_t main(void)
  221. {

  222.     /* Unlock protected registers */
  223.     SYS_UnlockReg();

  224.     /* Init System, peripheral clock and multi-function I/O */
  225.     SYS_Init();

  226.     /* Lock protected registers */
  227.     SYS_LockReg();

  228.     /* Init UART0 for testing */
  229.     UART0_Init();

  230.     /*---------------------------------------------------------------------------------------------------------*/
  231.     /* SAMPLE CODE                                                                                             */
  232.     /*---------------------------------------------------------------------------------------------------------*/

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

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

  235.     /* UART RS485 sample slave function */
  236.     RS485_9bitModeSlave();

  237.     while(1);

  238. }


 楼主| zhuotuzi 发表于 2017-1-28 10:06 | 显示全部楼层
extern char GetChar(void);
int32_t main(void);
void RS485_HANDLE(void);
void RS485_9bitModeSlave(void);
从这看跟那个主机模式很像。
 楼主| zhuotuzi 发表于 2017-1-28 10:07 | 显示全部楼层
从机不做地址什么的分配,只是听从主机的吩咐,因此没有发送地址指令什么的。
 楼主| zhuotuzi 发表于 2017-1-28 10:19 | 显示全部楼层
根据代码可以看出来485实际上还是跟串口一样一的
mintspring 发表于 2017-1-28 10:36 | 显示全部楼层
UART_DisableInt(UART0, (UART_IER_RDA_IEN_Msk | UART_IER_RLS_IEN_Msk | UART_IER_RTO_IEN_Msk));
串口关闭中断,比较复杂,需要知道端口,还有各种操作,其实后面的完全可以省略的。
yiyigirl2014 发表于 2017-1-28 11:05 | 显示全部楼层
其实作为终端,一般从机模式用的比较多。
yiyigirl2014 发表于 2017-1-29 17:34 | 显示全部楼层
从机模式可以用于终端设备,终端设备都是用的从机模式,上位机端口的可以用主机模式。
huangcunxiake 发表于 2017-1-30 12:46 | 显示全部楼层
没有451的猛,451的带DSP和FPU。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

214

主题

3375

帖子

7

粉丝
快速回复 在线客服 返回列表 返回顶部