go_away

Author Topic: turn an IO pin on and off  (Read 2026 times)

0 Members and 1 Guest are viewing this topic.

Offline daisordanTopic starter

  • Jr. Member
  • **
  • Posts: 15
  • Helpful? 0
turn an IO pin on and off
« on: February 25, 2011, 04:51:16 PM »
im using p18f4455 with C
If i wanna turn on all PORT D (RD0 to RD7)i should use "TRISD=0b00000000;" which 0 = output and 1 = input. If i wanna turn RD0 on it should be "TRISD=0b00000001;" But i found some other code on the internet which is "PORTD=0b00000000;"
what is the different between TRISD and PORTD? Are they doing the same things?
And now if i have to turn on RD0 for 5seconds then turn it off. turn on RD1 for 5 seconds and turn off. Should i do it like

TRISD=0b00000001;
Delay10KTCYx(50);
TRISD=0b00000000;
Delay10KTCYx(50);
TRISD=0b00000010;
Delay10KTCYx(50);
TRISD=0b00000000;

I am new from C code... thanks for the helping:)
« Last Edit: February 25, 2011, 08:11:38 PM by daisordan »

Offline hopslink

  • Robot Overlord
  • ****
  • Posts: 202
  • Helpful? 14
Re: turn an IO pin on and off
« Reply #1 on: February 25, 2011, 05:49:40 PM »
You need to read and understand the datasheet. TRISD and PORTD are not the same - from a PIC datasheet:

"All pins have data direction bits (TRIS registers) which can configure these pins as input or output.

A '1' in the TRISD register puts the corresponding out-put driver in a High-impedance mode. A '0' in the TRISD register puts the contents of the output latch on the selected pin(s)."

So to set a PORTD pin as an output you need to set its corresponding TRISD bit to 0. Then to output a 0 or 1 on the pin itself you write the value to the PORTD register.

So to your code, somewhere in your initialisation routine you need:
TRISD=0x00;       //set all PORTD pins as outputs 

and to turn the pins on and off in your code use:
PORTD=0b00000001;  // set PORTD,0
// your 5s delay here
PORTD=0b00000000;  // clear PORTD,0

Offline waltr

  • Supreme Robot
  • *****
  • Posts: 1,920
  • Helpful? 97
Re: turn an IO pin on and off
« Reply #2 on: February 25, 2011, 09:39:18 PM »
And don't forget to check if the port pin have any analog features. If they do then these need to be disabled to use the pin for digital IO. Look at the Pin Diagram in the data sheet.

A good PIC tutorial:
http://www.gooligum.com.au/tutorials.html

Offline daisordanTopic starter

  • Jr. Member
  • **
  • Posts: 15
  • Helpful? 0
Re: turn an IO pin on and off
« Reply #3 on: February 26, 2011, 02:58:04 PM »
thanks for your time. i know much more about the register right.
There are some more example on the internet and they used LATx. But they do the similar coding like PORTx. So i can use either of them?
They say there are three registers to operate for each pin. TRIS register, PORT register and LAT register

Offline waltr

  • Supreme Robot
  • *****
  • Posts: 1,920
  • Helpful? 97
Re: turn an IO pin on and off
« Reply #4 on: February 26, 2011, 04:28:52 PM »
Yep, for the PIC18F chips registers TRISx set the digital IO port direction, PORTx is for reading the value on the port pin and LATx is to set the port pin output.

Offline daisordanTopic starter

  • Jr. Member
  • **
  • Posts: 15
  • Helpful? 0
