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.
Hi i am interesting in you project and i would like Learn more about this microcnotroler
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!
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.
Hello colleagues, its fantastic post concerning teachingand entirely explained, keep it up
all the time.
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!
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!