Vous êtes sur la page 1sur 10

//PROGRAMA PARA ODOMETRO //El siguiente programa adquirir seales pulsantes digitales del odometro, cada pul so significa

una vuelta. //Con esta seal calculara la velocidad del carro y distancia recorrida, cuyos dat os seran mostrados en LCD //y la distancia recorrida sera guardada en una memoria eeprom via SPI, para que cada vez que se encienda //la circuiteria tenga grabada el recorrido y lo acumule. //LOGICA PARA EL ODOMETRO: //Inicio con Timer desactivado, cuando recibe un flanco de subida---activar time r //Cuando recibe el siguiente flanco de subida, calcula el diferencial de tiempo y con ello la velocidad //y distancia recorrida, teniendo el dato del diametro de la llanta. //Caso 1: //En el caso de que suceda solo un flanco de subida en los primeros 60 segundos -- desactivar y colocar a //cero todo otra vez. #include #include #include #include #include #include #include <p33fj32mc204.h> <LCD_C30.c> <libpic30.h> "delay.h" <stdio.h> <stdlib.h> <string.h>

/* Configuration Bit Settings */ _FOSCSEL(IESO_OFF & FNOSC_FRC); // Oscilador primario _FOSC(FCKSM_CSECMD & IOL1WAY_ON & OSCIOFNC_OFF & POSCMD_HS); // Conmutacin de Clo ck habilitad, Fail-Safe Clock des-habilitado, OSC2 Clout, Cristal XT. _FWDT(FWDTEN_OFF & WINDIS_OFF & WDTPRE_PR128 & WDTPOST_PS32768);// Watchdog deshabilitado. _FPOR(PWMPIN_ON & HPOL_ON & LPOL_ON & ALTI2C_OFF & FPWRT_PWR128) _FICD(JTAGEN_ON & ICS_PGD2) _FBS(BSS_NO_FLASH & BWRP_WRPROTECT_OFF) _FGS(GSS_OFF & GWRP_OFF) #define delay_ms(x) __delay32(((x*FCY)/1000L)) #define LED LATAbits.LATA0 #define WPN LATCbits.LATC3 #define CSN LATCbits.LATC4 #define HOLDN LATCbits.LATC5 //#define FCY 40000000 #define BAUDRATE 38400 #define BRGVAL ((FCY/BAUDRATE)/16)-1 ///// #define #define #define #define e */ #define #define IC_INT_PRIOR_1 IC_INT_ON IC_IDLE_STOP IC_TIMER3_SRC IC_INT_1CAPTURE IC_EVERY_FALL_EDGE 0xfff9 0xffff 0xffff 0xff7f /* /* /* /* //antes 38400

Input Capture PriorityLevel 1 */ Input Capture Enable */ IC stop in sleep mode */ Timer3 is the clock source for Captur

0xff9f /* Interrupt on first Capture */ 0xfffa /* Every falling edge */

////// int zzz=0,hhh=0,jjj=0; int conteo_int=0; int conteo_timer=0; int comenzar_calculo=0; int activar_interrupcion=0; int velocidad_cero=0; int cont_igual_velocidad=0; int cont_memory=0; int guardar_memoria=0; long direccion_memory=0; double double double double char char char char char char time_flanco=0; velocidad_carro=0; velocidad_carro_anterior=0; distancia_carro=0;

recepcion='0'; atmel='0'; fallo_memoria=0x00; string_lcd[32]; string_lcd2[32]; dist_carro_memory[32];

//void delay_ms(float conteo); void Configuracion_40MIPS(void); void configuracion_SPI_MASTER(void); void configuracion_INT(void); void configurar_timer(void); char verificar_memoria(void); void escribir_memoria(long direccion,char dato); char leer_memoria(long direccion); void configuracion_UART(void); unsigned int *buffer; unsigned int timer_first_edge, timer_second_edge; void __attribute__((interrupt, no_auto_psv)) _INT1Interrupt(void) { //LED=~LED; conteo_int++; if(conteo_int==1){ TMR1=0x00; T1CONbits.TON=1;//activo conteo de timer } if(conteo_int==2){//Significa que ya tengo los 2 flancos de subida para calcular la velocidad _INT1IE = 0; //desactivo interrupcion, para calcular velocidad y recorrido y mostrar en LCD time_flanco=TMR1;

