terça-feira, 7 de setembro de 2021

Controle remoto via WIFI - nodemcu (ESP8266) - Modo cliente e servidor

 Olá pessoal que acompanha este blog!

    Vou demonstrar aqui como fazer um controle remoto de 3 canais usando o modulo wifi ESP8266 pela interface do Arduino, um das placas estará rodando como servidor web e a outra como cliente web. 

    Para reduzir o tempo de resposta optei por não envia pagina nenhuma apenas o comando para informar o estado dos 3 botões que foram colocados na placa do nodemcu, por ser muito simples e basico não vou colocar o esquemático apenas a imagem da protoboard, creio que seja o suficiente para que vcs entendam o circuito.


    A placa é alimentada com 5V da usb ou 5V de uma fonte externa pelo pino Vin e GND, os leds são ligados a resistores de 220R ao GND e aos pinos D1,D2 e D3.Os botões São ligado ao GND e ao pinos D1,D2,D3 diretamente pois não precisam de resistores externos de pull up´s. Coloquei as placas uma ao lado da outra pra facilitar a visualização e o vídeo veja abaixo ( https://youtu.be/KVtNlUg0EF0):


O código fonte:

Código do servidor (lê os botões):

//desenvolvedor: Aguivone M. Fogia
//Data : 07/09/2021                        // Deu certo
//Blog: Microcontroladores-C 
//exemplo com NodeMCU - modo servidor
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>//caso use o modo servidor

//------------------------------------------------------------------------------------
// definição dos pinos
//------------------------------------------------------------------------------------
#define       LED         2        // led do modulo wifi
#define       BOT_1        D1         // botão 1
#define       BOT_2        D2         // botão 2
#define       BOT_3        D3         // botão 3

WiFiServer server(80);//usa porta 80

void setup() 
{
  pinMode(LED, OUTPUT);        // inicializa o led da placa
  pinMode(BOT_1, INPUT_PULLUP);  // habilita pull up interno do pino
  pinMode(BOT_2, INPUT_PULLUP);  // habilita pull up interno do pino
  pinMode(BOT_3, INPUT_PULLUP);  /// habilita pull up interno do pino
  setupWiFi();  
}

void loop() 
{
  // checa se tem algum dispositivo conectado!
  WiFiClient client = server.available();
  if (!client) 
      { 
       digitalWrite(LED, LOW);
       delay(100); 
       digitalWrite(LED, HIGH);
       delay(100); //espera conexão   
       return;
       }

  // Lê a primeir linha dos dados recebidos pelo pacote ethernet
  String req = client.readStringUntil('\r');
  client.flush(); 

  // prepara pagina ehtenet
  String s = "S-";
  if (digitalRead(BOT_1) == LOW)                         //botão pressionado
  {
    s += "1";
  }
  else
  {
    s += "0"; 
  } 
  if (digitalRead(BOT_2) == LOW)                         //botão pressionado
  {
    s += "1";
  }
  else
  {
    s += "0"; 
  } 
  if (digitalRead(BOT_3) == LOW)                         //botão pressionado
  {
    s += "1";
  }
  else
  {
    s += "0"; 
  }
  s += "*\n";
  // envia dados
  client.print(s);
  delay(100); //tempo de tratamento por parte do cliente
  //cliente desconectado
  // a cada requisição a pagina é enviada e o cliente é desconectado
}

void setupWiFi()
{
    //////////////////////
    // definições da WiFi  //
    //////////////////////
  const char*  WiFi_Senha = "123456789";//senha que você quer usar(deve ser em branco(aberta) ou maior que 8 caráteres,senão não funciona e não troca o nome da wifi)

  const char*  WiFi_Nome = "MICROCONTROLADORES-C";//nome que você quer dar a sua rede 
  IPAddress ip(192,168,50,4);//ok
  IPAddress gateway(192,168,50,1);//ok
  IPAddress subnet(255,255,255,0);//ok
  //////inicializa a wifi//////////////////////////////////////////////  
  uint8_t mac[WL_MAC_ADDR_LENGTH];
  WiFi.softAPmacAddress(mac);//mac qualquer pra testar
  WiFi.softAPConfig(ip, gateway, subnet);
  WiFi.mode(WIFI_STA);//modo acess point e servidor
  //  WiFi.mode(WIFI_AP_STA);//modo acess point e servidor
  WiFi.softAP(WiFi_Nome, WiFi_Senha); 
  WiFi.begin(); 
  server.begin();
}

Código do cliente(aciona os leds):

//desenvolvedor: Aguivone M. Fogia
//Data : 07/09/2021                        // Deu certo
//Blog: Microcontroladores-C 
//exemplo com NodeMCU - modo cliente
#include <ESP8266WiFi.h>

#define       LED       2        // led do modulo wifi
#define       LED1      D1        
#define       LED2      D2        
#define       LED3      D3        

char nome_wifi[] = "MICROCONTROLADORES-C";                // nome da rede wifi
char senha[] = "123456789";                          // senha deve ter no minimo 8 caracteres 

const char* host = "192.168.50.4";


void setup()
{
  Serial.begin(115200);
  pinMode(LED, OUTPUT);        // inicializa o led da placa
  pinMode(LED1, OUTPUT); 
  pinMode(LED2, OUTPUT); 
  pinMode(LED3, OUTPUT); 
  digitalWrite(LED1, LOW);
  digitalWrite(LED2, LOW);
  digitalWrite(LED3, LOW);
  Serial.println();

  Serial.printf("Connecting to %s ", nome_wifi);
  WiFi.begin(nome_wifi,senha);
  while (WiFi.status() != WL_CONNECTED)
  {
       digitalWrite(LED, LOW);//sem conexão pisca led da placa do node
       delay(300); 
       digitalWrite(LED, HIGH);
       delay(300); //espera conexão
  }
  Serial.println(" connected");
}


void loop()
{
  WiFiClient client;

  Serial.printf("\n[Connecting to %s ... ", host);
  if (client.connect(host, 80))
  {
    Serial.println("connected]");
    Serial.println("[Sending a request]");
    client.print(String("GET /") + " HTTP/1.1\r\n" +
                 "Host: " + host + "\r\n" +
                 "Connection: close\r\n" +
                 "\r\n"
                );

    Serial.println("[Response:]");
    while (client.connected() || client.available())
    {
      if (client.available())
      {
        String pacote = client.readStringUntil('\n');
        Serial.println(pacote);          
          if(pacote.indexOf("*")> 0) 
          {
             int pos = pacote.indexOf("*");
             if(pacote[pos-1]=='1')
             {
               digitalWrite(LED1,HIGH); 
             }
             else
             {
              digitalWrite(LED1,LOW);
             }
             if(pacote[pos-2]=='1')
             {
               digitalWrite(LED2,HIGH); 
             }
             else
             {
              digitalWrite(LED2,LOW);
             }
             if(pacote[pos-3]=='1')
             {
               digitalWrite(LED3,HIGH); 
             }
             else
             {
              digitalWrite(LED3,LOW);
             }
          }
          else
          {
            digitalWrite(LED1,LOW);
            digitalWrite(LED2,LOW);
            digitalWrite(LED3,LOW); 
          }

          client.flush();        
      }
    }
    client.stop();
    Serial.println("\n[Disconnected]");
  }
  else
  {
    Serial.println("connection failed!]");   
  }
  delay(200);
}

formatado por http://hilite.me/  07/09/2021

Até a próxima! Que a paz de cristo esteja com vcs.

quarta-feira, 1 de setembro de 2021

Voltímetro pela porta serial com 8051F382 - Simplicity Studio

 Olá, pessoal !

    Passando pra deixar mas um exemplo de código, aqui demonstrando como usar o modulo analógico digital do microcontrolador  C8051F382, e imprimir isto na porta serial RS232.

O código fonte:   

// Target:         C8051F382
// Tool chain:     Simplicity Studio / Keil C51 9.51
// Command Line:   None
//
//
//     Release 1.0
//     12_05_2021
//     autor:Aguivone M. Fógia
//     exemplo de como usar o ADC( e comunicação serial
//     usando o port 2.7
//

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

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

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

#define SYSCLK        12000000         // SYSCLK frequency in Hz
#define BAUDRATE      115200           // Baud rate of UART in bps
#define INT_DEC       256              // Integrate and decimate ratio

#define TIMER0_RELOAD_HIGH  0          // Timer0 High register
#define TIMER0_RELOAD_LOW 255          // Timer0 Low register

//-----------------------------------------------------------------------------
// Function PROTOTYPES
//-----------------------------------------------------------------------------
SI_INTERRUPT_PROTO(ADC0_ISR, ADC0EOC_IRQn);
SI_INTERRUPT_PROTO(Timer2_ISR, TIMER2_IRQn);

void Oscillator_Init (void);
void Port_Init (void);
void Timer2_Init(void);
void ADC0_Init(void);
void UART0_Init (void);
unsigned char porta4 = 0XFF;


void delay_ms(int16_t ms);

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

int32_t RESULT;            // ADC0 decimated value, one for each
                                       // analog input

//-----------------------------------------------------------------------------
// SiLabs_Startup() Routine
// ----------------------------------------------------------------------------

void SiLabs_Startup (void)
{
   PCA0MD &= ~0x40;                    // WDTE = 0 (clear watchdog timer
}

//-----------------------------------------------------------------------------
// MAIN Routine
//-----------------------------------------------------------------------------
void main (void)
{
   uint32_t measurement;
   bool   flag;
                                       // enable)

   Oscillator_Init ();                 // Initialize system clock to
                                       // 12MHz
   Port_Init ();                       // Initialize crossbar and GPIO
   Timer2_Init();                      // Init Timer2 to generate
                                       // overflows to trigger ADC
   UART0_Init();                       // Initialize UART0 for printf's
   ADC0_Init();                        // Initialize ADC0

   IE_EA = 1;                             // Enable global interrupts
   while (1)
   {
      IE_EA = 0;                          // Disable interrupts
      printf("\f");
         // The 10-bit ADC value is averaged across INT_DEC measurements.
         // The result is then stored in RESULT, and is right-justified
         // The measured voltage applied to the port pins is then:
         //
         //                           Vref (mV)
         //   measurement (mV) =   --------------- * Result (bits)
         //                        (2^10)-1 (bits)

      measurement =  RESULT * 4.887;
      printf("Tensao lida: %4ld mV\n",measurement);
      IE_EA = 1;                          // Re-enable interrupts
      delay_ms(10);
      if(flag==1)
        {
         P4 = 0;
         flag = 0;
        }
      else
        {
          P4 = 255;
          flag = 1;
        }
   }
}

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

//-----------------------------------------------------------------------------
// SYSCLK_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : None
//
// This routine initializes the system clock to use the internal 12MHz
// oscillator as its clock source.  Also enables missing clock detector reset.
//
void Oscillator_Init (void)
{
   OSCICN = 0x83;                      // Configure internal oscillator for
                                       // its highest frequency
   RSTSRC = 0x04;                      // Enable missing clock detector
}

//-----------------------------------------------------------------------------
// Port_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : None
//
// Configure the Crossbar and GPIO ports.
//
// P0.4 - UART TX (push-pull)
// P0.5 - UART RX
// P2.7 - analog input (ADC0)
//
//-----------------------------------------------------------------------------
void Port_Init (void)
{
   P2SKIP = 0x80;                      // pula a entrada analogica

   XBR0   = 0x01;                     // CP1AE,CP1E,CP0AE,CP0E,SYSCKE,SMB0E,SPI0E,(UART0E)
   XBR2   = 0x00;                     // RESRV,RSRV,RESRV,RESRV,RESRV,RESRV,SMB1E, UART1E
   XBR1   = 0xC2;                     // WEAKPUD,(XBARE),T1E,T0E,ECIE,(PCA0ME):000:Nenhum,001:CEX0,010:CEX0eCEX1,...

   VDM0CN = 0x80;                     // Colocado porque senão da problema na gravacao da flash(já estava isso)
   RSTSRC = 0x02;                     // ativa reset de falha de oscilação.

   P0MDOUT |= 0x10;                    // Enable TX0 as a push-pull output
   P1MDOUT = 0x00;                     // enable Switches as open-drain
   P2MDOUT = 0x00;                     // enable Switches as open-drain
   P3MDOUT = 0x00;                     // enable Switches as open-drain
   P4MDOUT = 0x04;                     // enable Switches as open-drain

   //configura portas
   P0MDIN  = 0xFF;                     //  are digital
   P1MDIN  = 0xFF;                     //  are digital
   P2MDIN  = 0x7F;                      //seta pino P2.7 como entrada analogica
   P3MDIN  = 0xFF;                     //  are digital
   P4MDIN  = 0xFF;                     //  are digital


}

//-----------------------------------------------------------------------------
// Timer2_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : None
//
// Configure Timer2 to 16-bit auto-reload and generate an interrupt at 10 us
// intervals.  Timer2 overflows automatically triggers ADC0 conversion.
//
//-----------------------------------------------------------------------------
void Timer2_Init (void)
{
   TMR2CN = 0x00;                      // Stop Timer2; Clear TF2;
                                       // use SYSCLK as timebase, 16-bit
                                       // auto-reload
   CKCON |= 0x10;                      // Select SYSCLK for timer 2 source
   TMR2RL = 65535 - (SYSCLK / 10000);  // Init reload value for 10 us
   TMR2 = 0xffff;                      // Set to reload immediately
   IE_ET2 = 1;                            // Enable Timer2 interrupts
   TMR2CN_TR2 = 1;                            // Start Timer2
}

//-----------------------------------------------------------------------------
// ADC0_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : None
//
// Configures ADC0 to make single-ended analog measurements on Port 2 according
// to the values of <ANALOG_INPUTS> and <PIN_TABLE>.
//
//-----------------------------------------------------------------------------
void ADC0_Init (void)
{
   ADC0CN = 0x02;                      // ADC0 disabled, normal tracking,
                                       // conversion triggered on TMR2 overflow

   REF0CN = 0x03;                      // Enable internal VREF
   AMX0P = 0X1A;                       // ADC0 input = P2.7 (para microcontrolador de 48 pinos)
   AMX0N = 0x1F;                       // ADC0 negative input = GND
                                       // i.e., single ended mode

   ADC0CF = ((SYSCLK/3000000)-1)<<3;   // Set SAR clock to 3MHz
   ADC0CF |= 0x00;                     // Right-justify results
   EIE1 |= 0x08;                       // Enable ADC0 EOC interrupt
   ADC0CN_ADEN = 1;                          // Enable ADC0
}

//-----------------------------------------------------------------------------
// 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
   // seta automaticamente o valor a ser colocado no TH1
   if (SYSCLK/BAUDRATE/2/256 < 1) {
      TH1 = -(SYSCLK/BAUDRATE/2);
      CKCON |=  0x08;                  // T1M = 1; SCA1:0 = xx
   } 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 if (SYSCLK/BAUDRATE/2/256 < 48) {
      TH1 = -(SYSCLK/BAUDRATE/2/48);
      CKCON &= ~0x0B;                  // T1M = 0; SCA1:0 = 10
      CKCON |=  0x02;
   } else {
      while (1);                       // Error.  Unsupported baud rate
   }

   TL1 = TH1;                          // Init Timer1
   TMOD &= ~0xF0;                      // TMOD: timer 1 in 8-bit autoreload
   TMOD |=  0x20;
   TCON_TR1 = 1;                            // START Timer1
   SCON0_TI = 1;                            // Indicate TX0 ready
}

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

