Neste exemplo é demonstrado alguns aspectos na configuração deste microcontrolador :
1 - Como configurar o PLL para gerar 48MHZ interno.
2 - Configurando a serial para receber e enviar dados, com funções prontas e mais otimizadas.
3 - Como acionar e configura o PORT4.
4 - Exemplo de leitura de pinos e acionamento das IO's.
Aqui é usado o caracter '/' para indicar inicio de dados, mas pode ser trocado por outro, e o caracter '\n' para fim de dados. Assim basta digitar num terminal serial os dados da seguinte forma : "/dados\n."
O código fonte :
//Autor : Aguivone M. F.
//Compilador: Simplicity studio - Silicon labs
// EXEMPLO DE COMO USAR A A SERIAL E OS PINOS DO MICROCONTROLADOR C8051F380-A-GQ
//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include <SI_C8051F380_Register_Enums.h>
//-----------------------------------------------------------------------------
// Global CONSTANTS
//-----------------------------------------------------------------------------
#define SYSCLK 48000000 // frequencia em Hz
#define BAUDRATE 9600 // Baud rate da UART0 em bps
// todos o led são ligados ao VCC
#define LED_freq1 0x7F
#define LED_freq2 0xBF
#define LED_Status 0xF7 // P4.3
#define LED_ping 0xEF //P4.4
unsigned char porta4 = 0XFF;
//-----------------------------------------------------------------------------
// Function PROTOTYPES
//-----------------------------------------------------------------------------
SI_INTERRUPT_PROTO(UART0_Interrupt, UART0_IRQn);
void SYSCLK_Init (void);
void UART0_Init (void);
void PORT_Init (void);
//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------
// variaveis da serial RS232
#define UART_BUFFERSIZE 30
uint8_t UART_Buffer_rx[UART_BUFFERSIZE];
uint8_t UART_Buffer_tx[UART_BUFFERSIZE];//para transmissão
uint8_t pos_buffer=0;
uint8_t tam_buffer_tx=0;
uint8_t pos_buffer_tx=0;
bool tem_recp = 0;
bool rec_232 = 0;
bool trans_232 = 0;
uint16_t pisca =0;
char liga_pino_status = 0;
//-----------------------------------------------------------------------------
// SiLabs_Startup() - POSIÇÃO INICIAL A SER EXECUTADA
// ----------------------------------------------------------------------------
void SiLabs_Startup (void)
{
PCA0MD &= ~0x40; // WDTE = 0 (clear watchdog timer
}
//-----------------------------------------------------------------------------
// tratamento especial para port 4
//-----------------------------------------------------------------------------
void Desliga_Port4(const char pino)
{//desliga em nivel alto
porta4 = porta4 | (~pino);
P4 = porta4;
}
void Liga_Port4(const char pino)
{
porta4 = porta4 & pino;
P4 = porta4;
}
//-----------------------------------------------------------------------------
// PORT_Init - INICIALIZA AS PORTAS
//-----------------------------------------------------------------------------
//
// 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)
{
P0MDIN = 0xFF; // are digital
P0MDOUT = 0x20; // 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
P4MDOUT = 0x04; // enable Switches as open-drain
P4MDIN = 0xFF; // are digital
P4 = 0XFF ; //portas de p4 ligadas (desliga leds)
}
//-----------------------------------------------------------------------------
// SYSCLK - INICIA A CONFIGURAÇÃO DO CLOCK
//-----------------------------------------------------------------------------
void SYSCLK_Init (void)
{ // configurado para 48mhz
OSCICN = 0X83; // IHFOsc Enable, sem divisão ira rodar a 12MHz
CLKMUL = 0XC0; // talvez nem precise neste microcontrolador -> habilita e inicializa pll
CLKSEL = 0X03; // SYSCLK derived from the Internal High-Frequency Oscillator.sem divisão 48MHZ se estiver habilitado o clksel
PFE0CN = 0X20; //(para High Speed) Prefetch Engine Control,otimiza tempo de execu��o lendo 2 bytes de execu��o por vez
/* FLSCL.FOSE(7) = 0 for < 10MHz and 1 for SYSCLK > 10MHz
FLSCL.FLRT(4) = 0 for < 25MHz and 1 for SYSCLK > 25MHz */
FLSCL = 0x90;
CKCON = 0x30;
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;
}
IE_ES0 = 1; //habilita interrupção de serial
TL1 = TH1; // Init Timer1
TMOD &= ~0xF0; // TMOD: timer 1 in 8-bit autoreload
TMOD |= 0x20;
TCON_TR1 = 1; // START Timer1
}
//-----------------------------------------------------------------------------
// 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)
{
char RX_232 = SBUF0;
SCON0_RI = 0;
if(pos_buffer >= UART_BUFFERSIZE) // tem um bug no compilador ou chip que faz reseta
{//erro descarta, pois é maior que o tamanho maximo do buffer
rec_232=0; //não recebendo
pos_buffer=0;//limpa buffer
tem_recp = 0;//sinaliza fim de pacote
}
if(rec_232 && RX_232 == '\n')
{//esta recebendo e chegou delimitador de fim
rec_232=0; //não recebendo
tem_recp = 1;//sinaliza fim de pacote
Liga_Port4(LED_ping);
}
if(rec_232)
{//esta recebendo
UART_Buffer_rx[pos_buffer] = RX_232;
pos_buffer++;
}
if(RX_232 == '/')
{
pos_buffer=0;//sinaliza recepção
rec_232=1; //recebendo
}
}
if (SCON0_TI) //testa se tem transmissão
{
SCON0_TI = 0; // limpa flag de tranmissão
if(trans_232 == 1)
{
if (pos_buffer_tx < tam_buffer_tx)
{// transmitindo
SBUF0 = UART_Buffer_tx[pos_buffer_tx];//escreve na porta serial
pos_buffer_tx++;
}
else
{
trans_232 = 0; //fim de transmissao
pos_buffer_tx =0;
}
}
}
}
void escreve_frase(char dados[] ,uint8_t tam)
{
while(trans_232); //faz nada só espera enviar todo o pacote talvez por um time out
//se ja houver dados para ser enviado espera terminar para comecar a enviar. // veja que pode travar um pouco aqui o processamento
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
}
//-----------------------------------------------------------------------------
// MAIN Routine
//-----------------------------------------------------------------------------
void main (void)
{ // enable)
PORT_Init(); // Initialize Port I/O
SYSCLK_Init (); // Initialize Oscillator
UART0_Init();
IE_EA = 1;//habilita todas as interrupções
escreve_frase("Escreva na formato: /xx\n \r" ,25);
while(1)
{
if(tem_recp)//recebeu dados
{
//trata os dados recebidos que estão em : UART_Buffer_RX
escreve_frase("\n\r",2);//salta linha e retorna para o inicio de linha
escreve_frase("recebeu dados =>" ,16);
escreve_frase(UART_Buffer_rx ,pos_buffer);
pos_buffer = 0;
tem_recp = 0;//sinaliza que já leu
Desliga_Port4(LED_ping);
}
pisca++;
if(pisca > 65500)
{ // pisca led
if(liga_pino_status == 0)
{
liga_pino_status = 1;
Liga_Port4(LED_Status);
SCON0_TI = 0;
}
else
{
liga_pino_status = 0;
Desliga_Port4(LED_Status);
}
pisca =0;
}
}
}
//-----------------------------------------------------------------------------
// End Of File
//-----------------------------------------------------------------------------
Formatado em http://hilite.me/ acessado em 03_11_2023.
Nenhum comentário :
Postar um comentário
olá,digite aqui seu comentário!