TMR1=0x00; T1CONbits.TON=0;//Desactivo timer comenzar_calculo=1; } _INT1IF = 0; } void __attribute__((__interrupt__, no_auto_psv)) _T1Interrupt(void) { conteo_timer++; if(conteo_timer==3){//Cuando pase 1.25 segundos el desborde del timer //LED=~LED; conteo_timer=0; velocidad_cero=1; } TMR1 = 0x00; IFS0bits.T1IF = 0; } int main(void){ //delay_ms(10);//Para estabilizar alimentacion //Configuracion Configuracion_40MIPS();//Configuro microcontrolador a 40MIPS AD1PCFGL=0x1FF;//configuro los pines digitales TRISCbits.TRISC3=0; TRISCbits.TRISC4=0; TRISCbits.TRISC5=0; TRISAbits.TRISA0=0; delay_ms(10); //Configuraciones iniciales de la memoria CSN=1; WPN=1; HOLDN=1; // LED=1; OpenLCD(LINEAS_5X7); configuracion_SPI_MASTER();//Configuro microcontrolador como Master spi 80Khz //configuracion_UART(); configurar_timer(); configuracion_INT();//configure pin a utilizar como iterrpcion - modulo input capture delay_ms(10); //desde 0x0000 hasta 0x3FFF direccion_memory=0x1500; //////////////////////////////PARA GRABAR DATOS INICIALES EN MEMORIA//// ////////////// /* //Limpia el flag de interrupcion del timer

