Soy nuevo en PIC32 MCU, escribí un pequeño código para ejecutar el UART.
El MCU es el Microchip PIC32MX795F512H , el código usa interrupciones para manejar la recepción y transmisión en el canal 5 de UART (UART5), básicamente el código devuelve la entrada del usuario.
El código es casi funcional, solo un comportamiento extraño: los primeros 8 bits se devuelven correctamente y luego se transmiten 3 caracteres a la consola.
La entrada es azertya
y la MCU devuelve: azertyaaaa
(agrega aaa
, la letra a fue el primer carácter ingresado) y, a veces, azertyaÿÿÿ
; luego, para una entrada de caracteres, devuelve los caracteres y otros tres (no aleatorios).
#include <p32xxxx.h>
#include <plib.h>
#include "uart.h"
#define GetSystemClock() (80000000ul)
#define GetPeripheralClock() (GetSystemClock()/(1 << OSCCONbits.PBDIV))
#define GetInstructionClock() (GetSystemClock())
#pragma config FPLLMUL = MUL_20, FPLLIDIV = DIV_2, FPLLODIV = DIV_1, FWDTEN = OFF
#pragma config POSCMOD = HS, FNOSC = PRIPLL, FPBDIV = DIV_1
#define US_TO_CT_TICKS (CPU_CT_HZ/1000000UL)
#define UARTCH1 UART5
/*------------------------- Interruptions -----------------------------------*/
void __ISR(_UART_5_VECTOR, ipl2) IntUART5Handler(void){
if(INTGetFlag(INT_SOURCE_UART_RX(UARTCH1)))
{
INTClearFlag(INT_SOURCE_UART_RX(UARTCH1));
PutCharacter(UARTGetDataByte(UARTCH1), UARTCH1);
mPORTBToggleBits ( BIT_12 );
}
if ( INTGetFlag(INT_SOURCE_UART_TX(UARTCH1)) ){
INTClearFlag(INT_SOURCE_UART_TX(UARTCH1));
PutCharacter(UARTGetDataByte(UARTCH1), UARTCH1);
mPORTBToggleBits ( BIT_15);
}
}
/*---------------------------------------------------------------------------*/
int main (void){
SYSTEMConfig(GetSystemClock(), SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE);
ConfUART(UARTCH1);
mJTAGPortEnable(DEBUG_JTAGPORT_OFF);
mPORTBClearBits( BIT_15 | BIT_14 | BIT_13 | BIT_12 | BIT_11 | BIT_10 | BIT_9 | BIT_8 | BIT_7 | BIT_6 | BIT_5 | BIT_5 | BIT_4 | BIT_3 | BIT_2 | BIT_1 | BIT_0 );
mPORTBSetPinsDigitalOut( BIT_15 | BIT_14 | BIT_13 | BIT_12 | BIT_11 | BIT_10 | BIT_9 | BIT_8 | BIT_7 | BIT_6 | BIT_5 | BIT_5 | BIT_4 | BIT_3 | BIT_2 | BIT_1 | BIT_0 );
WriteToUART("Test1_Test2_Test3_Test4_Test5\n", UARTCH1);
return 0;
}
#include <plib.h>
#define GetSystemClock() (80000000ul)
#define GetPeripheralClock() (GetSystemClock()/(1 << OSCCONbits.PBDIV))
#define T_RATE_X (9600)
void WriteToUART(const char *string, char UARTCH){
while(*string != '\0')
{
while(!UARTTransmitterIsReady(UARTCH));
UARTSendDataByte(UARTCH, *string);
string++;
while(!UARTTransmissionHasCompleted(UARTCH));
}
}
void PutCharacter(const char character, char UARTCH){
while(!UARTTransmitterIsReady(UARTCH));
UARTSendDataByte(UARTCH, character);
while(!UARTTransmissionHasCompleted(UARTCH));
}
void ConfUART(char UARTCH){
UARTConfigure (UARTCH, UART_ENABLE_PINS_TX_RX_ONLY);
UARTSetFifoMode (UARTCH, UART_INTERRUPT_ON_TX_NOT_FULL | UART_INTERRUPT_ON_RX_NOT_EMPTY);
UARTSetLineControl (UARTCH, UART_DATA_SIZE_8_BITS | UART_PARITY_NONE | UART_STOP_BITS_1); /* 8 Bits, Pas de parité, 1 STOP Bits */
UARTSetDataRate (UARTCH, GetPeripheralClock(), T_RATE_X);
UARTEnable (UARTCH, UART_ENABLE_FLAGS(UART_PERIPHERAL | UART_RX | UART_TX));
INTEnable (INT_SOURCE_UART_RX(UARTCH), INT_ENABLED);
INTSetVectorPriority (INT_VECTOR_UART(UARTCH), INT_PRIORITY_LEVEL_2);
INTSetVectorSubPriority (INT_VECTOR_UART(UARTCH), INT_SUB_PRIORITY_LEVEL_0);
INTConfigureSystem (INT_SYSTEM_CONFIG_MULT_VECTOR);
INTEnableInterrupts();
}
Su función de escritura UART está diseñada para dejar de transmitir cuando encuentra un carácter NULL en su cadena ('\ 0' o 0x00). No terminas en nulo tus cadenas. No sabe cuándo dejar de enviar, por lo que continúa y envía todo lo que encuentra hasta que encuentra un carácter NULL.
Para solucionar esto, siempre que envíe una cadena, debe agregar '\ 0' al final de la misma.
EDITAR: De acuerdo, la función PutChar corrige eso: ¿necesita borrar la interrupción manualmente? Parece que hay dos fuentes secundarias que se unen con OR para causar la interrupción principal: las borra, pero ¿necesita borrar también la interrupción principal? Eso podría causar este problema. ¿Ha probado su línea UART Tx y ha comprobado la velocidad en baudios de esa manera? Eso podría ser un problema: si está utilizando una fuente de reloj de baja precisión, es posible que no tenga en cuenta la velocidad en baudios.
También edite: ¿ve su puerto alternar cada vez que envía los bytes adicionales?
Corríjame si me equivoco, pero parece que está en la interrupción UART5, pero está borrando los indicadores RX y TX de UART1.
usuario9451
EnojadoEE
EnojadoEE
usuario9451