IurkivTech

EletronicaLogo
Artigo do site Embarcados
Apostila UFJF – TivaWare CCS
Placa de desenvolvimento EK-TM4C129EXL
Datasheet
TivaWare – Documentação das funções
GitHub
Google Drive

Aqui registro os dados relevantes para configurar a UART com interrupção para recebimento de dados (UARTRX) da placa de desenvolvimento EK-TM4C129EXL.

No arquivo “main.c”, configuro os pinos, o periférico (UART), a interrupção e crio a função que trata a interrupção.

/* Teste02-Uart : Código de teste criado para testar a configuração do CCS e da biblioteca TivaWare.
 *
 * Objetivo: demonstrar como realizar a configuração da UART com interrupção na UARTRX.
 *
 * Autor: aiurkiv
 *
 * Placa: EK-TMC129EXL Rev A
 *
 * *** Resumo, arrumar depois.
 * Para configurar uma interrupção, tenho de primeiramente criar uma função do tipo void.
 * Após devo declarar a função como extern no arquivo "tm4c129encpdt_startup_ccs.c" (linha 57 do arquivo)
 * Também devo colocar o nome da função no vetor de de interrupção. (ver arquivo tm4... linha 92)
 *
 * Configuração:
 * - UART0, PA0 e PA1 - RX e TX respectivamente
 * - GPIO A, pinos 0 e 1 - RX e TX respectivamente
 * - Configuração UART: 9600, 1 stop bit, sem paridade.
 * - Habilito interrupção na UART0 e a configuro por tempo de recebimento.
 *
 * Como quero que os leds acendam quando o botão for precionado, a lógica do código tem de ser invertida
 * devido a lógica dos botões ser invertida (é como negar o sinal 2x). Ou seja, se a leitura do botão
 * for 1, ele não está apertado e o led deve ficar apagado, Já se a leitura do botão for 0, ele está
 * apertado e o led deve acender.
*/

#include <stdint.h>
#include <stdio.h>
#include <stdbool.h>
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "driverlib/debug.h"
#include "driverlib/gpio.h"
#include "driverlib/interrupt.h"
#include "driverlib/pin_map.h"
#include "driverlib/rom.h"
#include "driverlib/rom_map.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"

#define TAMANHO     40
#define INICIO      17
#define DELAY_1S    1000


uint32_t g_ui32SysClock;

char dados[TAMANHO];
unsigned char posicao;      // Utilizo char pois aqui o vetor terá menos de 256 posições
bool flagPronto;


/* inicia_variaveis() - Função
 * Inicia o valor das variáveis
 */
void inicia_variaveis()
{
    sprintf(dados, "Dados recebidos: ");    // Preenche a frase nas primeiras 17 posições do vetor dados.
    posicao = INICIO;
    flagPronto = false;
}

/* UARTIntHandler() - Interrupção UART RX
 *
 * Adiciona os dados recebidos ao vetor até o momento que encontra o char '\n'
 * Após seta a flagPronto que indica que recebeu os dados e adicionou ao vetor dados.
 */
void UARTIntHandler(void)
{
    uint32_t ui32Status;

    // Pega o estado da interrupção
    ui32Status = UARTIntStatus(UART0_BASE, true);

    // Limpa a flag de interrupção
    UARTIntClear(UART0_BASE, ui32Status);

    // Permanece em loop enquanto houver dados para ler
    while(UARTCharsAvail(UART0_BASE))
    {
        // Adiciona um char recebido na "posicao" do vetor
        dados[posicao] = (char)UARTCharGetNonBlocking(UART0_BASE);
        if(dados[posicao] == '\n')
            flagPronto = true;
        posicao++;
        if(posicao >= TAMANHO)
            posicao = INICIO;
    }
}

/* UARTSend() - Função
 *
 * Envia um vetor pela UART até encontrar o caracter '\n' (envia inclusive o '\n').
 */
void UARTSend(const uint8_t *pui8Buffer)
{
    // Loop while there are more characters to send.
    while(1)
    {
        // Write the next character to the UART.
        UARTCharPutNonBlocking(UART0_BASE, *pui8Buffer);
        if(*pui8Buffer == '\n')
            return;
        else
            *pui8Buffer++;
    }
}

