#include <avr/io.h>
#define F_CPU 16000000UL
#include <util/delay.h>
#include <avr/interrupt.h>
#define Bus_Datos PORTK
#define Bus_Control PORTF
#define RS PORTF5
#define RW PORTF6
#define E PORTF7
//Inicializar timers
void inicializar_timer4(void);
void inicializar_timer0(void);
//Comandos para situar el cursor en inicio de líneas.
#define DDRA_LINEA1 0x80 //1000 0000
#define DDRA_LINEA2 0xC0 //1100 0000
#define DDRA_LINEA3 0x94 //1001 0100
#define DDRA_LINEA4 0xD4 //1101 0100
void inicializar();
//Funciones para escribir en el LCD
void lcd_inicializar();
void lcd_escribir_c(char caracter);
void lcd_escribir(char *cadena);
void posicionar_cursor(unsigned char x, unsigned char y);
void lcd_comando(unsigned char comando);
void escribir_valor_decimal(unsigned int registro);
void escribir_espacio(unsigned long int registro);
/***************** VARIABLES ***********************/
volatile unsigned int cuenta;
volatile unsigned int cuenta_old;
volatile unsigned char contador;
volatile unsigned int suma_cuenta;
volatile unsigned long int espacio;
int main(void)
{
inicializar();
lcd_inicializar();
inicializar_timer4();
inicializar_timer0();
char linea1[]="www.jmnlab.com"; //Poner en la Flash de programa las cadenas.
char linea2[]="Contar los pulsos";
char linea3[]="de un encoder";
char linea4[]="Pulsos/seg:";
char linea5[]="Velocidad:";
char linea6[]="Espacio:";
char linea7[]="***Encoders MiniZ***";
posicionar_cursor(1,4);
lcd_escribir(linea1);
posicionar_cursor(3,3);
lcd_escribir(linea2);
posicionar_cursor(4,4);
lcd_escribir(linea3);
_delay_ms(3000);
lcd_comando(0x01);
posicionar_cursor(1,1);
lcd_escribir(linea7);
posicionar_cursor(2,1);
lcd_escribir(linea4);
posicionar_cursor(3,1);
lcd_escribir(linea5);
posicionar_cursor(4,1);
lcd_escribir(linea6);
posicionar_cursor(3,17);
lcd_escribir_c('m');
lcd_escribir_c('m');
lcd_escribir_c('/');
lcd_escribir_c('s');
posicionar_cursor(4,17);
lcd_escribir_c('m');
unsigned int suma_cuenta_local=0;
unsigned int velocidad=0;
while(1)
{
if(contador>62)
{
suma_cuenta_local=suma_cuenta;
contador=0;
suma_cuenta=0;
posicionar_cursor(2,13);
escribir_valor_decimal(suma_cuenta_local);
velocidad= suma_cuenta_local*12;
posicionar_cursor(3,12);
escribir_valor_decimal(velocidad);
espacio= espacio + (unsigned long int)suma_cuenta_local*12036;
posicionar_cursor(4,10);
escribir_espacio(espacio);
}
}
}
void inicializar() //Configurar hardware del pic.
{
DDRK=0xFF; //1111 1111
PORTK=0x00;
DDRF|=((1<<RS)|(1<<RW)|(1<<E)); //1110 0000
PORTF &= ~(1<<E);
}
/*************************************************************************/
void lcd_inicializar() //Se mandan los comandos de configuración según el dibujo.
{
_delay_ms(100);
lcd_comando(0x3C); //Function Set RS0 RW0 0011NF** 0011 1100
lcd_comando(0x3C); //Function Set
lcd_comando(0x0C); //Display ON/OFF Control RS0 RW0 00001DCB 0000 1100
lcd_comando(0x01); //Display Clear RS0 RW0 00000001
lcd_comando(0x06); //Entry Mode Set RS0 RW0 000001I/DS 0000 0110
}
void lcd_escribir_c(char caracter)
{
Bus_Control |= (1<<RS); //RS1 Dato
Bus_Control &= ~(1<<RW); //RS0
Bus_Datos = caracter;
Bus_Control |= (1<<E);
_delay_us(100);
Bus_Control &= ~(1<<E);
_delay_ms(10);
}
void lcd_comando(unsigned char comando)
{
Bus_Control &= ~(1<<RS); //RS0 Comando
Bus_Control &= ~(1<<RW); //RW0
Bus_Datos = comando; //Comando
Bus_Control |= (1<<E);
_delay_us(100);
Bus_Control &= ~(1<<E);
_delay_ms(10);
}
void lcd_escribir(char *cadena)
{
char *inicio = cadena;
unsigned char i=0;
for(i=0;((inicio[i]!='\0')&&(i<20));i++)
{
Bus_Control |= (1<<RS); //RS0 RW0 caracter
Bus_Control &= ~(1<<RW);
Bus_Datos = inicio[i];
Bus_Control |= (1<<E);
_delay_us(100);
Bus_Control &= ~(1<<E);
_delay_ms(3);
}
}
void posicionar_cursor(unsigned char x, unsigned char y) //línea x 1 a 4, carácter y de 1 a 20.
{
unsigned char comando=DDRA_LINEA1;
switch(x)
{
case 1:
{
comando=DDRA_LINEA1+y-1;
}break;
case 2:
{
comando=DDRA_LINEA2+y-1;
}break;
case 3:
{
comando=DDRA_LINEA3+y-1;
}break;
case 4:
{
comando=DDRA_LINEA4+y-1;
}break;
default:break;
}
lcd_comando(comando);
}
/****************************************************************************************************/
void inicializar_timer4(void) //Configura el timer y la interrupción.
{
// DDRA |= (1<<PA7); //Puerto A7 pin osciloscopio
OCR4A= 0x0F9F;
TCCR4B
|=((1<<WGM42)|(1<<CS41)|(1<<CS40));
//Los bits que no se tocan a 0 por defecto
TIMSK4 |= (1<<OCIE4A);
sei();
}
void inicializar_timer0(void)
{
TCCR0B
|=((1<<CS02)|(1<<CS01)|(1<<CS00));
//Normal Mode y reloj externo flanco de subida
}
/***************************************************************************************************/
ISR(TIMER4_COMPA_vect)
{
unsigned int cuenta_actual=TCNT0;
if (cuenta_actual>cuenta_old)
{
cuenta=cuenta_actual-cuenta_old;
suma_cuenta=suma_cuenta+cuenta;
}
else if(cuenta_actual<cuenta_old)
{
cuenta=256+cuenta_actual-cuenta_old;
suma_cuenta=suma_cuenta+cuenta;
}
cuenta_old=TCNT0;
contador++;
TIFR4 |= (1<<OCF4A);
}
/************************* Escribir registros *****************************************************/
void escribir_valor_decimal(unsigned int registro) //Escribir binario a decimal.
{
char miles=0;
char centenas = 0;
char decenas = 0;
char unidades = 0;
while(registro>=1000)
{
registro= registro -1000;
miles++;
}
while(registro>=100)
{
registro= registro -100;
centenas++;
}
while(registro>=10)
{
registro=registro -10;
decenas++;
}
while(registro>0)
{
registro=registro-1;
unidades++;
}
lcd_escribir_c(miles | 0b00110000);
lcd_escribir_c(centenas | 0b00110000);
lcd_escribir_c(decenas | 0b00110000);
lcd_escribir_c(unidades | 0b00110000);
}
void escribir_espacio(unsigned long int registro)
{
char miles=0;
char centenas = 0;
char decenas = 0;
char unidades = 0;
char decena_cm=0;
while(registro>=1000000000)
{
registro= registro -1000000000;
miles++;
}
while(registro>=100000000)
{
registro= registro -100000000;
centenas++;
}
while(registro>=10000000)
{
registro= registro -10000000;
decenas++;
}
while(registro>=1000000)
{
registro= registro -1000000;
unidades++;
}
while(registro>=100000)
{
registro= registro -100000;
decena_cm++;
}
lcd_escribir_c(miles | 0b00110000);
lcd_escribir_c(centenas | 0b00110000);
lcd_escribir_c(decenas | 0b00110000);
lcd_escribir_c(unidades | 0b00110000);
lcd_escribir_c('.');
lcd_escribir_c(decena_cm | 0b00110000);
}