• AVR Freaks

AnsweredHot!dsPIC30F4013 UART issue

Author
rmz22
New Member
  • Total Posts : 25
  • Reward points : 0
  • Joined: 2020/11/18 15:30:35
  • Location: 0
  • Status: offline
2021/01/18 09:20:42 (permalink)
0

dsPIC30F4013 UART issue

Hi guys, I'm hoping you can help me solve a strange issue I'm facing with the UART module when trying to communicate a laptop with a dsPIC30F4013 through a serial-USB converter. I'm currently using a simple Python (TKInter) GUI to control very basic Led behavior (On/Off/Blink) just to figure out the intricacies, though this will later be used to communicate 2 MCUs through a MAX232, but I'm getting ahead of myself...

Expected behavior: The GUI has 3 buttons, ON button sends a '1', OFF button sends a '2' and Blinking mode sends a '3'. When button is pressed, dsPIC should control, accordingly, a Led connected to RF4.
 
Current behavior: The pulse is sent, but the dsPIC doesn't respond to '1' (ON) or '3' (Blink) commands, it only responds to '2' (OFF), but it doesn't even behave as expected: it turns the Led on for about 300-400 ms and then turns it back off, once per button press, no blink. This behavior is always the same, regardless of which button I press first, or how many times I press any button (which I think indicates that there are no "buffer delays", so to speak).
 
The GUI uses UTF-8 encoding and I have corroborated (oscilloscope) that the data arriving at the dsPIC's U1RX pin corresponds to the expected UTF-8 code (1 = 0b00110001, 2 = 0b00110010, 3 = 0b00110011).

I found a similar issue here (/forums/m827522.aspx, please add microchip.com before the extension, due to forum issues with links, etc.) however, the solution that helped OP doesn't work for me. I have used RAM, volatile variables as suggested by users "ric" and "balmerjd" to ensure I'm checking every sent value against my designated conditions and not losing the data at U1RXREG after every read, which follows FIFO logic. I have configured all related registers (U1MODE, U1STA, U1RXREG, etc.) with help of the dsPIC30F FRM and the specific 4013 datasheet and, as far as I can tell, the settings are correct (for 8-bit, no parity bits, one stop bit).

