Setbit(portB,1); Setbit(portB,2); B1 off B2 On ????

General discussion on mikroPascal PRO for PIC.
Post Reply
Author
Message
tacoroos
Posts: 50
Joined: 03 Oct 2005 20:46
Location: Nederland
Contact:

Setbit(portB,1); Setbit(portB,2); B1 off B2 On ????

#1 Post by tacoroos » 08 Nov 2022 20:19

usage P18F2685 10 Mhz
pascal pro with license version 7.6.0

if i put a led on pord B1 and B2
and I set B1 high then B2 goes low
and vice-versa

on port A and C the same

checked with the icd
Step over F8
B1 on B2 off

runing without icd both led stay off

Code: Select all

  
   PORTB := 0x00;
  TRISB1_bit := 0; // Set RB1 as Output
  TRISB2_bit := 0; // Set RB2 as Output

  Setbit(portB,1);
  Setbit(portB,2);


  while (TRUE) do    // Endless loop



Setbit(portB,1); //led turns on B1 High B2 Lo led off
 
///  next 

Setbit(portB,2); ////  led of B1 turns off en led on B2 turns on

Delay_ms(1000) ;
end;

tried this too with pord A and C

what could that be is a mystery to me

thanks for any replies
Taco

janni
Posts: 5373
Joined: 18 Feb 2006 13:17
Contact:

Re: Setbit(portB,1); Setbit(portB,2); B1 off B2 On ????

#2 Post by janni » 08 Nov 2022 21:21

You may have stumbled on RMW (Read-Modify-Write) effect. Before switching a port bit processor reads the entire port, modifies the single bit and then writes whole port. Depending on what's the actual voltage at other port pins at the moment, it may lead to undesired effects. ICD introduces pauses between instructions, so effect may be different then when processor runs freely.

In processors equipped with output latches (accessible through LATx registers), like PIC18s, one should use LATx registers to switch individual output pins' states thus avoiding the RMW effect (there are other methods to avoid it, but unnecessary when operating on LATx registers).

Also remember to configure respective output port pins as digital (when configured as analog - default after reset - PORTx.y reads zero).

tacoroos
Posts: 50
Joined: 03 Oct 2005 20:46
Location: Nederland
Contact:

Re: Setbit(portB,1); Setbit(portB,2); B1 off B2 On ????

#3 Post by tacoroos » 08 Nov 2022 23:22

thanks for your reply

janni wrote:
08 Nov 2022 21:21
You may have stumbled on RMW (Read-Modify-Write) effect. Before switching a port bit processor reads the entire port, modifies the single bit and then writes whole port. Depending on what's the actual voltage at other port pins at the moment, it may lead to undesired effects. ICD introduces pauses between instructions, so effect may be different then when processor runs freely.
I know something about this (RMW (Read-Modify-Write) effect)
that's not it

if i don't use icd the same happens

" then when processor runs freely"

Code: Select all

Setbit(portB,1); // (B1)Green led On
Delay_ms(1000);// Pauze 
Setbit(portB,2); // Red Led(B2) On (B1)Green led Off
now both led red and green should stay lit
and so they don't

if I switch b1 with B2 same but in reverse

Code: Select all

Setbit(portB,2); // (B2)Red led On
Delay_ms(1000);// Pauze 
Setbit(portB,1); // Green Led(B1) On (B2) Red led Off
or B1 on and B2 off or B2 on B1 off

(Both LEDs have been tested and are working)


I think compiler is doing
SetBit changes to ClearBit and vice versa
or is that not possible

tacoroos
Posts: 50
Joined: 03 Oct 2005 20:46
Location: Nederland
Contact:

Re: Setbit(portB,1); Setbit(portB,2); B1 off B2 On ????

#4 Post by tacoroos » 08 Nov 2022 23:40

found something
if i disable the procedure interrupt
then it will work as it should

Setup timmers and interupt on PortB,0 // falling Edge

Code: Select all

//Timer 0 1 sec
  T0CON          := 0x85;
  TMR0H          := 0x67;
  TMR0L          := 0x69;
  GIE_bit         := 1;    // Set GIE, PEIE
  TMR0IE_bit   := 1;     // Enable TMRO interrupt   (1)
  
  //Timer 1    1 ms
  T1CON             := 0x01;
  TMR1IF_bit := 0;
  TMR1H             := 0xF6;
  TMR1L             := 0x3C;
  TMR1IE_bit := 1;
  INTCON     := 0xC0;
  
  //Timer 2   1/ms
    T2CON         := 0x4C;  // Set TMR0 in 8bit mode, assign prescaler to TMR0
    TMR2IE_bit         := 1;
    PR2                 := 249;
    INTCON         := 0xC0;

  INTCON.GIE:=1;        // Enable Global Interrupt
  cnt := 0;                // initialize cnt
  
 INTCON2.INTEDG0:=0;  // Set Interrupt detection on falling Edge
 INTCON.INT0IF:=0;       // Clear INT0IF flag
 INTCON.INT0IE:=1;       // Enable INT0 external interrupt
  
  TMR1ON_bit := 0;//stop timer 0
  TMR2IE_bit := 1;   



