/******************************************************* This program was created by the CodeWizardAVR V3.04 Advanced Automatic Program Generator © Copyright 1998-2013 Pavel Haiduc, HP InfoTech s.r.l. http://www.hpinfotech.com Project : Version : Date : 15.12.2015 Author : Company : Comments: Chip type : ATmega8 Program type : Application AVR Core Clock frequency: 8,000000 MHz Memory model : Small External RAM size : 0 Data Stack size : 256 *******************************************************/ #include #include #include //Definitions #define LED_Green PORTD.1 #define RO PIND.7 #define RE PORTD.6 #define DE PORTB.7 #define DI PORTB.6 #define CRC_POLYNOMIAL 0x31 #define TX_RATE 1 #define PACKET_LENGTH 10 #define UREF 5.05 #define R25 50000 #define B25 4331 #define RD 5100 #define DHT11_INIT_TIME 20 #define DHT11_PORT PIND.4 #define DHT11_STARTBIT 3 #define TIMER_0 0x84 #define TIMER_2 0x03 // Declare your global variables here unsigned char led_green_status = 0; eeprom unsigned char my_address @0x00; unsigned char rs485_rx[PACKET_LENGTH]; unsigned char rs485_tx[PACKET_LENGTH]; unsigned char rx_data[PACKET_LENGTH - 6]; unsigned char rx_length = 0; unsigned char rx_type; unsigned char tx_data[PACKET_LENGTH - 6]; unsigned char i; unsigned char x; unsigned char y; unsigned char remainder; unsigned char tx_byte = 0; unsigned char tx_bit = 0; unsigned char tx_status = 0; unsigned char tx_clock = 1; unsigned char rx_count = 0; unsigned char rx_counter = 0; unsigned char rx_rate = 0; unsigned char rx_byte = 0; unsigned char rx_bit = 0; unsigned char rx_offset = 0; double temp[6]; double Uadc; unsigned int Rt; unsigned char temp_count = 1; unsigned char temp_ref_time = 10; unsigned char dht11_counter = 0; unsigned char dht11_count = 20; unsigned char dht11_data[5]; unsigned char dht11_bit = 7; unsigned char dht11_byte = 0; unsigned char dht11_time = 0; unsigned char dht11_check = 0; unsigned char dht11_first_low = 0; unsigned char dht11_run = 0; unsigned char dht11_start_low = 0; unsigned char dht11_start_high = 0; unsigned char dht11_humidity = 0; unsigned char dht11_temp = 0; // Function prototypes void dht11_start(); void led_green_ref(){ if(led_green_status){ LED_Green = 1; led_green_status = (led_green_status & 0b11111000) | ((led_green_status & 0b00000111) - 1); if((led_green_status & 0b00111111) == 0){ led_green_status = 0; LED_Green = 0; } else{ if((led_green_status & 0b00000111) == 0){ led_green_status = led_green_status | ((led_green_status >> 3) & 0b00000111); if(led_green_status & 0b10000000){ led_green_status = led_green_status & 0b01111111; LED_Green = 0; } else{ led_green_status = led_green_status | 0b10000000; LED_Green = 1; } } } } } void led_green_flash(unsigned int delay){ delay = (delay / 100) & 0b00000111; delay++; led_green_status = delay; } void led_green_blink(unsigned int delay){ delay = (delay / 100) & 0b00000111; delay++; led_green_status = (1 << 7) | delay << 3 | delay; } unsigned char crc(unsigned char const data_crc[], unsigned char length){ remainder = 0; for(x = 0; x < length; x++){ remainder ^= data_crc[x]; for(y = 8; y > 0; y--){ if(remainder & 0x80){ remainder = (remainder << 1) ^ CRC_POLYNOMIAL; } else{ remainder = (remainder << 1); } } } return (remainder); } void send_rs485(unsigned char dest_address, unsigned char tx_type, unsigned char *data, unsigned char data_length){ if(tx_status == 0){ rs485_tx[0] = 0b01010101; rs485_tx[1] = my_address; rs485_tx[2] = dest_address; rs485_tx[3] = tx_type; rs485_tx[4] = 6 + data_length; for(i = 0; i < data_length; i++){ rs485_tx[i + 5] = data[i]; } rs485_tx[data_length + 5] = crc(rs485_tx, data_length + 5); tx_byte = 0; tx_bit = 7; tx_status = 1; tx_clock = 1; } } void collision_detect(){ if(RO != DI){ tx_status = 1; tx_clock = 1; tx_bit = 7; tx_byte = 0; DE = 0; } } void tx_ref(){ if(tx_status) {if(tx_clock == 1){ if((tx_status & 0b00000010) && (tx_byte < rs485_tx[4])){ DE = 1; DI = (rs485_tx[tx_byte] >> tx_bit) & 1; tx_clock = TX_RATE; if(tx_bit == 0){ tx_bit = 7; tx_byte++; } else{ tx_bit--; } collision_detect(); } else{ if((tx_status & 0b00000001) && ((tx_status & 0b00000010) == 0) && (rx_count == 0)){ tx_status ^= 0b00000010; } else{ if(tx_byte == rs485_tx[4]){ tx_status = 0; tx_clock = 1; tx_bit = 7; tx_byte = 0; DE = 0; } } } } else{ tx_clock--; }} } void packet_rx(){ led_green_flash(100); } void rx_ref(){ if((tx_status & 0b00000010) == 0){ if(rx_byte < PACKET_LENGTH){ if(rs485_rx[0] == 0){ if(RO == 0){ rx_count++; } else{ if(rx_count){ for(i = 1; i < PACKET_LENGTH; i++){ rs485_rx[i] = 0; } rs485_rx[rx_byte] |= 0b01000000; rx_bit = 5; rx_counter = 1; rx_offset = rx_count / 2; } } } else{ if(rx_counter){ if(rx_counter == (rx_count + rx_offset)){ rx_counter = rx_offset; if(RO){ switch(rx_bit){ case 0: rs485_rx[rx_byte] |= 0b00000001; break; case 1: rs485_rx[rx_byte] |= 0b00000010; break; case 2: rs485_rx[rx_byte] |= 0b00000100; break; case 3: rs485_rx[rx_byte] |= 0b00001000; break; case 4: rs485_rx[rx_byte] |= 0b00010000; break; case 5: rs485_rx[rx_byte] |= 0b00100000; break; case 6: rs485_rx[rx_byte] |= 0b01000000; break; case 7: rs485_rx[rx_byte] |= 0b10000000; break; } } if(rx_bit == 0){ rx_bit = 7; rx_byte++; } else{ rx_bit--; } } rx_counter++; } } } else{ if(crc(rs485_rx, rs485_rx[4]) == 0){ rx_type = rs485_rx[3]; for(i = 0; i < (rs485_rx[4] - 6); i++){ rx_data[i] = rs485_rx[i + 5]; } packet_rx(); } rs485_rx[0] = 0; rx_count = 0; rx_counter = 0; rx_byte = 0; } } } void temp_ref(){ if(temp_count == temp_ref_time){ if((ADMUX & 0b00000111) == 5){ ADMUX &= 0b11111000; dht11_start(); } else{ ADMUX++; } temp_count = 1; ADCSRA |= 0x40; } else{ temp_count++; } } void dht11_data_ok(){ dht11_humidity = dht11_data[0]; dht11_temp = dht11_data[2]; led_green_flash(100); send_rs485(0, temp[0], dht11_data, 4); } void dht11_start(){ DDRD.4 = 1; dht11_counter = 1; } void dht11_data_check(){ dht11_check = 0; for(i = 0; i < 4; i++){ dht11_check += dht11_data[i]; } if(dht11_data[4] == dht11_check){ dht11_data_ok(); } } void dht11_ref(){ if(dht11_counter > dht11_count){ if(dht11_run == 0){ if(DHT11_PORT){ dht11_start_high++; } else{ if((dht11_start_high >= (DHT11_STARTBIT - 1)) && (dht11_start_low >= (DHT11_STARTBIT - 1))){ dht11_run = 1; dht11_start_low = 0; dht11_start_high = 1; } else{ dht11_start_high = 0; dht11_start_low++; } } } else{ if(DHT11_PORT){ dht11_time++; dht11_first_low = 1; } else{ if(dht11_first_low){ if(dht11_time > 2){ switch(dht11_bit){ case 0: dht11_data[dht11_byte] |= 0b00000001; break; case 1: dht11_data[dht11_byte] |= 0b00000010; break; case 2: dht11_data[dht11_byte] |= 0b00000100; break; case 3: dht11_data[dht11_byte] |= 0b00001000; break; case 4: dht11_data[dht11_byte] |= 0b00010000; break; case 5: dht11_data[dht11_byte] |= 0b00100000; break; case 6: dht11_data[dht11_byte] |= 0b01000000; break; case 7: dht11_data[dht11_byte] |= 0b10000000; break; } } if(dht11_bit == 0 && dht11_byte != 4){ dht11_byte++; dht11_bit = 7; } else{ if(dht11_bit == 0){ dht11_counter = 0; dht11_bit = 7; dht11_byte = 0; dht11_data_check(); dht11_run = 0; } else{ dht11_bit--; } } dht11_time = 0; dht11_first_low = 0; } } } } } // External Interrupt 0 service routine Button 1 interrupt [EXT_INT0] void ext_int0_isr(void) { // Place your code here send_rs485(0, temp[0], dht11_data, 4); } // Timer 0 overflow interrupt service routine 22 us interrupt [TIM0_OVF] void timer0_ovf_isr(void) { // Reinitialize Timer 0 value TCNT0=TIMER_0; // Place your code here dht11_ref(); } // Timer1 overflow interrupt service routine 100 ms interrupt [TIM1_OVF] void timer1_ovf_isr(void) { // Reinitialize Timer1 value TCNT1H=0xCF2C >> 8; TCNT1L=0xCF2C & 0xff; // Place your code here temp_ref(); led_green_ref(); } // Timer2 overflow interrupt service routine 1 ms interrupt [TIM2_OVF] void timer2_ovf_isr(void) { // Reinitialize Timer2 value TCNT2=TIMER_2; // Place your code here rx_ref(); tx_ref(); if(dht11_counter == dht11_count){ for(i = 0; i < 5; i++){ dht11_data[i] = 0; } DDRD.4 = 0; } if((dht11_counter <= dht11_count) && (dht11_counter > 0)){ dht11_counter++; } } // Voltage Reference: AVCC pin #define ADC_VREF_TYPE ((0<