for(cont_memory=0;cont_memory<10;cont_memory++){ escribir_memoria((direccion_memory+cont_memory),0x30);//grabo 32 espacios de memoria con ceros delay_ms(10); } delay_ms(10); //////////////////////////////////////////////// */ /* distancia_carro=231.164; sprintf(dist_carro_memory,"%.1f",distancia_carro); for(cont_memory=0;cont_memory<=(strlen(dist_carro_memory)-1);cont_memory ++){ escribir_memoria((direccion_memory+cont_memory),dist_carro_memor y[cont_memory]); delay_ms(10); } */ ////////////////////////PARA LEER DATOS GUARDADOS AL INICIO for(cont_memory=0;cont_memory<7;cont_memory++){ dist_carro_memory[cont_memory]=leer_memoria((direccion_memory+co nt_memory)); delay_ms(10); } distancia_carro=atof(dist_carro_memory); while(1){ if(velocidad_carro==velocidad_carro_anterior) cont_igual_velocidad++; if(cont_igual_velocidad>=300){//Aproximadamente 1 segundo de esp era velocidad_carro=0; cont_igual_velocidad=0; //caso que este a velocidad 0Km/h por 1 segundo guardar en memoria if(guardar_memoria==1) { //Guardo en memoria el recorrido actual. sprintf(dist_carro_memory,"%.1f",distancia_carro ); for(cont_memory=0;cont_memory<=(strlen(dist_carr o_memory)-1);cont_memory++){ escribir_memoria((direccion_memory+cont_ memory),dist_carro_memory[cont_memory]); delay_ms(10); } LED=~LED; guardar_memoria=0; }

} sprintf(string_lcd,"%.0f Km/h",velocidad_carro); velocidad_carro_anterior=velocidad_carro; sprintf(string_lcd2,"%.1fKm",(distancia_carro/1000)); //sprintf(string_lcd2,"%c memory",atmel);//solo prueba putcLCD('\f'); __delay_us(2); GotoxyLCD(1,1); __delay_us(2); putsLCD(string_lcd); __delay_us(2); GotoxyLCD(1,2); __delay_us(2); putsLCD(string_lcd2); delay_ms(3); //Una vez finalizada la muestra en el LCD, muestrear la velocida d if(activar_interrupcion==0){ activar_interrupcion=1; conteo_int=0; _INT1IE = 1; //activo interrupcion _INT1IF = 0; //limpio flag } if(comenzar_calculo==1) { time_flanco = time_flanco*6.4; time_flanco = time_flanco/1000000; //printf("%.6fZ%dF",time_flanco,conteo_timer); time_flanco = time_flanco + (((double)conteo_timer)*0.41 9328); //sumar cantidad de desbordes //debido a que se sabe la distancia entre 2 lecturas em metros -- longitud llanta 1.5metros velocidad_carro=1.5/time_flanco; distancia_carro=distancia_carro+3; velocidad_carro=(velocidad_carro/1000)*3600;//para conve rtirlo a kilometros/hora //LED=~LED; comenzar_calculo=0; activar_interrupcion=0; conteo_timer=0; cont_igual_velocidad=0; guardar_memoria=1; }

} /* atmel=verificar_memoria(); if(atmel!=0x60){ //Mostrar en LCD fallo en memoria en vez de la distancia //activar flag de fallo en memoria

fallo_memoria=0x01; Nop(); } else{ //desactivar flag de fallo en memoria fallo_memoria=0x00; Nop(); } */ /* escribir_memoria(0x001517,0x11); delay_ms(10); U1TXREG=leer_memoria(0x001517); while(U1STAbits.UTXBF); while(!U1STAbits.TRMT); */ while(1){ //U1TXREG=(char)buffer; while(U1STAbits.UTXBF); while(!U1STAbits.TRMT); } return 0; } /* void delay_ms(float conteo){ for(zzz=1;zzz<=conteo*4;zzz++){ for(hhh=0;hhh<=115;hhh++) for(jjj=0;jjj<=10;jjj++); } }*/ void Configuracion_40MIPS(void){ //Clock de 40mips _PLLPOST=0x00;// 2 _PLLPRE=0x02;// 4 _PLLDIV=0x1E;// 40 // inicializa swhicheo fast rc a primaria hs __builtin_write_OSCCONH(0x03); __builtin_write_OSCCONL(0x01); // espera a que shichee while (OSCCONbits.COSC!= 3); // Espera a que clock se abra while (OSCCONbits.LOCK!= 1);// configura I/O como digitales } void configuracion_SPI_MASTER(void){ //Entrada RPINR20bits.SDI1R=0x12; //SDI RP18 //Salida RPOR8bits.RP16R=0x07;//SDO RP16 RPOR8bits.RP17R=0x08;//SCK RP17

//while(PORTCbits.RC1==0); //while(PORTCbits.RC1==1); PORTCbits.RC0=0; IFS0bits.SPI1IF=0;//desactivamos el flag de interrupcin IEC0bits.SPI1IE = 0; //activamos la interrupcion por SPI //SPI1CON1bits.PPRE=3;//preescaler primario 1:1 //SPI1CON1bits.SPRE=7;//preescaler secundario 1:1 SPI1CON1bits.PPRE=0x00;//preescaler primario 1:8 SPI1CON1bits.SPRE=0x00;//preescaler secundario 1:64 ////Con los preescaler, Fcy=10Mhz, Fsck=Fcy/(PP*PS)=40Mhz/(64*8)=78kHz SPI1CON1bits.MSTEN=1;//modo maestro SPI1CON1bits.CKP=0;//polarizacion, descanzo bajo y activo alto SPI1CON1bits.SSEN=0;//uso SS de cualquier puerto que desee SPI1CON1bits.CKE=1;//activacion de cambios en flanco de bajada SPI1CON1bits.SMP=0;//data es muestreada a la mitad de la recepcion o tra nsmision SPI1CON1bits.MODE16=0;//transmision de 8 bits SPI1CON1bits.DISSDO=0;//pin SDO controlado por el modulo SPI1CON1bits.DISSCK=0;//Internal reloj SPI es habilitado SPI1STATbits.SPIROV=0;//limpiando el indicador de buffer lleno SPI1STATbits.SPIEN=1;//habilitamos el modulo SPI } void configuracion_UART(void){ //Configurar RC8 COMO TRASNMISION RP24 RPOR12bits.RP24R=3; //Configurar RC9 COMO RECEPCION RP25 RPINR18bits.U1RXR=0x19; ////******Configuracion del modulo uart RCONbits.SWDTEN = 0; // Disable Watch Dog Timer //Configuracion para trabajar con PLL //while(OSCCONbits.LOCK!= 1) {}; // Wait for PLL to lock U1MODEbits.STSEL = 0; // 1 Stop bit U1MODEbits.PDSEL = 0; // No Parity, 8 data bits U1MODEbits.ABAUD = 0; // Auto-Baud Disabled U1MODEbits.BRGH = 0; // Low-Speed mode U1BRG = BRGVAL; // BAUD Rate Setting for 4800 U1STAbits.URXISEL = 0; // Interrupt after one RX character is received IFS0bits.U1RXIF = 0; // Clear the Recieve Interrupt Flag IEC0bits.U1RXIE = 1; // Enable Recieve Interrupts U1MODEbits.UARTEN = 1; // Enable UART U1STAbits.UTXEN = 1; // Enable UART TX IPC2bits.U1RXIP=5;//prioridad de recepcion IPC3bits.U1TXIP=6;//prioridad de transmision } void escribir_memoria(long direccion,char dato){ /////--------------------------------HABILITO ESCRITURA CSN=0;

while(SPI1STATbits.SPITBF); SPI1BUF = 0x06; while(!SPI1STATbits.SPIRBF); recepcion=SPI1BUF; CSN=1; delay_ms(10); /////--------------------------------ESCRIBIR //ACTIVO ESCRITURA CSN=0; while(SPI1STATbits.SPITBF); SPI1BUF = 0x02; while(!SPI1STATbits.SPIRBF); recepcion=SPI1BUF; //ESCRIBO DIRECCION //***********DIRECCION 0xXXXXXX /* while(SPI1STATbits.SPITBF); SPI1BUF = ((direccion>>16) & 0x000000FF); while(!SPI1STATbits.SPIRBF); recepcion=SPI1BUF; */ while(SPI1STATbits.SPITBF); SPI1BUF = ((direccion>>8) & 0x000000FF); while(!SPI1STATbits.SPIRBF); recepcion=SPI1BUF; while(SPI1STATbits.SPITBF); SPI1BUF = (direccion & 0x000000FF); while(!SPI1STATbits.SPIRBF); recepcion=SPI1BUF; //**************************** //ESCRIBO DATO while(SPI1STATbits.SPITBF); SPI1BUF = dato; while(!SPI1STATbits.SPIRBF); recepcion=SPI1BUF; CSN=1; } char leer_memoria(long direccion){ CSN=0; while(SPI1STATbits.SPITBF); SPI1BUF = 0x03;

while(!SPI1STATbits.SPIRBF); recepcion=SPI1BUF; //ESCRIBO DIRECCION //***********DIRECCION 0xXXXXXX /* while(SPI1STATbits.SPITBF); SPI1BUF = ((direccion>>16) & 0x000000FF); while(!SPI1STATbits.SPIRBF); recepcion=SPI1BUF; */ while(SPI1STATbits.SPITBF); SPI1BUF = ((direccion>>8) & 0x000000FF); while(!SPI1STATbits.SPIRBF); recepcion=SPI1BUF; while(SPI1STATbits.SPITBF); SPI1BUF = (direccion & 0x000000FF); while(!SPI1STATbits.SPIRBF); recepcion=SPI1BUF; //**************************** //LEO DATO while(SPI1STATbits.SPITBF); SPI1BUF = 0x00; while(!SPI1STATbits.SPIRBF); recepcion=SPI1BUF; CSN=1; return recepcion; } char verificar_memoria(void){ //--------------------------LEO IDENTIFICADOR--------------------------------CSN=0; while(SPI1STATbits.SPITBF); SPI1BUF = 0x15; while(!SPI1STATbits.SPIRBF); recepcion=SPI1BUF; while(SPI1STATbits.SPITBF); SPI1BUF = 0x00; while(!SPI1STATbits.SPIRBF); recepcion=SPI1BUF; while(SPI1STATbits.SPITBF); SPI1BUF = 0x00;

while(!SPI1STATbits.SPIRBF); recepcion=SPI1BUF; CSN=1; return recepcion; } void configuracion_INT(void){ _INT1IF = 0; //RPINR0bits.INT1R=0x0E;//Configuro interrupcion externa 1 RP14 -- PARA ENTRADA 12V RPINR0bits.INT1R=0x01;//Configuro interrupcion externa 1 RP1 -- PARA ENT RADA 3.3V INTCON2bits.INT1EP=0;//Configuro como flanco de subida _INT1IE = 0; //aun no activo la interrupcion } void configurar_timer(void){ //Habilito interrupcion del timer y lo coloco como prioridad 1 _T1IF = 0x00; //Limpio el bit de interrupcion _T1IP = 0x01; //Asigno prioridad a la interrupcion _T1IE = 0x01; //Habilitacion de la interrupcion TMR1 = 0x00; //Reseteo al conteo del timer PR1 = 0xFFF0; //Asigno el periodo del timer //T1CON = 0xFFA9; //Inicio el timer //Preescaler 64 //Total maximo contar 419.328ms //Fcy=40Mhz=>6.4us -- 1--// 419.328ms 65520 este es el tiempo de desbo rde aprox maximo del timer. //T1CON = 0xFF30; //Inicio el timer //Preescaler 256 T1CONbits.TCKPS=3; //preescaler al clock en 256 T1CONbits.TON=0; //aun no Inicio timer1 }

Vous aimerez peut-être aussi