I am struggling in trying to put a UART Port working (no flow control and no parity bit) in a PIC32MX in order to comunicate with a Fingerprint for too long, so I decided to get back to you guys. I just can put the fingerprint reader in digital I/O's because I have no more UART PORTs available. There's no problem for the TX pin but when it comes to enable RX pin (CN interrupt) I am seeing a problem.
This is the Fingerprint Reader I am using an this is the datasheet for the PIC.
I am using the CN4/RB2 Port for the Interrupt (Rx) and the RB0 to transmit. The compiler is XC32.
#include "NVMem.h" #define Baudrate 4800 //bps #define OneBitDelay (1000000/Baudrate) // microseconds #define DataBitCount 8 // no parity, no flow control #define UART_RX TRISBbits.TRISB2 // UART RX pin #define UART_TX LATBbits.LATB0 // UART TX pin #define UART_RX_DIR TRISBbits.TRISB2 // UART RX pin direction #define UART_TX_DIR TRISBbits.TRISB0 // UART TX pin direction int volatile readB = 0; unsigned char UART_Receive(void); void UART_Transmit(const char); void __ISR(_CHANGE_NOTICE_VECTOR, ipl5) ChangeNoticeHandler(void) { readB = PORTB; // Read PORTB to clear CN4 mismatch condition if (readB){ UART_Transmit(UART_Receive()); } LATDINV = 0x0F; // PORTG = 0xff; // Toggle outputs. IFS1CLR = 0x0001; // Be sure to clear the CN interrupt status } unsigned char UART_Receive(void) { unsigned char DataValue = 0; unsigned char i = 0; while(UART_RX==1); delay_us(OneBitDelay); delay_us(OneBitDelay/2); for ( i = 0; i < DataBitCount; i++ ) { if ( UART_RX == 1 ) //if received bit is high { DataValue += (1<<i); } delay_us(OneBitDelay); } if ( UART_RX == 1 ) //Stop bit should be high { return DataValue; } else //some error occurred ! { delay_us(OneBitDelay); return 0x000; } } void UART_Transmit(const char DataValue) { /* Basic Logic TX pin is usually high. A high to low bit is the starting bit and a low to high bit is the ending bit. No parity bit. No flow control. BitCount is the number of bits to transmit. Data is transmitted LSB first. */ // Send Start Bit UART_TX = 0; delay_us(OneBitDelay); unsigned char i; for ( i = 0; i < DataBitCount; i++ ) { //Set Data pin according to the DataValue if( ((DataValue>>i)&0x1) == 0x1 ) //if Bit is high { UART_TX = 1; } else //if Bit is low { UART_TX = 0; } delay_us(OneBitDelay); } //Send Stop Bit UART_TX = 1; } void FingerprintRun(Task * task){ CNCON = 0x8000; // Enable CN module CNEN = 0x00000010; // Enable individual CN pin CN4 CNPUE = 0x00000010; // Enable weak pull up for pin CN4 UART_TX = 1; // TX pin is high in idle state UART_RX_DIR = 1; // Input UART_TX_DIR = 0; // Output readB = PORTB; IPC6SET = 0x00140000; // Set priority level=5 IPC6SET = 0x00030000; // Set Subpriority level=3 IEC1SET = 0x0001; // Enable Change Notice interrupts UART_Transmit ('H'); UART_Transmit ('i'); UART_Transmit ('\r'); while(UART_RX==0){ asm("nop"); } while(1) { } } While debugging the Program Counter never goes to the interrupt.