![]() |
Programação do LPC2378 usando o arm-elf-gcc Parte 3: Configuração da porta serial |
![]() |
Anterior | Indice | Próximo |
Agora vamos analisar o programa a03_uart/, que configura a porta serial, escreve uma mensagem e faz eco da porta serial.
No início do módulo main.c temos a função U0init() que habilita e configura a porta serial. Então pode-se usar as funções void U0putchar(int c), int U0getchar() e void U0puts para comunicar-se com um terminal através da porta serial.
Iniciar expandindo o arquivo a03_uart.tgz e abrindo um shell e entrando no diretório a03_uart. Prepara-se o microprocessador para programar a Flash, conectando o cabo serial e colocando em modo de programação. Então pode-se compilar o programa e gravar na Flash com o comando
make ispPara testar o programa recomenda-se usar um teminal serial, como o ltser.exe. O programa escreve uma mensagem e fica pronto para fazer eco do que é digitado.
Tendo o programa mon23 instalado na FLASH e sendo executado, pode-se testar este programa rodando na RAM. Para isto usa-se o comando
make tserEste comando compila o programa e envia-o para a RAM usando o terminal ltser. Para executar o programa usa-se o comando "P" do monitor mon23.
O LPC2378 tem quatro portas seriais (UART0, UART1, UART2 e UART3), que podem ser configuradas de modo semelhante à UART tipo 16550. Inicialmente devemos selecionar as funções TxD0 e RxD0 nos pinos do microprocessador. Os registradores PINSEL0 até PINSEL9 servem para selecionar uma das 4 possíveis funções de cada pino do microcontrolador. A cada pino correspondem 2 bits dos registradores PINSEL. Os sinais TXD0 e RXD0 são selecionados colocando o valor 01 nos bits 5:4 e 6:7 do PINSEL0. Para evitar o efeito colateral de alterar a configuração de outros pinos, recomenda-se usar uma operação ou com o valor anterior do PINSEL0:
PINSEL0 |= 0x50; /* Habilita TxD0 e RxD0 */Aa portas seriais podem usar buffers tipo FIFO de 16 níveis para evitar perdas de dados. Para habilita-las usa-se o comando:
U0FCR = 0x7; /* Habilita as FIFOs e reset */Especificamente os bits do registrador U0FCR são os seguintes:
U0FCR 0xE000C008 |
FIFO Control Register: Configura a flia tipo FIFO da UART. bit 7 e 6: Estes bits controlam o nivel de enchimento da FIFO que causa o disparo de uma interrupção: 00 Dispara com 1 caractere.bit 5,4,3: Não usados; sempre zero bit 2: Inicializa a FIFO de transmissão bit 1: Inicializa a FIFO de recebimento bit 0: Habilita as FIFOs (deve ser 1 para que a FIFO funcione) |
U0LCR 0xE000C00C |
Line Control Register: Configura a UART. bit 7: DLAB Habilita o acesso ao divisor de Baud Rate bit 6: Set Break bit 5: Paridade fixa bit 4: Paridade par bit 3: Habilita a paridade bit 2: Dois stop bits bit 1 e 0: Número de bits de dados-5 |
U0DLL 0xE000C000 | Divisor de Baud-Rate menos significativo |
U0DLM 0xE000C004 | Divisor de Baud-Rate mais significativo |
#define PCLK 12000000 #define BAUDRATE 19200 /* Configuracao da Porta Serial 0 */ void U0init(void) { /* 01 nos bits 7,6 do PCLKSEL0 Para selecionar divisor por 1 no PCLK da UART0 */ PCLKSEL0 = (PCLKSEL0 & (~0xc0)) | 0x40; /* 01 e 01 nos bits 7,6 e 5,4 do PINSEL0: Seleciona pinos P0.2 e P0.3 como TxD0 e RxD0 */ PINSEL0 = (PINSEL0 & (~0xf0)) | 0x50; U0FCR = 0x7; /* Habilita as FIFOs e reset */ U0LCR = 0x83; /* Habilita acesso ao divisor de baud-rate (DLAB) */ U0DLL = ((PCLK/BAUDRATE+8) >> 4) & 0xff; U0DLM = ((PCLK/BAUDRATE) >> 12) & 0xff; U0LCR = 0x03; /* Configura UART0 como 8N1 */ }Existe também um registrador preescalonador do clock que pode servir para obter valores exatos ou melhores aproximações do baud rate desejado. Trata-se do U0FDR (Fractional Divider Register):
U0FDR 0xE000C028 |
Fractional Divider Register bit 7 a 4: MULVAL bit 3 a 0: DIVADDVAL |
Este registrador preescalona o PCLK da UART pelo fator MULVAL/(MULVAL+DIVADDVAL). Desta forma o divisor de Baud-Rate U0DLM:U0DLL passa a ser calculado pela fórmula:
U0FDR = (MULVAL << 4) + DIVADDVAL; Divisor = PCLK * MULVAL / ((MULVAL + DIVADDVAL)*16*BaudRate) U0DLM = Divisor >> 8; ; Byte mais significativo U0DLL = Divisor & 0xff; ; Byte menos significativo
Por exemplo, se PCLK = 72 MHz, pode-se configurar a UART para exatamente 19200 Baud com MULVAL = 8, DIVADDVAL=7, U0DLM=0 e U0DLL=125.
Depois de feita a configuração, pode-se enviar ou receber dados pela porta serial usando os registradores:
U0RBR 0xE000C000 | Receiver Buffer Register, para leitura. Este registrador tem o byte de dado recebido. |
U0THR 0xE000C000 | Mesmo endereço que o U0RBR, mas para escrita. Aqui vai o dado a ser transmitido. |
U0LSR 0xE000C014 |
Line Status Register: Só leitura; Informa o estado da UART. bit 7: Erro na fila de recebinmento. bit 6: TEMT Toda a fila de transmissão está vazia. bit 5: THRE Indica que tem lugar livre no transmissor. bit 4: Break Interrupt: Acontece quando RX fica em 0 durante mais tempo que um caractere inteiro. bit 3: Framing error: Erro de enquadramento. Foi lido zero quando o stop-bit (sempre 1) era esperado. bit 2: Houve um erro de paridade bit 1: OE Overrun error. Um byte de dados foi perdido porque foi sobreescrito sem ter sido lido. bit 0: RDR Indica que tem dado recebido. |
Usando estes registradores pode-se escrever funções para ler e para escrever bytes na UART.
/* Mascaras para selecionar bits do U0LSR */ #define THREMPTY 0x20 #define RXDREADY 0x01 /* Le um caractere recebido na UART0 */ char UART0getchar(void) { while((U0LSR & RXDREADY) == 0); /* Espera ter dado recebido */ return U0RBR; /* Le e retorna o dado recebido */ } /* Envia um caractere pela UART0 */ void UART0putchar(char c) { while((U0LSR & THREMPTY) == 0); /* Espera o transmissor ficar disponivel */ U0THR = c; /* Transmite */ }
Anterior | Indice | Próximo |