Programas Tiva 04 - Uart

PONTIFICIA UNIVERSIDAD CATÓLICA DEL PERÚ FACULTAD DE CIENCIAS E INGENIERÍA SISTEMAS DIGITALES IEE256 H0522 H0523 (Primer

Views 55 Downloads 1 File size 1MB

Report DMCA / Copyright

DOWNLOAD FILE

Recommend stories

Citation preview

PONTIFICIA UNIVERSIDAD CATÓLICA DEL PERÚ FACULTAD DE CIENCIAS E INGENIERÍA SISTEMAS DIGITALES IEE256 H0522 H0523 (Primer Semestre 2019)

RECEPTOR / TRANSMISOR UNIVERSAL ASÍNCRONO (UART) Para la resolución de los problemas planteados incluimos en los programas el archivo tm4c123gh6pm.h donde se encuentra las definiciones de los registros del UART que vamos a utilizar: //***************************************************************************** // // UART registers (UART0) // //***************************************************************************** #define UART0_DR_R (*((volatile uint32_t *)0x4000C000)) #define UART0_RSR_R (*((volatile uint32_t *)0x4000C004)) #define UART0_ECR_R (*((volatile uint32_t *)0x4000C004)) #define UART0_FR_R (*((volatile uint32_t *)0x4000C018)) #define UART0_ILPR_R (*((volatile uint32_t *)0x4000C020)) #define UART0_IBRD_R (*((volatile uint32_t *)0x4000C024)) #define UART0_FBRD_R (*((volatile uint32_t *)0x4000C028)) #define UART0_LCRH_R (*((volatile uint32_t *)0x4000C02C)) #define UART0_CTL_R (*((volatile uint32_t *)0x4000C030)) #define UART0_IFLS_R (*((volatile uint32_t *)0x4000C034)) #define UART0_IM_R (*((volatile uint32_t *)0x4000C038)) #define UART0_RIS_R (*((volatile uint32_t *)0x4000C03C)) #define UART0_MIS_R (*((volatile uint32_t *)0x4000C040)) #define UART0_ICR_R (*((volatile uint32_t *)0x4000C044)) #define UART0_DMACTL_R (*((volatile uint32_t *)0x4000C048)) #define UART0_9BITADDR_R (*((volatile uint32_t *)0x4000C0A4)) #define UART0_9BITAMASK_R (*((volatile uint32_t *)0x4000C0A8)) #define UART0_PP_R (*((volatile uint32_t *)0x4000CFC0)) #define UART0_CC_R (*((volatile uint32_t *)0x4000CFC8)) //*****************************************************************************

Por otro lado, trabajaremos con la tarjeta Tiva C Launchpad que utiliza el UART0 para comunicación serial, el UART0 emplea los pines PA0 como receptor (U0RX) y PA1 como transmisor (U0TX), como se ve en el diagrama esquemático.

Los problemas están planteados para comunicar el microcontrolador con una computadora personal donde se debe ejecutar un programa terminal serial. Se recomienda utilizar el terminal PuTTY.

Al ejecutar el PuTTY debe configurar los parámetros de comunicación serial, deben ser iguales a los que configuró para el microcontrolador:

También debe ingresar el puerto serial de la PC al que está conectado el microcontrolador, para saber cuál es debe ingresar al Administrador de dispositivos de Windows y verificar los Puertos (COM y LPT). En estos gráficos se ve que el puerto serial que utiliza la PC para comunicarse . con el microcontrolador es el COM9

PROBLEMAS RESUELTOS PROBLEMA 01: Tenemos conectado al microcontrolador TM4C123GH6PM una computadora personal en la que se está ejecutando un programa de Terminal Serial, desarrollar un programa para el microcontrolador que realice un eco, es decir, cada dato que reciba por el puerto serial lo debe transmitir por el mismo puerto. Los parámetros de comunicación deben ser 9600, 8, N, 1 y la frecuencia de reloj del sistema es de 16MHz.

SOLUCIÓN Diagrama de flujo a.- Programa principal:

INICIO ConfigPtoSerial()

datoRx

EsperaDato()

TransmiteDato(datoRx)

b.- Funciones

datoRx ← EsperaDato( )

TransmiteDato(datoTx)

INICIO

NO

¿Hay dato recibido? SÍ

INICIO

NO

¿Se puede transmitir? SÍ

Leer datoRx del Pto Serial

Escribir datoTx en Pto Serial

FIN

FIN

Código del programa: /****************************************************************************************/ /****************************************************************************************/ /***** PONTIFICIA UNIVERSIDAD CATÓLICA DEL PERÚ *****/ /***** FACULTAD DE CIENCIAS E INGENIERÍA *****/ /***** SISTEMAS DIGITALES *****/ /****************************************************************************************/ /***** Tema: Comunicación Serial UART *****/ /***** Proyecto: UART_P01_Eco *****/ /****************************************************************************************/ /***** Microcontrolador: TM4C123GH6PM *****/ /***** EvalBoard: Tiva C Series TM4C123G LaunchPad *****/ /***** Autor: Rolando Sánchez Ponce *****/ /***** Fecha: Octubre 2017 *****/ /***** Última revisión: Mayo 2019 *****/ /****************************************************************************************/ /***** Enunciado: *****/ /***** Se implementa un programa de eco utilizando el módulo UART0. Cada dato que *****/ /***** se recibe por el puerto serial se retransmite por el puerto serial. *****/ /***** Parámetros de comunicación: 9600, 8, N, 1 *****/ /***** Frecuencia de reloj del sistema 16MHz *****/ /****************************************************************************************/ /****************************************************************************************/ #include #include "tm4c123gh6pm.h" /****************************************************************************************/ /***** F U N C I O N E S *****/ /****************************************************************************************/ /****************************************************************************************/ /***** InicializaPtoSerial() *****/ /****************************************************************************************/ /***** Configura el UART0 con los siguientes parámetros de comunicación serial: *****/ /***** 9600, 8, N, 1. Frecuencia del reloj del sistema 16MHz. *****/ /****************************************************************************************/ /***** ENTRADAS: Ninguna *****/ /***** SALIDA: Ninguna *****/ /****************************************************************************************/ void InicializaPtoSerial(void){ // Activamos el reloj para el UART0 SYSCTL_RCGCUART_R |= SYSCTL_RCGCUART_R0; while(!(SYSCTL_PRUART_R & SYSCTL_PRUART_R0)); // Inhabilitamos el UART0 UART0_CTL_R &= ~UART_CTL_UARTEN; // Velocidad 9600bps (Fsysclk = 16MHz) UART0_IBRD_R = (UART0_IBRD_R & 0xFFFF0000) | 104; UART0_FBRD_R = (UART0_FBRD_R & 0xFFFFFFC0) | 11; // 8, N, 1, FIFOs habilitados UART0_LCRH_R = (UART0_LCRH_R & 0xFFFFFF00) | 0x70; // Habilitamos el UART0, recepción y transmisión UART0_CTL_R |= (UART_CTL_RXE | UART_CTL_TXE | UART_CTL_UARTEN); // Activamos la señal de reloj para GPIOA SYSCTL_RCGCGPIO_R |= SYSCTL_RCGCGPIO_R0; while(!(SYSCTL_PRGPIO_R & SYSCTL_PRGPIO_R0)); // Activamos funciones alternas para PA0 y PA1 GPIO_PORTA_AFSEL_R |= 0x03; // Conectamos UART0 a PA0 y PA1 GPIO_PORTA_PCTL_R = (GPIO_PORTA_PCTL_R&0xFFFFFF00)|0x00000011; // Desactivamos funciones analógicas en PA0 y PA1 GPIO_PORTA_AMSEL_R &= ~(0x03); // Activamos funciones digitales en PA0 y PA1 GPIO_PORTA_DEN_R |= 0x03; }

/****************************************************************************************/ /***** EsperaDato() *****/ /****************************************************************************************/ /***** Lee un dato recibido por el puerto serial, para esto espera que haya un dato *****/ /***** en el buffer de recepción del UART0 para leerlo. *****/ /****************************************************************************************/ /***** ENTRADAS: Ninguna *****/ /***** SALIDA: Dato recibido por el UART0 *****/ /****************************************************************************************/ uint8_t EsperaDato(void){ uint8_t datoRx; while(UART0_FR_R & UART_FR_RXFE); datoRx = (uint8_t)UART0_DR_R; return datoRx; } /****************************************************************************************/ /***** TransmiteDato() *****/ /****************************************************************************************/ /***** Escribe un byte en el buffer de transmisión del UART0 para ser transmitido *****/ /***** por el puerto serial. Si el buffer estuviera lleno espera hasta que se pueda *****/ /***** escribir. *****/ /****************************************************************************************/ /***** ENTRADAS: *****/ /***** datoTx: Dato a transmitir por el puerto serial *****/ /***** SALIDA: Ninguna *****/ /****************************************************************************************/ void TransmiteDato(uint8_t datoTx){ while(UART0_FR_R & UART_FR_TXFF); UART0_DR_R = datoTx; } /****************************************************************************************/ /***** P R O G R A M A P R I N C I P A L *****/ /****************************************************************************************/ int main(void){ uint8_t datoRx; InicializaPtoSerial(); while(1){ datoRx = EsperaDato(); TransmiteDato(datoRx); } } /****************************************************************************************/ /***** F I N D E L P R O G R A M A *****/ /****************************************************************************************/

Captura de pantalla:

PROBLEMA 02: Se tiene conectado al módulo EK-TM4C123GXL una computadora personal en la que se está ejecutando un programa Terminal Serial (PuTTY). Se quiere desarrollar un programa para el microcontrolador que espere recibir una cadena de caracteres, finaliza la recepción de la cadena al recibir el carácter CR (el usuario en el terminal presiona la tecla ENTER), una vez recibida la cadena la retransmite con todos sus caracteres alfabéticos en mayúsculas. Luego se espera el ingreso de una nueva cadena de caracteres. Los parámetros de comunicación deben ser 9600, 8, N, 1 y la frecuencia del reloj del sistema es de 16MHz.

SOLUCIÓN Diagrama de flujo a.- Programa principal

INICIO ConfigPtoSerial()

EsperaCadena(MiCad[ ])

CadMayuscula(MiCad[ ])

TransmiteCadena(MiCad[ ])

b.- Funciones

INICIO

EsperaCadena(CadASCIIZ[ ])

hay1Caracter fin F i 0

datoRx

F

EsperaDato( )

¿datoRx = ENTER?



NO

¿hay1Caracter?



¿hay1Caracter?

NO



hay1Caracter

V

TransmiteDato(datoRx)

CadASCIIZ[i]

i

NO

CadASCIIZ[i] fin

V

datoRx

i+1

¿ fin ? SÍ FIN

INICIO i

0

TransmiteCadena(CadASCIIZ[ ]) ¿CadASCIIZ[i] = 0?



NO TransmiteDato(CadASCIIZ[i]) i

i+1

FIN

0

NO

CadMayusculas(CadASCIIZ[ ]) INICIO i

0



¿CadASCIIZ[i] = 0? NO ¿a

CadASCIIZ[i]

FIN z?

NO

SÍ CadASCIIZ[i]

CadASCIIZ[i] – 20H

i

i+1

Código del programa: /****************************************************************************************/ /****************************************************************************************/ /***** PONTIFICIA UNIVERSIDAD CATÓLICA DEL PERÚ *****/ /***** FACULTAD DE CIENCIAS E INGENIERÍA *****/ /***** SISTEMAS DIGITALES *****/ /****************************************************************************************/ /***** Tema: Comunicación Serial UART *****/ /***** Proyecto: UART_P02_EcoCadMay *****/ /****************************************************************************************/ /***** Microcontrolador: TM4C123GH6PM *****/ /***** EvalBoard: Tiva C Series TM4C123G LaunchPad *****/ /***** Autor: Rolando Sánchez Ponce *****/ /***** Fecha: Octubre 2017 *****/ /***** Última revisión: Mayo 2019 *****/ /****************************************************************************************/ /***** Enunciado: *****/ /***** Se espera la recepción de una cadena de caracteres ASCII (eco por cada ca*****/ /***** racter), una vez recibida se retransmite toda la cadena en mayúsculas. *****/ /***** Módulo: UART0. Parámetros de comunicación: 9600, 8, N, 1 *****/ /***** Frecuencia de reloj del sistema 16MHz *****/ /****************************************************************************************/ /****************************************************************************************/ #include #include "tm4c123gh6pm.h" /****************************************************************************************/ /***** C O N S T A N T E S *****/ /****************************************************************************************/ /***** #define FALSE #define TRUE

CONSTANTES BOOLEANAS 0 1

*****/

/***** #define LF 10 #define FF 12 #define CR 13

CONSTANTES PARA PARA CARACTERES ASCII // Nueva línea // Nueva página // Retorno de carro

*****/

/****************************************************************************************/ /***** F U N C I O N E S *****/ /****************************************************************************************/ /****************************************************************************************/ /***** InicializaPtoSerial() *****/ /****************************************************************************************/ /***** Configura el UART0 con los siguientes parámetros de comunicación serial: *****/ /***** 9600, 8, N, 1. Frecuencia del reloj del sistema 16MHz. *****/ /****************************************************************************************/ /***** ENTRADAS: Ninguna *****/ /***** SALIDA: Ninguna *****/ /****************************************************************************************/ void InicializaPtoSerial(void){ SYSCTL_RCGCUART_R |= SYSCTL_RCGCUART_R0; while(!(SYSCTL_PRUART_R & SYSCTL_PRUART_R0)); UART0_CTL_R &= ~UART_CTL_UARTEN; UART0_IBRD_R = (UART0_IBRD_R & 0xFFFF0000) | 104; UART0_FBRD_R = (UART0_FBRD_R & 0xFFFFFFC0) | 11; UART0_LCRH_R = (UART0_LCRH_R & 0xFFFFFF00) | 0x70; UART0_CTL_R |= (UART_CTL_RXE | UART_CTL_TXE | UART_CTL_UARTEN); SYSCTL_RCGCGPIO_R |= SYSCTL_RCGCGPIO_R0; while(!(SYSCTL_PRGPIO_R & SYSCTL_PRGPIO_R0)); GPIO_PORTA_AFSEL_R |= 0x03; GPIO_PORTA_PCTL_R = (GPIO_PORTA_PCTL_R&0xFFFFFF00)|0x00000011; GPIO_PORTA_AMSEL_R &= ~(0x03); GPIO_PORTA_DEN_R |= 0x03; } /****************************************************************************************/ /***** EsperaDato() *****/ /****************************************************************************************/ /***** Lee un dato recibido por el puerto serial, para esto espera que haya un dato *****/ /***** en el buffer de recepción del UART0 para leerlo. *****/ /****************************************************************************************/ /***** ENTRADAS: Ninguna *****/ /***** SALIDA: Dato recibido por el UART0 *****/ /****************************************************************************************/ uint8_t EsperaDato(void){ uint8_t datoRx; while(UART0_FR_R & UART_FR_RXFE); datoRx = (uint8_t)UART0_DR_R; return datoRx; } /****************************************************************************************/ /***** TransmiteDato() *****/ /****************************************************************************************/ /***** Escribe un byte en el buffer de transmisión del UART0 para ser transmitido *****/ /***** por el puerto serial. Si el buffer estuviera lleno espera hasta que se pueda *****/ /***** escribir. *****/ /****************************************************************************************/ /***** ENTRADAS: *****/ /***** datoTx: Dato a transmitir por el puerto serial *****/ /***** SALIDA: Ninguna *****/ /****************************************************************************************/ void TransmiteDato(uint8_t datoTx){ while(UART0_FR_R & UART_FR_TXFF); UART0_DR_R = datoTx; }

/****************************************************************************************/ /***** SiguienteLinea() *****/ /****************************************************************************************/ /***** Transmite los caracteres necesarios para posicionar el cursor de la pantalla *****/ /***** del terminal al inicio de la siguiente línea. *****/ /****************************************************************************************/ /***** ENTRADAS: Ninguna *****/ /***** SALIDA: Ninguna *****/ /****************************************************************************************/ void SiguienteLinea(void){ // Transmitimos nueva línea (LF) TransmiteDato(LF); // Transmitimos retorno de carro (CR) TransmiteDato(CR); }

/****************************************************************************************/ /***** EsperaCadena() *****/ /****************************************************************************************/ /***** Recibe por el puerto serial una cadena de caracteres ASCII y la almacena en *****/ /***** un arreglo. El usuario ingresa ENTER para finalizar y debe ingresar por lo *****/ /***** menos un caracter antes del ENTER. La función inserta 0 al final de la cade- *****/ /***** na para que sea ASCIIZ. La función hace un eco por cada caracter recibido y *****/ /***** posiciona el cursor al inicio de la siguiente línea al salir. *****/ /****************************************************************************************/ /***** ENTRADAS: *****/ /***** cadenaASCIIZ[]: Dirección de inicio de la cadena ASCIIZ a recibir. *****/ /***** SALIDA: Ninguna *****/ /****************************************************************************************/ void EsperaCadena(uint8_t cadenaASCIIZ[]){ uint8_t datoRx; uint8_t hay1CaracterFlag = FALSE; uint8_t finFlag = FALSE; uint8_t i = 0; do{ // Esperamos recibir un dato por el puerto serial. datoRx = EsperaDato(); // Si dato recibido es diferente de ENTER. if(datoRx != CR){ if(!hay1CaracterFlag) hay1CaracterFlag = TRUE; TransmiteDato(datoRx); cadenaASCIIZ[i++] = datoRx; } // Si dato recibido es ENTER. else if(hay1CaracterFlag){ cadenaASCIIZ[i] = 0; SiguienteLinea(); finFlag = TRUE; } }while(!finFlag); }

/****************************************************************************************/ /***** TransmiteCadena() *****/ /****************************************************************************************/ /***** Transmite por el puerto serial una cadena ASCIIZ. *****/ /****************************************************************************************/ /***** ENTRADAS: *****/ /***** cadenaASCIIZ[]: Dirección de inicio de la cadena ASCIIZ a transmitir. *****/ /***** SALIDA: Ninguna *****/ /****************************************************************************************/

void TransmiteCadena(const uint8_t cadenaASCIIZ[]){ uint8_t i; for(i=0; cadenaASCIIZ[i]; i++){ TransmiteDato(cadenaASCIIZ[i]); } } /****************************************************************************************/ /***** CadMayusculas() *****/ /****************************************************************************************/ /***** Convierte los caracteres en minúsculas de una cadena ASCIIZ a mayúsculas. *****/ /****************************************************************************************/ /***** ENTRADAS: *****/ /***** cadenaASCIIZ[]: Dirección de inicio de la cadena ASCIIZ a convertir. *****/ /***** SALIDA: Ninguna *****/ /****************************************************************************************/ void CadMayuscula(uint8_t cadenaASCIIZ[]){ uint8_t i; for(i=0; cadenaASCIIZ[i]; i++){ if(('a'