📄 tarea 2.c
字号:
/*
Tarea 2
Medidor de distancia
Presentado por:
Raymundo Yamamoto
2004-0081
*/
//Agregando librerias
#include <mega16.h>
#include <delay.h>
#include <stdio.h>
//Definiendo variables de salida
#define LCD_DATA PORTA
#define LCD_E PORTD.6
#define LCD_RS PORTD.4
//Funcion para retrasar
void lcd_busy()
{
delay_ms(5); //Esperando 5 ms
}
//Funcion necesaria para escribir la LCD
void lcd_wr_ir(unsigned char cmd)
{
LCD_E = 0; //PORTD.6=0
lcd_busy(); //esperando
LCD_RS = 0; //data register
LCD_DATA = cmd; //MSN
LCD_E = 1; //PORTD.6=1
LCD_E = 0; //PORTD.6=0
delay_us(200); //esperando
LCD_DATA = cmd << 4; //LSN
LCD_E = 1; //PORTD.6=1
LCD_E = 0; //PORTD.6=0
delay_us(200); //esperando
}
//Funcion necesaria para escrbir la LCD
void lcd_wr_dr(unsigned char cmd)
{
LCD_E = 0; //PORTD.6=0
lcd_busy(); //esperando
LCD_RS = 1; //data register
LCD_DATA = cmd; //MSN
LCD_E = 1; //PORTD.6=1
LCD_E = 0; //PORTD.6=0
delay_us(200); //esperando
LCD_DATA = cmd << 4; //LSN
LCD_E = 1; //PORTD.6=1
LCD_E = 0; //PORTD.6=0
delay_us(200); //esperando
}
//Funcion necesaria para escribir la LCD
void lcd_int()
{
// esto configura lost puertos para poder conectar la LCD
DDRA = (DDRA & 0x0F)| 0xf0; //los 4 msb tienen son el puerto de datos
DDRD.4 = 1; //Register select
DDRD.6 = 1; //Enable de la LCD
//-------------------------------------------------------------------
LCD_RS = 0; //por alguna razon
LCD_DATA = 0x30; //hay que hacer esto
LCD_E = 1; //para ponder poner la lcd en modo de 4bits
LCD_E = 0;
delay_ms(5);
LCD_DATA = 0x30;
LCD_E = 1;
LCD_E = 0;
delay_ms(5);
LCD_DATA = 0x30;
LCD_E = 1;
LCD_E = 0;
delay_ms(5);
LCD_DATA = 0x20;
LCD_E = 1;
LCD_E = 0;
delay_ms(5);
//-----------------------------------------------------------------
lcd_wr_ir(0b00101000); // interfaz 4bits, 1 linea, font 5x7
lcd_wr_ir(0b00101000); // interfaz 4bits, 1 linea, font 5x7
lcd_wr_ir(0b00101000); // interfaz 4bits, 1 linea, font 5x7
lcd_wr_ir(0b00000110); // lcd on, cursor on, blink on
lcd_wr_ir(0b00001111); // mueve cur. /c escr., pantalla quieta
lcd_wr_ir(0b00000001); // cursor a home.
}
//Definiendo PUTCHAR diferente
#define _ALTERNATE_PUTCHAR_
void putchar(char c)
{
lcd_wr_dr(c); //Escribiendo en la LCD
}
//Funcion para imprimir en la LCD
void lcd_puts(flash unsigned char *s)
{
while (*s != '\0') //repetir hasta que se encuentre el fin de cadena
lcd_wr_dr(*s++); //escr. dato a la lcd y cambiar la dir apuntada
}
//Funcion para regresar cursor al inicio
void lcd_home()
{
lcd_wr_ir(0b00000001); // cursor a home.
}
unsigned int leer=1; //Esta variable sirve para controlar cuando se
//desea una lectura
//Interrupcion para indicar lectura
interrupt [EXT_INT1] void leer_dist()
{
leer=0; //Activar lectura
}
//Programa principal
void main()
{
/*
Declarando variables y tablas a usar
*/
unsigned int a;
unsigned char dist[]={30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,105,110,115,120,125,130,135,140,
145,150,155,160,165,170,175,180,185,190,195,200,210,220,230,240,250,260,270,280,300,310};
unsigned char adc[]={158,158,148,136,126,113,106,99,92,85,81,77,73,69,66,62,60,59,55,54,52,50,49,48,
47,45,43,42,40,39,38,37,36,35,34,33,32,31,30,29,28,27,26,25,24};
unsigned int i;
unsigned int i1;
unsigned int i2;
signed int y1;
signed int y2;
signed int x1;
signed int x2;
signed int y;
signed int x;
delay_ms(50); //esperando
lcd_int(); //Inicializando LCD
DDRA.0 = 0; // PORTA.0 de entrada
DDRD.3 &= 0b11110111; // PORTD.3 de entrada
MCUCR |= 0b00001100; // Flanco positivo
GICR |= 0b10000000; // INT 1 on
SREG |= 0b10000000; // Interrupciones on
ADMUX = 0b00100000; // Vref = AVCC, Left Just, single ended adc0 selected.
ADCSRA.7 = 1; // Enable ADC
ADCSRA.5 = 0; // Auto-trigger disable.
ADCSRA.3 = 0; // ADC interrupt disabled
// ADC prescaler set to 1/128
ADCSRA = (ADCSRA &0xF8) | 0x07;
while(1)
{
while(leer); //Esperando senal para comenzar
ADCSRA.6 = 1; //Comenzar conversion ADC
while (ADCSRA.6); //Esperando fin de conversion
ADCSRA.4 = 1; //Clear interrupt
lcd_home(); //Borrando LCD
a = ADCH; //Leer dato del ADC
i1=0; //Iniciando contador i1 en cero
i2=1; //Iniciando contador i2 en uno
//Comprovando si el numero esta entre el rango de interpolacion
if((24<=a)&&(a<=158))
{
//Si es esta, comezar interpolacion
//Seleccionando intervalo de interpolacion
for(i=0;!((adc[i1]>=a)&&(a>=adc[i2]));i++)
{
i1++; //incrementando contador i1
i2++; //incrementando contador i2
}
y1=dist[i1]; //y1 es la distancia en posicion de contador i1
y2=dist[i2]; //y2 es la distancia en posicion de contador i2
x1=adc[i1]; //x1 es el numero convertido del ADC en y1
x2=adc[i2]; //x2 es el numero convertido del ADC en y2
x=a; //x es la lectura del ADC
y2=(y2-y1)*1000; //Diferencia entre y2 y y1
//Esta se multiplica por 1000 para evitar
//que la variable tome el valor de cero
x2=(x2-x1); //Diferencia entre x2 y x1
x=(x-x1); //Diferencia entre x y x1
y2=(y2/x2); //Dividir y2 entre x2
y2=(y2*x); //Dividir y2 entre x
y2=(y2/1000); //Dividir y2 entre 1000
//Esta division se realiza para contrarestar
//el efecto de multiplicacion realizado
y=(y1+y2); //Resultado de los calculos
a=y; //Copiando valor de y en a
y=y/10; //Obteniendo parte entera de la medida
a=a%10; //Obteniendo parte fraccionaria de la medida
//Imprimiendo resultado en la LCD
printf("%d.%d Pulg.",y,a);
}
//Si no esta en el rango, no puede medir
else
{
//Imprimiendo error en la LCD
printf("FUERA DE RANGO");
}
leer=1; //Desactivando lectura
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -