sexta-feira, 3 de novembro de 2023

Configurando o 8051CF380 para 48MHZ ( através do pll, com oscilador interno) e configurando a porta serial

     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!