|
|
View previous topic :: View next topic |
Author |
Message |
elcrcp
Joined: 11 Mar 2016 Posts: 62 Location: izmir / Turkey
|
INT_RDA2 wont work |
Posted: Thu Mar 26, 2020 10:53 pm |
|
|
18f25J50 , 5.081
Hi guys, I search the forum and find similar problems but couldn't find a proper solution to situation. So I'm asking for your help again =)
I'm trying to communicate an esp-01 module with my 18f25j50 and I want to use uart2 interrupt but I couldn't make it work. I use A0 and A1 as TX2 and RX2. I did many controls and tried many changes but couldn't make it work. RDA2 interrupt never fires.
If I connect esp to uart1 pins and change RDA2 names to RDA then everything works perfect without problem, but again, I want to use UART2. I don't know if it is a compiler error or am I missing something from datasheet but I checked and got sure that there isn't any hardware problem.
Can you guys take a look and guide me please?
Here is the simple code, just sending a message to esp and reads the reply
I cut off some of the code like pin defines and SFR defines to make it short.
main.c
Code: |
#include <main.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "PCF8574_LCD.h"
#INT_RDA2
void RDA2_isr()
{
output_bit(buzzer_cont,1);
static int8 ctr2=0;
int8 chr2=getc();
if (chr2==13)
{
//If we have an end of line
EspRcvBuff[ctr2]='\0'; //null terminate string
ctr2=0; //clear the counter
incoming_message2=1;
}
else
{
EspRcvBuff[ctr2++]=chr2; //add character to string
if (ctr2>=ESPBUFFER_LENGHT-1)
ctr2--; //ensure buffer can not overflow
}
}
void clear_usart2_receiver(void)
{
char c;
c = RCREG2;
c = RCREG2;
c = RCREG2;
}
void chk_start_connection(){
char srch1[]="Connection_Established_Warning";
char srch2[]="Connection_Error";
if(strstr(EspRcvBuff,srch1)!=NULL){
fprintf(UART_CH1,"Connection Established\r\n");
EspRcvBuff="";
esp_response_acknowledged=1;
}
else if(strstr(EspRcvBuff,srch2)!=NULL){
fprintf(UART_CH1,"Connection Failed\r\n");
EspRcvBuff="";
esp_response_acknowledged=1;
}
else {
fprintf(UART_CH1,EspRcvBuff);
EspRcvBuff="";
}
}
void main()
{
OSCTUNE = 0b11000000; // select low frequency source and enable pll
OSCCON |= 0b01110000;
OSCCON &= 0b11111100; // set internal oscillator frequency and system clock
ADCON0 &= 0b11111110; // disable A / D converter
ANCON0 = 0xFF;
ANCON1 |= 0b00011111; // all pins are digital
output_bit(ESP_EN,0);
output_bit(buzzer_cont,0);
i2c_init(I2C_LCD,100000);
lcd_begin(0x4E);
lcd_cmd(LCD_CLEAR);
lcd_goto(1,1);
lcd_out("Test");
lcd_goto(1,2);
lcd_out("Print");
fprintf(UART_CH1,"LCD Write Done\r\n");
output_bit(ESP_EN,1);
delay_ms(250);
clear_usart2_receiver();
clear_interrupt(INT_RDA2);
enable_interrupts(INT_RDA2);
enable_interrupts( GLOBAL ); //Enable interrupts
fprintf(UART_CH1,"Interrupts Enabled\r\n");
delay_ms(250);
fprintf(UART_CH1,"Setup Done\r\n");
EspRcvBuff="";
fprintf(UART_CH1,"Buffer Cleared\r\n");
fprintf(UART_CH2,"Start_Connection\r\n");
fprintf(UART_CH1,"Connection Request Sent\r\n");
while(esp_response_acknowledged==0)
{
if(incoming_message2){
chk_start_connection();
incoming_message2=0;
}
}
fprintf(UART_CH1,"Reply Received\r\n");
WHILE (TRUE)
{
delay_cycles(1);
}
}
|
main.h
Code: |
#include <18F25J50.h>
#device ADC=10
/* Device fuses programmed to work with 48Mhz internal osc settings */
#fuses NOCPUDIV //System Clock by 1
#fuses INTRC_PLL_IO //Internal RC Osc with 4X PLL, no CLKOUT
#fuses PLL2 //Divide By 2(8MHz oscillator input)
/*------------------------------------------------------------------*/
#FUSES NOWDT //No Watch Dog Timer
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES NOPROTECT //Code not protected from reading
#FUSES T1DIG //Secondary Oscillator Source may be select regardless of T1CON.3 state
#FUSES NOLPT1OSC //Timer1 configured for higher power operation
#FUSES FCMEN //Fail-safe clock monitor enabled
#FUSES IESO //Internal External Switch Over mode enabled
#FUSES DSWDTOSC_INT //DSWDT uses INTRC as reference clock
#FUSES RTCOSC_INT //RTCC uses Internal 31KHz Oscillator as reference source
#FUSES DSBOR //BOR enabled in Deep Sleep
#FUSES DSWDT //Deep Sleep Watchdog Timer enabled
#fuses NOIOL1WAY //Allows multiple reconfigurations of peripheral pins
#FUSES MSSPMSK7 //MSSP uses 7 bit Masking mode
#FUSES WPFP //Write/Erase Protect Page Start/End Location, set to last page or use WPFP=x to set page
#FUSES WPEND //Flash pages WPFP to Configuration Words page are write/erase protected
#FUSES NOWPCFG //Configuration Words page is not erase/write-protected
#FUSES WPDIS //All Flash memory may be erased or written
#use delay(internal=48MHz)
#use rs232(baud=9600,UART1,parity=N,bits=8,ERRORS,stream=UART_CH1)
#pin_select RX2=PIN_A1
#pin_select TX2=PIN_A0
#use rs232(baud=9600,UART2,parity=N,bits=8,ERRORS,stream=UART_CH2)
#use i2c(MASTER, I2C1, FAST=100000, FORCE_HW, NOINIT,STREAM=I2C_LCD)
#pin_select SDI2=PIN_C0
#pin_select SDO2=PIN_C1
#pin_select SCK2OUT=PIN_C2
#use spi(MASTER, SPI2, ENABLE=PIN_C6, MODE=0, BITS=8, stream=SPI_CH2)
#define ESPBUFFER_LENGHT 50
volatile char EspRcvBuff[ESPBUFFER_LENGHT],RDARcvBuff[ESPBUFFER_LENGHT];
volatile int1 incoming_message2=0,incoming_message=0,esp_response_acknowledged=0;
|
I can get "Connection Request Sent" message but cannot get "Reply Received" message while trying uart2 but I'm able to get both ESP's responses and Reply Received message if I try uart1. _________________ There is nothing you can't do if you try |
|
|
elcrcp
Joined: 11 Mar 2016 Posts: 62 Location: izmir / Turkey
|
|
Posted: Thu Mar 26, 2020 11:56 pm |
|
|
I also tried same code with dsPIC30F6012A and got exact same result, perfectly working on UART1 and INT_RDA but not interrupting on UART2 and INT_RDA2 _________________ There is nothing you can't do if you try |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19496
|
|
Posted: Fri Mar 27, 2020 1:57 am |
|
|
Use the compiler. All the settings you are doing directly are
better done using compiler functions:
Code: |
setup_adc(ADC_OFF);
setup_adc_ports(NO_ANALOGS);
|
Since you don't post the register values used, there is no guarantee
that the existing code is talking to the right registers....
The oscillator should already be setup. Unless you have a very old
compiler the internal=48MHz should have done everything needed.
Now the receive code should be using the stream name. Otherwise
if the wrong UART is read, it'll hang forever in the receive interrupt.
There is an issue with how you clear the UART. Problem is that you do not
clear any error bits. If an error has become set, this will not be cleared
by reading the receive buffer, and since you clear the interrupt bit
the interrupt won't be called. Result if this has happened, the UART
will be completely hung....
The correct code to clear the UART is:
Code: |
void clear_usart2_receiver(void)
{
char c;
while (kbhit(UART_CH2))
c = getc(UART_CH2);
}
|
Which then includes the compiler's code to clear the framing and
overrun errors if they occur.
Framing errors in particular will occur on boot, so this is necessary....
I suspect this is the problem. As you switch on a framing error occurs.
Then without any error clearing code in the clear routine, the UART
is stuck.... |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Mar 27, 2020 2:25 am |
|
|
To amplify Ttelmah's comment:
Also, my very first thought as I started scanning your code, is "how's it
know where to get it from ?", regarding the getc() shown in bold below.
There's no stream specified. Also, according to CCS, you're supposed to use fgetc() here.
Quote: | #INT_RDA2
void RDA2_isr()
{
output_bit(buzzer_cont,1);
static int8 ctr2=0;
int8 chr2=getc();
if (chr2==13)
{
//If we have an end of line
EspRcvBuff[ctr2]='\0'; //null terminate string
ctr2=0; //clear the counter
incoming_message2=1;
}
else
{
EspRcvBuff[ctr2++]=chr2; //add character to string
if (ctr2>=ESPBUFFER_LENGHT-1)
ctr2--; //ensure buffer can not overflow
}
} |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19496
|
|
Posted: Fri Mar 27, 2020 2:29 am |
|
|
and of course, I am relying on the fact that getc, is overloaded, and if
given a stream name behaves just like fgetc... |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9221 Location: Greensville,Ontario
|
|
Posted: Fri Mar 27, 2020 5:37 am |
|
|
hmm.. before trying to use interrupts...
...have you done a simple 'loopback' program using UART2 to confirm that the PIC does use UART2 ?
I don't use that PIC, and see it has programmable pins, maybe there's a compiler bug ?
OR.... maybe a hardware error ? TX swapped for RX, solder bridge,???
I always start with the simple stuff first, confirm then move on.
Jay |
|
|
elcrcp
Joined: 11 Mar 2016 Posts: 62 Location: izmir / Turkey
|
|
Posted: Fri Mar 27, 2020 10:30 am |
|
|
Solved,
Thank you Jay, I always do these simple checks first, whenever there is a problem I start with checking if power is connected and go on checking step by step.
I corrected the buffer cleaner routine as Ttelmah said. I must say I had many problems with ccs's built in functions in the past so I make a habit of to do bit bang config.
You both are completely right Ttelmah and PCM, thank you. I totally overlooked getc(), as you say; how could it know where to read?
Since uart1 is the default of every uart command, it works fine fine getc without any stream name, but uart2 needed stream name. _________________ There is nothing you can't do if you try |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19496
|
|
Posted: Fri Mar 27, 2020 10:40 am |
|
|
So actually the interrupt was being called, but could never exit...
INT_RDA, and RDA2, both have the feature that they stay 'set' if data
isn't read. Explains what you were seeing... |
|
|
elcrcp
Joined: 11 Mar 2016 Posts: 62 Location: izmir / Turkey
|
|
Posted: Fri Mar 27, 2020 11:41 am |
|
|
Quote: | So actually the interrupt was being called, but could never exit... Sad
INT_RDA, and RDA2, both have the feature that they stay 'set' if data
isn't read. Explains what you were seeing... |
Actually I'm not sure about it, I think it wasn't entering into routine but hanging when called. I did set a pin for check to see if it was entering to routine but it never got set on interrupt calls. _________________ There is nothing you can't do if you try |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19496
|
|
Posted: Fri Mar 27, 2020 11:47 am |
|
|
OK. It might have been the UART clear then. If an error was set, then
the interrupt would never get called... |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Mar 27, 2020 12:02 pm |
|
|
In the code below, it jumps to the UART1 receiver routine. But there is
most likely nothing in the receiver, so it loops forever. This is the hang.
Quote: |
.... #use rs232(baud=9600,UART1,parity=N,bits=8,ERRORS,stream=UART_CH1)
00AE: BTFSS PIR1.RCIF // Do we have a char in UART1 receiver ?
00B0: BRA 00AE // If not, loop until we do (ie., hang)
00B2: MOVFF RCSTA1,rs232_errors
00B6: MOVFF RCREG1,01 // If yes, get char from UART1 receiver
00BA: BTFSS rs232_errors.1 // Skip next BRA if we got an error
00BC: BRA 00C2 // If no error, exit
00BE: BCF RCSTA1.CREN1
00C0: BSF RCSTA1.CREN1
00C2: GOTO 00C8 (RETURN)
....................
.... #pin_select RX2=PIN_A1
.... #pin_select TX2=PIN_A0
.... #use rs232(baud=9600,UART2,parity=N,bits=8,ERRORS,stream=UART_CH2)
*** Note no UART2 receiver code is generated. Only UART1 above ***
.... //-------------------------------
.... #INT_RDA2
.... void RDA2_isr()
00C6: BRA 00AE // Jump to the UART1 getc() routine
00C8: MOVFF 01,chr2 // Return to here from that (except, not...)
.... {
.... int8 chr2 = getc();
....
00CC: BCF PIR3.RC2IF // Clear UART2 receive interrupt flag
00CE: GOTO 0060 // Go to CCS interrupt exit code
.... }
.....
.... //====================================
..... void main() |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19496
|
|
Posted: Fri Mar 27, 2020 12:08 pm |
|
|
Yes, because his serial read is right at the start of the code, it won't
reach any code to signal it has reached the routine.... |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|