Jump to content

Why Is A Delay Needed When Using Several Set_bit() Functions In Succession?


Recommended Posts

Hello,

 

I am using the PIC 16F690 with the Low Pin Count Demo Board from Micro.

 

In an attempt to get the 4 LEDs located on PORTC's bits 0 through 3 to activate I did the following:

set_bit(portc, 0);
set_bit(portc, 1);
set_bit(portc, 2);
set_bit(portc, 3);

This results in only the LED on bit 3 of PORTC illuminating.

 

With a 'small' delay they all light up.

set_bit(portc, 0);
delay_ms(250);
set_bit(portc, 1);
delay_ms(250);
set_bit(portc, 2);
delay_ms(250);
set_bit(portc, 3);

Is this related to the read-modify-write problem? Although, it's not clear what's getting read in this simple case.

 

Kindly,

graham

Link to post
Share on other sites

Hi Graham,

 

It could be a rise time delay causing your problem. If you are running at a high clock rate the signal on the output pin may not have reached the high level threshold befor the next instruction read the port again.

 

Try adding a couple of NOP's between bit setting and see if that cures it.

 

Cheers

 

Reynard

Link to post
Share on other sites
Hi Graham,

 

It could be a rise time delay causing your problem. If you are running at a high clock rate the signal on the output pin may not have reached the high level threshold befor the next instruction read the port again.

 

Try adding a couple of NOP's between bit setting and see if that cures it.

 

Cheers

 

Reynard

 

Another way is to keep a copy of the register in regular memory, update that with set bit and then write the whole thing to the port. I think this is the well known read write modify problem.

Link to post
Share on other sites

Absolutely Russ. Keeping a shadow register for port bits is always a good idea.

 

Write the whole lot to the port when you are finished didling with the bits immediately or if output is not required immedialely I usually wait for a timer tick (5ms or so) and update everything then.

 

Cheers

 

Reynard

Link to post
Share on other sites

Thanks for the responses. I am still on the steep slope of the learning curve for these devices. I appreciate the help.

 

My background is C/C++ with embedded CPUs with an OS like VxWorks or Linux versus MCUs and no OS. The C++ compiler is what attracted me back to PICs. I have limited EE experience.

 

 

I tried up to 50 nop()'s inbetween the set_bit() calls and I could see the first three flash quickly. The end result was still the same. Only the last LED on bit 3 of portc remains lit.

 

I will use a shadow register and then lug the changes over at once, which appears to be correct technique. That works well.

 

For my curiosity, why are the other LEDs not remaining lit? The chip is running at 4 MHz and is not currently clocked by an external oscillator.

 

Here is the configuration word:

 

// Configuration for PIC16F690

#pragma DATA _CONFIG, _MCLRE_ON & _CP_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _BOR_OFF & _CPD_OFF & _PWRTE_ON

 

This is my understanding of the read-modify-write problem:

 

1) Read the port before it's had a chance to settle from the previous write. This results in a value that's unexpected and not representative of the previous write.

- Unless there is a read going on under the hood, my code is not performing them.

 

2) Modifying the value, based on a the suspect read.

 

3) Writing the unintended value back to the port.

 

In my case, it doesn't seem to be the same as the read-modify-write problem. Right? or Wrong? I will peak at the assembly.

 

Kindly,

graham

Link to post
Share on other sites

Here is the assembly with my comments after:

 

21:					set_bit(portc, 0);
  008	1283	 BCF 0x3, 0x5		 // Clear bit 5 on 0x3 (STATUS?)
  009	1407	 BSF 0x7, 0			 // Set bit 0 0x7 (portc) 
22:					set_bit(portc, 1); 
  00A	1487	 BSF 0x7, 0x1		 // Set bit 1 0x7 (portc)
23:					set_bit(portc, 2);
  00B	1507	 BSF 0x7, 0x2		 // Set bit 2 0x7 (portc)
24:					set_bit(portc, 3);
  00C	1587	 BSF 0x7, 0x3		// Set bit 3 0x7 (portc)

 

The BCF and BSF are all one instruction operands. Is this really the read-modify-write problem? Or something else that I don't understand yet?

 

Kindly,

graham

Link to post
Share on other sites

graham,

 

Yes indeed, the problem is related to read-modify-write mechanism and analogue features enabled by default as well.

If you add 'ansel = 0b00001111;' prior the set_bit() instructions then you disable analogue features for those pins and no delay should be required anymore.

Edited by Ettore
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...
×
×
  • Create New...