View previous topic :: View next topic |
Author |
Message |
anupama619
Joined: 10 Sep 2009 Posts: 47
|
How to write data into a sfr register???? |
Posted: Fri Oct 09, 2009 1:34 am |
|
|
Hai
How can I able to write a data into sfr registers??? I am using PIC16f877a and I want to write into INTCON register. But when I am using INTCON it showing error. Can anybody help me??? I am giving my code..
code:
SET_TRIS_B(0x01);
INTCON=0x00;
Hoping areplay
Thanks in advance....... |
|
|
Ttelmah Guest
|
|
Posted: Fri Oct 09, 2009 2:15 am |
|
|
Just declare INTCON....
By default, CCS, does not 'know' the function register names, since in general it is not necessary to use them. So the normal way to write to INTCON, in CCS, is to use the disable/enable interrupts function. However if you want to do something like clear all the bits at once, as you show, then just declare the register. So:
Code: |
#byte INTCON=0xB //Tell CCS, that the register at address 11, is called
//INTCON.
INTCON=0x00; //Now write to the register
|
Best Wishes |
|
|
anupama619
Joined: 10 Sep 2009 Posts: 47
|
thanks for replay |
Posted: Fri Oct 09, 2009 2:42 am |
|
|
Thanks for your reply. Now it is working. |
|
|
rnielsen
Joined: 23 Sep 2003 Posts: 852 Location: Utah
|
|
Posted: Fri Oct 09, 2009 12:43 pm |
|
|
If you want to have direct access to the sfr registers you, first, need to tell the compiler the address of each register you want to access. Then, you can define each bit in the register if you want.
Code: | #byte INTCON = 0x0B// define INTCON's address
#bit RBIF = INTCON.0
#bit INTF = INTCON.1
#bit TMR0IF = INTCON.2
#bit RBIE = INTCON.3
#bit INTE = INTCON.4
#bit TMR0IE = INTCON.5
#bit PEIE = INTCON.6
#bit GIE = INTCON.7 |
This has defined INTCON and each individual bit that it contains. Now, you won't necessarily want to manipulate each bit (or should for that matter) but this will enable you to do so if you want. This will work for most sfr's.
Now, you can assign each one to a value:
Code: | INTCON = 0x80;
GIE = 1; |
and so forth. Just be careful when manipulating the registers directly as it can get you in trouble and cause things to act weird.
Clear as mud?
Ronald |
|
|
anupama619
Joined: 10 Sep 2009 Posts: 47
|
Interrupt routine execution problem.. |
Posted: Sat Oct 10, 2009 6:11 am |
|
|
Sir,
In my project I want to receive more than 3 external interrupt. But now I am working with PIC16f877A. So I wrote a code like this.
CODE:
#include <16F877a.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#INT_EXT
void ext_isr()
{
if(input(PIN_B5))
{
printf("First Interrupt\n\n");
}
if(input(PIN_B6))
{
printf("Second Interrupt\n\n");
}
if(input(PIN_B7))
{
printf("Third Interrupt\n\n");
}
}
// main program that increments counter every second
void main()
{
long counter;
ext_int_edge(H_TO_L); // init interrupt triggering
enable_interrupts(INT_EXT);// turn on interrupts
enable_interrupts(GLOBAL);
printf("\n\n");
counter=0; // reset the counter
while(TRUE)
{
printf("The count value is: %5ld \r\n",counter);
counter++; // display count value and increment
delay_ms(1000); // every second
}
}
Pins B5, B6, & B7 are connected to positive point of 3 diode, which are the 3 interrupt points also. In my Isr routine I am checking for the interrupt. But it is not giving a proper output. Can anybody help me?.. Hoping a replay. Thanks in advance.. |
|
|
Ttelmah Guest
|
|
Posted: Sat Oct 10, 2009 9:33 am |
|
|
You are using the wrong interrupt.
INT_EXT, is an interrupt on the external interrupt pin - B0, on an 877. To detect changes on the four high port B pins, you need to use the PortB changed interrupt (INT_RB).
Remember also that the interrupt on these pins, will trigger when the pins fall, as well as when they rise (there is no programmable 'edge' detection on this interrupt), and pin B4, will also trigger the interrupt.
Best Wishes |
|
|
anupama619
Joined: 10 Sep 2009 Posts: 47
|
Interrupt routine execution problem.. |
Posted: Mon Oct 12, 2009 1:42 am |
|
|
Thanks for your reply.
But when I am using #INT_RB it is not entering in to the ISR routine. Here I am giving my code.
Code: |
#include <16F877a.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
/****Isr Routine****/
#INT_RB
void rb_isr()
{
printf("Inside Isr\n\n");
}
//Main Function
void main()
{
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
set_tris_b(0xff);
while(1)
{
OUTPUT_HIGH(pin_c4); //pin_c4 shorted externaly with Pin_b7
OUTPUT_LOW(pin_c4);
printf("Inside main\n");
delay_ms(1000);
}
} |
Can you please help me.
Thanks in advance. |
|
|
Ttelmah Guest
|
|
Posted: Mon Oct 12, 2009 2:35 am |
|
|
First thing, you _must_ read port B, inside the RB interrupt. Otherwise if the interrupt does trigger, it'll trigger for ever.....
Then, the key 'reason' you are not getting to the ISR, is you are not enabling the interrupts anywhere. You need to enable INT_RB, and the GLOBAL interrupt flag, before the interrupt routine will be called...
Best Wishes |
|
|
anupama619
Joined: 10 Sep 2009 Posts: 47
|
Interrupt routine execution problem.. |
Posted: Mon Oct 12, 2009 4:15 am |
|
|
Thanks for your reply.
I changed my code like this:
Code: |
int8 portState;
/****Isr Routine****/
#INT_RB
void rb_isr()
{
// disable_interrupts(INT_RB);// turn on interrupts
// disable_interrupts(GLOBAL);
portState=PORTB;
printf("Inside Isr\r\n");
printf("PORTB=%x\r\n",portState);
portState=0;
// enable_interrupts(INT_RB);// turn on interrupts
// enable_interrupts(GLOBAL);
}
void main()
{
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
enable_interrupts(INT_RB);// turn on interrupts
enable_interrupts(GLOBAL);
set_tris_b(0xff);
while(1)
{
OUTPUT_HIGH(pin_c4); //pin_c4 shorted externaly with Pin_b7
printf("Inside main\r\n");
delay_ms(1000);
}
}
|
In Hyperterminal it giving a result like this.
Quote: |
Inside Isr
PORTB=84
Inside Isr
PORTB=04
Inside Isr
PORTB=04
Inside Isr
PORTB=04
Inside Isr
PORTB=84
Inside Isr
PORTB=84
Inside Isr
PORTB=04
Inside Isr
PORTB=04
Inside Isr
PORTB=04
Inside Isr
PORTB=84
Inside Isr
PORTB=04
Inside main
|
But I am expecting a value of 0x80. How can I be able to read exact value? Can you please help me?
Thanks in advance. |
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1615 Location: Central Illinois, USA
|
|
Posted: Fri Oct 16, 2009 12:28 am |
|
|
Ttelmah wrote: | Just declare INTCON....
Code: |
#byte INTCON=0xB //Tell CCS, that the register at address 11, is called
//INTCON.
INTCON=0x00; //Now write to the register
|
|
If I may offer another nice variation that makes the code more portable these days is:
#byte INTCON = getenv("sfr:INTCON")
I've been trying to make that more habit on stuff I do of late.. (especially MCHP conversions that hardwire locations. Yikes.
-Ben _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
RckRllRfg
Joined: 20 Jul 2011 Posts: 60
|
Thanks - Great post regarding access to the FSRs |
Posted: Tue Oct 25, 2011 12:10 pm |
|
|
A quick thanks for this post. These are the gems that make the forums so useful.
RckRllRfg |
|
|
|