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 support@ccsinfo.com

PIC12F1840 INT_RDA & INT_TBE

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



Joined: 03 Dec 2008
Posts: 45

View user's profile Send private message

PIC12F1840 INT_RDA & INT_TBE
PostPosted: Sat Jan 07, 2012 11:24 am     Reply with quote

I use 4 MHz INTRC working under baud 9600
Code:

#fuses INTRC_IO
#use delay(internal=4M)
#use 232(baud=9600,xmit=pin_a4,rcv=pin_a5)

#byte RCSTA=0x19D
#byte TXSTA=0x19e
#bit  TXIE=0x091.4//pie1.4
#byte TXREG=0x19a
#byte RCREG=0x199
#bit  SYNC=TXSTA.4
#bit  SPEN=RCSTA.7//enable uart
#bit  CREN=RCSTA.4//enable RX
int1 st=0;

#int_rda
void rx_isr()
{
   int16 data=0;
   data=RCREG;   
   
   if(data=='I')
        {
          st=!st
          if(st) output_high(pin_a2);//LED on
          if(!st) output_low(pin_a2);//LEN off
         }
 }

#int_tbe
void tx_isr()
{
   int8 data=0;
   if(txcount>0)
        {
             TXREG=tx[txcount--];
             if(txcount==0) TXIE=0;
         }
}

char tx[16];

void main()
{
       
   int8 j=0;

        char s[16]="THIS IS A TEST!";
/*
   TXSTA=0x24;
   SPBRGL=25;// set baud=9600

   SPEN=1;//enable async serial
   CREN=1;// enable rx
   SYNC=0;//async
   RXDTSEL=1;//pin_a5 rx
   TXCKSEL=1;//pin_a4 tx
*/
   enable_interrupts(INT_RDA);
   enable_interrupts(GLOBAL);
   while(true)
   {
   for(j=0;j<TX_SIZE;j++)
   {
      tx[j]=s[j];
               //putc(tx[j]);
   }
   TXREG=0x20;
   TXIE=1;
   }
}

My questions are:
1. Please see code between /* */, if I don't add them on then it will only works with printf and putc() commmand. The interrupts INT_RDA and INT_TBE are all doesn't work.

2. So I add code between /* */ on. And the INT_RDA and INT_TBE worked but only sometimes.

Can somebody give me a help.

Thanks
Ttelmah



Joined: 11 Mar 2010
Posts: 19339

View user's profile Send private message

PostPosted: Sat Jan 07, 2012 12:39 pm     Reply with quote

Look at the examples....
EX_STISR.C

The key point to understand, is that once the transmit buffer is empty, and you have no characters waiting to send, you have to turn off INT_TBE. Then when you want to send characters, store the first into the hardware register, then the rest into a transmit buffer, and enable INT_TBE.
For 99.9% of things, you do not need to fiddle directly with registers in CCS. Use the supplied functions instead, it is the whole 'point' of the compiler. There are a few (rare) occasions where direct accesses are needed, and this is not one of them.
You can't use INT_TBE, and then putc, in the main. Instead use a buffered putc, as in the example.

Best Wishes
cchappyboy



Joined: 03 Dec 2008
Posts: 45

View user's profile Send private message

PostPosted: Mon Jan 09, 2012 10:20 am     Reply with quote

Hi Ttelmah, I tried EX_STISR.c

Please see below:
Code:

#include <12F1840.h>

#fuses   INTRC_IO
#use delay(internal=4M)
#use rs232(baud=9600, xmit=pin_a4,rcv=pin_a5)

#define T_BUFFER_SIZE 64
byte t_buffer[T_BUFFER_SIZE];
byte t_next_in = 0;
byte t_next_out = 0;


#int_tbe
void serial_isr() {

   if(t_next_in!=t_next_out)
   {
      putc(t_buffer[t_next_out]);
      t_next_out=(t_next_out+1) % T_BUFFER_SIZE;
   }
   else
      disable_interrupts(int_tbe);
}

void bputc(char c) {
   short restart;
   int ni;

   restart=t_next_in==t_next_out;
   t_buffer[t_next_in]=c;
   ni=(t_next_in+1) % T_BUFFER_SIZE;
   while(ni==t_next_out);
   t_next_in=ni;
   if(restart)
      enable_interrupts(int_tbe);
}

