Manejo de puertos de E/S – Parte 3

En el post anterior vimos como controlar un LED y un switch en lenguaje assembler. Ahora veremos como hacerlo en C. Los detalles básicos del programa pueden encontrarse acá.

Primero creamos una función que genere un retardo de aproximadamente 100ms. El código es el siguiente:

 C |  copy code |? 
01
void delay_100us(void) { //Retardo de aprox. 100ms                     
02
char cont;                     
03
cont=20;                     
04
 
05
asm {                      
06
 
07
loop:      nop            //1 ciclo                     
08
           nop                     
09
           nop                     
10
           nop                     
11
           dbnz cont,loop //7 ciclos                       
12
}

 

Como puede verse, el retardo se creó en lenguaje assembler. Para esto, se debe escribir el código entre asm {código en assembler}. Ahora cada vez que escribamos delay_100us(), se llamará a esta función.

Para lograr el retardo de 300ms, haremos lo siguiente:

 C |  copy code |? 
1
for (i=0; i<3000; i++) //Espero aprox. 300ms                   
2
    {                   
3
  delay_100us(); //Llamo función de retardo                   
4
    }

De esta manera, se repetirá 3000 veces el retardo de 100us, por lo que obtendremos uno de 300ms (como dije antes, esto es aproximado).

Lo último que quedaría explicar, sería el manejo del switch. En este caso, al principio del bucle infinito utilizamos la siguiente instrucción:

 C |  copy code |? 
1
if (!parpadea) {}

Entre las llaves escribimos el código para encender y apagar el LED. La variable parpadea está declarada como unsigned char e inicialmente tiene un valor de 1 y al tener un !, cuando parpadea sea 0, se ejecutará nuestro código. Para esto escribimos lo siguiente:

 C |  copy code |? 
1
if (PTAD_PTAD0) //Chequeo si el switch está presionado             
2
{             
3
while (PTAD_PTAD0) for (temp=100; temp; temp--);             
4
parpadea=!parpadea;               
5
}

De esta manera, cuando pulsemos el botón (esperamos un tiempo para evitar rebotes), cambiaremos el valor de la variable parpadea, pudiendo ejecutar de esta manera nuestro código principal.

Código completo:

 C |  copy code |? 
01
#include <hidef.h> /* for EnableInterrupts macro */         
02
#include "derivative.h" /* include peripheral declarations */         
03
 
04
 
05
 
06
void delay_100us(void) { //Retardo de aprox. 100ms         
07
char cont;         
08
cont=20;         
09
 
10
asm {          
11
 
12
loop:      nop //1 ciclo         
13
    nop         
14
    nop         
15
    nop         
16
    dbnz cont,loop //7 ciclos         
17
 
18
 }         
19
 
20
}         
21
 
22
void main(void) {         
23
  int i;         
24
  unsigned char parpadea=1;         
25
  unsigned int temp;         
26
  SOPT1 = 0x02; //Deshabilito watchdog         
27
  ICSC1=0x14; //Reloj interno, divido por 4 (CLK=8Mhz,BUS_CLK=2Mhz)         
28
  PTBDD_PTBDD0=1; //Configuro el bit 0 del puerto B como salida         
29
  PTADD_PTADD0=0; //Configuro el bit 0 del puerto A como entrada         
30
  PTAPE_PTAPE0=1; //Configuro la resistencia pull-up de PTAD0         
31
  EnableInterrupts;         
32
 
33
  for(;;) {         
34
  if (!parpadea)         
35
  {         
36
 
37
  PTBD_PTBD0=1; //Pongo el bit 0 del puerto B en 1         
38
  for (i=0; i<3000; i++) //Espero aprox. 300ms         
39
    {         
40
  delay_100us(); //Llamo función de retardo         
41
    }         
42
  PTBD_PTBD0=0; //Pongo el bit 0 del puerto B en 0         
43
  for (i=0; i<3000; i++) //Espero aprox. 300ms         
44
      {         
45
    delay_100us(); //Llamo función de retardo         
46
    }         
47
  }         
48
  if (PTAD_PTAD0) //Chequeo si el switch está presionado         
49
  {         
50
  while (PTAD_PTAD0) for (temp=100; temp; temp--);         
51
  parpadea=!parpadea;           
52
  }         
53
  } /* loop forever */         
54
  /* please make sure that you never leave main */         
55
}

Esto es todo por ahora. La próxima veremos como generar retardos más precisos utilizando el timer interno que posee el microcontrolador

Tags: , , , , ,

{ 6 comments to read ... please submit one more! }

  1. Hi i am interesting in you project and i would like Learn more about this microcnotroler

  2. This is a great tip particularly to those new to the blogosphere.
    Short but very accurate information… Thank you for
    sharing this one. A must read article!

  3. You made some really good points there. I looked on the web to learn more about the issue and found most people will go along with your views on this
    site.

  4. Hello colleagues, its fantastic post concerning teachingand entirely explained, keep it up
    all the time.

  5. Hey there would you mind letting me know which hosting company you’re utilizing? I’ve loaded your blog in 3 completely different web browsers
    and I must say this blog loads a lot quicker then most.

    Can you recommend a good hosting provider at a reasonable price?
    Kudos, I appreciate it!

  6. Wow that was odd. I just wrote an really long comment but after
    I clicked submit my comment didn’t appear. Grrrr… well I’m not writing all that over
    again. Anyways, just wanted to say superb blog!

{ 0 Pingbacks/Trackbacks }

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>