Skip to content

Instantly share code, notes, and snippets.

@manosv
Forked from hexagon5un/Tiny_Tachometer.c
Created December 1, 2016 15:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save manosv/465631fdc3b99539e18d9aa56cd0dc64 to your computer and use it in GitHub Desktop.
Save manosv/465631fdc3b99539e18d9aa56cd0dc64 to your computer and use it in GitHub Desktop.
PIC Code to Set 6 Pins With 3: http://wp.me/pk3lN-YHm
/*******************************************************************************
TINY TACHOMETER
TACOMETRO C/ PIC12F675 E LCD (M�TODO LPLEX - 3 FIOS)
METODO: LEITURA DO PERIODO
AUTOR: CLAUDIO LARIOS
C/ XTAL DE 4 MHZ
DATA:06/05/2016
MEDE DE 60 A 64000 RPM
USAR SENSOR HALL (UGS3140) E IM� FIXO AO EIXO OU OPTO ACOPLADOR
(UM PULSO POR VOLTA)
USO DID�TICO
ESTE ARQUIVO � PARTE INTEGRANTE DO BLOG LARIOS.TECNOLOGIA.WS
*******************************************************************************/
//#include <12F675.h>
#include <12F683.h>
#device adc=10
#use delay(clock=4000000)
#fuses NOWDT,HS, NOCPD, NOPROTECT, NOMCLR, PUT, BROWNOUT
#use fast_io(a)
//bytes
#byte trisio = 0x85
#byte gpio = 0x05
#byte cmcon = 0x19
#byte intcon = 0x0b
#byte option_reg = 0x81
//bit
#bit t0if = 0x0b.2 //timer0 overflow flag
#bit t1on = 0x10.0 //on/off tmr1
#bit t1if = 0x0c.0 //over flow tmr1
#bit t1ie = 0x8c.0 //liga interrup��o do tmr1
#bit gie = 0x0b.7 //geral int
#bit peie = 0x0b.6 //geral int perif�ricos
//pinos do lcd (metodo Lariosplex - 3 fios)
#bit DB76 = 0x5.0 //pino 7 db7=direto db6=resistor 10k +cap 10nF ao gnd
#bit DB54 = 0x5.1 //pino 6 db5=direto db4=resistor 10k +cap 10nF ao gnd
#bit E_RS = 0x5.2 //pino 5 E=direto RS=resistor 10k +cap 10nF ao gnd
#bit in = 0x5.3 //pino 4 entrada
#define vcarga 500 // por tentativa e erro (entre 200 a 500)
#define vdescarga 500//idem
#define v_delay_clk 2 // de 2 a 50 conforme LCD
#define time_max 0XFF00 //define o tempo do time_out
//vari�veis globais
unsigned int1 RS,f_out;
unsigned int8 dmilh,umilh,cent,dez,un,a;
unsigned int16 res,time_out;
unsigned int32 soma;
/*******************************************************************************
SUBROTINAS
*******************************************************************************/
void descarregar(){ DB76=0;DB54=0;E_RS=0; delay_us(vdescarga);}//tempo de descarga
void t_carga(){delay_us(vcarga);}//tempo de carga
void clk(){ E_RS=1; delay_cycles(v_delay_clk); E_RS=0;}//gera clock par Lcd
/*******************************************************************************
SUBROTINAS de LCD
*******************************************************************************/
/*******************************************************************************
ENVIA NIBBLE
*******************************************************************************/
void env_nible(unsigned int8 nib){
descarregar();//descarrega capacitores
nib&=0x0f;//limita
if(nib&0x01)DB54=1;//testa bit 0
if(nib&0x04)DB76=1;//testa bit 2
if(RS)E_RS=1;else E_RS=0;//comando ou dado
t_carga();
if(nib&0x02)DB54=1; else DB54=0;//testa bit 1
if(nib&0x08)DB76=1; else DB76=0;//testa bit 3
clk();//clock
}
/*******************************************************************************
ENVIA DADOS PARA O LCD
*******************************************************************************/
void env_lcd_d(unsigned int8 dado){
RS=1;//indica que enviar� 'dados'
env_nible(dado>>4);//high nibble primeiro
env_nible(dado);//low nibble
delay_ms(4);//delay
}
/*******************************************************************************
ENVIA COMANDOS PARA LCD
*******************************************************************************/
void env_lcd_c(unsigned int8 comando){
RS=0;//indica que enviar� 'comandos'
env_nible(comando>>4);//high nibble primeiro
env_nible(comando);//low nibble
delay_ms(4);//delay
}
/*******************************************************************************
INICIALIZA��O DO LCD
*******************************************************************************/
void Lcd_Init(){
unsigned int8 a;
descarregar();//descarrega capacitores
RS=0; //enviar� comando
delay_ms(40);//delay inicial
for(a=0;a<3;a++) { env_nible(3);delay_ms(5);}//envia 3x 0x03
env_nible(2);//envia 0x02
delay_ms(5);//delay 5 ms
env_lcd_c(0x28);//ajusta para 4 bits o modo de envio
env_lcd_c(0x06);// no shift
env_lcd_c(0x0c);//Display ON, Cursor OFF, Blink OFF
env_lcd_c(0x01);//limpa tela
}
/*******************************************************************************
MOSTRA NO LCD A LEITURA PROCESSADA
*******************************************************************************/
void mostra_res(){
unsigned int1 zesq=0;
if(!dmilh){dmilh=240;}else{ zesq=1;}//apaga zeros a esquerda
env_lcd_d(dmilh+'0');//envia dezena de milhar
if(!umilh&&!zesq){umilh=240;}else{ zesq=1;}
env_lcd_d(umilh+'0');//envia milhar
if(!cent&&!zesq){cent=240;}else{ zesq=1;}
env_lcd_d(cent+'0');//envia centena
if(!dez&&!zesq){dez=240;}else{zesq=1;}
env_lcd_d(dez+'0');//envia dezena
env_lcd_d(un+'0');//envia unidade
env_lcd_d(' ');//espa�o
}
/*******************************************************************************
CONVERTE DE HEXA PARA DECIMAL
*******************************************************************************/
void converte_res(){
dmilh=res/10000;//obt�m dezena de milhar
res=res%10000;//coloca o resto da conta acima
umilh=res/1000;//obtem a unidade de milhar
res=res%1000;//coloca o resto da conta acima
cent= res/100;//obtem a centena
res=res%100;//coloca o resto da conta acima
dez=res/10;//obtem a dezena
un=res%10;//coloca o resto da conta acima (obtem a unidade)
}
/*******************************************************************************
ROTINA DE AGUARDO DE MUNDAN�A SUPERVISIONADA
*******************************************************************************/
void enquanto_in_low(){//testa mudan�a no pino de entrada de sinal
time_out=0;//zera contador de time_out
while(!in&!f_out){time_out++; if(time_out>time_max)f_out=1;}//testa mudan�a
}
/*******************************************************************************
ROTINA DE AGUARDO DE MUNDAN�A SUPERVISIONADA
*******************************************************************************/
void enquanto_in_high(){//testa mudan�a no pino de entrada de sinal
time_out=0;//zera contador de time_out
while(in&!f_out){time_out++; if(time_out>time_max)f_out=1;}//testa mudan�a
}
/*******************************************************************************
ROTINA MAIN
*******************************************************************************/
void main() {
setup_adc_ports(NO_ANALOGS|VSS_VDD);//libera portas
setup_adc(ADC_OFF);//desliga conversor anal�gico/digital
setup_timer_0 (RTCC_DIV_1|RTCC_INTERNAL);//n�o usado
setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_8 );//timer 1 com prescaller/8
setup_vref(FALSE);//desliga vref
cmcon=7;//desliga comparador interno
trisio=0b111000;//ajusta entradas e sa�das
gpio=0;//zera tudo
descarregar();//descarga dos capacitores do Lariosplex
Lcd_Init();//inicializa Lcd
printf(env_lcd_d,"Tiny Tachometer");//mostra o nome
env_lcd_c(0xc0);//linha 2
printf(env_lcd_d,"Larios.Tecnol.Ws");// o blog
delay_ms(2000);//tempo de apresenta��o do nome no LCD
env_lcd_c(1);//apaga tela
env_lcd_c(0x80);//linha 1
printf(env_lcd_d,"Tiny Tachometer");//mostra o nome
env_lcd_c(0xc6); // 6� posic�o da linha 2
printf(env_lcd_d,"0 rpm" );//zeragem inicial
/*******************************************************************************
LOOP PRINCIPAL DE REPETI��O
*******************************************************************************/
for(;;){
/*******************************************************************************
ROTINA DE OPERA��O DO TACOMETRO (METODO: LEITURA DO PERIODO)
*******************************************************************************/
t1on=0;//desliga timer 1
set_timer1(0); //zera
t1if=0; //apaga flag de over flow tmr1
f_out=0;//reseta flag de time_out (seta se sinal na entrada for inexistente)
enquanto_in_low();//sincroniza
t1on=1;
enquanto_in_high();//sincroniza
enquanto_in_low();//sincroniza
t1on=0;//desliga timer 1
delay_us(5);
if(!f_out){//n�o houve falta de sinal na entrada
soma=get_timer1();
if(t1if) soma=soma+65535;
soma=soma*8;//corrige por causa do prescaller ter dividido por 8
soma=60000000/soma;//obtem o inverso do periodo (ou seja, a frequencia)
res=soma;//obt�m o valor da leitura
}
else{
res=0; //houve falta de sinal na entrada, zera ent�o o resultado
}
converte_res();// ajusta para decimal
//envia resultado para lcd
env_lcd_c(0xc2); // 3� posic�o da linha 2
mostra_res(); //mostra resultado no LCD
printf(env_lcd_d," rpm" );//envia 'rpm'
if(!f_out)delay_ms(250);//delay entre leituras para apresenta��o no LCD
enquanto_in_low();//sincroniza
enquanto_in_high();//sincroniza
}//for(;;)
}//void main() 
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment