CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

PIC16F627A UART interrupt problems

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
sunyean



Joined: 01 Oct 2005
Posts: 2

View user's profile Send private message

PIC16F627A UART interrupt problems
PostPosted: Sat Oct 01, 2005 10:01 am     Reply with quote

I am working with 16F627. I want to use a UART's receive interrupt and TIMER0 interrupt simultaneously. and use PORT B (PIN7~PIN5) as output.
I failed to operate them.

At first, when TIMER0 interrupt is active, UART interrupt does not work.
when I set the PORT direction using set_tris_b(), UART itself does not work. And disabled TIMER0 interrupt , UART interrupt works very well.

Anyway, I have to do trade-off coding Crying or Very sad for these codes. I really should use All these interrupt and PORT B as the same time.

What are problems here ?

Code:


#include <16f627a.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>

#define  LIMIT  255

#fuses XT,NOWDT,NOBROWNOUT
#use delay (clock=4000000)                            // 발진주파수 = 4MHz
#use RS232(baud=9600, XMIT=PIN_B2,RCV=PIN_B1)

...

#int_rda
void int_rcv()
{
    char c;
    putc(c=getc());
}

#int_rtcc
void int_tmr0()
{
    count ++;
    set_rtcc(0xfe);
}

void main()
{

    byte value = 0x00;                          // Port B의 제어값
    byte RED   = 0x00;
    byte GREEN = 0x00;
    byte BLUE = 0x00;

    set_tris_b(0x00);
    output_b(0x00);

    setup_counters(RTCC_INTERNAL,RTCC_DIV_16);  // Timer0 셋팅
    enable_interrupts(INT_RTCC);                // Timer interrupt 셋팅

    enable_interrupts(INT_RDA);

    enable_interrupts(GLOBAL);

    set_rtcc(0xfe);                             // Timer0 초기값 설정

    while(1)
    {
        ....
    }
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Oct 01, 2005 11:50 am     Reply with quote

1. Add NOLVP to the #fuses statement.
#fuses XT,NOWDT,NOBROWNOUT, NOLVP

2. Add the ERRORS parameter to the #use rs232() statement.
#use RS232(baud=9600, XMIT=PIN_B2,RCV=PIN_B1, ERRORS)


3. Change the RTCC preload value so it doesn't interrupt at
such a high rate. With such a short interval between
interrupts, there is probably not enough time to process
the current interrupt before another one occurs.
Try setting it to:

set_rtcc(0x00);

Do that in both places in your code.
Hans Wedemeyer



Joined: 15 Sep 2003
Posts: 226

View user's profile Send private message

try this
PostPosted: Sat Oct 01, 2005 9:08 pm     Reply with quote

Try this.
TIMER0 is fast... Dop as PCMProgrammer says and adjust your timer to be somwhat slower!

Ths will work, if the incoming data stream has a small time dealy between each byte.

#include <16f627a.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>

#define LIMIT 255

#fuses XT,NOWDT,NOBROWNOUT
#use delay (clock=4000000) // ????? = 4MHz
#use RS232(baud=9600, XMIT=PIN_B2,RCV=PIN_B1)

int count=0;
int RxFlag;
int RxData;

#byte RCREG = 0X1A

#int_rda
void int_rcv()
{
RxData=RCREG; // get byte and clear interrupt flag
RxFlag++; // tell the main loop something arrived...

// do NOT do this in the interrupt routine
// char c;
// putc(c=getc()); NO
}
////////////////////////////////////////////////////////////////////
//
#int_rtcc
void int_tmr0()
{
count ++;
set_rtcc(0xfe);
}
///////////////////////////////////////////////////////////////////
//
void main()
{

byte value = 0x00; // Port B? ???
byte RED = 0x00;
byte GREEN = 0x00;
byte BLUE = 0x00;

set_tris_b(0x00);
output_b(0x00);

setup_counters(RTCC_INTERNAL,RTCC_DIV_16); // Timer0 ??
enable_interrupts(INT_RTCC); // Timer interrupt ??

enable_interrupts(INT_RDA);

enable_interrupts(GLOBAL);

set_rtcc(0xfe); // Timer0 ??? ??

RxFlag=0;
while(1)
{
if(RxFlag)
{
putc(RxData);
RxFlag=0;
}
}
}
sunyean



Joined: 01 Oct 2005
Posts: 2

View user's profile Send private message

not working
PostPosted: Sun Oct 02, 2005 1:16 am     Reply with quote

still not working Crying or Very sad

Code:

#int_rda
void int_rcv()
{
RxData=RCREG; // get byte and clear interrupt flag
RxFlag++; // tell the main loop something arrived...

// do NOT do this in the interrupt routine
// char c;
// putc(c=getc()); NO
}

......


Follwing above code, I successed once, and then not worked.
umm, I thought TIMER0 is very short , that's why UART int is bothered ^^;

If I raise the clock, It can be solved ?

My source is about LED control that LED is blinking in regular (TIMER0) and sometime control signals(string) are received from PC.

When Blinking is good, UART is bad and UART good, blinking bad...

How can I solve this problem with 16F627 ?

I will try it agian with another PIC like 16F73. If the same problem happens, My code is wrong. If not, 16F627 must be not good MPU Crying or Very sad

Thank you two guys !!
sunyean



Joined: 01 Oct 2005
Posts: 2

View user's profile Send private message

it's OK on PIC16F73
PostPosted: Sun Oct 02, 2005 4:19 am     Reply with quote

I tested the code which is modified for 16F73.

SUCCESS!!

Of course, As time value setted in TIMER0 is very large, UART must be working well. when time value is small, UART did not work also.

but, I adopted the same code to 16F627, even though time value is small, it's failded.

In conclusion, PIC16F627 has a weak point when TIMER0 and UART REV interrupts are used simultaneously.

If assembler, it may be OK ^^;

Code:


#include <16f73.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>

#define  LIMIT  255

#fuses XT,NOWDT,NOBROWNOUT
#use delay (clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, RESTART_WDT, BITS=8, ERRORS)

#int_rda
void int_rcv()
{
    char c;

    putc(c=getc());
}


#int_rtcc
void int_tmr0()
{
    count ++;
    set_rtcc(0x00); // ----------> [b]here, time value must be large (0~255)[/b]
}


void main()
{

    setup_CCP1(CCP_OFF);
    set_tris_b(0x00);
    output_b(0x00);
    set_tris_c(0xff);

    setup_counters(RTCC_INTERNAL,RTCC_DIV_16);  // Timer0 셋팅
    enable_interrupts(INT_RTCC);                // Timer interrupt 셋팅

    enable_interrupts(INT_RDA);

    enable_interrupts(GLOBAL);

    set_rtcc(0x00); // ----------> [b]here, time value must be large (0~255)[/b]

    while(1)
    {
        if (count == 2)
        {
             output_b(0xFF);
             delay_ms(500);
             output_b(0x00);
             count = 0;
         }
    }

}



If you want to set a small time interval,
you need to use only UART interrupt, and use delay_us() or delay_ms() in the end of "while" roop
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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