اطلاعیه

Collapse
No announcement yet.

UART+RS485

Collapse
X
 
  • فیلتر
  • زمان
  • Show
Clear All
new posts

    UART+RS485

    سلام دوستان عزیز
    من به یه کد حداقلی برای راه اندازی uart برای پروتکل rs 485 احتیاج دارم کسی میتونه کمک کنه؟ (رجیستری با lpc1768) بسیار ممنون
    بزرگترین لذت انجام کاریست که میگویند نمیتوانی !!!

    #2
    پاسخ : UART+RS485

    من اینارو دارم
    کد:
    ****************************************************************************/
    #include "LPC17xx.h"
    #include "rs485.h"
    
    volatile uint32_t UARTStatus;
    volatile uint8_t UARTTxEmpty = 1;
    volatile uint8_t UARTBuffer[BUFSIZE];
    volatile uint32_t UARTCount = 0;
    volatile uint32_t garbageCount = 0;
    
    
    /*****************************************************************************
    ** Function name:		UART1_IRQHandler
    **
    ** Descriptions:		UART interrupt handler
    **
    ** parameters:			None
    ** Returned value:		None
    ** 
    *****************************************************************************/
    void UART1_IRQHandler(void)
    {
     volatile uint8_t IIRValue, LSRValue;
     volatile uint8_t Dummy = Dummy;
    
     IIRValue = LPC_UART1->IIR;
      
     IIRValue >>= 1;			/* skip pending bit in IIR */
     IIRValue &= 0x07;			/* check bit 1~3, interrupt identification */
     if (IIRValue == IIR_RLS)		/* Receive Line Status */
     {
      LSRValue = LPC_UART1->LSR;
      /* Receive Line Status */
    	if ( ((LSRValue & (LSR_PE|LSR_RDR)) == (LSR_PE|LSR_RDR)) 
    						&& (LPC_UART1->RS485CTRL & RS485_NMMEN) )
    	{
    	 Dummy = LPC_UART1->RBR;
    	 /* if address match, enable RX, otherwise, disable RX. */
    	 if ( Dummy == LPC_UART1->ADRMATCH )
    	 {
    		LPC_UART1->RS485CTRL &= ~RS485_RXDIS;	/* Enable RX */
    	 }
    	 else
    	 {
    		LPC_UART1->RS485CTRL |= RS485_RXDIS;		/* Disable RX */
    		while ( LPC_UART1->LSR & LSR_RDR ){
    		 Dummy = LPC_UART1->RBR;	/* Clear data from RX FIFO */
    		 garbageCount++;
    		}
    		return;
    	 }
    	}
      else if (LSRValue & (LSR_OE | LSR_PE | LSR_FE | LSR_RXFE | LSR_BI))
      {
       /* There are errors or break interrupt */
       /* Read LSR will clear the interrupt */
       UARTStatus = LSRValue;
       Dummy = LPC_UART1->RBR;/* Dummy read on RX to clear 
    							interrupt, then bail out */
       return;
      }
      else if (LSRValue & LSR_RDR)	/* Receive Data Ready */			
      {
       /* If no error on RLS, normal ready, save into the data buffer. */
       /* Note: read RBR will clear the interrupt */
       UARTBuffer[UARTCount++] = LPC_UART1->RBR;
       if (UARTCount == BUFSIZE)
       {
        UARTCount = 0;		/* buffer overflow */
       }	
      }
     }
     else if (IIRValue == IIR_RDA)	/* Receive Data Available */
     {
      /* Receive Data Available */
      UARTBuffer[UARTCount++] = LPC_UART1->RBR;
      if (UARTCount == BUFSIZE)
      {
       UARTCount = 0;		/* buffer overflow */
      }
     }
     else if (IIRValue == IIR_CTI)	/* Character timeout indicator */
     {
      /* Character Time-out indicator */
      UARTStatus |= 0x100;		/* Bit 9 as the CTI error */
     }
     else if (IIRValue == IIR_THRE)	/* THRE, transmit holding register empty */
     {
      /* THRE interrupt */
      LSRValue = LPC_UART1->LSR;		/* Check status in the LSR to see if
    							valid data in U0THR or not */
      if (LSRValue & LSR_THRE)
      {
       UARTTxEmpty = 1;
      }
      else
      {
       UARTTxEmpty = 0;
      }
     }
     return;
    }
    
    /*****************************************************************************
    ** Function name:		RS485Init
    **
    ** Descriptions:		Initialize UART0 port, setup pin select,
    **				clock, parity, stop bits, FIFO, etc.
    **
    ** parameters:			UART baudrate
    ** Returned value:		None
    ** 
    *****************************************************************************/
    void RS485Init(uint32_t baudrate)
    {
     uint32_t Fdiv;
     uint32_t regVal = regVal;
     uint32_t pclkdiv, pclk;
    
     UARTCount = 0;
    
     NVIC_DisableIRQ(UART1_IRQn);
    
     LPC_PINCON->PINSEL4 &= ~0x0000000F;
     LPC_PINCON->PINSEL4 |= 0x0000000A;	/* Enable RxD1 P2.1, TxD1 P2.0 */
    	
     /* By default, the PCLKSELx value is zero, thus, the PCLK for
     all the peripherals is 1/4 of the SystemFrequency. */
     /* Bit 8,9 are for UART1 */
     pclkdiv = (LPC_SC->PCLKSEL0 >> 8) & 0x03;
     switch ( pclkdiv )
     {
    	case 0x00:
    	default:
    	 pclk = SystemFrequency/4;
    	break;
    	case 0x01:
    	 pclk = SystemFrequency;
    	break; 
    	case 0x02:
    	 pclk = SystemFrequency/2;
    	break; 
    	case 0x03:
    	 pclk = SystemFrequency/8;
    	break;
     }
    
     LPC_UART1->LCR = 0x83;       /* 8 bits, no Parity, 1 Stop bit */
     Fdiv = ( pclk / 16 ) / baudrate ;	/*baud rate */
     LPC_UART1->DLM = Fdiv / 256;							
     LPC_UART1->DLL = Fdiv % 256;
     LPC_UART1->LCR = 0x03;		/* DLAB = 0 */
     LPC_UART1->FCR = 0x07;		/* Enable and reset TX and RX FIFO. */
    
     /* Read to clear the line status. */
     regVal = LPC_UART1->LSR;
     /* Ensure a clean start, no data in either TX or RX FIFO. */
     while ( LPC_UART1->LSR & (LSR_THRE|LSR_TEMT) != (LSR_THRE|LSR_TEMT) );
     while ( LPC_UART1->LSR & LSR_RDR )
     {
    	regVal = LPC_UART1->RBR;	/* Dump data from RX FIFO */
     }
    
     LPC_UART1->LCR |= ((0x3<<4)|(0x1<<3));	/* forced "0" sticky parity, parity enable */
     LPC_UART1->ADRMATCH = RS485_SLAVE_ADR;	/* UARTA 485 address, 0xC0 */
    #if RS485_NMM
     LPC_UART1->RS485CTRL = RS485_NMMEN;		/* NMM mode */
    #else
     LPC_UART1->RS485CTRL = RS485_NMMEN|RS485_AADEN|RS485_RXDIS;	/* AAD mode */
    #endif
    
     /* Below is the direction control setting. */
    #if DIR_CTRL
     /* Either DTR or RTS can be used as direction pin out. */
    #if 1
     LPC_PINCON->PINSEL1 &= ~(0x03<<8);
     LPC_PINCON->PINSEL1 |= (0x01<<8);		/* DTR1 as direction control */
     LPC_UART1->RS485CTRL |= RS485_DCTRL;
    #else
     LPC_PINCON->PINSEL1 &= ~(0x03<<12);
     LPC_PINCON->PINSEL1 |= (0x01<<12);	/* RTS1 as direction control */
     LPC_UART1->RS485CTRL |= (RS485_DCTRL|RS485_SEL);
    #endif
    #endif
    
     /* Enable UART1 Interrupt */
     NVIC_EnableIRQ(UART1_IRQn);
     LPC_UART1->IER = IER_RBR | IER_THRE | IER_RLS;	/* Enable UART interrupt */
     return;
    }
    
    /*****************************************************************************
    ** Function name:		RS485Send
    **
    ** Descriptions:		Send a block of data to the UART 0 port based
    **				on the data length
    **
    ** parameters:		buffer pointer, and data length
    ** Returned value:	None
    ** 
    *****************************************************************************/
    void RS485Send(uint8_t *BufferPtr, uint32_t Length)
    {
     uint32_t i;
     
     for ( i = 0; i < Length; i++ )
     {
    	/* THRE status, contain valid data */
      while ( !(UARTTxEmpty & 0x01) );
      LPC_UART1->THR = *BufferPtr;
      UARTTxEmpty = 0;	/* not empty in the THR until it shifts out */
    	/* At this point, bit 5 of LCR is always 1 for RS485 test */
    	if ( i == 0 )
    	 LPC_UART1->LCR &= ~(0x1<<4);		/* Sticky parity to 1 */
    	else
    	 LPC_UART1->LCR |= (0x1<<4);		/* Sticky parity to 0 */
    	LPC_UART1->LCR |= (0x1<<3);
    	BufferPtr++;
     }
     return;
    }
    
    /******************************************************************************
    **              End Of File
    ******************************************************************************/
    این فایل .h
    کد:
    ****************************************************************************/
    #ifndef __RS485_H 
    #define __RS485_H
    
    /* TO test RS485, program one board with RS485_RX to 1(RX), one
    board with RS485_RX to 0(TX). reset TX board to send out a string
    with a RS485 slave address first, and then check the content of 
    UARTBuffer in the RX board. */
    #define RS485_RX			0		/* 1 is RX, 0 is TX. */
    #define DIR_CTRL			0
    #define RS485_NMM			1		/* 1 is NMM mode, 0 is AAD mode. */
    
    /*if RS485_ENABLED is set, set RS485 slave address. */
    #define	RS485_SLAVE_ADR		0xC0
    
    #define IER_RBR		0x01
    #define IER_THRE	0x02
    #define IER_RLS		0x04
    
    #define IIR_PEND	0x01
    #define IIR_RLS		0x03
    #define IIR_RDA		0x02
    #define IIR_CTI		0x06
    #define IIR_THRE	0x01
    
    #define LSR_RDR		0x01
    #define LSR_OE		0x02
    #define LSR_PE		0x04
    #define LSR_FE		0x08
    #define LSR_BI		0x10
    #define LSR_THRE	0x20
    #define LSR_TEMT	0x40
    #define LSR_RXFE	0x80
    
    #define BUFSIZE		0x40
    
    /* RS485 mode definition. */
    #define RS485_NMMEN		(0x1<<0)
    #define RS485_RXDIS		(0x1<<1)
    #define RS485_AADEN		(0x1<<2)
    #define RS485_SEL		(0x1<<3)
    #define RS485_DCTRL		(0x1<<4)
    #define RS485_OINV		(0x1<<5)
    
    void RS485Init(uint32_t Baudrate);
    void UART_IRQHandler(void);
    void RS485Send(uint8_t *BufferPtr, uint32_t Length);
    
    #endif /* end __RS485_H */
    /*****************************************************************************
    **              End Of File
    ******************************************************************************/
    اینم خود مثال.main
    کد:
    ****************************************************************************/
    #include "LPC17xx.h"
    #include "rs485.h"
    
    extern volatile uint32_t UARTCount;
    extern volatile uint8_t UARTBuffer[BUFSIZE];
    volatile uint8_t UARTTxBuffer[BUFSIZE];
    
    int main (void) {
     uint8_t i;
    
     /* SystemClockUpdate() updates the SystemFrequency variable */
     SystemClockUpdate();
    
     /* Clear receive buffer, handled inside ISR. */
     for ( i = 0; i < BUFSIZE; i++ )
     {
    	UARTBuffer[i] = 0x00;	
     }
     
     /* NVIC is installed inside UARTInit file. */
     RS485Init(115200);
    
     /* To test RS485 mode, connect two boards, one is set to TX and
     the other is RX. The test is conducted on the inter-board communication. */
    #if RS485_RX
     /* If RX, do nothing, check the content of UARTBuffer */
     /* To get the test result, program the boards with both TX and RX program, 
     power up the board with the RX program first, start the debugger on the
     board with the RX program, power up the board with the TX program, stop 
     the debugger, and check the content of the UARTBuffer on the RX program,
     it should be the same as seen on UARTTxBuffer, 0x01-0x02-0x03.... */ 
     while ( 1 );
    
    #else
     /* If TX. send a string out start with RS485 slave address */
     UARTTxBuffer[0] = RS485_SLAVE_ADR;
     for ( i = 1; i < BUFSIZE; i++ )
     {
    	UARTTxBuffer[i] = i;	
     }
     RS485Send((uint8_t *)UARTTxBuffer, BUFSIZE);
     while ( 1 );
    #endif			/* #endif RS485_RX */
    
    }

    دیدگاه


      #3
      پاسخ : UART+RS485

      تشکر ولی خیلی شلوغ شد یه برنامه خیلی خیلی ساده میخوام که باهاش ور برم رجیستر هاشو یاد بگیرم بازم ممنون
      بزرگترین لذت انجام کاریست که میگویند نمیتوانی !!!

      دیدگاه


        #4
        پاسخ : UART+RS485

        دوتای اول هدر هست که سه تا تابع داره.از این کوچیک تر؟!

        دیدگاه


          #5
          پاسخ : UART+RS485

          دوستان یه زحمتی میکشید این کد رو دیباگ کنید فقط راه اندازی یوارته من وقتی دیباگ میکنم تو پایه های یوارت هیچی ندارم اشکالش چیه؟
          هدر
          کد:
          #include <LPC17xx.H>               /* LPC17xx definitions  */
          #include "Serial.h"
          
          /*----------------------------------------------------------------------------
           Initialize UART pins, Baudrate
           *----------------------------------------------------------------------------*/
          void SER_init (int uart) {
           LPC_UART_TypeDef *pUart;
            
           if (uart == 0) {                /* UART0 */
            LPC_PINCON->PINSEL0 |= (1 << 4);       /* Pin P0.2 used as TXD0 (Com0) */
            LPC_PINCON->PINSEL0 |= (1 << 6);       /* Pin P0.3 used as RXD0 (Com0) */
          
            pUart = (LPC_UART_TypeDef *)LPC_UART0;
           } else {                    /* UART1 */
            LPC_PINCON->PINSEL4 |= (2 << 0);       /* Pin P2.0 used as TXD1 (Com1) */
            LPC_PINCON->PINSEL4 |= (2 << 2);       /* Pin P2.1 used as RXD1 (Com1) */
          
            pUart = (LPC_UART_TypeDef *)LPC_UART1;
           }
          
           pUart->LCR  = 0x83;             /* 8 bits, no Parity, 1 Stop bit */
          // pUart->DLL  = 6;               /* 115200 Baud Rate @ 18.0 MHZ PCLK */
          // pUart->FDR  = 0x85;             /* FR = 1,627 DIVADDVAL = 5, MULVAL = 8 */
           pUart->DLL  = 9;               /* 115200 Baud Rate @ 25.0 MHZ PCLK */
           pUart->FDR  = 0x21;             /* FR 1,507, DIVADDVAL = 1, MULVAL = 2 */
           pUart->DLM  = 0;               /* High divisor latch = 0     */
           pUart->LCR  = 0x03;             /* DLAB = 0            */
          }
          
          
          /*----------------------------------------------------------------------------
           Write character to Serial Port
           *----------------------------------------------------------------------------*/
          int SER_putChar (int uart, int c) {
           LPC_UART_TypeDef *pUart;
          
           pUart = (uart == 0) ? (LPC_UART_TypeDef *)LPC_UART0 : (LPC_UART_TypeDef *)LPC_UART1;
           while (!(pUart->LSR & 0x20));
           return (pUart->THR = c);
          }
          
          
          /*----------------------------------------------------------------------------
           Read character from Serial Port  (blocking read)
           *----------------------------------------------------------------------------*/
          int SER_getChar (int uart) {
           LPC_UART_TypeDef *pUart;
          
           pUart = (uart == 0) ? (LPC_UART_TypeDef *)LPC_UART0 : (LPC_UART_TypeDef *)LPC_UART1;
           while (!(pUart->LSR & 0x01));
           return (pUart->RBR);
          }
          
          
          /*----------------------------------------------------------------------------
           Read character from Serial Port  (non blocking read)
           *----------------------------------------------------------------------------*/
          int SER_getChar_nb (int uart) {
           LPC_UART_TypeDef *pUart;
          
           pUart = (uart == 0) ? (LPC_UART_TypeDef *)LPC_UART0 : (LPC_UART_TypeDef *)LPC_UART1;
           if (pUart->LSR & 0x01)
            return (pUart->RBR);
           else
            return 0;
          }
          
          
          /*----------------------------------------------------------------------------
           Write character to Serial Port
           *----------------------------------------------------------------------------*/
          void SER_putString (int uart, unsigned char *s) {
          
           while (*s != 0) {
            SER_putChar(uart, *s++);
           }
          }
          و MAIN
          کد:
          /***************************************************************
          Project: simUART
          Auther: masoud Ansarian
          Date: 1389/7 - 2010
          Comment: simple UART project for LPC17/23V1.0 miniboard.
               115200 8-N-1
          ****************************************************************/
          
          #include <LPC17xx.H>
          #include "serial.h"
          
          /*----------------------------------------------------------*/
          #define UART_Num 0
          /*----------------------------------------------------------*/
          
          int main()
          {        
           unsigned char cc;
           SystemInit(); /* for setup main oscilator(cclk=100 MHz) and ... */
           SER_init(UART_Num);/* UART#UART_Num Initialization */
          
           SER_putString(UART_Num,"A"); 
          
           while(1)
           {
            SER_putString(UART_Num,"n");
            cc = SER_getChar(UART_Num);
            SER_putString(UART_Num,"You typed: ");
            SER_putChar(UART_Num, cc);
            SER_putString(UART_Num,"\r\n\n"); 
           }
          }
          /*----------------------------------------------------------*/
          بزرگترین لذت انجام کاریست که میگویند نمیتوانی !!!

          دیدگاه


            #6
            پاسخ : UART+RS485

            با این تابع یوارت رو انیشیال کن
            کد:
            void UARTInit( uint32_t SystemFrequency, uint32_t baudrate )
            {
             uint32_t Fdiv;
             uint32_t pclkdiv, pclk;
             
              LPC_SC->PCONP |= (0x1<<3);
              LPC_PINCON->PINSEL0 &= ~0x000000F0;
              LPC_PINCON->PINSEL0 |= 0x00000050; /* RxD0 is P0.3 and TxD0 is P0.2 */
              /* By default, the PCLKSELx value is zero, thus, the PCLK for
                all the peripherals is 1/4 of the SystemFrequency. */
                /* Bit 6~7 is for UART0 */
                pclkdiv = (LPC_SC->PCLKSEL0 >> 6) & 0x03;
                switch ( pclkdiv )
                {
                 case 0x00:
                 default:
                    pclk = SystemFrequency/4;
                    break;
                 case 0x01:
                    pclk = SystemFrequency;
                    break; 
                 case 0x02:
                    pclk = SystemFrequency/2;
                    break; 
                 case 0x03:
                    pclk = SystemFrequency/8;
                    break;
                }
            
              LPC_UART0->LCR = 0x83;        /* 8 bits, no Parity, 1 Stop bit */
              Fdiv = ( pclk / 16 ) / baudrate ;    /*baud rate */
              LPC_UART0->DLM = Fdiv / 256;                            
              LPC_UART0->DLL = Fdiv % 256;
              LPC_UART0->LCR = 0x03;        /* DLAB = 0 */
              LPC_UART0->FCR = 0x07|(0x1<<6);        /* Enable and reset TX and RX FIFO. */
            		LPC_UART0->IER = 0x01;    /* Enable UART0 interrupt */		
            		NVIC_SetPriority(UART0_IRQn,0);     /* Default priority group 0, can be 0(highest) - 31(lowest) */
              NVIC_EnableIRQ(UART0_IRQn);
            
            
              
             
            }
            
            /********************************************************************************************************/
            int UART0_SendByte (int ucData)
            {
            	while (!(LPC_UART0->LSR & 0x20));
              return (LPC_UART0->THR = ucData);
            }
            
            /*----------------------------------------------------------------------------
             Read character from Serial Port  (blocking read)
             *----------------------------------------------------------------------------*/
            int UART0_GetChar (void) 
            {
             	while (!(LPC_UART0->LSR & 0x01));
             	return (LPC_UART0->RBR);
            }
            
            /*********************************************************************************************************/
            void UART0_SendString (unsigned char *s) 
            {
             	while (*s != 0) 
            	{
              		UART0_SendByte(*s++);
            	}
            }

            دیدگاه


              #7
              پاسخ : UART+RS485

              ممنون اقا اروین من به شکل زیر از کد شما استفاده کردم:
              کد:
              void main(){
              SystemInit ();
              UARTInit(017D7840,9600);
              UART0_SendString("Abc");
               for(j=0;j<60000;j++);}
              تو حالت دیباگ رو پایه ی rx همیشه 1 وروی پایه ی tx همیشه 0 دارم . اون کد قبلی ام همینطوری بود اشکال کجاست؟
              بزرگترین لذت انجام کاریست که میگویند نمیتوانی !!!

              دیدگاه


                #8
                پاسخ : UART+RS485

                فرکانس میکروی شما اگه 100 هست و تغیری ندادی به این شکل
                UARTInit(100e6,9600 );

                دیدگاه


                  #9
                  پاسخ : UART+RS485

                  دمت گرم ولی بازم درست نشد. :angry: نکته ی دیگه ای نداره؟
                  بزرگترین لذت انجام کاریست که میگویند نمیتوانی !!!

                  دیدگاه


                    #10
                    پاسخ : UART+RS485

                    ببین برنامه سیم 900 حرفه ای که تو همین بخش گداشتم رو بگیر بریز یارتش فعاله وکار میکنه.فقط قبل از کامپایر تابع sim900 int رو فعالش کن.من با // قیر فعالش کردم.بریز بعد سیمولاتور رو باز کن بالای صفحه uart 1 رو انتخاب کن بعد شبع سازی کن ببین at باید بیاد.اینکار رو بدون برد انجام بده.با خوذ کیل

                    دیدگاه


                      #11
                      پاسخ : UART+RS485

                      اقا درست شد یعنی درست بود دیباگر کیل علافم کرده بود . برنامه رو ریختم تو میکرو کار کرد .
                      بزرگترین لذت انجام کاریست که میگویند نمیتوانی !!!

                      دیدگاه

                      لطفا صبر کنید...
                      X