You'll find my code attached below, with the MCU's code at the top, followed by the Python TKinter code (where I doubt there'll be any issues, since it's fairly simple and, as I've stated, I've made sure that the data sent to MCU's pin matches the number).
You'll notice that, in my code, I left out the following section from balmerjd's code:

    while (1)
    {
        if (uart_received)
        {
            while(U1STAbits.UTXBF == 1);
            U1TXREG = dataIn;
            uart_received=0;
       }
    }


 
Reason being, I don't really understand why he's checking bit UTXBF and writing to U1TXREG, since, as far as I understood OP's question, they're not trying to transmit anything (nor am I), but run a function in main() depending on what's received at U1RXREG. In case you're wondering if this is why the code isn't working for me, its inclusion in my project doesn't help either.

As always, any hints are really appreciated.

Thanks in advance,
Rob

Software/Hardware used:
MPLAB X IDE v5.40
XC16 Compiler
PICkit 3
USB to Serial DB9 (male) RS232 cable
 

#define FCY 5000000UL
#include <p30F4013.h>
#include <libpic30.h>
#include "config.h"
volatile unsigned char dataIn = 0;
volatile int uart_received = 0;
void config_uart(void);

int main(void) {
    TRISFbits.TRISF2=1;         //RF2/U1RXpin [25] as input
    TRISFbits.TRISF4=0;         //Output LED
    config_uart();    
    while(1){
        if(uart_received){
            switch(dataIn){
                case '1':   
                    LATFbits.LATF4 = 1; //Turn LED ON
                    uart_received=0;
                    break;
                case '2':    
                    LATFbits.LATF4 = 0; //Turn LED OFF
                    uart_received=0;
                    break;
                case '3':               //Blink LED
                    LATFbits.LATF4 = 1;
                    __delay_ms(400);
                    LATFbits.LATF4 = 0;
                    __delay_ms(400);
                    uart_received=0;
                    break;
            }
        }
    }
    return 0;
}

void config_uart(void){
    U1MODEbits.UARTEN = 0;      //Disable UART1 prior to config.
    U1MODEbits.STSEL = 0;       //1 Stop bit
    U1MODEbits.PDSEL = 0b00;    //8-bit data, no parity bit
    U1STAbits.URXISEL = 0b00;   //Interrupt flag set when a character is received  
    U1BRG = 32;                 //Desired Baud Rate: 9600, with 20MHz Xtal; [ Fcy/(16*BR) - 1] = [5,000 MHz/153,600 -1] = 31.5 )
    IPC2bits.U1RXIP = 5;        //Set Receive Interrupt Priority
    IEC0bits.U1RXIE = 1;        //Enable Receive Interrupt
    IFS0bits. U1RXIF = 0;       //Lower Receive Interrupt Flag
    U1MODEbits.UARTEN = 1;      //Enable UART1
}

void __attribute__ ((__interrupt__,no_auto_psv)) _U1RXInterrupt(void){
    unsigned char byteIn=0x00;  
    byteIn=U1RXREG;  
    if(byteIn == '1' || byteIn == '2' || byteIn == '3'){    //ON, OFF & Blinking commands, respectively
        dataIn = byteIn;       //If byteIn corresponds to a command, store...
    }
    else{                       //...Otherwise ignore
        dataIn = '-';
    }
    if(byteIn!=0x00){           //To avoid cycling in interrupt, raise global flag polled in main()
        uart_received=1;
    }
    IFS0bits.U1RXIF = 0;        //Clear Reception Interrupt flag
}

 
Python GUI code

from tkinter import *
from tkinter.font import Font
from time import sleep
import serial
from serial import Serial
import time
import sys
port = serial.Serial()
port.baudrate=9600
port.timeout=3
port.port='COM4'
port.open()
print('Serial Port ready')
window = Tk()
window.title("Python - dsPIC30F4013")
window.geometry('320x300')

def button1():
    global vent
    mystring = str(1)
    b = mystring.encode('UTF-8')
    print("Button 1 has been pressed")
    port.write(b)
    tex.delete(1.0,END)
    tex.insert(1.0, "Led On")
    
def button2():
    global vent
    mystring = str(2)
    b = mystring.encode('UTF-8')
    print("Button 2 has been pressed")
    port.write(b)
    tex.delete(1.0,END)
from tkinter import *
from tkinter.font import Font
from time import sleep
import serial
from serial import Serial
import time
import sys
port = serial.Serial()
port.baudrate=9600
port.timeout=3
port.port='COM4'
port.open()
print('Serial Port ready')
window = Tk()
window.title("Python - dsPIC30F4013")
window.geometry('320x300')

def button1():
    global vent
    mystring = str(1)
    b = mystring.encode('UTF-8')
    print("Button 1 has been pressed")
    port.write(b)
    tex.delete(1.0,END)
    tex.insert(1.0, "Led On")
    
def button2():
    global vent
    mystring = str(2)
    b = mystring.encode('UTF-8')
    print("Button 2 has been pressed")
    port.write(b)
    tex.delete(1.0,END)
    tex.insert(1.0, "Led Off")
    
def button3():
    global vent
    mystring = str(3)
    b = mystring.encode('UTF-8')
    print("Button 3 has been pressed")
    port.write(b)
    tex.delete(1.0,END)
    tex.insert(1.0, "Led Blinking")
    
l1=Button(window,text='LED On',command=button1, cursor='circle')
l2=Button(window,text='LED Off',command=button2, cursor='circle')
l3=Button(window,text='LED Blink',command=button3, cursor='circle')
lab1=Label(window, text='Led state', width=15, height=3)
lab2=Label(window, text='Python serial w/PIC', width=38, height=4)
tex=Text(window,width=20,height=2)
l1.place(x=130,y=200)
l2.place(x=220,y=200)
l3.place(x=160,y=250)
lab1.place(x=150,y=100)
lab2.place(x=50,y=40)
tex.place(x=125,y=140)
window.mainloop()
port.close()
print('Port closed')
sys.exit(0)

 
#1
ric
Super Member
  • Total Posts : 29861
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: online
Re: dsPIC30F4013 UART issue 2021/01/18 12:36:27 (permalink) ☄ Helpfulby rmz22 2021/01/18 16:40:11
4.5 (2)
rmz22
You'll notice that, in my code, I left out the following section from balmerjd's code:
...
Reason being, I don't really understand why he's checking bit UTXBF and writing to U1TXREG, since, as far as I understood OP's question, they're not trying to transmit anything (nor am I), but run a function in main() depending on what's received at U1RXREG. In case you're wondering if this is why the code isn't working for me, its inclusion in my project doesn't help either.

It would appear that user was echoing every received character back to the sender, which isn't a bad idea for debiugging purposes, to confirm it was received correctly.
 

Software/Hardware used:
MPLAB X IDE v5.40
XC16 Compiler
PICkit 3
USB to Serial DB9 (male) RS232 cable

You don't mention if there is a MAX232 style buffer between the DE9 connector and your PIC's RX pin, which is required to de-invert the signal.
You did describe what you think is being received at that pin, but without seeing the trace we can't be sure if your describing true or inverted data.
 
In your main switch() statement, you should have a default clause to display if an unknown character is received.
This is "defensive programming", to help you detect when things you didn't expect are happening.
 

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#2
rmz22
New Member
  • Total Posts : 25
  • Reward points : 0
  • Joined: 2020/11/18 15:30:35
  • Location: 0
  • Status: offline
Re: dsPIC30F4013 UART issue 2021/01/18 15:30:45 (permalink)
0
Hi ric, thanks for taking the time to go through my code.

ric
You don't mention if there is a MAX232 style buffer between the DE9 connector and your PIC's RX pin, which is required to de-invert the signal.
You did describe what you think is being received at that pin, but without seeing the trace we can't be sure if your describing true or inverted data.
 

Upon acquiring the DE9 to USB cable, it was my understanding that the internal PCB that can be seen in the connector handled TTL-232 conversion (and viceversa) so that I could just wire the serial outputs to the TX, RX & Ground pins on my breadboard, where the PIC is mounted. After your suggestion, however, I'll try to configure a stand-alone MAX232 IC to see if my assumption was wrong.
ric
In your main switch() statement, you should have a default clause to display if an unknown character is received.
This is "defensive programming", to help you detect when things you didn't expect are happening.

Thank you for your suggestion, I've discovered a curious thing after setting up a "default" case that toggles the state of LATBbits.LATB12 (connected to a second Led): When I send a "1" or a "3" (which should correspond to On and Blink, respectively) the Led wired to LATB12 is toggled on/off, but when I send a "2" (Off) the LATB12 doesn't change and the original LATF4 Led behaves as before (comes on for a few ms and then switches off), which suggests to me that the PIC doesn't "see" the 1's and 3's I send but does "see" 2's... although somehow reads these 2's as something else, since case 2 is supposed to switch the Led at LATF4 off, very odd indeed.
 
I will try to make some informed changes to both source codes and come back if I find anything of interest.

Best regards,
Rob
#3
ric
Super Member
  • Total Posts : 29861
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: online
Re: dsPIC30F4013 UART issue 2021/01/18 15:37:41 (permalink) ☄ Helpfulby rmz22 2021/01/18 16:40:13
5 (1)
rmz22
Upon acquiring the DE9 to USB cable, it was my understanding that the internal PCB that can be seen in the connector handled TTL-232 conversion (and viceversa) so that I could just wire the serial outputs to the TX, RX & Ground pins on my breadboard, where the PIC is mounted.

I don't know what "internal PCB" you are referring to.
The DE9 to USB cable will be outputting RS232 voltages, which are inverted data, not TTL.
You most definitely do NOT want to be connecting them directly to your PIC.
 
When first starting with RS232 on a microcontroller, it's easier to start with sending known data from the PIC to the PC.
Then you can instantly tell if your baud rate and polarity are correct.
 
post edited by ric - 2021/01/18 15:38:59

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#4
rmz22
New Member
  • Total Posts : 25
  • Reward points : 0
  • Joined: 2020/11/18 15:30:35
  • Location: 0
  • Status: offline
Re: dsPIC30F4013 UART issue 2021/01/18 16:39:50 (permalink)
0
I mean the one located inside the cable's header, which I got from a local electronics shop, I thought that it had a built-in MAX232, which I guess it doesn't. I'm aware that there's an inherent RS232 voltage difference that might damange the PIC, but since I thought the MAX232 was there, I had the PIC directly wired to the serial cable's pins. I guess I'll try to burn the PIC with a reliable .hex file with tested functionality to check for damages. 

As for the suggested way to start with RS232 comms, I will try that approach. Thanks again!

I am, however, still curious... If I am indeed (incorrectly) plugging the RS232 to the Pic without a proper interface, why do you think it is that the PIC is responding to one very specific command (given that there's only 2 "cases" that turn that Led on)? Could it really be that the "non-inverted" signal that's being sent to the Pic just so happens to match the char I'm looking for in my "case"?

Best regards,
Rob
#5
ric
Super Member
  • Total Posts : 29861
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: online
Re: dsPIC30F4013 UART issue 2021/01/18 16:43:58 (permalink) ☼ Best Answerby rmz22 2021/01/27 16:14:17
0
rmz22
I mean the one located inside the cable's header, which I got from a local electronics shop, I thought that it had a built-in MAX232, which I guess it doesn't.

It does. There will be an internal USB-TTL serial chip, then that will be driving an MAX232 style buffer to produce RS232 level signals for the external interface.
You can get cables that do USB-TTL serial directly, but they do NOT have DE9 connectors.
 

I'm aware that there's an inherent RS232 voltage difference that might damange the PIC, but since I thought the MAX232 was there, I had the PIC directly wired to the serial cable's pins.

Bad assumption.
 

I am, however, still curious... If I am indeed (incorrectly) plugging the RS232 to the Pic without a proper interface, why do you think it is that the PIC is responding to one very specific command (given that there's only 2 "cases" that turn that Led on)? Could it really be that the "non-inverted" signal that's being sent to the Pic just so happens to match the char I'm looking for in my "case"?

Just luck how it is interpreting the inverted signal.
That is why you should always have that default case to indicate that you are getting bad characters.
 

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#6
rmz22
New Member
  • Total Posts : 25
  • Reward points : 0
  • Joined: 2020/11/18 15:30:35
  • Location: 0
  • Status: offline
Re: dsPIC30F4013 UART issue 2021/01/27 12:24:32 (permalink)
0
Hi again, after some time (and adding the external MAX232 IC to my board) I figured out what was partially causing the issue (other than the lack of the MAX232): I am using a USB docking hub to connect my mouse and the USB-Serial converter cable to my laptop (I've run out of USB ports) and sometimes this causes communication to glitch, which I only noticed because my mouse was acting up on me. It's a bit strange because the Device Manager was recognizing the COM3 all the time, but anyway... Now that the PC-to-dsPIC transmission works as intended (Led is controlled with no issues), I'm facing a different issue with dsPIC-to-PC Tx:
 
I'm using the "putsUART1" function (found in "MPLAB XB16 16-Bit Language Tool libraries") to write to UART1 and monitor it with Hercules software (same one used to send data to dsPIC). Communication works when I call the function from Software (for instance, if I call it inside the loop entered when data is received) but it doesn't when I poll a button to send a string on command, so:
 
This works (The string I write to UART is constantly being received on my laptop)

 
    while(1){
        if(uart_received){
            putsUART1((unsigned int *)Txdata);
            switch(dataIn){
                case '1':   
                    LATFbits.LATF4 = 1; //Turn LED ON
                    break;
                case '2':    
                    LATFbits.LATF4 = 0; //Turn LED OFF
                    break;
                case '3':               //Blink LED
                    LATFbits.LATF4 = 1;
                    __delay_ms(400);
                    LATFbits.LATF4 = 0;
                    __delay_ms(400);
                    break;
                default:
                    LATBbits.LATB12 = 1 - LATBbits.LATB12;
            }
 

 
This compiles with no issues, but it doesn't work (I can still send commands from Lap->dsPIC and Led works fine, but no dsPIC->Lap comms I can monitor on Hercules):
NOTE: I've of course previously defined UARTTX_BUTTOn as RB0 and also configured the TRISRB0 as input.

 
    while(1){
        if(UARTTX_BUTTON==1){   //Detect pulse in RB0 (UARTTX_BUTTON = PORTBbits.RB0)
            __delay_ms(300);
            putsUART1((unsigned int *)Txdata);
 
        if(uart_received){
 
            switch(dataIn){
 
        .     #Same switch cases go here, ignored for brevity
 
        .
 
            }
        }
 


Since my end goal is to communicate 2 dsPICS through buttons that will implement different functions, I really need the physical aspect to work. I'd appreciate any ideas/clues that might point me in the right direction.

Thank you in advance,
Rob
 
------
EDIT:
------
Issue solved, I had forgotten to configure the ADPCFG register appropriately, it's working as intended now!
post edited by rmz22 - 2021/01/27 13:57:09
#7
RISC
Super Member
  • Total Posts : 5960
  • Reward points : 0
  • Status: offline
Re: dsPIC30F4013 UART issue 2021/01/27 15:58:41 (permalink)
0
Hi,
As I read in your code FCY = 5000000, so I assume you have an external 20MHz XTAL ?
Is that right ? 
Can you please show your configuration bits ?
Regards

For support make sure to check first here : http://microchipdeveloper.com
There are hundreds of PIC, AVR, SAM...which one do YOU use ?
#8
rmz22
New Member
  • Total Posts : 25
  • Reward points : 0
  • Joined: 2020/11/18 15:30:35
  • Location: 0
  • Status: offline
Re: dsPIC30F4013 UART issue 2021/01/27 16:18:22 (permalink)
0
Hi RISC,
The issue has now been resolved, nonetheless, I appreciate your reply. I have an external 20MHz XTAL, indeed. I hadn't taken what ric said in the comments above into consideration, but now both Receiving and Transmitting functions are working as expected. Next up, I'll try to communicate the dsPIC30F4013 with a dsPIC30F4011, I hope that goes smoothly.

Best regards,
Rob
#9
Jump to:
© 2021 APG vNext Commercial Version 4.5