void main() {

 enable_interrupts(GLOBAL);
 printf(bputc,"\r\n\Running...\r\n");

   do {
      delay_ms(2000);
     output_high(pin_a2);// LED on
      printf(bputc,"This is buffered data\r\n");
   } while (TRUE);
}

It doesn't work. The only worked part is the output_high(pin_a2).
I tried printf("This is a test!"); without printf(bputc,"\r\nRunning...\r\n"). and there is output on screen. So I guess the #int_tbe doesn't work. So I guess I need to do something extra, not only the
Code:
#use rs232(baud=9600, xmit=pin_a4, rcv=pin_a5)

and enable_interrupts(INT_TBE), but something else? This is pic12f1840. Maybe this is the one out of the 99.9%. What do you think?

Thanks
Ttelmah



Joined: 11 Mar 2010
Posts: 19339

View user's profile Send private message

PostPosted: Mon Jan 09, 2012 10:41 am     Reply with quote

Try using #pin select to tell the compiler that you want to use TX/RX on the pins, and then using UART1, rather than the pin numbers in the #use RS232.
There is a common problem on chips with multiple peripherals selected on individual pins, with the compiler not 'realising' you are using the hardware UART. When this happens INT_TBE, and RDA won't work.

Best Wishes
cchappyboy



Joined: 03 Dec 2008
Posts: 45

View user's profile Send private message

PostPosted: Mon Jan 09, 2012 11:31 am     Reply with quote

Thanks Ttelmah.

It looks it 's not in this case.
I put there whatever it is
Code:

#pin_selects tx=pin_a4
#pin_selects rx=pin_a5

or
Code:

#pin_selects tx1=pin_a4
#pin_selects rx1=pin_a5

or
Code:

#pin_selects u1tx=pin_a4
#pin_selects u1rx=pin_a5

they all show
Quote:

*** Error 7 "TXINT.c" Line 6(12,22): Invalid Pre-Processor directive Invalid Pin ID
Ttelmah



Joined: 11 Mar 2010
Posts: 19339

View user's profile Send private message

PostPosted: Mon Jan 09, 2012 2:34 pm     Reply with quote

Have you tried just using UART as opposed to the pins in the setup?.

Best Wishes
cchappyboy



Joined: 03 Dec 2008
Posts: 45

View user's profile Send private message

PostPosted: Tue Jan 10, 2012 11:38 am     Reply with quote

No I didn't do that because the hardware pins set should be pin_a4 is TX and pin_a5 is RX.

I add some code to my program and now it works with #int_ and #int_tbe
Code:

#bit  RXDTSEL=APFCON.7//if =1 pin_a5 to be rx ,=0 Pin_a1
#bit  TXCKSEL=APFCON.2// if =1 pin_a4 to be tx,
#bit  TXEN=TXSTA.5
#bit  TXIE=0x091.4//pie1.4
#bit  SPEN=RCSTA.7//enable uart
#bit  CREN=RCSTA.4//enable RX
#bit  SYNC=TXSTA.4

in the main()
add on
Code:

TXSTA=0x04;
SPBRGL=25;//set baud=9600

TXEN=1;//when async =1 enable tx
SPEN=1;//async enable
CREN=1;//when it is async =1 enable rx
SYNC=0;
RXDTSEL=1;//pin_a5 RX
TXCKSEL=1;//PIN_A4 TX

I don't know why but if i just rely on the command
Code:
#use rs232(baud=9600, xmit=pin_a4,rcv=pin_a5)

and
Code:

enable_interrupts(INT_RDA);
enable_interrupts(INT_TBE);
enable_interrupts(GLOBAL);

it doesn't work.

I am not sure is that compiler's issue or something else.
And i think the #pin_selects doesn't work for this chip pic12f1840 that is only 8 pins and the pins are not selectable.
I have experience with 33fj128mc804 it does work for it by not in this case.

Anyways Thank you so much for your concern and help.
Ttelmah



Joined: 11 Mar 2010
Posts: 19339

View user's profile Send private message

PostPosted: Tue Jan 10, 2012 3:01 pm     Reply with quote

There are issues with several of the newer chips where multiple peripherals exist on one set of pins. The compiler in a lot of cases doesn't quite get it right.
In several cases though it _will_ work correctly if you just select the UART, rather than using the pin number. It knows where the UART hardware is, and uses it. When pins are selected, because the UART is so far down the list of things on the pins, this is when it gets confused, and switches to using the software UART instead.

Best Wishes
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