Exemplo de como fazer uma comunicação serial usando o microcontrolador C8051F832 de 16 pinos. Basta colocar os caractere precedido por "*" para indicar fim de recepção.
/* * * Compilador : Simplicity studio * Microcontroladores compativeis : C8051F832 * Autor: Aguivone Moretti Fógia * Versão: 1.0 * Data : 22_07_2022 -> inicio de teste de comunicação serial * Descrição: * teste de comunicação serial * Basta envia um dado e depois o caracter "*" para indicar fim de recepção * exemplo: teste* ira ter como retorno "TESTE" */ //----------------------------------------------------------------------------- // Includes //----------------------------------------------------------------------------- #include "si_toolchain.h" #include <SI_C8051F800_Defs.h> // SFR #include <stdio.h> #include <string.h> #define SYSCLK 24500000 // SYSCLK em hertz usando clock interno #define BAUDRATE 19200 // Baud rate em bps //----------------------------------------------------------------------------- // Function PROTOTYPES //----------------------------------------------------------------------------- void SYSCLK_Init (void); void UART0_Init (void); void PORT_Init (void); SI_INTERRUPT_PROTO(UART0_ISR, INTERRUPT_UART0); //----------------------------------------------------------------------------- // variaveis globais //----------------------------------------------------------------------------- #define UART_TAM_MAX 64 uint8_t UART_Buffer[UART_TAM_MAX] = {0}; uint8_t UART_buffer_tamanho = 0; uint8_t UART_primeira_entrada = 0; uint8_t UART_primeira_saida = 0; uint8_t Enviar_dados =1; static uint8_t Caracter_temporario; //----------------------------------------------------------------------------- // SiLabs_Startup() // ---------------------------------------------------------------------------- // Essa rotina roda sempre primeiro que o rotina main //----------------------------------------------------------------------------- void SiLabs_Startup (void) { PCA0MD &= ~0x40; // WDTE = 0 (desliga watchdog ) } //----------------------------------------------------------------------------- //Rotina principal //----------------------------------------------------------------------------- void main (void) { PORT_Init(); // inicializa portas SYSCLK_Init (); // inicializa oscilador UART0_Init(); // inicializa UART IE_EA = 1; // habilita interrupções UART_Buffer[0] ='D'; UART_Buffer[1] ='I'; UART_Buffer[2] ='G'; UART_Buffer[3] ='I'; UART_Buffer[4] ='T'; UART_Buffer[5] ='E'; UART_Buffer[6] =' '; UART_Buffer[7] ='A'; UART_Buffer[8] ='L'; UART_Buffer[9] ='G'; UART_Buffer[10] ='O'; UART_Buffer[11] ='!'; UART_buffer_tamanho = 12; // atualiza tamanho do buffer UART_primeira_entrada = 12; Enviar_dados = 0; // limpa flag SCON0_TI = 1; // indica pra trasnmitir pois tem dados while(1) { // se houver dados recebido será enviado if((Enviar_dados == 1) && (UART_buffer_tamanho != 0) && (Caracter_temporario == '*'))//tx pronto /buffer cheio / finalizador de pacote { Enviar_dados = 0; // limpa flag SCON0_TI = 1; // indica pra trasnmitir pois tem dados } } } //----------------------------------------------------------------------------- // Initialization Subroutines //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // PORT_Init //----------------------------------------------------------------------------- // // Return Value : None // Parameters : None // // Configure the Crossbar and GPIO ports. // // P0.4 digital push-pull UART TX = como saida // P0.5 digital open-drain UART RX = como entrada // //----------------------------------------------------------------------------- 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 precision // oscillator at its maximum frequency and enables the missing clock // detector. // //----------------------------------------------------------------------------- void SYSCLK_Init (void) { OSCICN |= 0x83; // Enable the precision internal osc. RSTSRC = 0x06; // habilita detector de falta de clock e // deixa monitor de VDD habilitado. CLKSEL = 0x00; // seleciona a precisão interna. // clock sem divisão } //----------------------------------------------------------------------------- // 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 RI0 and TI0 bits #if (SYSCLK/BAUDRATE/2/256 < 1) TH1 = -(SYSCLK/BAUDRATE/2); CKCON &= ~0x0B; // T1M = 1; SCA1:0 = xx CKCON |= 0x08; #elif (SYSCLK/BAUDRATE/2/256 < 4) TH1 = -(SYSCLK/BAUDRATE/2/4); CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 01 CKCON |= 0x01; #elif (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; #endif TL1 = TH1; // Initialize Timer1 TMOD &= ~0xf0; // TMOD: timer 1 in 8-bit autoreload TMOD |= 0x20; TCON_TR1 = 1; // START Timer1 Enviar_dados = 1; // Flag showing that UART can transmit IP |= 0x10; // Make UART high priority IE_ES0 = 1; // Enable UART0 interrupts SCON0_TI = 1; } //----------------------------------------------------------------------------- // Interrupt Service Routines //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // UART0_Interrupt //----------------------------------------------------------------------------- // // This routine is invoked whenever a character is entered or displayed on the // Hyperterminal. // //----------------------------------------------------------------------------- SI_INTERRUPT(UART0_ISR, UART0_IRQn) { if (SCON0_RI == 1) { if( UART_buffer_tamanho == 0) {// tem dados UART_primeira_entrada = 0; } SCON0_RI = 0; // limpa flag de interrupção de recepção Caracter_temporario = SBUF0; // Lê o caracter que está no buffer if (UART_buffer_tamanho < UART_TAM_MAX) { UART_Buffer[UART_primeira_entrada] = Caracter_temporario; // coloca no buffer para transmitir UART_buffer_tamanho++; // atualiza tamanho do buffer UART_primeira_entrada++; // atualiza contagem } } if (SCON0_TI == 1) // verifica se houve interrupção de transmissão { SCON0_TI = 0; // limpa flag if (UART_buffer_tamanho != 0) // se tiver dados a enviar envia { //tem um pacote valido if ( UART_buffer_tamanho == UART_primeira_entrada ) { UART_primeira_saida = 0; } // armazena informação em Caracter_temporario Caracter_temporario = UART_Buffer[UART_primeira_saida]; if ((Caracter_temporario >= 0x61) && (Caracter_temporario <= 0x7A)) { // se não tiver em caixa alta(maiuscula) passa para caixa alta. Caracter_temporario -= 32; } SBUF0 = Caracter_temporario; // coloca no registrador de transmissão de dados UART_primeira_saida++; // atualiza contagem UART_buffer_tamanho--; // decrementa o tamanho } else { UART_buffer_tamanho = 0; // zera contagem Enviar_dados = 1; // indica que dados foram enviado } } } //----------------------------------------------------------------------------- // End Of File //-----------------------------------------------------------------------------
Formato no site http://hilite.me/ no dia 22/07/2022.
Nenhum comentário :
Postar um comentário
olá,digite aqui seu comentário!