Pages: [1]   Go Down
Author Topic: PORTx vs. digitalRead()  (Read 993 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 15
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have something that's mystifying me and I'm hoping someone can explain.

Background:
I'm using PORTB in this case.
I have DDRB = 0xFF; and PORTB = 0xFF;

I have an external chip that pulls down one of 6 pins on PORTB. Each one triggers a pin change interrupt. First thing I do in the ISR is check which was pulled low. Now when I just read in PORTB, they all appear high. When I use a for loop and use digitalRead(), it correctly tells me which one was low.

I could use the for loop method, but I'm wondering why just reading PORTB doesn't work.

I've looked at digitalRead, which after doing some checks returns this:

return (_SFR_IO8(port_to_input[digitalPinToPort(pin)]) >> digitalPinToBit(pin)) & 0x01;

Which I've managed to turn into this:

_SFR_IO8(port_to_input[2]); //PB is defined as 2 in pins_arduino.c

which successfully works as well.

SOO my question is can anyone explain why this SFR_IO8 trick works but simply reading PORTB does not?




Logged

Forum Administrator
Cambridge, MA
Offline Offline
Faraday Member
*****
Karma: 12
Posts: 3538
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Huh, strange; I don't have any ideas off of the top of my head.  Can you post the full source for your sketch (or a simplified version that illustrates the problem)?
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 15
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Yeah it is strange...here is the code:

Code:
#include <avr/portpins.h>
#include <avr/interrupt.h>

/*
Interupt-based QT300 1-WIRE driver
*/

#define TBR 200  //baud period in microseconds (110-200 allowed)
#define TWU 40  //wake up time
#define TSCK 40 //half period of clock (min 30)
#define TDS 80 //data spacing duration  (min 75)
#define TSAMP 15

#define CHAN 1 // number of channels to be sampled (not used yet)

//Connectors and corresponding arudino pins
#define       J1      2
#define       J2      3
#define       J3      4
#define       J4      5
#define       J5      6
#define       J6      7
#define       J7      8
#define       J8      9
#define       J9      10
#define       J10      11
#define       J11      12
#define       J12      13


//macros to disable pin change interrupts and mask/unmask them
#define DISABLE_INT  PCICR &= !(0x05)
#define ENABLE_INT PCICR |= 0x05
#define MASK0 PCMSK0 |= 0x3F
#define MASK2 PCMSK2 |= 0xFC
#define UNMASK0 PCMSK0 &= !(0x3F)
#define UNMASK2 PCMSK2 &= !(0xFC)

//states
#define DEFAULT 0
#define PRINT 1
#define SEND 2

//which PIN to send/recieve from:
int req = J4;
 
volatile uint16_t qt_data = 0;

volatile uint8_t state;
volatile byte portreading = 0;


int ch = 0;
int i = 0;
int bl = 0;                 // used to count the time of the acquisition burst

int dec_reading = 0;

void setup() {

  
  //disable PCinterrupts
  DISABLE_INT;
  UNMASK0;
  UNMASK2;

  //set PORTB to outputs
  DDRB = 0xFF;
  PORTB = 0xFF;
  
  DDRD = 0xFF;
  PORTD = 0xFF;
  
  
  Serial.begin(115200);      
  delay(500);                

  
   ENABLE_INT;
   MASK0;
   MASK2;

   state = SEND;
 

}//setup()

void loop(){
    
    switch (state) {
      
    case SEND:
  
    
     //send acquisition request
     send_req(req);
     state = DEFAULT;
     break;
      
    
     case PRINT:

     Serial.print(qt_data);
     Serial.println("");
     Serial.print(portreading,BIN);
     Serial.println("");
  
     state = SEND;
    
     break;
    
    
    default:
    
    
    break;
  
    }
 
}//loop()


uint16_t get_bytes(int pin) {
    
 
    static uint8_t qtMSB;
    static uint8_t qtLSB;
    
    qtMSB = 0;
    qtLSB = 0;
    
    //this delay needs to be determined by how long it takes to go through ISR
    delayMicroseconds(TBR);  //TBD
    delayMicroseconds(TBR/2);
    
    //first byte
    
    for (i = 0; i < 8; i++) {
    
    
      qtMSB |= (digitalRead(pin) << i);
      //qtMSB |= (PORTB1 << i);
      delayMicroseconds(TBR);
      
 
     }
  
    delayMicroseconds(85);
    
  
    while (digitalRead(pin)  != HIGH);
    while (digitalRead(pin) != LOW);
  
  
    delayMicroseconds(TBR);
    delayMicroseconds(TBR/2);
    
    //second byte
    for (i = 0; i < 8; i++) {
      
      qtLSB |= (digitalRead(pin) << i);
      //qtLSB |= PORTB1 << i;
      delayMicroseconds(TBR);
  
    }
  
  
  
  
   return qtLSB + (qtMSB << 8);

  
}

//send acquisition request to qt300 on selected pin
void send_req(int pin) {
  

    DISABLE_INT;
    UNMASK0;
    UNMASK2;
    
  
    DDRB |= 0xFF;
    DDRD |= 0xFF;
    
    //send wake up pulse
    digitalWrite(pin, LOW);
    delayMicroseconds(TWU);
    
    //send baud rate pulse
    digitalWrite(pin, HIGH);
    delayMicroseconds(TBR);
    digitalWrite(pin, LOW);
    
    
    delayMicroseconds(TWU); //twu
    digitalWrite(pin, HIGH);
  
    DDRB &= 0x00;
    DDRD &= 0x00;
    delayMicroseconds(TBR);
    
    ENABLE_INT;
    MASK0;
    MASK2;    
    
  
}

ISR(__vector_default)
{
    Serial.println("DEFAULT");
    state = PRINT;
}



ISR (PCINT0_vect) {
  
   DISABLE_INT;
   UNMASK0;
   UNMASK2;
  
   //portreadin = PORTB; //doesn't work, always gives all HIGH
   portreading = _SFR_IO8(port_to_input[2]);
 
   qt_data = get_bytes(req);  
  
   state = PRINT;

   ENABLE_INT;
   MASK0;
   MASK2;
  
}//ISR(PCINT0_vect);


ISR (PCINT2_vect) {

   DISABLE_INT;
   UNMASK0;
   UNMASK2;
 
   //portreading = PORTD;
   portreading = _SFR_IO8(port_to_input[4]);
  
   qt_data = get_bytes(req);  
  
   state = PRINT;

   ENABLE_INT;
   MASK0;
   MASK2;  
  
}//ISR(PCINT2_vect);
Logged

Austin, TX
Offline Offline
Jr. Member
**
Karma: 1
Posts: 94
Shh! I am hunting wabbit. Killlll the wabbit!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Use PINB to read the values of the pins.  PORTB is used to write the values
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 15
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ahh thanks, I'll give that a try.
Logged

Pages: [1]   Go Up
Jump to: