Básicamente, estoy buscando programar un PIC16F917, de modo que un int particular aumente en uno cada vez que presione un botón.
Ahora tengo el ADC en funcionamiento, tengo bucles para contar, pero parece que me falta el conocimiento y la experiencia para ponerlo todo junto, y bloquear la entrada a cero antes de que int aumente en un número mayor que uno.
El siguiente código es lo que he escrito hasta ahora. El problema con esto es que aumenta varias veces por pulsación (tantos ciclos de retraso durante los que se mantuvo pulsado el botón), y me encantaría que solo cuente por uno. Estaba pensando en crear una nueva función e int, pero parece que no puedo armarlo, se necesita mucha ayuda.
Gracias por ayudar, Ezra
#include <xc.h>
#include "config-bits.h"
#define _XTAL_FREQ 4000000
int result;
int output;
void delay()
{
int i;
for(i=0; i<100; i++)
{
/*Timer Stuff*/
}
}
int main()
{
TRISA=1; //Set all pins to input
TRISB=1;
TRISC=1;
TRISD=1;
TRISE=1;
TRISDbits.TRISD0 = 0; //LED output
ANSELbits.ANS0 = 1; //Select ADC input
ADCON0bits.ADFM = 1; //ADC result is right justified
ADCON0bits.VCFG = 0; //Vdd is the +ve reference
ADCON1bits.ADCS = 0b001; //Fosc/8 is the conversion clock
//This is selected because the conversion
//clock period (Tad) must be greater than 1.5us.
//With a Fosc of 4MHz, Fosc/8 results in a Tad
//of 2us.
ADCON0bits.CHS = 0; //select analog input, AN2
ADCON0bits.ADON = 1; //Turn on the ADC
while(1)
{
delay(); //Wait the acquisition time (about 5us).
ADCON0bits.GO = 1; //start the conversion
while(ADCON0bits.GO==1){}; //wait for the conversion to end
result = (ADRESH<<8)+ADRESL; //combine the 10 bits of the conversion
if(result > 512)
{
PORTD=output++;
delay();
}
else
{
NOP();
}
}
}
Utilice una variable para recordar si el último resultado fue < 512. Antes de incrementar la variable de salida, compruebe si el resultado anterior fue < 512. ¿Podría haber utilizado una entrada digital en lugar de una analógica?
Bien, primero algunas cosas. TRISA=1
no pone todo el PORTA como entrada como está escrito en el comentario, es equivalente a 0b00000001
poner todo el puerto como entrada que tiene que hacer TRISA=255
o TRISA=0xFF
que es igual a 0b11111111
.
No sé cómo conectaste el botón al microcontrolador, pero mirando tu programa debería ser algo como esto:
simular este circuito : esquema creado con CircuitLab
De esta manera debería funcionar, obtienes 5V cuando se presiona el botón y 0V cuando está abierto. Sin embargo, aún puede obtener un voltaje inestable en el momento en que se presiona el botón (llamado rebote), se ve así:
Entonces, puede parecer que el botón se presiona varias veces debido a este efecto de rebote, para resolver esto, debe tomar más muestras y promediarlas, luego use el resultado promedio para decidir qué hacer.
Pero hay otra forma, que es más fácil en este caso, solo quiere leer si el interruptor está presionado ('1') o no ('0') para que no necesite y ADC, puede hacerlo solo con una entrada digital, no necesitas una analógica. El esquema sería el mismo, pero el programa C sería algo como esto (supongamos que el interruptor está conectado a RA0):
int main() {
TRISA=1; // Set RA0 as input
TRISD=0x00;
PORTD=0x00;
while(1){
if(TRISAbits.RA0) {
PORTD += 1;
delay(); // We use the delay to avoid the bouncing effect (some milliseconds)
while(TRISAbits.RA0);
}
}
}
Las entradas analógicas a veces son útiles cuando tiene que leer muchos botones y desea guardar algunas entradas de MCU:
En este circuito cada botón produce un voltaje diferente en la entrada del ADC. Entonces, con la entrada analógica, lee ese voltaje y determina qué botón se presionó.
if(TRISAbits.RA0)
es lo mismo que if(TRISAbits.RA0 == 1)
de la misma manera if(!TRISAbits.RA0)
es lo mismo que if(TRISAbits.RA0 == 0)
. Eso es solo algunas cosas de C :)
Rogelio Rowland
ezra_vdj
Golaž
Rogelio Rowland
ezra_vdj
ezra_vdj
Rogelio Rowland