quarta-feira, 1 de setembro de 2021

Acessando a porta serial RS232 com o 8051F382 - Simplicity studio

    Olá, pessoal!

    Neste exemplo tudo enviado ao microcontrolador é repetido de volta pela porta serial, nos exemplos não utilizo cristal externo pois o chip já possui um interno.

O código fonte :

// Target:         C8051F382
// Tool chain:     Simplicity Studio / Keil C51 9.51
// Autor: Aguivone M. Fogia
// Data: 01/09/2021
//

//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------

#include <SI_C8051F380_Register_Enums.h>
#include <stdio.h>

//-----------------------------------------------------------------------------
// Global CONSTANTS
//-----------------------------------------------------------------------------

#define SYSCLK      12000000           // SYSCLK frequency in Hz
#define BAUDRATE        9600           // Baud rate of UART in bps

//-----------------------------------------------------------------------------
// Function PROTOTYPES
//-----------------------------------------------------------------------------
SI_INTERRUPT_PROTO(UART0_Interrupt, UART0_IRQn);

void SYSCLK_Init (void);
void UART0_Init (void);
void PORT_Init (void);
void  escreve_frase(uint8_t dados[] ,uint8_t tam);
void  escreve_recebido(uint8_t tam);

//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------

#define UART_BUFFERSIZE 10
uint8_t UART_Buffer[UART_BUFFERSIZE];
uint8_t UART_Buffer_tx[UART_BUFFERSIZE];//para transmissão
uint8_t UART_Buffer_Size = 0;
uint8_t UART_Input_First = 0;
uint8_t UART_Output_First = 0;
uint8_t pos_buffer=0;
uint8_t tam_buffer_tx=0;
uint8_t pos_buffer_tx=0;
static char RX_232;
static char TX_232;
bool tem_recp = 0;
bool rec_232 = 0;
bool trans_232 = 0;


//entradas

SI_SBIT(SW1, SFR_P0, 6);                  // SW1 ='0' means switch pressed
SI_SBIT(SW2, SFR_P0, 7);                  // SW2 ='0' means switch pressed

unsigned char porta4 = 0XFF;



//-----------------------------------------------------------------------------
// SiLabs_Startup() Routine
// ----------------------------------------------------------------------------
// This function is called immediately after reset, before the initialization
// code is run in SILABS_STARTUP.A51 (which runs before main() ). This is a
// useful place to disable the watchdog timer, which is enable by default
// and may trigger before main() in some instances.
//-----------------------------------------------------------------------------
void SiLabs_Startup (void)
{
   PCA0MD &= ~0x40;                    // WDTE = 0 (clear watchdog timer
}


//-----------------------------------------------------------------------------
// MAIN Routine
//-----------------------------------------------------------------------------

void main (void)
{

                                       // enable)
   PORT_Init();                        // Initialize Port I/O
   SYSCLK_Init ();                     // Initialize Oscillator
   UART0_Init();
   IE_EA = 1;
   escreve_frase("Iniciando!",10);
   while(1)
   {
      // If the complete word has been entered via the terminal followed by
      // carriage return or newline
       if(tem_recp)//recebeu dados
          {
             escreve_recebido(pos_buffer);
             tem_recp = 0;//sinaliza que já leu
          }
  }
}


void  escreve_frase(char dados[] ,uint8_t tam)
{
    tam_buffer_tx = 0;
    while(tam > tam_buffer_tx)
      {
         UART_Buffer_tx[tam_buffer_tx] = dados[tam_buffer_tx];//transfere dados
         tam_buffer_tx++;
      }
    trans_232 = 1;//sinaliza que deve transmitir
    SCON0_TI = 1; //para dar inicio a transmissão
}
void  escreve_recebido(uint8_t tam)
{
    tam_buffer_tx = 0;
    while(tam > tam_buffer_tx)
      {
         UART_Buffer_tx[tam_buffer_tx] = UART_Buffer[tam_buffer_tx];//transfere dados
         tam_buffer_tx++;
      }
    trans_232 = 1;//sinaliza que deve transmitir
    SCON0_TI = 1; //para dar inicio a transmissão
}

//-----------------------------------------------------------------------------
// Initialization Subroutines
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// PORT_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : None
//
// Configure the Crossbar and GPIO ports.
//
// P0.4   digital   push-pull    UART TX
// P0.5   digital   open-drain   UART RX
//
//-----------------------------------------------------------------------------

