Software > Software

PIC PORT value with Switch statements

<< < (4/4)

snow:
> But, I guess my whole question was, how would you implement a switch statement with only the last 4 bits?

You should use: switch(PORTB&0b00001111), but here you have to implement 16 different cases! 0001, 0010, 0011 (two soundes recieved at the same time).

I would do something like (you can put this code into interrupt routine as well):

--- Code: ---void main()
{
//set up TRISB and TMR1

unsigned int time4,time5,time6,time7;
unsigned char state;

state=0;

while(1)
{
if(RB4==0)
{
if(state&1<<4==0)
{
time4 = TMR1H<<8 + TMR1L;
state|=1<<4;
}
}

if(RB5==0)
{
if(state&1<<5==0)
{
time5 = TMR1H<<8 + TMR1L;
state|=1<<5;
}
}

if(RB6==0)
{
if(state&1<<6==0)
{
time5 = TMR1H<<8 + TMR1L;
state|=1<<6;
}
}

if(RB7==0)
{
if(state&1<<7==0)
{
time5 = TMR1H<<8 + TMR1L;
state|=1<<7;
}
}

if(state==0b11110000)
{
//rs232(time4); ....

state=0;
}
}


}
--- End code ---

Something like this. But you should also make sure your timer doesnt overlap (you can set TMR1 to 0 when you recieve first pulse) or you can track which sensor recieved first and then you do substract its value from all recorded values.

And another thing might(?) happen is that one (or more) sensors wont recieve singal. Make sure you know how will that affect your program exectution. Solution would be to measure time from first recieved signal and start some timer which will reset everything if you dont get all the signals.

I am also working with hitech c compiler. Or sometimes with c30 compiler.

Hal9000:
Thanks for that snow! Yeah, it's been pretty difficult, even though it looks like an easy task. I just want to make everything happen as fast as possible. As for the interrupts, I found out that the PIC just generates one general interrupt, and then you have to find out which one it was with if loops hahah. Sounds a bit dodge to me but it goes something like this:


--- Code: ---static void interrupt
isr(void)                       // Here be interrupt function - the name is
                                // unimportant.
{
        if(T0IF) {                              // timer interrupt
                TMR0 -= 250;                    // reload the timer - 250uS per interrupt
                T0IF = 0;                       // clear the interrupt flag
                if(relay_timer != 0)            // is the relay timer running?
                        relay_timer--;          // decrement it
                if(relay_timer == 0)            // if it has time out
                        RELAY = 1;              // turn the relay off
                PORTB ^= 0x40;                  // toggle a bit to say we're alive
        }
        if(INTF) {                              // did we see a button press?
                RELAY = 0;                      // turn the relay on
                relay_timer = 4000;             // start the timer - 4000 ticks = 1 second
                INTF = 0;                       // clear the interrupt
        }
}


For the high-end devices, the vector address is specified e.g. the timer0
interrupt is usually at location 0x10 (see the data sheet for vector
addresses). Here's the example:

void interrupt timer0_isr(void) @ 0x10

--- End code ---

Hal9000:
Ok! I know this is a bit lame to all you who have done it before, but I actually did it! Thanks for all your help!


--- Code: ---
void interrupt isr(void)
{
if(RBIE && RBIF)
{
printf("7");
RBIF = 0;
}
if(TMR1IF && TMR1IE)
{
printf("F");
TMR1IF = 0;
}
}

--- End code ---

Admin:
post all your code please! :P i might reference it in the future if i ever need to use a PIC . . .

Hal9000:
Well, It uses PICCLite, and I'm doing it on the PIC16F628A

Some of the stuff isn't commented out, and it doesn't do EXACTLY what I want it to yet, but the main thing is, the interrupt works.....and that's what you wanted, right?

The top part of the interrupt deals with the RB (Interrupt on change) feature

The bottom beals with the Timer1 overflow (see datasheet)

Cheers for now, and hope that helps

Ian :)


--- Code: ---#include <pic.h>
#include <stdio.h>
#include "usart.h"

