0
\$\begingroup\$

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.

\$\endgroup\$
9
  • \$\begingroup\$ usually you use an RX char interrupt source from the UART module rather than individual pin interrupt. Also see this question: electronics.stackexchange.com/questions/135638/… \$\endgroup\$ Commented Jan 14, 2016 at 15:37
  • \$\begingroup\$ Well I am not using the RX interrupt source from the UART module because I have no more available. Not only this, I have no PPS (peripheral pin select) in this Pic. I am reusing an old design. \$\endgroup\$ Commented Jan 14, 2016 at 15:41
  • \$\begingroup\$ Don't understand? Why no more available? \$\endgroup\$ Commented Jan 14, 2016 at 15:43
  • 1
    \$\begingroup\$ @Icy I think he's trying to bit-bang a 'software UART', but I don't see any attempt to read or write bits at any particular baud-rate - no delays or timing anywhere in the code ... \$\endgroup\$ Commented Jan 14, 2016 at 15:55
  • 1
    \$\begingroup\$ I don't think there are ready-made delay_us/delay_ms functions in XC32 for the PIC32. microchip.com/forums/m769139.aspx has some info on writing your own. \$\endgroup\$ Commented Jan 14, 2016 at 16:26

1 Answer 1

1
\$\begingroup\$

your line: CNEN = 0x00000010; // Enable individual CN pin CN4

should be: CNEN = 0x00010000; // Enable individual CN pin CN4

and similar for CNPUE

You also need to implement timing in your software as per @brhans comments

Using delays in your interrupt routine is not be good practice - the CPU will not be able to do any other processing - including responding to other interrupts, in the time it takes to read each character, much better to start a timer and sample the port bit on that timers interrupt.

\$\endgroup\$
1
  • \$\begingroup\$ So can you give me a brief explanation of how to use the timer in this case. \$\endgroup\$ Commented Jan 14, 2016 at 16:57

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.