Re: turn an IO pin on and off
« Reply #5 on: February 26, 2011, 04:54:41 PM »
Do u mean 3 of them should come out together??i still got confuse on LATx and PORTx :-[

Offline waltr

  • Supreme Robot
  • *****
  • Posts: 1,920
  • Helpful? 97
Re: turn an IO pin on and off
« Reply #6 on: February 26, 2011, 07:01:22 PM »
The simple rule is:
READ from PORTx
WRITE to LATx.

For details read carefully the IO PORT section of the data sheet.

Offline paulstreats

  • Supreme Robot
  • *****
  • Posts: 1,381
  • Helpful? 21
Re: turn an IO pin on and off
« Reply #7 on: February 26, 2011, 07:46:40 PM »
for clarification,

if portD7 has a pushbutton on it, then you would read it with PORT i.e. switch = PORTD7

if you have an LED on portD7 then to turn it on you would use LAT i.e. LATD7

(to confuse matters, you can get away with using the PORT to set output most of the time, it's not always necessary to use LAT but it is good practice. One day a program may work perfectly well by setting the port with a PORT command then a simple change in your program may cause it to stop functioning).

 To control an individual bit rather than having to write the full register you can do:

 #define LED1 PORTDbits.RD7

so:

LED1 = 1;

will turn on PORTD7;
(remember theres no semi colon after the #define statement)

Of course this just uses the PORT command so may not always work. you may want to define the LAT bit instead

#define LED1 LATDbitd.LATD7

 hope this helped.

Offline daisordanTopic starter

  • Jr. Member
  • **
  • Posts: 15
  • Helpful? 0
Re: turn an IO pin on and off
« Reply #8 on: March 01, 2011, 09:37:03 AM »
Thanks for the replay. So now my code should be :

void main (void){ 
       
   TRISD=0b00000000;      
   PORTD=0b00000000;
     
   PORTDbits.RD0 = 1;
   Delay10TCYx(70);
   Delay10KTCYx(45);
   PORTDbits.RD0 = 0;   
        while(1);   
}

Because i need to set to pulse be 2.6ms for RD0. Like turn on RD0, set the pulse be 2.6ms, turn it off. What im now doing is set all PORTD be output, turn all the PORTD off, turn on RD0 and read from the port for 2.6ms, turn if off. I think my code should be fine but it is not working....as u guys say
READ from PORTx
WRITE to LATx.
So i dun need to use LAT here. For here,I use the pulse to control the servo degree to left/right. so just need read and dun need to write anythings. Is there any other problem in my code :(?


Offline TheBadger

  • Jr. Member
  • **
  • Posts: 33
  • Helpful? 0
Re: turn an IO pin on and off
« Reply #9 on: March 01, 2011, 09:42:04 AM »
Configure the TRIS
Read from the PORT
Write to the LAT

Offline waltr

  • Supreme Robot
  • *****
  • Posts: 1,920
  • Helpful? 97
Re: turn an IO pin on and off
« Reply #10 on: March 01, 2011, 09:59:24 AM »
We keep saying:
"Write to the LAT"
What about that is so hard to understand????????? ???

And does Port D have ANY analog functions as per the data sheet's pin diagram and table???????

Offline daisordanTopic starter

  • Jr. Member
  • **
  • Posts: 15
  • Helpful? 0
Re: turn an IO pin on and off
« Reply #11 on: March 01, 2011, 11:08:34 AM »
im now clear for the logic now. Sorry for keep asking those simple questions :(. There is no analog functions on RD on the data sheet. Now i work it like :
   TRISD=0b00000001;      
   PORTD=0b00000000;

   PORTDbits.RD0 = 1;
   Delay10TCYx(35);
   PORTDbits.RD0 = 0;

It is now working, but the servo keep moving the same angle when i change to long delay or short delay. im using Fosc=1MHz. Cycle = Time delay*Fosc)/4, Cycle=(1.4ms*1MHz)/4 = 350.

Offline paulstreats

  • Supreme Robot
  • *****
  • Posts: 1,381
  • Helpful? 21
Re: turn an IO pin on and off
« Reply #12 on: March 01, 2011, 01:11:15 PM »
I think that you arent understanding the terminology correctly.

When people say that you write to a port, they mean set it. So when you are setting a 1 to RD0 you are writing to it. Also when you set a 0 to RD0 you are also writing a 0 to it.

in this case:
Quote
PORTDbits.RD0 = 1;
Delay10TCYx(35);
PORTDbits.RD0 = 0;

should read

Quote
LATDbits.LATD0 = 1;
Delay10TCYx(35);
LATDbits.LATD0 = 0;

The code you used does work, but if you are using the port for both read and write operations, then writing to it with a port command can mask the actual value that the port is receiving. In this case you need to use the LAT command to prevent this masking problem. So even though your code is working (as in its writing to the port), it is good practice to use the LAT command since it can prevent you stumbling into problems if you ever start to use the port pins for more than 1 type of operation.

try doing something like this:
Quote

void main (void){  
        
   TRISDbits.TRISD0 = 0;      
  
   while(1){    
      LATDbits.LATD0 = 0;
      Delay10TCYx(200);//delay for the low cycle (you need to optimize this for about 25ms)
      
      LATDbits.LATD0 = 1;  
      Delay10TCYx(35); //delay for the high cycle, you need to work on this
      //the loop will now retun to the top turning the port back low again
       }//end of while(1)    
}



Basically , the servo is now put into a loop, so you are repeatedly sending the same value to it. Servo's need to be kept active or else they turn off. Sometimes just sending them 1 pulse isnt enough to get them to the position they want to be before they turn off again. The timings for the low pulse is just as importat as the high pulse, if its too long then the servo turns off and loses power, if its too short then the servo ecomes jittery and you get false angles from it. But remember KEEP IT ACTIVE unless you want it to turn off.
« Last Edit: March 01, 2011, 01:12:40 PM by paulstreats »

Offline daisordanTopic starter

  • Jr. Member
  • **
  • Posts: 15
  • Helpful? 0
Re: turn an IO pin on and off
« Reply #13 on: March 02, 2011, 06:23:17 AM »
I have try both but now it doesnt work :(
/--------------- first try--------------/
void main (void){
   TRISD=0b00000000;   
   PORTD=0b00000000;
while(1){
   PORTDbits.RD0=0;
   Delay1KTCYx(5);         
   PORTDbits.RD0=1;
   Delay10TCYx(45);
}}
/---------------second try --------------/
void main (void){ 
       
   TRISDbits.TRISD0 = 0;     
 
   while(1){   
      LATDbits.LATD0 = 0;
      Delay1KTCYx(30);
     
      LATDbits.LATD0 = 1; 
      Delay10TCYx(35); /
       }
}
   

 


Get Your Ad Here

data_list