Interupt Timer 0,1,2 and B0

Code: Select all

procedure interrupt;
begin

  if (TMR0IF_bit <> 0) then  // timmer 0 1sec
      begin
      TMR0IF_bit := 0;
      TMR0H         := 0x67;
      TMR0L         := 0x69;        // clear TMR0IF
      Inc(Sec);             // Increment value of counter on every interrupt
      end;

  if (TMR1IF_bit <> 0) then  //timmer  1ms
      begin
      TMR1IF_bit := 0;
      TMR1H         := 0xF6;
      TMR1L         := 0x3C;
      Inc(cnt);             // Increment value of counter on every interrupt
      end;

  if (TMR2IF_bit <> 0) then   // timmer 2 1ms
    begin
     TMR2IF_bit := 0;
     Inc(Offtime);         // Increment value of counter on every interrupt
    end;

 if TestBit(INTCON, INT0IF)  Then
  begin
   if INTCON2.INTEDG0=0 then
    Begin
     inc(Puls);
     If (DCF >=30) and (DCF <= 50) Then Begin code1[Puls]:=0;  End;
     If (DCF >=80) and (DCF <= 100) Then Begin code1[Puls]:=1;  End;
     if Puls =58 then
      Begin
       newcode:=code1;
      end;
      INTCON.INT0IF :=0;// Clear Interrupt Flag
   End;

  If portB.0 =1 then
  Begin
   TMR1ON_bit := 0; //timmer 1 on
   INTCON2.INTEDG0 := 0;   //* Set Interrupt detection on falling Edge*/
   oldoff:=offtime;
   offtime:=0;
   TMR2ON_bit:=0; //timer 2 off
  end else
    Begin
     nieuwCNT:=cnt;
     Dcf:=cnt; 
     cnt:=0;
     TMR1ON_bit := 0; //timmer 1 off
     TMR2ON_bit:=1; //timer 2 on
     INTCON2.INTEDG0 := 1; // set Detec rising edge and start
    End;
   INTCON.INT0IF :=0;// Clear Interrupt Flag
  end;

 end;
maybe something is wrong here

thanks for answers

janni
Posts: 5373
Joined: 18 Feb 2006 13:17
Contact:

Re: Setbit(portB,1); Setbit(portB,2); B1 off B2 On ????

#5 Post by janni » 08 Nov 2022 23:42

Why don't you try

Code: Select all

Setbit(LATB,2); // (B2)Red led On
Setbit(LATB,1); // Green Led(B1) On
or simply

Code: Select all

LATB.2:=1;
LATB.1:=1;
instead of repeating variations of the same code? Depending on what's connected on port pins, delay may not help much with RMW effect.

tacoroos
Posts: 50
Joined: 03 Oct 2005 20:46
Location: Nederland
Contact:

Re: Setbit(portB,1); Setbit(portB,2); B1 off B2 On ????

#6 Post by tacoroos » 09 Nov 2022 00:09

janni wrote:
08 Nov 2022 23:42

Code: Select all

LATB.2:=1;
LATB.1:=1;
I already did this
and this is what i did now
janni wrote:
08 Nov 2022 23:42

Code: Select all

Setbit(LATB,2); // (B2)Red led On
Setbit(LATB,1); // Green Led(B1) On
now i have a red led on
and a green flashing LED
flashing 1 sec on off on of

as if the timmer 0 1sec timmer turn it on and off

tacoroos
Posts: 50
Joined: 03 Oct 2005 20:46
Location: Nederland
Contact:

Re: Setbit(portB,1); Setbit(portB,2); B1 off B2 On ????

#7 Post by tacoroos » 09 Nov 2022 00:23

problem solved
Thanks Janni

Setbit(LATB,1); was the trick

forgot about the green led to comment out then

Code: Select all

Setbit(LATB,2); // (B2)Red led On
Setbit(LATB,1); // Green Led(B1) On
    
//Setbit(portB,1);
//Delay_ms(1000);
Setbit(portB,2);
flashing green led

Code: Select all

Setbit(LATB,2); // (B2)Red led On
Setbit(LATB,1); // Green Led(B1) On
    
//Setbit(portB,1);
//Delay_ms(1000);
//Setbit(portB,2);
works properly

Post Reply

Return to “mikroPascal PRO for PIC General”