TODOPIC
Microcontroladores PIC => Todo en microcontroladores PIC => Mensaje iniciado por: aloalvaro en 25 de Mayo de 2008, 22:34:33
-
Hola a todos!!!
Tengo que diseñar el sistema adjunto en el pdf. Mi idea era utilizar un oscilador externo de 40 KHz, y jugar con el modulo PWM dependiendo del switch que se activase, pero no sé si es lo más óptimo. Además, en lo que se refiere a lo de los chirp del tercer interruptor, no entiendo muy bien a qué se refiere, ni cómo puedo generar la señal correspondiente a ese caso, así que os rogaría que si alguien sabe algo, me ayudáseis.
Muchas gracias a todos!!!!
Un saludo
-
Hola.
Pues la tercera opcion son secuencias de rafagas de 40kHz, 10 ciclos de 40kHz 100 veces en un segundo. Generar 40kHz es muy sencillo con el pic 12, y asi mismo es sencillo generar todas las variaciones que piden ( la de los interruptores ). Lo que si vas a obtener con ese esquematico es una senal mas bien debil para la emision del ultrasonido. No se si tendras ya elegido el transductor pero te recomiendo los 40TR12B.
Saludos
-
Gracias MLO, pero para generar 40 KHz, q es mejor...
Coger un cristal de 40 KHz y utilizarlo como base para tener las señales, o bien sería mejor escoger otro cristal???
Y en cuanto al transductor, usaré el que me has dicho, muchas gracias por el consejo!!!!
-
Hola.
Pues, me parce mejor utilizar el oscilador interno del pic12, y generar esa frecuencia ( desbordamientos de algun timer cada 25uS ) a traves de uno de los pines del micro, de esta manera tendrias una senal cuadrarda de 5v pico a 40kHz. Despues, si quieres potencia, tocaria hacer un acople con algun transistor entre el micro y el transductor.
Saludos
-
MLO, estoy bastante perdido
Llevo todo el dia intentando realizar las operaciones de los switches, y no he sido capaz ni siquiera de conseguir los 40 KHz con el oscilador interno. Por favor, ruego me eches una mano, me va un proyecto en ello.
Muchas gracias!!!
-
Hola.
Tienes algun codigo para el microcontrolador?? Seria bueno que lo postees para revisar que avances tienes y sacamos el proyecto adelante, te parece? Entre mas rapido postees el codigo, mas rapido llegara la ayuda :mrgreen: :mrgreen:
Saludos
-
Hola MLO
La verdad es que avazno muyy despacio, porque entre que soy bastante novato con esto de los PIC, y que el ensamblador me parece bastante lioso, no se si lo que estoy haciendo lo hago bien. He escrito algo de codigo de cara a generar los 40 KHz, pero no se si estara bien; al final tenias razon, tenia que usar el oscilador interno, el cual he visto que puede funcionar a 8MHz, entonces, de cara a generar la secuencia, se me habia ocurrido utiliza un juego de instrucciones, teniendo en cuenta lo que cada instruccion gasta en ciclos de reloj.
Intenté hacerlo en lenguaje C, pero me obligan a que sea en ensamblador; además, no sé como conseguir que la onda me dure 30seg, y dspues parar; por cierto, por mucho que he investigado, sigo sin entender lo de los chirps, asi que si me pudieses explicar un poco como va, te lo agradeceria.
En cuanto al segundo de los casos, tengo la impresión que es hacerlo con una PWM, es así???
Muchas gracias por toda la ayuda que me estás prestando!!!!!
Un saludo!!!!!
El codigo que he hecho de momento es el siguiente
include <P12F683.inc>
__CONFIG _IntRC_OSC & _WDT_OFF & _CP_OFF & _MCLRE_OFF
MOVLW b'00111010' ;GP5,GP4,GP1 inputs; GP2,GP0 outputs
MOVWF TRISIO
Main
BTFSS GPIO,5 ;Check Switch1, if closed, GOTO wave1
GOTO Wave1
BTFSS GPIO,4 ;Check Switch2, if closed, GOTO wave2
GOTO Wave2
BTFSS GPIO,1 ;Check Switch3, if closed, GOTO wave3
GOTO Wave3
GOTO Main
Timer25
MOVLW b'11000000' ;Clock 8MHz --> Fosc/4 = 2MHz --> Prescaler2--> 1MHz
MOVWF OPTION_REG ;
MOVLW 230 ;Initialising TMR0 to 230 to count 25us.
MOVWF TMR0 ;
BSF INTCON,7 ;Enabling interrupt
BSF INTCON,5 ;Enabling TMR0 interrupt
BCF INTCON,2 ;Cleaning interrupt flag
BTFSC GPIO,1 ;Checking Waveform, if 0, change to 1 and viceversa
BCF GPI0,2
BSF GPIO,2
GOTO Wave1
Hold ; generate 40kHz signal when GPIO.5 = 0;
btfsc gpio,5 ; Is data input at logic 0?
goto next ; Continue
Wave1
bsf gpio,2 ; Yes, so begin 40kHz sequence generation
btfsc gpio,5 ; 2uS
goto Hold ; 3uS
btfsc gpio,5 ; 4uS
goto Hold ; 5uS
btfsc gpio,5 ; 6uS
goto Hold ; 7uS
btfsc gpio,5 ; 8uS
goto Hold ; 9uS
btfsc gpio,5 ; 10uS
goto Hold ; 11uS
btfsc gpio,5 ; 12uS
goto Hold ; 13uS (~52% duty-cycle)
bcf gpio,2 ; 14uS turn off IR LED here
btfsc gpio,5 ; 15uS
goto Hold ; 16uS
btfsc gpio,5 ; 17uS
goto Hold ; 18uS
btfsc gpio,5 ; 19uS
goto Hold ; 20uS
btfsc gpio,5 ; 21uS
goto Hold ; 22uS
btfss gpio,5 ; 23uS If gpio,5 = 1 end sequence, else continue
goto Wave1 ; 25uS, GOTO requires 2uS, 25uS total=40kHz
goto Hold ; return & wait
END
simplemente queria saber si la parte etiquetada como Wave1 es correcta, y si esta bien diseñado (el pin 5 es el correspondiente al switch1, lo que hago es estar continuamente comparando si hay conexion directa con tierra, lo que equivaldria a un 0, y si es asi, sigo generando la secuencia de 40 KHz, pero no se si esta bien del todo; además, no sé donde meter que se ilumine el LED mientras tanto (lo tengo conectado al pin GP0), ni como considerar el factor de los 30seg)
gracias!!!!!
-
Hola.
Vamos por partes.
Primero dejemos claro lo que hay que hacer, es decir que salidas vamos a obtener en funcion de los switches.
1) Señal se salida a 40kHz y un led encendido durante 30 segundos, luego el micro entra en modo SLEEP
2) Un led encendido durante 30 segundos y la señal de salida de los 40kHz debe estar modulada por una señal de 2kHz, es decir, sale la señal de 40kHz pulsada a 2kHz, es decir :mrgreen: la señal de 40kHz esta activa durante 250uS y esta apagada durante 250uS y sigue asi durante 30 segundos y luego entra a modo SLEEP.
3) Un led encendido durante 30 segundos y deben salir 10 pulsos de 40kHz 100 veces en un segundo , es decir sale la señal de 40kHz durante 250uS (que equivalen a 10 pulsos de 40kHz) y luego la apagas durante 9750uS y luego de 30 segundos entras al modo SLEEP. Explico mejor lo de los chirps. Tienes que enviar 10 pulsos de 40kHz ( t = 250uS) pero tienes que repetir 100 veces eso en un segundo, es decir en 1000mS, dividiendo entre 100 tenemos un periodo de 10mS. En 10mS solo esta activa la señal durante 250uS el resto debe estar apagada, listo?
Lastimosamente yo programo en C ( CCS ), pero podriamos hacerlo primero ahi y luego pasarlo a ASM con el MPLAB IDE.
Espero tus comentarios
Saludos
-
Hola a todos.
Una pregunta ¿la frecuencia debe ser emitida con un pulso del pulsador, o debe durar lo que dure el pulsador pulsado? ¿se entiende lo que pregunto?
-
Hola LeonPic.
Segun el pdf, la señal se activa durante 30 segundos con la activacion del switche.
Saludos
-
Hola MLO
Muchas gracias de nuevo por toda la ayuda que me estas prestando, he tenido que aparcar el proyecto por unos dias porque tenia un par de examenes, pero ya lo tengo de vuelta, y al final puedo programarlo en C. De momento, para la primera de las ondas, he hecho lo siguiente, no se si estara bien
#include <p12f683.h>
#pragma config WDT = OFF // Cancelling Watch Dog Timer
//Variables declaration
int i;
void main(){
init();
while(1){
//checking if there has been a change at any GPIO inputs
if (INTCONbits.GPIF==1){
if (GPIObits.GP5==0){
wave1();
}
if (GPIObits.GP4==0){
wave2();
}
if (GPIObits.GP1==0){
wave3();
}
}
}
}
void init(){
configPort();
configTimer();
}
void configPort(){
TRISIO=0b00111010; //establishing inputs/outputs of the port
GPIObits.GP2=0; //clearing OUTPUT to the transducer
IOC = 0b00110010; //enabling Interrupt-on-change GPIO register
}
void configTimer(){
T1CON=0b00000000; //Internal clock, prescaler 1:1
}
void wave1(){
INTCONbits.GPIF=0; //clearing GPIO interrupt flag
//Same operation for 30 seconds
for(i=0;i<1200;i++){
GPIObits.GP0=1; //lighting LED
PIE1bits.TMR1IE=1; //enabling Timer1 interrupt
PIR1bits.TMR1IF=0; //assuring that the Timer1 interrupt flag is cleared
TMR1H=0x3C; //initiating counter to 15536, as it is necessary to count 50000 with prescaler 1:1 to obtain 25 ms, which // are needed for the signal of 40 KHz
TMR1L=0xB0;
T1CONbits.TMR1ON=1; //starting Timer1
//when TMR1 overflows, it is time to change the level of transducer signal
if(PIR1bits.TMR1IF==1){
if(GPIObits.GP2==0){
GPIObits.GP2=1;
}
GPIObits.GP2=0;
}
}
}
en cuanto a la segunda, mi intencion era usar el modulo PWM, aunque no se si es lo correcto, o por el contrerio, deberia usar variables que me guarden el estado de la señal de 40 KHz cada 250 us y luego continuar con ellas otros 250 us, ???
gracias!!!!
-
Finalmente, he acabado el código, no sé si estará bien, pero me gustaría que le echárais un vistazo si podéis, muchas gracias!!!!
#include <p12f683.h>
#pragma config WDT = OFF // Cancelling Watch Dog Timer
//Variables declaration
int i;
int counter;
int active;
int chirpCounter;
void main(){
init();
while(1){
//checking if there has been a change at any GPIO inputs
if (INTCONbits.GPIF==1){
if (GPIObits.GP5==0){
wave1();
sleep();
}
if (GPIObits.GP4==0){
wave2();
sleep();
}
if (GPIObits.GP1==0){
wave3();
sleep();
}
}
}
}
void init(){
configPort();
configTimer();
}
void configPort(){
TRISIO=0b00111010; //establishing inputs/outputs of the port
GPIObits.GP2=0; //clearing OUTPUT to the transducer
IOC = 0b00110010; //enabling Interrupt-on-change GPIO register
}
void configTimer(){
OPTION_REG=0b00000000; //Internal clock, prescaler 1:2
T1CON=0b00000000; //Internal clock, prescaler 1:1
T2CON=0b00000010; //Prescaler 1:16
}
void wave1(){
INTCONbits.GPIF=0; //clearing GPIO interrupt flag
counter=0;
PIE1bits.TMR2IE=1; //enabling Timer 2 interrupt
PIR1bits.TMR2IF=0; //clearing Timer2 Interrupt Flag
TMR2 = 0x06; //Need to count 250 --> 2 mseg
T2CONbits.TMR2ON=1; //timer2 starts
//Same operation for 30 seconds
while(counter<15000){
//Each time TMR2 overflows, it has to be restarted (15000 times)
if(PIR1bits.TMR2IF==1){
PIR1bits.TMR2IF=0;
counter++;
TMR2 = 0x06;
T2CONbits.TMR2ON=1;
}
GPIObits.GP0=1; //lighting LED
signal40();
}
GPIObits.GP0=0; //switching LED off
}
void wave2(){
INTCONbits.GPIF=0; //clearing GPIO interrupt flag
counter=0;
PIE1bits.TMR2IE=1; //enabling Timer 2 interrupt
PIR1bits.TMR2IF=0; //clearing Timer2 Interrupt Flag
TMR2 = 0x06; //Need to count 250 --> 2 mseg
T2CONbits.TMR2ON=1; //timer2 starts
INTCONbits.T0IE=1; //enabling Timer 0 interrupt
INTCONbits:T0IF=0; //clearing Timer0 Interrupt Flag
TMR0 = 0x06; //need to count 250 ms for a
//modulation frequency of 2 KHz
while(counter<15000){
//Each time TMR2 overflows, it has to be restarted (15000 times)
if(PIR1bits.TMR2IF==1){
PIR1bits.TMR2IF=0;
counter++;
TMR2 = 0x06;
T2CONbits.TMR2ON=1;
}
GPIObits.GP0=1; //lighting LED
if(active){
while(!INTCONbits.T0IF){
signal40();
}
INTCONbits.T0IF=0;
TMR0=0x06;
active=0;
}
while(!INTCONbits.T0IF){
signal20();
}
INTCONbits.T0IF=0;
TMR0=0x06;
active=1;
}
GPIObits.GP0=0; //switching LED off
}
void wave3(){
INTCONbits.GPIF=0; //clearing GPIO interrupt flag
counter=0;
chirpCounter=0;
PIE1bits.TMR2IE=1; //enabling Timer 2 interrupt
PIR1bits.TMR2IF=0; //clearing Timer2 Interrupt Flag
TMR2 = 0x06; //Need to count 250 --> 2 mseg
T2CONbits.TMR2ON=1; //timer2 starts
INTCONbits.T0IE=1; //enabling Timer 0 interrupt
INTCONbits:T0IF=0; //clearing Timer0 Interrupt Flag
TMR0=0x06; //need to count 250us
//Same operation for 30 seconds
while(counter<15000){
//Each time TMR2 overflows, it has to be restarted (15000 times)
if(PIR1bits.TMR2IF==1){
PIR1bits.TMR2IF=0;
counter++;
TMR2 = 0x06;
T2CONbits.TMR2ON=1;
}
GPIObits.GP0=1; //lighting LED
while(chirpCounter<40){
while(!INTCONbits.T0IF){
if(chirpCounter==0)
signal40();
if(chirpCounter>0 && chirpCounter<40)
GPIObits.GP2=0;
}
chirpCounter++;
}
if(chirpCounter==40)
chirpCounter=0;
}
GPIObits.GP0=0; //switching LED off
}
void signal40(){
PIE1bits.TMR1IE=1; //enabling Timer1 interrupt
PIR1bits.TMR1IF=0; //assuring that the Timer1 interrupt flag is //cleared
TMR1H=0xFF; //initiating counter to 65511, as it is necessaryto //count 25 with prescaler 1:1 to obtain 12.5 us of duty //cycle (50%), which are needed for the signal of 40 KH TMR1L=0xE7;
T1CONbits.TMR1ON=1; //starting Timer1
//when TMR1 overflows, it is time to change the level of
//transducer signal
if(PIR1bits.TMR1IF==1){
if(GPIObits.GP2==0){
GPIObits.GP2=1;
}
GPIObits.GP2=0;
}
}
void signal20(){
PIE1bits.TMR1IE=1; //enabling Timer1 interrupt
PIR1bits.TMR1IF=0; //assuring that the Timer1 interrupt flag is //cleared
TMR1H=0xFF; //initiating counter to 65511, as it is necessary to //count 50 with prescaler 1:1 to obtain 25 us of duty //cycle (50%), which are needed for the signal of 20 KH TMR1L=0xCE;
T1CONbits.TMR1ON=1; //starting Timer1
//when TMR1 overflows, it is time to change the level of
//transducer signal
if(PIR1bits.TMR1IF==1){
if(GPIObits.GP2==0){
GPIObits.GP2=1;
}
GPIObits.GP2=0;
}
}
Muchisimas gracias MLO por todo, la ayuda ha sido fundamental;me queda todavía simular con MPLAB, seguro que me da errores por todos lados!!!! pero si pudierais echarle un vistacillo y ver si veis algo a primera vista, os lo agradeceria!!!!
-
Hola aloalvaro.
Pues a simple vista el codigo parece estar bien, aunque hace rato no programo en c18. Porque no lo simulas en Proteus Isis? es una buena herramienta para estos casos. Felicitaciones por sacar tu codigo, mira que lo hiciste tu :-/
Saludos