/* main()
 *
 * Inicia a configuração do sistema e as variáveis.
 * Após fica em loop infinito aguardando o recebimento de dados pela UART sinalizado pela
 * flagPronto que é tratado por interrupção. Na interrupção também monto o vetor "dados" que
 * armazena os dados para enviar pela UART.
 * Quando a flagPronto é setada, envio o vetor dados pela UART.
 */
void main(void)
{
    // Configurando o clock em 120MHz.
    g_ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
                                         SYSCTL_OSC_MAIN |
                                         SYSCTL_USE_PLL |
                                         SYSCTL_CFG_VCO_480), 120000000);

    // Iniciando as variáveis globais.
    inicia_variaveis();

    // Habilito os periféricos da UART.
    // Conforme datasheet pg 751, UART0 é no IO PA. PA0 = U0RX, PA1 = U0TX
    // Tem de habilitar ambos os periféricos UART0 e GPIOA
    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);

    // Configuro PA0 and PA1 como pinos da UART0.
    GPIOPinConfigure(GPIO_PA0_U0RX);
    GPIOPinConfigure(GPIO_PA1_U0TX);
    GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);

    // Configuro a UART: 9600, 8 bits / 1 stop bit / sem paridade.
    UARTConfigSetExpClk(UART0_BASE, g_ui32SysClock, 9600,
                        (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
                         UART_CONFIG_PAR_NONE));

    // Habilito a interrupção global.
    IntMasterEnable();

    // Habilito a interrupção da UART0 por tempo de recebimento do dado
    IntEnable(INT_UART0);
    UARTIntEnable(UART0_BASE, UART_INT_RX | UART_INT_RT);

    // Delay inicial de 1s
    SysCtlDelay((g_ui32SysClock / (1000 * 3)) * DELAY_1S);

    // Sinaliza que programa iniciou.
    UARTSend((uint8_t *)"Iniciado\n");

    // Loop infinito
    while(1)
    {
        // Quando recebe dados pela UART, a interrupção monta a mensagem de retorno no vetor dados
        // e habilita flagPronto.
        if(flagPronto)
        {
            UARTSend((uint8_t *)dados);
            posicao = INICIO;
            flagPronto = false;
        }
    }
}

Cada interrupção está associada a um endereço fixo no microcontrolador, então quando o evento da interrupção acontece ele busca o endereço da função no vetor de interrupções. Aqui associei a função UARTIntHandler a UART0 no vetor de interrupções.

//*****************************************************************************
//
// Startup code for use with TI's Code Composer Studio.
//
// Copyright (c) 2011-2014 Texas Instruments Incorporated.  All rights reserved.
// Software License Agreement
// 
// Software License Agreement
//
// Texas Instruments (TI) is supplying this software for use solely and
// exclusively on TI's microcontroller products. The software is owned by
// TI and/or its suppliers, and is protected under applicable copyright
// laws. You may not combine this software with "viral" open-source
// software in order to form a larger program.
//
// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
// DAMAGES, FOR ANY REASON WHATSOEVER.
//
//*****************************************************************************

#include <stdint.h>

//*****************************************************************************
//
// Forward declaration of the default fault handlers.
//
//*****************************************************************************
void ResetISR(void);
static void NmiSR(void);
static void FaultISR(void);
static void IntDefaultHandler(void);

//*****************************************************************************
//
// External declaration for the reset handler that is to be called when the
// processor is started
//
//*****************************************************************************
extern void _c_int00(void);

//*****************************************************************************
//
// Linker variable that marks the top of the stack.
//
//*****************************************************************************
extern uint32_t __STACK_TOP;

//*****************************************************************************
//
// External declarations for the interrupt handlers used by the application.
//
//*****************************************************************************
extern void UARTIntHandler(void);


