/******************************************************* 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 : 20.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 //Definitions #define LED_Green PORTD.5 #define RO PIND.7 #define RE PORTD.6 #define DE PORTB.7 #define DI PORTB.6 #define PIR PIND.4 #define CRC_POLYNOMIAL 0x31 #define TX_RATE 1 #define PACKET_LENGTH 10 #define TIMER_2 0x05 #define TIME_ON 10 // 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; unsigned char pir_status = 0; 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; } } 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_clock == 1) && tx_status){ 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 pir_ref(){ if(PIR){ if(pir_status == 0){ pir_status = 1; send_rs485(0xAA, TIME_ON, 0, 0); } } else{ pir_status = 0; } } // External Interrupt 0 service routine Button 1 interrupt [EXT_INT0] void ext_int0_isr(void) { // Place your code here send_rs485(0, 0xAA, 0, 0); } // 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 led_green_ref(); pir_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(); } void main(void) { // Declare your local variables here // Input/Output Ports initialization // Port B initialization // Function: Bit7=Out Bit6=Out Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In DDRB=(1<