För att ge er lite bättre överblick och sammanhang lägger jag upp hela koden här.
Jag har ännu inte kommenterat koden men jag hoppas att den inte är allt för svår att tyda. Kör med olika tillstånd som enheten kan hamna i.
Kod: Markera allt
#include "USART.h"
#include "ERx00TRS.h"
#include "1Wire_Common.h"
#include "1Wire_Node.h"
#include "Common.h"
//byte ROM_id[8];
byte ROM_id[8]={0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01};
byte ROM_data[16];
byte rf_channel;
byte rf_node_nr;
byte rf_incomming_data[BASESTATION_DATA_SIZE];
byte rf_incomming_data_length;
byte tmr1_counter=0;
unsigned tmr2_counter=0;
byte lost_counter=0;
byte next_sync=60;
enum states { START=0, LEARN, WAKE_UP, PREPARE_WAITING, WAITING, TIMEOUT, RECIVING, RECIVE_BYTE, RECIVED, NORMAL, SLEEP } state;
void main() {
byte i=0;
init();
ow_get_id(&ROM_id,OW_PORT,OW_PIN);
delay_ms(20);
state = START;
while(1) {
Lcd_Chr(1,4,(tmr1_counter/10)+0x30);
Lcd_Chr(1,5,(tmr1_counter%10)+0x30);
Lcd_Chr(1,10,(tmr2_counter/10000)+0x30);
Lcd_Chr(1,11,((tmr2_counter%10000)/1000)+0x30);
Lcd_Chr(2,4,rf_channel+0x30);
Lcd_Chr(2,9,(rf_node_nr/10)+0x30);
Lcd_Chr(2,10,(rf_node_nr%10)+0x30);
switch (state) {
case START : LCD_Out(2,12, "START");
RF_MODULE=OFF;
INTCON.INTF=0;
INTCON.INTE=1; // Aktivera LEARN-knapp
asm {
SLEEP
NOP
}
break;
case LEARN : LCD_Out(2,12, "LEARN");
RF_MODULE=ON;
delay_ms(200);
init_ER();
rf_channel=0;
rf_node_nr=0;
ER_Set_Channel(rf_channel);
ER_Set_Data_ID(rf_node_nr);
delay_ms(100);
Usart_Write_Data(&ROM_id,8);
for (i=8;i<NODE_DATA_SIZE;i++)
Usart_Write(0x00);
state = PREPARE_WAITING;
break;
case WAKE_UP : LCD_Out(2,12, "WAKEU");
tmr1_counter=0;
RF_MODULE=ON;
delay_ms(200);
init_ER();
ER_Set_Channel(rf_channel);
ER_Set_Data_ID(rf_node_nr);
state = PREPARE_WAITING;
break;
case PREPARE_WAITING : LCD_Out(2,12, "PREPA");
rf_incomming_data_length=0;
tmr2_counter=0;
PIR1.TMR2IF = 0;
// PIE1.TMR2IE = 1;
PIR1.RCIF = 0;
PIE1.RCIE = 1;
state = WAITING;
break;
case WAITING : LCD_Out(2,12, "WAITI");
break;
case TIMEOUT :
lost_counter++;
state=PREPARE_WAITING;
break;
case RECIVING :
LCD_chr(1,13,(rf_incomming_data_length+0x30));
LCD_Out(2,12, "RXING");
break;
case RECIVED : LCD_Out(2,12, "RXED ");
PIR1.TMR2IF=0;
PIE1.TMR2IE=0;
PIR1.RCIF = 0;
PIE1.RCIE = 0;
lost_counter=0;
Lcd_Chr(1,13,rf_incomming_data_length+0x30);
LCD_chr(1,15,(rf_incomming_data[0]/10)+0x30);
LCD_chr(1,16,(rf_incomming_data[0]%10)+0x30);
switch (rf_incomming_data[0]) {
case WRITE_SCRATCHPAD :
rf_channel=rf_incomming_data[1];
rf_node_nr=rf_incomming_data[2];
ER_Set_Channel(rf_channel);
ER_Set_Data_ID(rf_node_nr);
break;
case READ_SCRATCHPAD :
next_sync=rf_incomming_data[1];
Usart_Write_Data(&ROM_id,8);
Usart_Write_Data(&ROM_data,24);
tmr1_counter=0;
break;
default :
break;
}
RF_MODULE=OFF;
state=NORMAL;
break;
case NORMAL : LCD_Out(2,12, "NORMA");
if (ROM_id[0]==0x28)
ow_get_ds18b20_data(&ROM_data,OW_PORT,OW_PIN);
else {
if (ROM_id[0]==0x26)
ow_get_ds2438_data(&ROM_data,OW_PORT,OW_PIN);
}
delay_ms(20);
PIE1.TMR1IE = 1;
tmr1_counter=0;
state=SLEEP;
break;
case SLEEP : LCD_Out(2,12, "SLEEP");
asm {
SLEEP
NOP
}
break;
default : break;
}
}
}
void interrupt() {
if (PIR1.TMR1IF && PIE1.TMR1IE) {
if(tmr1_counter<next_sync)
tmr1_counter++;
else
state=WAKE_UP;
TMR1H=0x80;
PIR1.TMR1IF = 0;
}
if (INTCON.INTF && INTCON.INTE) {
state = LEARN;
INTCON.INTF=0;
}
if (PIR1.RCIF && PIE1.RCIE) {
TMR2=0;
state=RECIVING;
if (!rf_incomming_data_length) {
PIR1.TMR2IF=0;
// PIE1.TMR2IE=1;
}
if(rf_incomming_data_length < BASESTATION_DATA_SIZE) {
rf_incomming_data[rf_incomming_data_length]=RCREG;
if(RCSTA.OERR) {
RCSTA.CREN=0;
RCSTA.CREN=1;
}
}
else {
state=RECIVED;
}
rf_incomming_data_length++;
}
if (PIR1.TMR2IF && PIE1.TMR2IE) {
if (state==RECIVING)
state=RECIVED;
if (state==WAITING) {
if (tmr2_counter<18310)
tmr2_counter++;
else
state=TIMEOUT;
}
PIR1.TMR2IF=0;
}
}
void init() {
// OSCCON = 0x60; // 4 Mhz
// ANSEL = 0x00;
ADCON1 = 0x06;
PORTA = 0x00;
PORTB = 0x00;
TRISA = 0b11111110;
TRISB = 0b11111111;
T1CON = 0x0F; // Extern klockkristall
T2CON = 0x07; // 1:16 prescale
// T1CON = 0x30; // Interna klockan
PIR1.TMR1IF = 0;
PIE1.TMR1IE = 1;
INTCON = 0xD0;
Usart_Init(19200);
Lcd_Init(&PORTD);
LCD_Cmd(LCD_CLEAR); // Clear display
LCD_Cmd(LCD_CURSOR_OFF); // Turn cursor off
LCD_Out(1,1, "T1: T2:"); // Print text to LCD, 2nd row, 1st column
LCD_Out(2,1, "C#: N#: "); // Print text to LCD, 2nd row, 1st column
tmr1_counter=1;
}