//*****************************************************************************
//
// The vector table.  Note that the proper constructs must be placed on this to
// ensure that it ends up at physical address 0x0000.0000 or at the start of
// the program if located at a start address other than 0.
//
//*****************************************************************************
#pragma DATA_SECTION(g_pfnVectors, ".intvecs")
void (* const g_pfnVectors[])(void) =
{
    (void (*)(void))((uint32_t)&__STACK_TOP),
                                            // The initial stack pointer
    ResetISR,                               // The reset handler
    NmiSR,                                  // The NMI handler
    FaultISR,                               // The hard fault handler
    IntDefaultHandler,                      // The MPU fault handler
    IntDefaultHandler,                      // The bus fault handler
    IntDefaultHandler,                      // The usage fault handler
    0,                                      // Reserved
    0,                                      // Reserved
    0,                                      // Reserved
    0,                                      // Reserved
    IntDefaultHandler,                      // SVCall handler
    IntDefaultHandler,                      // Debug monitor handler
    0,                                      // Reserved
    IntDefaultHandler,                      // The PendSV handler
    IntDefaultHandler,                      // The SysTick handler
    IntDefaultHandler,                      // GPIO Port A
    IntDefaultHandler,                      // GPIO Port B
    IntDefaultHandler,                      // GPIO Port C
    IntDefaultHandler,                      // GPIO Port D
    IntDefaultHandler,                      // GPIO Port E
    UARTIntHandler,                         // UART0 Rx and Tx
    IntDefaultHandler,                      // UART1 Rx and Tx
    IntDefaultHandler,                      // SSI0 Rx and Tx
    IntDefaultHandler,                      // I2C0 Master and Slave
    IntDefaultHandler,                      // PWM Fault
    IntDefaultHandler,                      // PWM Generator 0
    IntDefaultHandler,                      // PWM Generator 1
    IntDefaultHandler,                      // PWM Generator 2
    IntDefaultHandler,                      // Quadrature Encoder 0
    IntDefaultHandler,                      // ADC Sequence 0
    IntDefaultHandler,                      // ADC Sequence 1
    IntDefaultHandler,                      // ADC Sequence 2
    IntDefaultHandler,                      // ADC Sequence 3
    IntDefaultHandler,                      // Watchdog timer
    IntDefaultHandler,                      // Timer 0 subtimer A
    IntDefaultHandler,                      // Timer 0 subtimer B
    IntDefaultHandler,                      // Timer 1 subtimer A
    IntDefaultHandler,                      // Timer 1 subtimer B
    IntDefaultHandler,                      // Timer 2 subtimer A
    IntDefaultHandler,                      // Timer 2 subtimer B
    IntDefaultHandler,                      // Analog Comparator 0
    IntDefaultHandler,                      // Analog Comparator 1
    IntDefaultHandler,                      // Analog Comparator 2
    IntDefaultHandler,                      // System Control (PLL, OSC, BO)
    IntDefaultHandler,                      // FLASH Control
    IntDefaultHandler,                      // GPIO Port F
    IntDefaultHandler,                      // GPIO Port G
    IntDefaultHandler,                      // GPIO Port H
    IntDefaultHandler,                      // UART2 Rx and Tx
    IntDefaultHandler,                      // SSI1 Rx and Tx
    IntDefaultHandler,                      // Timer 3 subtimer A
    IntDefaultHandler,                      // Timer 3 subtimer B
    IntDefaultHandler,                      // I2C1 Master and Slave
    IntDefaultHandler,                      // CAN0
    IntDefaultHandler,                      // CAN1
    IntDefaultHandler,                      // Ethernet
    IntDefaultHandler,                      // Hibernate
    IntDefaultHandler,                      // USB0
    IntDefaultHandler,                      // PWM Generator 3
    IntDefaultHandler,                      // uDMA Software Transfer
    IntDefaultHandler,                      // uDMA Error
    IntDefaultHandler,                      // ADC1 Sequence 0
    IntDefaultHandler,                      // ADC1 Sequence 1
    IntDefaultHandler,                      // ADC1 Sequence 2
    IntDefaultHandler,                      // ADC1 Sequence 3
    IntDefaultHandler,                      // External Bus Interface 0
    IntDefaultHandler,                      // GPIO Port J
    IntDefaultHandler,                      // GPIO Port K
    IntDefaultHandler,                      // GPIO Port L
    IntDefaultHandler,                      // SSI2 Rx and Tx
    IntDefaultHandler,                      // SSI3 Rx and Tx
    IntDefaultHandler,                      // UART3 Rx and Tx
    IntDefaultHandler,                      // UART4 Rx and Tx
    IntDefaultHandler,                      // UART5 Rx and Tx
    IntDefaultHandler,                      // UART6 Rx and Tx
    IntDefaultHandler,                      // UART7 Rx and Tx
    IntDefaultHandler,                      // I2C2 Master and Slave
    IntDefaultHandler,                      // I2C3 Master and Slave
    IntDefaultHandler,                      // Timer 4 subtimer A
    IntDefaultHandler,                      // Timer 4 subtimer B
    IntDefaultHandler,                      // Timer 5 subtimer A
    IntDefaultHandler,                      // Timer 5 subtimer B
    IntDefaultHandler,                      // FPU
    0,                                      // Reserved
    0,                                      // Reserved
    IntDefaultHandler,                      // I2C4 Master and Slave
    IntDefaultHandler,                      // I2C5 Master and Slave
    IntDefaultHandler,                      // GPIO Port M
    IntDefaultHandler,                      // GPIO Port N
    0,                                      // Reserved
    IntDefaultHandler,                      // Tamper
    IntDefaultHandler,                      // GPIO Port P (Summary or P0)
    IntDefaultHandler,                      // GPIO Port P1
    IntDefaultHandler,                      // GPIO Port P2
    IntDefaultHandler,                      // GPIO Port P3
    IntDefaultHandler,                      // GPIO Port P4
    IntDefaultHandler,                      // GPIO Port P5
    IntDefaultHandler,                      // GPIO Port P6
    IntDefaultHandler,                      // GPIO Port P7
    IntDefaultHandler,                      // GPIO Port Q (Summary or Q0)
    IntDefaultHandler,                      // GPIO Port Q1
    IntDefaultHandler,                      // GPIO Port Q2
    IntDefaultHandler,                      // GPIO Port Q3
    IntDefaultHandler,                      // GPIO Port Q4
    IntDefaultHandler,                      // GPIO Port Q5
    IntDefaultHandler,                      // GPIO Port Q6
    IntDefaultHandler,                      // GPIO Port Q7
    IntDefaultHandler,                      // GPIO Port R
    IntDefaultHandler,                      // GPIO Port S
    IntDefaultHandler,                      // SHA/MD5 0
    IntDefaultHandler,                      // AES 0
    IntDefaultHandler,                      // DES3DES 0
    IntDefaultHandler,                      // LCD Controller 0
    IntDefaultHandler,                      // Timer 6 subtimer A
    IntDefaultHandler,                      // Timer 6 subtimer B
    IntDefaultHandler,                      // Timer 7 subtimer A
    IntDefaultHandler,                      // Timer 7 subtimer B
    IntDefaultHandler,                      // I2C6 Master and Slave
    IntDefaultHandler,                      // I2C7 Master and Slave
    IntDefaultHandler,                      // HIM Scan Matrix Keyboard 0
    IntDefaultHandler,                      // One Wire 0
    IntDefaultHandler,                      // HIM PS/2 0
    IntDefaultHandler,                      // HIM LED Sequencer 0
    IntDefaultHandler,                      // HIM Consumer IR 0
    IntDefaultHandler,                      // I2C8 Master and Slave
    IntDefaultHandler,                      // I2C9 Master and Slave
    IntDefaultHandler,                      // GPIO Port T
    IntDefaultHandler,                      // Fan 1
    0,                                      // Reserved
};

