#include <avr/io.h>
#define F_CPU 16000000UL
#include <util/delay.h>
#include <avr/interrupt.h>
#include <util/delay_basic.h>
void inicializar_puertos(void);
void reset(void);
void i2c_MT(unsigned char direccion, unsigned char dato);
unsigned char i2c_MR(unsigned char direccion);
void i2c_error(void);
volatile unsigned char r_estado=0x02;
volatile unsigned char comunicaciones=0;
volatile unsigned int encoder0;
volatile unsigned int encoder1;
volatile unsigned char baterial;
volatile unsigned char bateriah;
volatile unsigned char direccionl;
volatile unsigned char direccionh;
volatile unsigned char sensoresd;
volatile unsigned char sensoresi;
volatile unsigned char posicion;
volatile unsigned char velocidad;
int main(void)
{
inicializar_puertos();
reset();
while(1)
{
if(comunicaciones != 0)
{
comunicaciones=0;
//***//
posicion=i2c_MR(0xE2);
_delay_us(20);
velocidad=i2c_MR(0xE2);
_delay_us(20);
//***//
r_estado=i2c_MR(0xE2);
_delay_us(20);
i2c_MT(0xE2, baterial);
_delay_us(20);
i2c_MT(0xE2, bateriah);
_delay_us(20);
i2c_MT(0xE2, direccionl);
_delay_us(20);
i2c_MT(0xE2, direccionh);
_delay_us(20);
i2c_MT(0xE2, sensoresd);
_delay_us(20);
i2c_MT(0xE2, sensoresi);
_delay_us(20);
i2c_MT(0xE2, (char)encoder0);
_delay_us(20);
i2c_MT(0xE2, (char)encoder1);
_delay_us(20);
i2c_MT(0xE2, r_estado);
}
if((r_estado&0x01)!=0)
PORTD |= (1<<PORTD5);
else
PORTD &= ~(1<<PORTD5);
if((r_estado&0x02)!=0)
PORTD |= (1<<PORTD4);
else
PORTD &= ~(1<<PORTD4);
if((r_estado&0x04)!=0)
PORTD |= (1<<PORTD3);
else
PORTD &= ~(1<<PORTD3);
}
}
void reset(void)
{
cli();
PORTD |= ((1<<PORTD3)|(1<<PORTD4)|(1<<PORTD5));
_delay_ms(250);
PORTD &= ~((1<<PORTD3)|(1<<PORTD4)|(1<<PORTD5));
_delay_ms(250);
PORTD |= ((1<<PORTD3)|(1<<PORTD4)|(1<<PORTD5));
_delay_ms(250);
PORTD &= ~((1<<PORTD3)|(1<<PORTD4)|(1<<PORTD5));
_delay_ms(250);
PORTD |= ((1<<PORTD3)|(1<<PORTD4)|(1<<PORTD5));
_delay_ms(250);
PORTD &= ~((1<<PORTD3)|(1<<PORTD4)|(1<<PORTD5));
_delay_ms(250);
sei();
}
void inicializar_puertos(void)
{
DDRD |= ((1<<PD2)|(1<<PD3)|(1<<PD4)|(1<<PD5)); //Salidas
//Configurar Timer2. Tic 5.33 ms.
OCR2 = 0x52; //0x52
TCCR2 |=((1<<WGM21)|(1<<CS22)|(1<<CS21)|(1<<CS20));
TIMSK |= (1<<OCIE2);
sei();
//Inicializar I2C.
TWBR = 0b01001111; //Período SCL 11 us
//Inicializar ADC
//Free Running Mode, por defecto seleccionado
ADCSRA |=
((1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0));
//Prescaler 128, Fadc 125 KHz @ 16MHz.
ADCSRA |= (1<<ADATE);
// ADMUX |= (1<<ADLAR);
//8 bits.
ADCSRA |= (1<<ADEN);
//Enable
ADC
ADCSRA |= (1<<ADSC);
//Comenzar conversiones.
//Inicializar timers encoders.
TCCR0
|=((1<<CS02)|(1<<CS01)|(1<<CS00));
//Normal Mode y reloj externo flanco de subida.
TCCR1B
|=((1<<CS12)|(1<<CS11)|(1<<CS10));
//Normal Mode y reloj externo flanco de
subida.
}
ISR(TIMER2_COMP_vect)
{
static unsigned char cont;
unsigned int copia_posicion;
unsigned int copia_velocidad;
unsigned char cuenta0_actual;
static unsigned char cuenta0_old;
static unsigned char contador_encoders;
static unsigned int suma_cuenta0;
unsigned int cuenta1_actual;
static unsigned int cuenta1_old;
static unsigned int suma_cuenta1;
// unsigned int suma_adc_alto = 0; //
// unsigned int suma_adc_bajo = 0; //
cont++;
switch(cont)
{
case 1: //Generar señal de control
{
comunicaciones=0;
copia_posicion=posicion*16;
copia_velocidad=velocidad*16;
PORTD |=(1<<PORTD2);
_delay_us(400);
PORTD &= ~(1<<PORTD2);
_delay_loop_2(2400+copia_posicion);
//4000 = 1ms.
PORTD|=(1<<PORTD2);
_delay_us(400);
PORTD&= ~(1<<PORTD2);
_delay_loop_2(2400+copia_velocidad);
PORTD|=(1<<PORTD2);
_delay_us(420);
PORTD&= ~(1<<PORTD2);
ADCSRA |= (1<<ADEN);
ADCSRA |= (1<<ADSC);
_delay_us(350);
baterial=ADCL;
//Lectura ADC Batería.
bateriah=ADCH;
ADCSRA &= ~(1<<ADEN);
ADMUX &= ~(1<<MUX0); //Se
selecciona ADC para la dirección.
/* PORTD |=(1<<PORTD2);
_delay_ms(2);
PORTD &= ~(1<<PORTD2);*/
}break;
case 2: //Comunicaciones, leer ADC batería.
{
comunicaciones=1;
}break;
case 3:
//Leer ADC, Encoders, Errores, Establecer
variable.
{
comunicaciones=0;
cont=0;
//*********************************//Lectura ADC dirección.
ADCSRA |= (1<<ADEN);
ADCSRA |= (1<<ADSC);
_delay_us(350);
direccionl=ADCL;
direccionh=ADCH;
ADCSRA &= ~(1<<ADEN);
ADMUX |= (1<<MUX0); //Se selecciona
ADC para la batería.
/* ADCSRA |= (1<<ADEN);
ADCSRA |= (1<<ADSC);
_delay_us(350);
suma_adc_bajo
= suma_adc_bajo + ADCL;
suma_adc_alto = suma_adc_alto + ADCH;
_delay_us(350);
suma_adc_bajo
= suma_adc_bajo + ADCL;
suma_adc_alto = suma_adc_alto + ADCH;
_delay_us(350);
suma_adc_bajo
= suma_adc_bajo + ADCL;
suma_adc_alto = suma_adc_alto + ADCH;
_delay_us(350);
suma_adc_bajo
= suma_adc_bajo + ADCL;
suma_adc_alto = suma_adc_alto + ADCH;
suma_adc_bajo = suma_adc_bajo/4;
suma_adc_alto = suma_adc_alto/4;
direccionl = (char)suma_adc_bajo;
direccionh = (char)suma_adc_alto;*/
//Se
leen los encoders
//Encoder 0, 8 bits.
cuenta0_actual=TCNT0;
if
(cuenta0_actual>cuenta0_old)
suma_cuenta0 = suma_cuenta0 + cuenta0_actual -
cuenta0_old;
else if(cuenta0_actual<cuenta0_old)
suma_cuenta0 = suma_cuenta0 + 256 + cuenta0_actual - cuenta0_old;
cuenta0_old=TCNT0;
cuenta1_actual=TCNT1;
if
(cuenta1_actual>cuenta1_old)
suma_cuenta1 = suma_cuenta1 + cuenta1_actual -
cuenta1_old;
else if(cuenta0_actual<cuenta0_old)
suma_cuenta1 = suma_cuenta1 + 1024 + cuenta1_actual - cuenta1_old;
cuenta1_old=TCNT1;
contador_encoders++;
if(contador_encoders>20)
{
encoder0 = suma_cuenta0;
encoder1 = suma_cuenta1;
suma_cuenta0 = 0;
suma_cuenta1 = 0;
contador_encoders = 0;
}
//Leer sensores;
sensoresi = PINC;
sensoresd =
PINA;
}break;
}
TIFR |= (1<<OCF2);
}
void i2c_MT(unsigned char direccion, unsigned char dato)
{
TWCR |=
(1<<TWEA);
//Se enciende el módulo
TWCR &=
~(1<<TWSTO);
//enviar señal de start.
TWCR |= ((1<<TWINT)|(1<<TWSTA)|(1<<TWEN));
while (!(TWCR &
(1<<TWINT)))
//Esperar a TWINT
{
if(comunicaciones!=0)
break;
}
//comprobar resultado de la operación anterior.
if ((TWSR & 0xF8) !=
0x08)
//(xxxxx000) != (0x08 Start)
i2c_error();
TWDR =
((direccion)&(0b11111110));
//Enviar dirección y escritura
TWCR &= ~((1<<TWSTO)|(1<<TWSTA));
TWCR |= ((1<<TWINT)|(1<<TWEN));
while (!(TWCR &
(1<<TWINT)))
//Esperar a TWINT
{
if(comunicaciones!=0)
break;
}
//comprobar condición.
if ((TWSR & 0xF8) !=
0x18)
//(xxxxx000) != (0x18 SLA +W)
i2c_error();
TWDR =
dato;
//Cargar byte a enviar
TWCR &= ~((1<<TWSTO)|(1<<TWSTA));
TWCR |= ((1<<TWINT)|(1<<TWEN));
while (!(TWCR & (1<<TWINT)))
//Esperar a TWINT
{
if(comunicaciones!=0)
break;
}
//comprobar condición.
if ((TWSR & 0xF8) !=
0x28)
//(xxxxx000) != (0x28 dato+ack)
i2c_error();
TWCR &=
~(1<<TWSTA);
//enviar señal de stop.
TWCR |= ((1<<TWINT)|(1<<TWEN)|(1<<TWSTO));
_delay_us(20);
}
unsigned char i2c_MR(unsigned char direccion)
{
unsigned char dato=0;
TWCR |= (1<<TWEA);
TWCR &=
~(1<<TWSTO);
//enviar señal de start.
TWCR |= ((1<<TWINT)|(1<<TWSTA)|(1<<TWEN));
while (!(TWCR & (1<<TWINT))) //Esperar a TWINT
{
if(comunicaciones!=0)
break;
}
//comprobar resultado de la operación
anterior.
if ((TWSR & 0xF8) !=
0x08)
//(xxxxx000) != (0x08 Start)
i2c_error();
//enviar byte.
TWDR = ((direccion)|(0b00000001)); //Cargar byte de dirección
TWCR &= ~((1<<TWSTO)|(1<<TWSTA));
TWCR |= ((1<<TWINT)|(1<<TWEN));
while (!(TWCR & (1<<TWINT))) //Esperar a TWINT
{
if(comunicaciones!=0)
break;
}
//comprobar condición.
if ((TWSR & 0xF8) !=
0x40)
//(xxxxx000) != (0x40 SLA +R)
i2c_error();
TWCR &= ~((1<<TWSTO)|(1<<TWSTA)|(1<<TWEA));//Leer segundo byte NO ACK
TWCR |= ((1<<TWINT)|(1<<TWEN));
while (!(TWCR & (1<<TWINT))) //Esperar a TWINT
{
if(comunicaciones!=0)
break;
}
if ((TWSR & 0xF8) !=
0x58)
//(xxxxx000) != (0x58 dato+ no ack)
i2c_error();
dato=TWDR;
TWCR &=
~(1<<TWSTA);
//enviar señal de stop.
TWCR |= ((1<<TWEA)|(1<<TWINT)|(1<<TWEN)|(1<<TWSTO));
_delay_us(20);
return(dato);
}
void i2c_error(void)
{
}