![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
Dat Bui
Joined: 07 Mar 2019 Posts: 3
|
Fault Int_rda interrupt when save data into Rom - Pic18F8723 |
Posted: Thu Mar 07, 2019 1:35 am |
|
|
Hi,
I am using rs232 communication between a pic18f8723 on master circuit and 16 pic16F886 on slave circuit through a mux16 using pic18F8723.
(master-mux16-16slave). The problem is when i save data into master rom, the uart port will stop working. The master pic could transfer data to slave pic and hmi but could not receive data from slave and hmi.
Please help.
Here is my source code on master:
Code: |
#include <Master.h>
#include <Math.h>
#include "Global.c"
#include "Function.c"
#include "StateMachine.c"
#include "ProcessRx.c"
#INT_TIMER1
void TIMER1_isr(void)
{
set_timer1(TIMER1_REG);
if(SERVO_ON) {
if(MAIN_STATE > 0) {
if(PUL_COUNT < PUL_VALUE[MAIN_STATE]) {
PUL_COUNT++;
} else {
MAIN_STATE++;
PUL_COUNT = 0;
}
if(MAIN_STATE > STATE_DAC1) {
SERVO_ON = 0;
}
}
output_toggle(DRV_PUL);
} else output_high(DRV_PUL);
}
#INT_TIMER2
void TIMER2_isr(void)
{
if(HMI_NOREP_REG == HMI_NO_REP) HMI_NOREP_FLAG = 1; else HMI_NOREP_REG++;
if(HMI_FRE_REG == HMI_UPDATE) HMI_FRE_FLAG = 1; else HMI_FRE_REG++;
if(STOPTIME_REG > 0) STOPTIME_REG --; else DELAY_FLAG = 1;
if(CONNECTION_REG > 0) CONNECTION_REG--;
if(BUZZER_REG == 0) BUZZER_REG = 2000; else BUZZER_REG--;
if(DELAY_TIME == 0) {
if(AUTOMATIC_RUN) CTL_SEC++;
if(CTL_SEC >= 60) {
CTL_SEC = 0; CTL_MIN++;
if(CTL_MIN >= 60) {CTL_MIN = 0; CTL_HOUR++;}
}
if(TIME_STATE_REG > 0 ) TIME_STATE_REG--; else TIME_STA = 1;
DELAY_TIME = 999;
} else DELAY_TIME--;
shift_left(&IN_START_REG,1,input(IN_START));
shift_left(&IN_SENSOR_REG,1,input(IN_PRSEN));
shift_left(&IN_CONTACT_REG,1,input(IN_CONTA));
if(IN_SENSOR_REG == 0) SENSOR_ENA = 1;
else if(IN_SENSOR_REG == 0xFF && SENSOR_ENA) SENSOR_EDGE = 1;
if(IN_CONTACT_REG == 0xF0) SENSOR_FAIL = 1;
if(IN_SENSOR_REG == 0xF0 || IN_SENSOR_REG == 0x0F) SENSOR_FAIL = 0;
if(MUX_TIMEOUT_REG > 0) MUX_TIMEOUT_REG--; else MUX_TIMEOUT_FLAG = 1;
if(WDRX_REG > 0 ) {
if(WDRX_REG == 1) {
RX_COUNTER = 0;
Rx_fifo_wr = 0;
Rx_fifo_rd = 0;
WDRX_REG = 0;
} else WDRX_REG--;
}
if(WDRX2_REG > 0 ) {
if(WDRX2_REG == 1) {
RX2_COUNTER = 0;
Rx2_fifo_wr = 0;
Rx2_fifo_rd = 0;
WDRX2_REG = 0;
} else WDRX2_REG--;
}
}
#INT_RDA
void RDA_isr(void)
{
RX_FIFO[Rx_fifo_wr] = getc(PORT1);
if(Rx_fifo_wr < RX_FIFO_SIZE - 1) Rx_fifo_wr ++; else Rx_fifo_wr = 0;
}
#INT_TBE
void TBE_isr(void)
{
if (Tx_fifo_rd != Tx_fifo_wr) {
putc(TX_FIFO[Tx_fifo_rd],PORT1);
Tx_fifo_rd++;
} else disable_interrupts(INT_TBE);
}
#INT_RDA2
void RDA2_isr(void)
{
RX2_FIFO[Rx2_fifo_wr] = getc(PORT2);
if(Rx2_fifo_wr < RX2_FIFO_SIZE - 1) Rx2_fifo_wr ++; else Rx2_fifo_wr = 0;
}
#INT_TBE2
void TBE2_isr(void)
{
if (Tx2_fifo_rd != Tx2_fifo_wr) {
putc(TX2_FIFO[Tx2_fifo_rd],PORT2);
Tx2_fifo_rd++;
} else disable_interrupts(INT_TBE2);
}
void main()
{
setup_adc_ports(AN0,VSS_VDD);
setup_adc(ADC_CLOCK_DIV_2|ADC_TAD_MUL_0);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1); //6.5 ms overflow
setup_timer_2(T2_DIV_BY_4,249,10); //100 us overflow, 1.0 ms interrupt
delay_ms(1000);
init_param();
init_HMI();
enable_interrupts(INT_TIMER1);
enable_interrupts(INT_TIMER2);
enable_interrupts(INT_RDA);
clear_interrupt(INT_TBE);
enable_interrupts(INT_RDA2);
clear_interrupt(INT_TBE2);
enable_interrupts(GLOBAL);
while(TRUE)
{
//TODO: User Code
check_status();
Main_StateMachine();
if(IN_SENSOR_REG == 0) bit_set(HAND_CTL_ACT,1); else bit_clear(HAND_CTL_ACT,1);
if(IN_CONTACT_REG == 0) bit_set(HAND_CTL_ACT,2); else bit_clear(HAND_CTL_ACT,2);
if(MUX_TIMEOUT_FLAG) Process_Mux();
Process_Rx();
Process_Rx2();
output_drv();
if(HMI_FRE_FLAG && !HMI_NOREP_FLAG) Reply_HMI();
if(PWR_ON) PowerOn_act();
}
}
|
Here is source on slave:
Code: |
#include <Slave.h>
#include <Math.h>
#include "Global.c"
#include "Function.c"
#INT_RDA
void RDA_isr(void)
{
RX_FIFO[Rx_fifo_wr] = getc();
if(Rx_fifo_wr < RX_FIFO_SIZE - 1) Rx_fifo_wr ++; else Rx_fifo_wr = 0;
}
#INT_TIMER2
void TIMER2_isr(void)
{
if(WD_TIMER_REG == 1) {
WD_TIMER_REG = 0;
Rx_fifo_rd = 0;
Rx_fifo_wr = 0;
RX_COUNTER = 0;
DATA_FIFO[0] = 0;
DATA_FIFO[1] = 0;
} else {
if(WD_TIMER_REG > 0) WD_TIMER_REG--;
}
if(DELAY_REG > 0) DELAY_REG--; else DELAY_FLAG = 1;
if(I2C_FRE_REG < I2C_FRE) I2C_FRE_REG++; else I2C_FRE_FLAG = 1;
if(TIMEOUT_REG > 0) {
if (TIMEOUT_REG == 1) {
bit_clear(OUT_DRIVER,0);
DELAY_REG = PWOFF_PARAM;
DELAY_FLAG = 0;
TIMEOUT_REG = 0;
MAIN_STATE = WAIT_STATE;
}
TIMEOUT_REG--;
}
}
void main()
{
delay_ms(100);
init();
setup_timer_2(T2_DIV_BY_1,199,10); //100 us overflow, 1,0 ms interrupt
//setup_timer_2(T2_DIV_BY_4,124,10); //100 us overflow, 1,0 ms interrupt
exe = 0;
enable_interrupts(INT_RDA);
enable_interrupts(INT_TIMER2);
enable_interrupts(GLOBAL);
while(TRUE)
{
//TODO: User Code
process_Rx();
switch(MAIN_STATE) {
case PWUP_STATE:
output_low(SSR_PIN);
bit_set(OUT_STATUS,0);
if(DELAY_FLAG) {
CHN = 0;
MAIN_STATE = INIT_STATE;
}
if(!bit_test(OUT_DRIVER,0)) {
DELAY_REG = PWOFF_PARAM;
DELAY_FLAG = 0;
MAIN_STATE = WAIT_STATE;
}
break;
case INIT_STATE:
//Sel_chn(CHN);
//i2c_pwrinit();
delay_ms(10);
if(CHN >= 7) {
if(INIT_COUNT >= 10) {
CHN = 0;
I2C_RD_WR = 0; // Write
MAIN_STATE = RUN_STATE;
SAMPLE_COUNT = 0;
} else INIT_COUNT++;
}
if(CHN < 7) CHN++; else CHN = 0;
if(!bit_test(OUT_DRIVER,0)) {
DELAY_REG = PWOFF_PARAM;
DELAY_FLAG = 0;
MAIN_STATE = WAIT_STATE;
}
break;
case RUN_STATE:
if(I2C_FRE_FLAG) {
I2C_FRE_REG = 0;
I2C_FRE_FLAG = 0;
Sel_chn(CHN);
if(I2C_RD_WR) i2c_act_rd(CHN); else i2c_act_wr(CHN);
if(CHN < 7) CHN++; else {I2C_RD_WR = ~I2C_RD_WR; CHN = 0;}
if(SAMPLE_COUNT < SAMPLE) SAMPLE_COUNT++; else SAMPLE_COUNT = 0;
}
if(!bit_test(OUT_DRIVER,0)) {
DELAY_REG = PWOFF_PARAM;
DELAY_FLAG = 0;
MAIN_STATE = WAIT_STATE;
}
break;
case WAIT_STATE:
if(DELAY_FLAG) MAIN_STATE = IDLE_STATE;
if(bit_test(OUT_DRIVER,0)) {
CHN = 0;
MAIN_STATE = RUN_STATE;
SAMPLE_COUNT = 0;
}
break;
default:
if(bit_test(OUT_DRIVER,0)) {
DELAY_REG = 2000;
DELAY_FLAG = 0;
MAIN_STATE = PWUP_STATE;
} else {
output_high(SSR_PIN);
bit_clear(OUT_STATUS,0);
}
break;
}
}
} |
|
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19368
|
|
Posted: Thu Mar 07, 2019 1:56 am |
|
|
You carefully don't show critical line. The #USE RS232.
This _must_ have the keyword 'ERRORS', or the UART will lockup, if
it receives data that is not handled. I suspect this is missing, and so the
UART stops working.
However the key thing that is 'causing' the actual problem, is that
once the 'unlock' sequence is started to write to memory, interrupts
have to be disabled, till the write. So serial communications need to stop
while a write occurs. If you look at the bootloader code, you will see
that once it receives a block to write, it sends a handshake to stop the
comms, while the write is actually performed.
With 'ERRORS' in the #USE RS232, missed byte(s) while the write takes
place, will no longer hang the UART, but your bus protocol will need to
be able to recover from one or more bytes having been lost. |
|
![](templates/subSilver/images/spacer.gif) |
Dat Bui
Joined: 07 Mar 2019 Posts: 3
|
|
Posted: Fri Mar 08, 2019 9:12 pm |
|
|
Ttelmah wrote: | You carefully don't show critical line. The #USE RS232.
This _must_ have the keyword 'ERRORS', or the UART will lockup, if
it receives data that is not handled. I suspect this is missing, and so the
UART stops working.
However the key thing that is 'causing' the actual problem, is that
once the 'unlock' sequence is started to write to memory, interrupts
have to be disabled, till the write. So serial communications need to stop
while a write occurs. If you look at the bootloader code, you will see
that once it receives a block to write, it sends a handshake to stop the
comms, while the write is actually performed.
With 'ERRORS' in the #USE RS232, missed byte(s) while the write takes
place, will no longer hang the UART, but your bus protocol will need to
be able to recover from one or more bytes having been lost. |
Thanks for your answer,
The first thing is i already config
Code: |
#use rs232(baud=19200,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=PORT1)
#use rs232(baud=19200,parity=N,xmit=PIN_G1,rcv=PIN_G2,bits=8,stream=PORT2) |
on other tap.
And the second thing, as I mention before, The UART are not completely stop working. The master pic could Write but not Read the data. Do you know how to fix it ?
P/S: Maybe some version of ccs devices.dat file isn't suitable for hardware int_rda interrupt. I don't know how to check my version is suitable or not. My version is 5.081. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19368
|
|
Posted: Sat Mar 09, 2019 1:22 am |
|
|
Yes, As I said, you do not have the keyword 'ERRORS' in your RS232
configuration.
If ERRORS is not there, the receive part of the UART will stop working, if a
character is missed. With ERRORS there the character will still be missed
but the receive part will be reset and continue working:
Code: |
#use rs232(baud=19200, parity=N, xmit=PIN_C6, rcv=PIN_C7, bits=8, ERRORS, stream=PORT1)
#use rs232(baud=19200, parity=N, xmit=PIN_G1, rcv=PIN_G2, bits=8, ERRORS stream=PORT2)
|
'ERRORS', _must_ always be used with the hardware UART, unless
_you_ are yourself explicitly resetting the error condition on the
UART. Repeat _must_. Otherwise if a character is not handled
the receive part of the UART _will_ stop working. |
|
![](templates/subSilver/images/spacer.gif) |
Dat Bui
Joined: 07 Mar 2019 Posts: 3
|
|
Posted: Tue Mar 12, 2019 12:18 am |
|
|
Ttelmah wrote: | Yes, As I said, you do not have the keyword 'ERRORS' in your RS232
configuration.
If ERRORS is not there, the receive part of the UART will stop working, if a
character is missed. With ERRORS there the character will still be missed
but the receive part will be reset and continue working:
Code: |
#use rs232(baud=19200, parity=N, xmit=PIN_C6, rcv=PIN_C7, bits=8, ERRORS, stream=PORT1)
#use rs232(baud=19200, parity=N, xmit=PIN_G1, rcv=PIN_G2, bits=8, ERRORS stream=PORT2)
|
'ERRORS', _must_ always be used with the hardware UART, unless
_you_ are yourself explicitly resetting the error condition on the
UART. Repeat _must_. Otherwise if a character is not handled
the receive part of the UART _will_ stop working. |
Wow!!! Thanks for your advice, I fixed the problem =))) |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|