powerEngine.c
286 lines
| 5.4 KiB
| text/x-c
|
CLexer
|
r216 | /* | ||
* powerEngine.c | ||||
* | ||||
* Created on: Mar 23, 2015 | ||||
* Author: shinobi | ||||
*/ | ||||
#include "powerEngined.h" | ||||
#include "usi_i2c_slave.h" | ||||
#include <util/delay.h> | ||||
#include <avr/interrupt.h> | ||||
#define DQ_HIGH DQ_PORT |= (1<<DQ_BIT) | ||||
#define DQ_LOW DQ_PORT &= ~(1<<DQ_BIT) | ||||
#define DQ_INPUT DQ_DDR &= ~(1<<DQ_BIT) | ||||
#define DQ_OUTPUT DQ_DDR |= (1<<DQ_BIT) | ||||
#define DQ_READ ((DQ_PIN&(1<<DQ_BIT))!=0)?0x01:0x00 | ||||
#define US (1000000.0/ F_CPU ) | ||||
#define TM0_ON TCCR0B |=(0<<CS02)|(0<<CS01)|(1<<CS00) | ||||
#define TM0_OFF TCCR0B &= ~((1<<CS02)|(1<<CS01)|(1<<CS00)) | ||||
#define TM1_ON TCCR1 |= (1<<CS13)|(1<<CS12)|(1<<CS11)|(1<<CS10) | ||||
#define TM1_OFF TCCR1 &= ~((1<<CS13)|(1<<CS12)|(1<<CS11)|(1<<CS10)) | ||||
#define MAX_TM_CYCLES 15 | ||||
volatile uint8_t presenced_flg = 0; | ||||
volatile uint8_t process_flg = 0; | ||||
volatile uint8_t tm_cycles = 0; | ||||
extern char* USI_Slave_register_buffer[]; | ||||
/*! | ||||
* \fn write_0_signal | ||||
* \brief genera el simbolo que corresponde a '0' logico en el protocolo | ||||
* especificatdo en el datasheet del IC DS2438Z | ||||
* \see write_1_signal | ||||
* \see write_byte | ||||
*/ | ||||
void write_0_signal(){ | ||||
DQ_LOW; | ||||
_delay_us(65); | ||||
DQ_HIGH; | ||||
_delay_us(1); | ||||
} | ||||
/*! | ||||
* \fn write_1_signal | ||||
* \brief genera el simbolo que corresponde a '1' logico en el protocolo | ||||
* especificatdo en el datasheet del IC DS2438Z | ||||
* \see write_0_signal | ||||
* \see write_byte | ||||
*/ | ||||
void write_1_signal(){ | ||||
DQ_LOW; | ||||
_delay_us(10); | ||||
DQ_HIGH; | ||||
_delay_us(56); | ||||
} | ||||
/*! | ||||
* \fn write_byte | ||||
* \brief Escribe un byte por el puerto DQ | ||||
* \param byte El byte a escribir | ||||
* \see write_0_signal | ||||
* \see write_1_signal | ||||
*/ | ||||
void write_byte(uint8_t byte){ | ||||
uint8_t mask = 0x00; | ||||
while(mask!=0){ | ||||
if((byte&mask)!=0){ | ||||
write_1_signal(); | ||||
}else{ | ||||
write_0_signal(); | ||||
} | ||||
mask = (uint8_t)(mask << 1); | ||||
} | ||||
} | ||||
/*! | ||||
* \fn write_bytes | ||||
* \brief Escribe "len" bytes por el puerto DQ | ||||
* \param pbytes Puntero a inicio de buffer que contiene los bytes | ||||
* \param len >Numero de bytes a escribir | ||||
* \see write_byte | ||||
*/ | ||||
void write_bytes(uint8_t* pbytes,uint8_t len){ | ||||
do{ | ||||
len-=1; | ||||
write_byte(pbytes[len]); | ||||
}while(len>0); | ||||
} | ||||
/*! | ||||
* \fn read_signal | ||||
* \brief Lee un bit del puerto DQ | ||||
* \return '1' o '0'. | ||||
* \see read_byte | ||||
*/ | ||||
uint8_t read_signal(){ | ||||
uint8_t bit = 0; | ||||
DQ_LOW; | ||||
_delay_us(2); | ||||
DQ_HIGH; | ||||
DQ_INPUT; | ||||
_delay_us(8); | ||||
bit = DQ_READ; | ||||
_delay_us(55); | ||||
DQ_OUTPUT; | ||||
DQ_HIGH; | ||||
_delay_us(1); | ||||
return bit; | ||||
} | ||||
/*! | ||||
* \fn read_byte | ||||
* \brief Lee un byte de el puerto DQ | ||||
* \see read_signal | ||||
* \see read_bytes | ||||
*/ | ||||
uint8_t read_byte(){ | ||||
uint8_t shift = 0x00; | ||||
uint8_t byte = 0x00; | ||||
uint8_t bit= 0; | ||||
while(shift< 8){ | ||||
bit = read_signal(); | ||||
byte |= (bit<<shift); | ||||
shift++; | ||||
} | ||||
return byte; | ||||
} | ||||
/*! | ||||
* \fn read_bytes | ||||
* \brief Lee "len" bytes de el puerto DQ | ||||
* \param pbytes puntero a buffer, contendra los bytes leidos. | ||||
* \param len Numero de bytes a leer. | ||||
* \see read_byte | ||||
*/ | ||||
void read_bytes(uint8_t* pbytes, uint8_t len){ | ||||
do{ | ||||
len-=1; | ||||
pbytes[len] = read_byte(); | ||||
}while(len>0); | ||||
} | ||||
/*! | ||||
* \fn initialization | ||||
* \brief Inicia o reinicia al IC DS2438Z | ||||
*/ | ||||
void initialization(){ | ||||
TCNT0 = 0x0000; | ||||
presenced_flg = 0; | ||||
DQ_LOW; | ||||
_delay_us(490); | ||||
TM0_ON; | ||||
DQ_HIGH; | ||||
while(presenced_flg != 1){} | ||||
} | ||||
/*! | ||||
* \fn memory_read | ||||
* \brief Realiza la lectura de toda la memoria del IC DS2438Z | ||||
*/ | ||||
void memory_read(uint8_t* pbytes, uint8_t page_addr){ | ||||
uint8_t crc; | ||||
initialization(); | ||||
write_byte(SKIP_ROM); | ||||
write_byte(READ_SP); | ||||
write_byte(page_addr); | ||||
read_bytes(pbytes,8); | ||||
crc = read_byte(); | ||||
initialization(); | ||||
} | ||||
/*! | ||||
* \fn convert | ||||
* \brief Inicia la conversion ADC de los parametros desados | ||||
* \param cmd CONVERT_T para iniciar la conversion de temperatura. CONVERT_V | ||||
* para iniciar la conversion de voltaje. | ||||
*/ | ||||
void convert(uint8_t cmd){ | ||||
uint8_t bit = 0; | ||||
initialization(); | ||||
write_byte(SKIP_ROM); | ||||
write_byte(cmd); | ||||
do{ | ||||
bit = read_signal(); | ||||
}while(bit != 1); | ||||
initialization(); | ||||
} | ||||
/*! | ||||
* \fn void send_data | ||||
* \brief Envia data al sistema enbebido por puerto twi | ||||
* \param pbytes Puntero a buffer de bytes a enviar. | ||||
* \param len Numero de bytes a enviar. Debe ser menor o igual a USI_SLAVE_REGISTER_COUNT. | ||||
*/ | ||||
void send_data(uint8_t* pbytes, uint8_t len){ | ||||
int i; | ||||
for(i=0;i<USI_SLAVE_REGISTER_COUNT;i++){ | ||||
if(i<len){ | ||||
USI_Slave_register_buffer[i]=(char)(pbytes[i]); | ||||
}else{ | ||||
USI_Slave_register_buffer[i]='\0'; | ||||
} | ||||
} | ||||
} | ||||
//usado para cronometrar la lectura del presence pulse | ||||
ISR(TIM0_COMPA_vect ){ | ||||
TM0_OFF; | ||||
} | ||||
//detecta el nivel bajo. usado para detectar el presence pulse | ||||
ISR(PCINT0_vect){ | ||||
uint16_t cnt; | ||||
if((PINB&(1<<PINB3))==0x00){ | ||||
if((cnt>=60*US)&&(cnt<=240*US)){ | ||||
presenced_flg=1; | ||||
} | ||||
} | ||||
} | ||||
ISR(TIM1_COMPB_vect){ | ||||
tm_cycles++; // cuenta de 60 segundos | ||||
if(tm_cycles>=MAX_TM_CYCLES){ | ||||
process_flg = 1; | ||||
tm_cycles=0; | ||||
} | ||||
} | ||||
int main(){ | ||||
uint8_t pbytes[8]; | ||||
// inicializa | ||||
USI_I2C_Init(I2C_SLAVE_ADDR); | ||||
cli(); | ||||
// interrupcion externa | ||||
GIMSK |= _BV(PCIE); // Turn on Pin Change interrupt | ||||
PCMSK |= _BV(PCINT3); // Which pins are affected by the interrupt | ||||
// timer0 CTC con OCRA como top. Debe interrumpir en 250us luego de | ||||
// TM0_ON | ||||
TCCR0A = (1<<COM0A1)|(1<<COM0A0)|(1<<WGM01)|(0<<WGM00); | ||||
TCCR0B = (0<<WGM02); | ||||
TM0_OFF; | ||||
OCR0A = (uint8_t)(250*US); | ||||
// timer1 CTC TOP : OCR1C ; pre-scaler 16384 | ||||
TCCR1 = (1<<COM1A1)|(1<<COM1A0); | ||||
TM1_OFF; | ||||
OCR1A = (uint8_t)(244*US);// x 15 ciclo x 16384 (pre-scaler) | ||||
//Activa interrupciones de timers | ||||
TIMSK |= (1<<OCIE1A)|(1<<OCIE0A); | ||||
presenced_flg=0; | ||||
sei(); | ||||
do{ | ||||
process_flg = 0; | ||||
convert(CONV_T); | ||||
convert(CONV_V); | ||||
memory_read(pbytes,PAGE_0); | ||||
send_data(pbytes,8); | ||||
while(!(process_flg==1)){}; | ||||
}while(1==1); | ||||
return 0; | ||||
} | ||||