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!