Jump to content
Sign in to follow this  
carlosfandango

Noobie Boostc Question, Set_bit And Clear_bit

Recommended Posts

Dear All, I'm new to boostc and this forum, but I do have a lot of programming experience on microcontrollers / windows .NET etc. I did use PICs many years ago (actually I was surprised to discover my ten year old PIC16F84As were still current!).

 

I'm using a PICKIT 2 with a 'low pin count' microchip demo board (16F690 fitted) and the lite version of the boostc comiler / IDE with no major problems, all seems to be working smoothly.

 

As a first test I thought I'd have a go at a short PWM routine to make an LED fade up and down cyclically. I started off working with a single LED as supplied on the demo board to pin RC0, and wrote a short program using tmr0 interrupt. The interrupt sets a flag which is read by main() to determine a pulse width period. The period is increased / decreased at a sort of 'human' rate to be, well, 'pleasing' in some way. This works exactly as expected, so no problems there.

 

However I have run into a problem that I can't quite understand and I'm sure there's an easy answer that will be quite obvious... WHEN I know what it is, as usual!! In my main() routine, just before the PWM loop executes, I decided to turn on the LED on bit 1 of portc. As far as I can see, this should come on and stay on - but it doesn't. I tried numerous things subsequently to manipulate the port but it seems that using set_bit on bit 0 is affecting the state of bit 1. I looked at the inline code for set_bit and clear_bit but the code looks fine (no reason why it shouldn't). If I change the code to write numeric values to the port instead of setting individual bits, it does indeed work as expected - so I guess the PIC is in good shape.

 

Have I missed something in the config, or just something much simpler? Here's the code (I attached the c file too, as I don't know how to format code here yet - sorry):

 

#include <system.h>

 

#pragma OPTIMIZE "1" // Regular optimisation

 

//Target PIC16F690 configuration word

#pragma DATA _CONFIG, _PWRTE_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _CP_OFF & _BOR_OFF & _MCLRE_OFF & _IESO_OFF & _FCMEN_OFF

 

//Set clock frequency

#pragma CLOCK_FREQ 8000000

 

#define t0_val 200

 

bool glob1;

 

void interrupt( void )

{

 

//Handle timer0 interrupt

if( intcon & (1<<T0IF) )

{

// All this interrupt routine does is clear the interrupt

// bit and set a flag used by main()

clear_bit( intcon, T0IF ); //clear timer 0 interrupt bit

glob1 = true;

}

 

//Handle timer1 interrupt

if( pir1 & (1<<TMR1IF) )

{

clear_bit( pir1, TMR1IF ); //clear timer 1 interrupt bit

}

 

//Handle timer2 interrupt

if( pir1 & (1<<TMR2IF) )

{

clear_bit( pir1, TMR2IF ); //clear timer 2 interrupt bit

}

 

}

 

void main(void)