//*****************************************************************************
//
// This is the code that gets called when the processor first starts execution
// following a reset event.  Only the absolutely necessary set is performed,
// after which the application supplied entry() routine is called.  Any fancy
// actions (such as making decisions based on the reset cause register, and
// resetting the bits in that register) are left solely in the hands of the
// application.
//
//*****************************************************************************
void
ResetISR(void)
{
    //
    // Jump to the CCS C initialization routine.  This will enable the
    // floating-point unit as well, so that does not need to be done here.
    //
    __asm("    .global _c_int00\n"
          "    b.w     _c_int00");
}

//*****************************************************************************
//
// This is the code that gets called when the processor receives a NMI.  This
// simply enters an infinite loop, preserving the system state for examination
// by a debugger.
//
//*****************************************************************************
static void
NmiSR(void)
{
    //
    // Enter an infinite loop.
    //
    while(1)
    {
    }
}

//*****************************************************************************
//
// This is the code that gets called when the processor receives a fault
// interrupt.  This simply enters an infinite loop, preserving the system state
// for examination by a debugger.
//
//*****************************************************************************
static void
FaultISR(void)
{
    //
    // Enter an infinite loop.
    //
    while(1)
    {
    }
}

//*****************************************************************************
//
// This is the code that gets called when the processor receives an unexpected
// interrupt.  This simply enters an infinite loop, preserving the system state
// for examination by a debugger.
//
//*****************************************************************************
static void
IntDefaultHandler(void)
{
    //
    // Go into an infinite loop.
    //
    while(1)
    {
    }
}

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Rolar para cima