desarrollo de una unidad de adquisición y monitorización de datos

Anuncio
Volumen III
Anexos
DESARROLLO DE UNA UNIDAD
DE ADQUISICIÓN Y
MONITORIZACIÓN DE DATOS
PARA UN VEHICULO DE
AUTOMOCIÓN
TFG presentado para optar al título de GRADO en
INGENIERÍA ELECTRÓNICA INDUSTRIAL Y
AUTOMÁTICA
por Daniel Bassons González, Marc Mestre
López
Barcelona, 11 de Enero de 2016
Director: Manuel Manzanares Brotons
Departamento de EEL (D710)
Universitat Politècnica de Catalunya (UPC)
Tabla de contenido de anexos
1. PROGRAMACIÓN DEL PROTOTIPO ...............................................................................2
2. LIBRERIA RELOJ EN TIEMPO REAL ..............................................................................17
Desarrollo de una unidad de adquisición y monitorización de datos
para un vehículo de automoción
Capítulo 1
Programación del prototipo
#include <18F46j50.h>
#device adc=10
#fuses NOWDT
#fuses HS
// No Watch Dog Timer
// High speed clock
#use delay(clock=16M)
#include <DS1307.c>
#include <24256.c>
#include <LCD.C>
#include <math.h>
// Libreria para calculos matematicos
#include <stddef.h>
// Libreria para asignar tamaños
#include <stdlib.h>
// Libreria reloj interno real
// Libreria eeprom 256kb
// Libreria del display lcd
// Libreria para gestion de memoria
#define led_alert PIN_B3
// Led rojo para saber si la salida esta fuera del rango de trabajo
#define led_start PIN_C2
// Led verde parpadeo cuando lee datos de los sensores
#define led_power_on PIN_A5
// Led verde alimentacion
#define led_parp PIN_A3
// Led amarillo, parpadea cuando el USB o el reset de eeprom esta
funcionando
#define led_on output_high
// Led encendido
#define led_off output_low
// Led apagado
#use i2c(master, sda=RTC_SDA, scl=RTC_SCL)
// Asigna los pines del bus I2C
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
// Asigna los pines del puerto serie
float
rpm_out,ntc_temp,CO2_adc,CO2_out,map_consm,spd_out,data,out=0,tiempo=0
;
float
epp_rpm=0,epp_ntc=0,epp_CO2=0,epp_consm=0,epp_spd=0,epp_tiempo=0;
int32 segundos_total=0;
int16
n=0,t=4,p=0,m=0,point=0,z=0,k=0,y=0,usb_start=0,usb_count=0,led_count=
0,lcd_count;
int16
2
Desarrollo de una unidad de adquisición y monitorización de datos
para un vehículo de automoción
rpm_count=0,spd_count=0,rpm_cntd=0,rpm_vueltas=0,lcd_but=0,lcd_cntd=1,
start=0,CO2_in=0;
int16
spd_cntd=0,eeprom_count=0,main_count=0,spd_vueltas=0,eeprom_reset=0,fe
cha_count=0,ntc_in=0;
int8 lcd_flag=0,spd_flag=0,rpm_flag=0,flag_reset=0,flag_usb=0;
int8
day,mth,interv=0,year,dow,hora,minuto,segundo,hr,min,sec,erase=0xFF;
void
void
void
void
void
void
void
NTC();
CO2();
SPD();
RPM();
MAP();
USB();
R232();
void usb_wait_for_enumeration();
void write_float_ext_eeprom(int16 m, float data);
void read_float_ext_eeprom(int16 t);
void write_point_ext_eeprom(int16 n, int16 p);
void read_point_ext_eeprom(int16 k);
void write_erase_ext_eeprom(int16 z, float erase);
#int_rtcc
void clock_isr()
// Interrupcion del timer 0
{
++main_count;
// 10 counts en 1s
++led_count;
++eeprom_count;
++rpm_count;
++spd_count;
++usb_count;
++lcd_count;
++fecha_count;
set_timer0(15535);
//0.25^-6(4/Fosc)*prescaler(8)*(65535-15535)= 0.1s = 10 ticks/s
}
void read_point_ext_eeprom(int16 k)
{
int i;
for (i = 0; i < 4; i++)
{
*((int8*)&point + i) = read_ext_eeprom(i + k);
delay_us(20);
}
}
void write_point_ext_eeprom(int16 n, int16 p)
{
int i;
for (i = 0; i < 4; i++)
{
write_ext_eeprom(i + n, *((int8*)&p + i) );
3
Desarrollo de una unidad de adquisición y monitorización de datos
para un vehículo de automoción
delay_us(20);
}
}
void read_float_ext_eeprom(int16 t)
{
int16 i;
for (i = 0; i < 4; i++)
{
*((int8*)&out + i) = read_ext_eeprom(i + t);
delay_us(20);
}
}
void write_float_ext_eeprom(int16 m, float data)
{
int i;
for (i = 0; i < 4; i++)
{
write_ext_eeprom(i + m, *((int8*)&data + i) );
delay_us(20);
}
}
void write_erase_ext_eeprom(int16 z, int8 erase)
{
int16 j;
for (j = 0; j < 1800; j++)
{
write_ext_eeprom(z + j, erase);
// 1680 bytes de borrado para pruebas de 5min
delay_us(20);
y++;
if (led_count<=1)
{
led_on(led_parp);
}
if ((led_count>1)&&(led_count<=2))
{
led_off(led_parp);
}
if ((led_count>2))
{
led_count=0;
}
}
}
void main()
{
setup_adc_ports(sAN0,sAN1|VSS_VDD);
// Configuracion del micro + inicializacion
4
Desarrollo de una unidad de adquisición y monitorización de datos
para un vehículo de automoción
setup_adc(ADC_CLOCK_DIV_16);
setup_spi(SPI_SS_DISABLED);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL | RTCC_DIV_8);
setup_timer_1(T1_INTERNAL | T1_DIV_BY_4);
setup_timer_2(T2_DISABLED,0,1);
setup_ccp1(CCP_OFF);
setup_comparator(NC_NC_NC_NC);
set_timer0(15535);
enable_interrupts(INT_RTCC);
enable_interrupts(GLOBAL);
ds1307_init();
lcd_init();
delay_us(20);
// Configuracion del micro + inicializacion
while (true)
{
delay_us(20);
led_on(led_power_on);
usb_start=input(Pin_D3);
start=input(Pin_C1);
eeprom_reset=input(Pin_C0);
delay_us(20);
if
((start==0)&&(eeprom_reset==0)&&(flag_reset==0)&&(usb_start==0)&&(flag
_usb==0))
// Inicio S.A.D
{
int i,j;
lcd_cntd=1;
led_off(led_start);
led_off(led_parp);
printf(lcd_putc, "\f");
lcd_gotoxy(6,1);
printf(lcd_putc, "S.A.D");
char lcd_ini[32] = "Pulse Start o Reset ";
for (i=16;i>0;i--)
// Movimiento derecha a izquierda hasta x=1
{
lcd_gotoxy(i,2);
printf(lcd_putc,"%s",lcd_ini);
delay_ms(300);
usb_start=input(Pin_D3);
// Leemos cada 50ms para cortar bucle si es necesario
start=input(Pin_C1);
eeprom_reset=input(Pin_C0);
if ((start==1)&&(flag_reset==0)&&(flag_usb==0))
// Condiciones de corte
{
printf(lcd_putc, "\f");
break;
}
if
((start==0)&&(eeprom_reset==1)&&(flag_reset==0)&&(usb_start==0)&&(flag
_usb==0))
{
5
Desarrollo de una unidad de adquisición y monitorización de datos
para un vehículo de automoción
printf(lcd_putc, "\f");
break;
}
if
((start==0)&&(eeprom_reset==0)&&(flag_reset==0)&&(usb_start==1)&&(flag
_usb==0))
{
printf(lcd_putc, "\f");
break;
}
}
for (j=1;j<20;j++)
// Movimiento derecha a izquierda desde x=1
{
lcd_gotoxy(1,2);
printf(lcd_putc,"%s",lcd_ini+j);
delay_ms(300);
usb_start=input(Pin_D3);
// Leemos cada 50ms para cortar bucle si es necesario
start=input(Pin_C1);
eeprom_reset=input(Pin_C0);
if ((start==1)&&(flag_reset==0)&&(flag_usb==0))
// Condiciones de corte
{
printf(lcd_putc, "\f");
break;
}
if
((start==0)&&(eeprom_reset==1)&&(flag_reset==0)&&(usb_start==0)&&(flag
_usb==0))
{
printf(lcd_putc, "\f");
break;
}
if
((start==0)&&(eeprom_reset==0)&&(flag_reset==0)&&(usb_start==1)&&(flag
_usb==0))
{
printf(lcd_putc, "\f");
break;
}
}
}
if
((start==0)&&(eeprom_reset==1)&&(flag_reset==0)&&(usb_start==0)&&(flag
_usb==0))
// Reset eeprom
{
printf(lcd_putc, "\f");
lcd_gotoxy(3,2);
printf(lcd_putc,"Borrando...");
flag_reset=1;
write_erase_ext_eeprom(z,erase);
if (y>=1800)
// 1680 bytes de borrado para pruebas de 5min (5040bytes = 15min)
{
printf(lcd_putc, "\f");
6
Desarrollo de una unidad de adquisición y monitorización de datos
para un vehículo de automoción
lcd_gotoxy(4,2);
printf(lcd_putc,"Listo!");
led_off(led_parp);
delay_ms(1000);
flag_reset=0;
y=0;
}
}
if
((start==0)&&(eeprom_reset==0)&&(flag_reset==0)&&(usb_start==1)&&(flag
_usb==0))
// Habilitar USB o RS232
{
flag_usb=1;
printf(lcd_putc, "\f");
lcd_gotoxy(1,2);
printf(lcd_putc,"Comunicando USB");
usb_count=0;
//USB();
R232();
}
if ((start==1)&&(flag_reset==0)&&(flag_usb==0))
// Funcionamiento datos ON
{
// ADQUISICION DE DATOS
if (main_count<2)
{
NTC();
if (ntc_temp<=300.0)
{
led_off(led_alert);
}
else
led_on(led_alert);
}
if ((main_count>=2)&&(main_count<4))
{
CO2();
if (CO2_out<=10000.0)
{
led_off(led_alert);
}
else
led_on(led_alert);
}
if (main_count==4)
{
spd_count=0;
}
if ((main_count>=4)&&(main_count<25))
{
SPD();
if (spd_out<=250.0)
{
7
Desarrollo de una unidad de adquisición y monitorización de datos
para un vehículo de automoción
led_off(led_alert);
}
else
led_on(led_alert);
}
if (main_count==25)
{
rpm_count=0;
}
if ((main_count>=25)&&(main_count<46))
{
RPM();
if (rpm_out<=8000.0)
{
led_off(led_alert);
}
else
led_on(led_alert);
}
if ((main_count>=46)&&(main_count<48))
{
MAP();
if (map_consm<=30.0)
{
led_off(led_alert);
}
else
led_on(led_alert);
}
if (main_count>=50)
{
main_count=0;
rpm_cntd=0;
rpm_count=0;
spd_cntd=0;
spd_count=0;
}
// Led parpadeo start (adquisicion de datos)
if (led_count<=1)
{
led_on(led_start);
}
if ((led_count>1)&&(led_count<=2))
{
led_off(led_start);
}
if ((led_count>2))
{
led_count=0;
}
// EEPROM Escritura
if (eeprom_count==48)
8
Desarrollo de una unidad de adquisición y monitorización de datos
para un vehículo de automoción
// Write/read puntero, write datos
{
if (p<4)
// Incializacion puntero ( 4 bytes para puntero)
{
p=4;
write_point_ext_eeprom(n,p);
delay_us(5);
}
if ((p>=4)&&(p<1680))
// rango de almacenamiento de las direcciones (5min=300s
// 300s/5s*28bytes = 1680 bytes)
{
delay_us(5);
ds1307_get_time(hr,min,sec);
// lee tiempo actual
tiempo=((hr*3600)+(min*60)+(sec));
// tiempo actual en segundos totales
//
//
//
//
delay_us(5);
read_point_ext_eeprom(k);
lee puntero
m=point;
delay_us(5);
m pasa a ser puntero
write_float_ext_eeprom(m,tiempo);
escribimos temp ntc en eeprom posicion puntero
m=m+4;
cada float ocupa 4 bytes, avanzamos puntero 4 posiciones
delay_us(5);
write_float_ext_eeprom(m,ntc_temp);
m=m+4;
delay_us(5);
write_float_ext_eeprom(m,CO2_out);
m=m+4;
delay_us(5);
write_float_ext_eeprom(m,rpm_out);
m=m+4;
delay_us(5);
write_float_ext_eeprom(m,spd_out);
m=m+4;
delay_us(5);
write_float_ext_eeprom(m,map_consm);
m=m+4;
p=m;
delay_us(5);
write_point_ext_eeprom(n,p);
delay_us(5);
}
}
if (eeprom_count>=50)
{
eeprom_count=0;
}
// reset contador eeprom
// LCD DISPLAY
lcd_but=input(pin_B2);
9
Desarrollo de una unidad de adquisición y monitorización de datos
para un vehículo de automoción
if (lcd_but == 1)
{
lcd_flag=1;
}
// flanco de bajada evitando rebote mecanico
if ((lcd_but == 0)&&(lcd_flag == 1))
bajada evitando rebote mecanico
{
lcd_cntd++;
lcd_flag=0;
printf(lcd_putc, "\f");
}
// lee flanco de
if (lcd_cntd == 1)
{
lcd_gotoxy(6,1);
printf(lcd_putc, "S.A.D");
lcd_gotoxy(3,2);
printf(lcd_putc,"Pulse 'Set'");
fecha_count=0;
while (lcd_but == 1)
{
lcd_but=input(pin_B2);
if (fecha_count==50)
{
day=21;
mth=12;
year=15;
dow=1;
hr=12;
min=0;
sec=0;
ds1307_set_date_time(day,mth,year,dow,hr,min,sec);
lcd_flag=0;
fecha_count=0;
printf(lcd_putc, "\f");
lcd_gotoxy(1,2);
printf(lcd_putc,"Reloj programado");
delay_ms(800);
printf(lcd_putc, "\f");
}
}
}
If (lcd_count>=2)
{
ds1307_get_time(hr,min,sec);
if (lcd_cntd == 2)
{
if (ntc_in <=0)
{
lcd_gotoxy(9,1);
printf(lcd_putc,"%02u:%02u:%02u ",hr,min,sec);
lcd_gotoxy(1,2);
printf(lcd_putc,"T = -- C");
}
else
{
10
Desarrollo de una unidad de adquisición y monitorización de datos
para un vehículo de automoción
lcd_gotoxy(9,1);
printf(lcd_putc,"%02u:%02u:%02u ",hr,min,sec);
lcd_gotoxy(1,2);
printf(lcd_putc,"T = %04.1f C",ntc_temp);
}
}
if (lcd_cntd == 3)
{
if (CO2_adc>1.625)
{
lcd_gotoxy(9,1);
printf(lcd_putc,"%02u:%02u:%02u ",hr,min,sec);
lcd_gotoxy(1,2);
printf(lcd_putc,"CO2 <400 ppm");
}
if ((CO2_adc<=1.625)&&(CO2_adc>=1.325))
{
lcd_gotoxy(9,1);
printf(lcd_putc,"%02u:%02u:%02u ",hr,min,sec);
lcd_gotoxy(1,2);
printf(lcd_putc,"CO2 = %04.1f ppm",CO2_out);
}
if (CO2_adc<1.325)
{
lcd_gotoxy(9,1);
printf(lcd_putc,"%02u:%02u:%02u ",hr,min,sec);
lcd_gotoxy(1,2);
printf(lcd_putc,"CO2 >10000 ppm");
}
}
if (lcd_cntd == 4)
{
lcd_gotoxy(9,1);
printf(lcd_putc,"%02u:%02u:%02u ",hr,min,sec);
lcd_gotoxy(1,2);
printf(lcd_putc,"Vel = %04.1f Km/h",spd_out);
}
if (lcd_cntd == 5)
{
lcd_gotoxy(9,1);
printf(lcd_putc,"%02u:%02u:%02u ",hr,min,sec);
lcd_gotoxy(1,2);
printf(lcd_putc,"RPM = %04.1f",rpm_out);
}
if (lcd_cntd == 6)
{
lcd_gotoxy(9,1);
printf(lcd_putc,"%02u:%02u:%02u ",hr,min,sec);
lcd_gotoxy(1,2);
printf(lcd_putc,"Consm = %04.1f L/h",map_consm);
}
lcd_count=0;
}
if (lcd_cntd > 6)
{
11
Desarrollo de una unidad de adquisición y monitorización de datos
para un vehículo de automoción
lcd_cntd=2;
}
}
}
}
void NTC()
{
float ntc_adc,ntc_rt,ntc_x;
setup_adc_ports(sAN0,sAN1|VSS_VDD);
set_adc_channel(0);
puerto queremos leer
delay_us(20);
ntc_in=read_adc();
delay_us(20);
// para seleccionar que
if (ntc_in <=0)
{
ntc_temp=999;
}
else
{
// FORMULA INICIO
ntc_adc=3.0*ntc_in/1024.0;
ntc_rt=ntc_adc*100000.0/(3.0-ntc_adc);
ntc_x=log(ntc_rt/100000.0);
// para linealizar la
curva de respuesta del sensor
ntc_x=(1.0/298.15)+(ntc_x*(1.0/4250.0)); // beta_ntc= 4250
ntc_temp=1.0/ntc_x;
ntc_temp=ntc_temp-273.15;
// FORMULA FIN
}
}
void CO2()
{
float CO2_ini,CO2_dispers,AO_gain,CO2_x,CO2_y,CO2_z;
// dsp = dispersion
CO2_ini=0.325;
CO2_dispers=0.0171;
AO_gain=5.0;
set_adc_channel(1);
delay_us(20);
CO2_in=read_adc();
delay_us(20);
// punto de trabajo inicial
// valor dispersion formula logaritmica
// para seleccionar que puerto queremos leer
CO2_adc=3.0*CO2_in/1024.0;
if (CO2_adc < 1.325)
{
CO2_out=50000;
}
if ((CO2_adc<=1.625)&&(CO2_adc>=1.325))
{
// FORMULA INICIO
12
Desarrollo de una unidad de adquisición y monitorización de datos
para un vehículo de automoción
CO2_x=CO2_adc-(CO2_ini*AO_gain);
CO2_y=log10(400.0)-log10(1000.0);
CO2_z=(CO2_x*CO2_y)/(CO2_dispers*AO_gain);
CO2_out=pow(10,CO2_z+log10(400.0));
// FORMULA FIN
}
if (CO2_adc > 1.625)
{
CO2_out=1;
}
}
void SPD()
{
float spd_radio=0.31075;
int8 spd_in;
spd_in=input(pin_B1);
if (spd_count<20)
{
if (spd_in == 1)
{
spd_flag=1;
}
if ((spd_in == 0)&&(spd_flag == 1))
{
spd_cntd++;
spd_flag=0;
}
}
if (spd_count>=20)
{
spd_vueltas=spd_cntd/4;
spd_out=(2*pi*spd_vueltas/2*spd_radio*3.6);
}
}
void RPM()
{
int8 rpm_in;
rpm_in=input(pin_B0);
if (rpm_count<20)
{
if (rpm_in == 1)
{
rpm_flag=1;
}
if ((rpm_in == 0)&&(rpm_flag == 1))
{
rpm_cntd++;
rpm_flag=0;
}
}
13
Desarrollo de una unidad de adquisición y monitorización de datos
para un vehículo de automoción
if (rpm_count==20)
{
rpm_vueltas=rpm_cntd;
rpm_out=(60*rpm_vueltas/2);
// 1min = 60s// rpm = vueltas*minuto//2s contando vueltas
}
}
void MAP()
{
float map_pres,map_adc,map_vol;
// variables para nuestra ecuacion
int16 map_in;
setup_adc_ports(sAN0,sAN2|VSS_VDD);
set_adc_channel(2);
// para seleccionar que puerto queremos leer
delay_us(20);
map_in=read_adc();
delay_us(20);
// FORMULA INICIO
map_adc=5.0*map_in/1024;
map_pres=(map_adc+0.2)/0.02;
map_vol=1.382477124*0.00001;
// Datos calculados en la memoria técnica
map_consm=map_vol*rpm_out*map_pres;
// FORMULA FIN
}
void R232()
{
float sum=1.0;
delay_ms(500);
printf(lcd_putc, "\f");
lcd_gotoxy(3,2);
printf(lcd_putc,"USB conectado");
printf("\nS.A.D\r");
delay_ms(500);
printf(lcd_putc, "\f");
t=4;
while (usb_start==1)
{
usb_start=input(Pin_D3);
if (led_count<=1)
{
led_on(led_parp);
}
if ((led_count>1)&&(led_count<=2))
{
led_off(led_parp);
}
if ((led_count>2))
{
14
Desarrollo de una unidad de adquisición y monitorización de datos
para un vehículo de automoción
led_count=0;
}
if (sum>0)
// Lectura de toda la eeprom
{
lcd_gotoxy(3,2);
printf(lcd_putc,"Leyendo datos...");
delay_ms(200);
interv++;
read_float_ext_eeprom(t);
epp_tiempo=out;
segundos_total=epp_tiempo;
hora=segundos_total/3600;
minuto=(segundos_total/60)%60;
segundo=segundos_total%60;
printf("\n\r");
printf("\nIntervalo = %02u
%02u:%02u:%02u\r",interv,hora,minuto,segundo);
printf("\n\r");
t=t+4;
delay_us(20);
read_float_ext_eeprom(t);
epp_ntc=out;
if (epp_ntc==999)
{
printf("\nT = -- C\r");
}
else
{
printf("\nT = %04.2f C\r",epp_ntc);
}
t=t+4;
delay_us(20);
read_float_ext_eeprom(t);
epp_CO2=out;
if (epp_CO2==50000)
{
printf(lcd_putc,"\nCO2 >10000 ppm \r");
}
if (epp_CO2==1)
{
printf(lcd_putc,"\nCO2 <400 ppm \r");
}
else
{
printf("\nCO2 = %04.1f ppm\r",epp_CO2);
}
t=t+4;
delay_us(20);
read_float_ext_eeprom(t);
epp_rpm=out;
printf("\nRPM = %04.1f \r",epp_rpm);
t=t+4;
delay_us(20);
read_float_ext_eeprom(t);
epp_spd=out;
printf("\nSPD = %04.1f \r",epp_spd);
t=t+4;
delay_us(20);
read_float_ext_eeprom(t);
15
Desarrollo de una unidad de adquisición y monitorización de datos
para un vehículo de automoción
epp_consm=out;
printf("\nConsm = %04.1f \r",epp_consm);
t=t+4;
delay_us(20);
printf(lcd_putc, "\f");
sum = epp_rpm + epp_CO2 + epp_consm + epp_spd;
}
if (sum<=0)
{
lcd_gotoxy(3,2);
printf(lcd_putc,"Listo!");
interv=0;
}
}
flag_usb=0;
}
16
Desarrollo de una unidad de adquisición y monitorización de datos
para un vehículo de automoción
Capítulo 2
Librería reloj en tiempo real
//////////////////////////////////////////////////////////////////////
//////////
///
DS1307.C
///
///
Driver for Real Time Clock
///
///
///
/// ds1307_init() - Enable oscillator without clearing the seconds
register -///
///
used when PIC loses power and DS1307 run from 3V
BAT
///
///
- Disable squarewave output
///
///
///
/// ds1307_set_date_time(day,mth,year,dow,hour,min,sec) Set the
date/time
///
///
///
/// ds1307_get_date(day,mth,year,dow)
Get the date
///
///
///
/// ds1307_get_time(hr,min,sec)
Get the time
///
///
///
//////////////////////////////////////////////////////////////////////
//////////
#define
#define
#define
#define
RTC_SDA PIN_B5
RTC_SCL PIN_B4
EEPROM_SDA PIN_B5
EEPROM_SCL PIN_B4
#use i2c(master, sda=RTC_SDA, scl=RTC_SCL)
17
Desarrollo de una unidad de adquisición y monitorización de datos
para un vehículo de automoción
BYTE bin2bcd(BYTE binary_value);
BYTE bcd2bin(BYTE bcd_value);
void ds1307_init(void)
{
BYTE seconds = 0;
i2c_start();
i2c_write(0xD0);
// WR to RTC
i2c_write(0x00);
// REG 0
i2c_start();
i2c_write(0xD1);
// RD from RTC
seconds = bcd2bin(i2c_read(0)); // Read current "seconds" in DS1307
i2c_stop();
seconds &= 0x7F;
delay_us(3);
i2c_start();
i2c_write(0xD0);
// WR to RTC
i2c_write(0x00);
// REG 0
i2c_write(bin2bcd(seconds));
// Start oscillator with current "seconds value
i2c_start();
i2c_write(0xD0);
// WR to RTC
i2c_write(0x07);
// Control Register
i2c_write(0x80);
// Disable squarewave output pin
i2c_stop();
}
void ds1307_set_date_time(BYTE day, BYTE mth, BYTE year, BYTE dow,
BYTE hr, BYTE min, BYTE sec)
{
sec &= 0x7F;
hr &= 0x3F;
i2c_start();
i2c_write(0xD0);
i2c_write(0x00);
i2c_write(bin2bcd(sec));
i2c_write(bin2bcd(min));
i2c_write(bin2bcd(hr));
i2c_write(bin2bcd(dow));
i2c_write(bin2bcd(day));
i2c_write(bin2bcd(mth));
i2c_write(bin2bcd(year));
i2c_write(0x80);
i2c_stop();
// I2C write address
// Start at REG 0 - Seconds
// REG 0
// REG 1
// REG 2
// REG 3
// REG 4
// REG 5
// REG 6
// REG 7 - Disable squarewave output pin
}
void ds1307_get_date(BYTE &day, BYTE &mth, BYTE &year, BYTE &dow)
{
i2c_start();
i2c_write(0xD0);
i2c_write(0x03);
// Start at REG 3 - Day of week
i2c_start();
i2c_write(0xD1);
dow = bcd2bin(i2c_read() & 0x7f);
// REG 3
day = bcd2bin(i2c_read() & 0x3f);
// REG 4
18
Desarrollo de una unidad de adquisición y monitorización de datos
para un vehículo de automoción
mth = bcd2bin(i2c_read() & 0x1f);
year = bcd2bin(i2c_read(0));
i2c_stop();
// REG 5
// REG 6
}
void ds1307_get_time(BYTE &hr, BYTE &min, BYTE &sec)
{
i2c_start();
i2c_write(0xD0);
i2c_write(0x00);
// Start at REG 0 - Seconds
i2c_start();
i2c_write(0xD1);
sec = bcd2bin(i2c_read() & 0x7f);
min = bcd2bin(i2c_read() & 0x7f);
hr = bcd2bin(i2c_read(0) & 0x3f);
i2c_stop();
}
BYTE bin2bcd(BYTE binary_value)
{
BYTE temp;
BYTE retval;
temp = binary_value;
retval = 0;
while(true)
{
// Get the tens digit by doing multiple subtraction
// of 10 from the binary value.
if(temp >= 10)
{
temp -= 10;
retval += 0x10;
}
else // Get the ones digit by adding the remainder.
{
retval += temp;
break;
}
}
return(retval);
}
// Input range - 00 to 99.
BYTE bcd2bin(BYTE bcd_value)
{
BYTE temp;
temp = bcd_value;
// Shifting upper digit right by 1 is same as multiplying by 8.
temp >>= 1;
// Isolate the bits for the upper digit.
temp &= 0x78;
// Now return: (Tens * 8) + (Tens * 2) + Ones
19
Desarrollo de una unidad de adquisición y monitorización de datos
para un vehículo de automoción
return(temp + (temp >> 2) + (bcd_value & 0x0f));
}
20
Descargar