{

bool flag2;

bool update = true;

bool reverse = false;

unsigned char LED1 = 0;

unsigned int time = 0;

 

//Configure port A

trisa = 0x00;

//Configure port B

trisb = 0x00;

//Configure port C

trisc = 0x00;

 

//Initialize port A

porta = 0x00;

//Initialize port B

portb = 0x00;

//Initialize port C

portc = 0x00;

 

//cmcon = 7; //disable comparators

 

//Set Timer0 mode

clear_bit( option_reg, T0CS ); //configure timer0 as a timer

//Set prescaler assignment

clear_bit( option_reg, PSA ); //prescaler is assigned to timer0

//Set prescaler rate

clear_bit( option_reg, PS2 ); //prescaler rate 1:2

clear_bit( option_reg, PS1 );

clear_bit( option_reg, PS0 );

//Set timer0 source edge selection

set_bit( option_reg, T0SE ); //increment on high-to-low transition on RA4/T0CKI pin

 

//Set timer 1 prescaler rate

clear_bit( t1con, T1CKPS1 ); //prescaler rate 1:1

clear_bit( t1con, T1CKPS0 );

//Set timer 1 mode

clear_bit( t1con, TMR1ON ); //disable timer 1

 

//Set timer 2 prescaler rate

clear_bit( t2con, T2CKPS1 ); //prescaler rate 1:1

clear_bit( t2con, T2CKPS0 );

//Set timer 2 postscaler rate

clear_bit( t2con, TOUTPS3 ); //postscaler rate 1:1

clear_bit( t2con, TOUTPS2 );

clear_bit( t2con, TOUTPS1 );

clear_bit( t2con, TOUTPS0 );

//Set timer 2 mode (enable or disable)

clear_bit( t2con, TMR2ON ); //enable timer 2

 

// Set internal oscillator to 8MHz

set_bit(osccon,4);

set_bit(osccon,5);

set_bit(osccon,6);

 

tmr0 = t0_val;

//Enable interrupts (Timer0)

intcon = 0xA0;

 

// Flash some LEDs!

//Endless loop

set_bit( portc, 1 ); // Shouldn't this LED stay ON?

while( 1 )

{

if (glob1)

{

// Flag from interrupt routine - reset

glob1 = false;

// Turn on LED port...

set_bit(portc,0); // Currently only 1 LED handled

time++; // Approximately 4000 interrupts per second

// Update check; if 10 interrupts have gone by then

// update state - i.e., pulse width - of LED

if (time >= 10)

{

update = true;

time = 0;

}

}

 

if (update)

{

if ( reverse ) LED1--;

else LED1++;

if ( LED1 == 255 ) reverse = true;

if ( LED1 == 0 ) reverse = false;

update = false;

}

 

// If the set time period has expired, turn LED off

if (tmr0 > LED1) clear_bit( portc, 0 );

 

}

}

Share this post


Link to post
Share on other sites
However I have run into a problem that I can't quite understand and I'm sure there's an easy answer that will be quite obvious... WHEN I know what it is, as usual!! In my main() routine, just before the PWM loop executes, I decided to turn on the LED on bit 1 of portc. As far as I can see, this should come on and stay on - but it doesn't. I tried numerous things subsequently to manipulate the port but it seems that using set_bit on bit 0 is affecting the state of bit 1. I looked at the inline code for set_bit and clear_bit but the code looks fine (no reason why it shouldn't). If I change the code to write numeric values to the port instead of setting individual bits, it does indeed work as expected - so I guess the PIC is in good shape.
Sounds like the classic read modify write issue, when ports externally are being dragged down by whatever is connected to them. Remember that when a port is read on a PIC16 the actually logic level on the pins are read, not the last data written. This is not a problem on PIC18 if you use the LAT register as this actually holds the last data written.

 

Possible solutions:

1) Don't drag down the outputs with excessive load.

2) Use a shadow register to hold the data written to the port.

 

Regards

Dave

Share this post


Link to post
Share on other sites
However I have run into a problem that I can't quite understand and I'm sure there's an easy answer that will be quite obvious... WHEN I know what it is, as usual!! In my main() routine, just before the PWM loop executes, I decided to turn on the LED on bit 1 of portc. As far as I can see, this should come on and stay on - but it doesn't. I tried numerous things subsequently to manipulate the port but it seems that using set_bit on bit 0 is affecting the state of bit 1. I looked at the inline code for set_bit and clear_bit but the code looks fine (no reason why it shouldn't). If I change the code to write numeric values to the port instead of setting individual bits, it does indeed work as expected - so I guess the PIC is in good shape.
Sounds like the classic read modify write issue, when ports externally are being dragged down by whatever is connected to them. Remember that when a port is read on a PIC16 the actually logic level on the pins are read, not the last data written. This is not a problem on PIC18 if you use the LAT register as this actually holds the last data written.

 

Possible solutions:

1) Don't drag down the outputs with excessive load.

2) Use a shadow register to hold the data written to the port.

 

Regards

Dave

 

I understand and see the problem now quite clearly. Well, thanks very much for clearing that up so quickly for me - I can move on now!

 

-CF

Share this post


Link to post
Share on other sites

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
Sign in to follow this  

×
×
  • Create New...