/********************************************************************************************************************************
 * Author: Ian Robinson *
 * Date Created: December 2006 *
 * Project: EG3001 Project1 : Ultrasonic 3D position location *
 * Project Synopsis: A project to show ultrasonic 3D position location over an RS-232 link using the principle of trilateration *
 ********************************************************************************************************************************/

__CONFIG(BORDIS & UNPROTECT & MCLRDIS & PWRTEN & WDTDIS & INTIO);

#define PORTBIT(adr, bit) ((unsigned)(&adr)*8+(bit))

static bit LED0 @ PORTBIT(PORTB, 0);
// B1 used for RX
// B2 used for TX
static bit LED3 @ PORTBIT(PORTB, 3);
static bit RX1 @ PORTBIT(PORTB, 4); // RX1 (RB4) TOP RIGHT
static bit RX2 @ PORTBIT(PORTB, 5); // RX2 (RB5) BOTTOM RIGHT
static bit RX3 @ PORTBIT(PORTB, 6); // RX3 (RB6) TOP LEFT  (SET AS INPUTS WHEN TIMER 1 FUNCTIONS)
static bit RX4 @ PORTBIT(PORTB, 7); // RX4 (RB7) BOTTOM LEFT (SET AS INPUTS WHEN TIMER 1 FUNCTIONS)

//TRISB4 =1; //Put RB4 into input mode
//TRISB5 =1; //Put RB5 into input mode
//TRISB6 =1; //Put RB6 into input mode
//TRISB7 =1; //Put RB7 into input mode

/***********************************************Variable Declaration************************************************************/

unsigned int i,j; //for loop pause
unsigned int timerReading;
unsigned int timerReadingRX1;
unsigned int timerReadingRX2;
unsigned int compare;

unsigned int time4=0;
unsigned int time5=0;
unsigned int time6=0;
unsigned int time7=0;

/***********************************************Function Declaration************************************************************/
void initialRecieve(void);
void check1(void);
void check2(void);
/***********************************************Main Function*******************************************************************/

void interrupt isr(void)
{
if(RBIE && RBIF)
{
// if(RB4==0)
// {
// time4 = (TMR1H << 8) + TMR1L;
// }
// if(RB5==0)
// {
// time5 = (TMR1H << 8) + TMR1L;
// }
// RBIF = 0;
time4 = (TMR1H << 8) + TMR1L;
time5 = (TMR1H << 8) + TMR1L;
RBIF = 0;
}

if(TMR1IF && TMR1IE)
{
// TMR1ON = 0;
printf("RB4 is ",time4);
printf("\n");
printf("RB5 is ",time5);
printf("\n");
// printf("%10u\n",time6);
// printf("%10u\n",time7);
// time4,time5,time6,time7 = 0;
// timerReading = 0;
// TMR1ON = 1;
TMR1IF = 0;
}
}


void main(void){

unsigned char input;

INTCON=0; // purpose of disabling the interrupts.

init_comms(); // set up the USART - settings defined in usart.h

T1CON = 0b00001100; // Timer 1 control register set-up
TMR1H = 0; // Clear high bit
TMR1L = 0; // Clear low bit
T1OSCEN = 0; // Disable Built-in oscillator between RB6 and RB7

GIE = 1; // enable global interrupts
PEIE = 1; // enable peripheral interrupts

TMR1IF = 0; // clear Timer 1 interrupt flag
TMR1ON = 1; // start Timer 1
TMR1IE = 1; // enable Timer 1 interrupt


RBIE = 1; // enable interrupt on change
RBIF = 0; // clear interrupt on change flag

timerReading = 0;
compare = 0;

/***********************************************While Loop*********************************************************************/

while(1){

// initialRecieve();

// TMR1ON = 0;
// timerReading = (TMR1H << 8) + TMR1L;
// TMR1ON = 1;
// printf("%10u\t",timerReading);


// if(RB7 == 0)
// {
// //printf("%10u\t",timerReading);
// printf("RB7");
// }

}
}

/***********************************************End of Main and While Loop**************************************************************/


--- End code ---

Navigation

[0] Message Index

[*] Previous page

Go to full version