//-----------------------------------------------------------------------------
// Timer2_ISR
//-----------------------------------------------------------------------------
//usa overflow para verificar o ADC
//
//incrementa o proximo ADC a ser lido quando for ler 2 ou mais ADCS
SI_INTERRUPT(Timer2_ISR, TIMER2_IRQn)
{
   TMR2CN_TF2H = 0;                           //limpa interrupção do timer 2
   //para 1 adc somente pode até desligar esse timer
}

//-----------------------------------------------------------------------------
// ADC0_ISR
//-----------------------------------------------------------------------------
//
// This ISR averages <INT_DEC> samples for each analog MUX input then prints
// the results to the terminal.  The ISR is called after each ADC conversion,
// which is triggered by Timer2.
//
//-----------------------------------------------------------------------------
SI_INTERRUPT(ADC0_ISR, ADC0EOC_IRQn)
{

   ADC0CN_ADINT = 0;                         // Clear ADC conversion complete
   RESULT = ADC0;    // Read the ADC value and add it to the
                                       // running total
}

//-----------------------------------------------------------------------------
// Support Subroutines
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Timer0_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   :
//   1) int16_t ms - number of milliseconds to wait
//                        range is positive range of an int: 0 to 32767
//
// This function configures the Timer0 as a 16-bit timer, interrupt enabled.
// Using the internal osc. at 12MHz with a prescaler of 1:8 and reloading the
// T0 registers with TIMER0_RELOAD_HIGH/LOW, it will wait for <ms>
// milliseconds.
// Note: The Timer0 uses a 1:12 prescaler
//-----------------------------------------------------------------------------
void delay_ms(int16_t ms)
{
   TH0 = TIMER0_RELOAD_HIGH;           // Init Timer0 High register
   TL0 = TIMER0_RELOAD_LOW ;           // Init Timer0 Low register
   TMOD |= 0x01;                       // Timer0 in 16-bit mode
   CKCON &= 0xFC;                      // Timer0 uses a 1:12 prescaler
   TCON_TR0  = 1;                           // Timer0 ON

   while(ms)
   {
      TCON_TF0 = 0;                         // Clear flag to initialize
      while(!TCON_TF0);                     // Wait until timer overflows
      ms--;                            // Decrement ms
   }

   TCON_TR0 = 0;                            // Timer0 OFF
}

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

formatado  por : http://hilite.me/  01/09/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