void PORT_Init (void)
{
   P0MDOUT |= 0x10;                    // Enable UTX as push-pull output
   XBR0     = 0x01;                    // Enable UART on P0.4(TX) and P0.5(RX)
   XBR1     = 0x40;                    // Enable crossbar and weak pull-ups
}

//-----------------------------------------------------------------------------
// SYSCLK_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : None
//
// This routine initializes the system clock to use the internal oscillator
// at its maximum frequency.
// Also enables the Missing Clock Detector.
//-----------------------------------------------------------------------------

void SYSCLK_Init (void)
{
   OSCICN |= 0x03;                     // Configure internal oscillator for
                                       // its maximum frequency
   RSTSRC  = 0x04;                     // Enable missing clock detector
}

//-----------------------------------------------------------------------------
// UART0_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : None
//
// Configure the UART0 using Timer1, for <BAUDRATE> and 8-N-1.
//-----------------------------------------------------------------------------

void UART0_Init (void)
{
   SCON0 = 0x10;                       // SCON0: 8-bit variable bit rate
                                       //        level of STOP bit is ignored
                                       //        RX enabled
                                       //        ninth bits are zeros
                                       //        clear SCON0_RI and SCON0_TI bits
   if (SYSCLK/BAUDRATE/2/256 < 1) {
      TH1 = -(SYSCLK/BAUDRATE/2);
      CKCON &= ~0x0B;                  // T1M = 1; SCA1:0 = xx
      CKCON |=  0x08;
   } else if (SYSCLK/BAUDRATE/2/256 < 4) {
      TH1 = -(SYSCLK/BAUDRATE/2/4);
      CKCON &= ~0x0B;                  // T1M = 0; SCA1:0 = 01
      CKCON |=  0x01;
   } else if (SYSCLK/BAUDRATE/2/256 < 12) {
      TH1 = -(SYSCLK/BAUDRATE/2/12);
      CKCON &= ~0x0B;                  // T1M = 0; SCA1:0 = 00
   } else {
      TH1 = -(SYSCLK/BAUDRATE/2/48);
      CKCON &= ~0x0B;                  // T1M = 0; SCA1:0 = 10
      CKCON |=  0x02;
   }

   TL1 = TH1;                          // init Timer1
   TMOD &= ~0xf0;                      // TMOD: timer 1 in 8-bit autoreload
   TMOD |=  0x20;
   TCON_TR1 = 1;                            // START Timer1
   IP |= 0x10;                         // Make UART high priority
   IE_ES0 = 1;                            // Enable UART0 interrupts

}

//-----------------------------------------------------------------------------
// Interrupt Service Routines
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// UART0_Interrupt
//-----------------------------------------------------------------------------
//
// This routine is invoked whenever a character is entered or displayed on the
// Hyperterminal.
//
//-----------------------------------------------------------------------------

SI_INTERRUPT(UART0_Interrupt, UART0_IRQn)
{
   if (SCON0_RI == 1)
   {
       SCON0_RI = 0;
       RX_232 = SBUF0;
       if(pos_buffer > UART_BUFFERSIZE)  // tem um bug no compilador ou chip que faz reseta
                {//erro descarta
                  rec_232=0; //não recebendo
                  pos_buffer=0;//limpa buffer
                  tem_recp = 0;//sinaliza fim de pacote
                }
       if(rec_232 && RX_232 == '*')
                {//esta recebendo e chegou delimitador de fim
                  rec_232=0; //não recebendo
                  tem_recp = 1;//sinaliza fim de pacote
                }
       if(rec_232)
         {//esta recebendo
           UART_Buffer[pos_buffer] = RX_232;
           pos_buffer++;
         }
       if(RX_232 == '#')
         {
           pos_buffer=0;//sinaliza recepção
           rec_232=1; //recebendo
         }
   }
   if (SCON0_TI)                 // Check if transmit flag is set
     {
        SCON0_TI = 0;                          // Clear interrupt flag
        if(trans_232 == 1)
          {

           if (pos_buffer_tx <  tam_buffer_tx)
            {
             // Store a character in the variable byte
             TX_232 = UART_Buffer_tx[pos_buffer_tx];
             pos_buffer_tx++;             // Decrease array size
             SBUF0 = TX_232;                   // Transmit to Hyperterminal

            }
            else
              {
                trans_232 = 0; //fim de transmissao
                pos_buffer_tx =0;
              }
        }
     }

}

//-----------------------------------------------------------------------------
// End Of File
//-----------------------------------------------------------------------------

Formatado por : http://hilite.me/  01/09/2021



Nenhum comentário :

Postar um comentário

olá,digite aqui seu comentário!