#define begin { #define end } #include #include #include #define identifier 0xBB unsigned int time2; unsigned char i; int ADC_val; unsigned char ADC_start[8] = {0b00011000,0b00011001,0b00011010,0b00011011,0b00011100,0b00011101,0b00011110,0b00011111}; int ADC_buffer[8]; char CAN_buffer[10]; unsigned char ADC_buffer_full, CAN_buffer_full, poll_ADC, ADC_running; unsigned char time2_extended; void initialize(); void get_ADC(); void prepare_CAN(); void transmit_CAN(); //********************************************* void main() begin initialize(); spi_write(0x0f,0x07); // normal mode spi_write(0x2b,0x04); // txb0 empty interrput enabled spi_write(0x31,identifier>>3); // load identifier spi_write(0x32,identifier<<5); // load identifier spi_write(0x60,0x00); spi_write(0x20,0xff); spi_write(0x00,0xaa); spi_write(0x02,0xaa); // set filters to block transmitters from receiving any packets while(1) begin if (poll_ADC) get_ADC(); // read data from the ADC if (ADC_buffer_full) prepare_CAN(); // format data for CAN if (CAN_buffer_full) transmit_CAN(); // transmit over CAN end end //********************************************************** void transmit_CAN() begin spi_write(0x35,0x08); // 8 data bytes spi_write(0x36,identifier); // byte 0 = identifier spi_write(0x37,time2_extended); // bytes 1-3 = time stamp spi_write(0x38,(unsigned char)(time2>>8)); spi_write(0x39,(unsigned char)(time2)); for (i = 0; i<4; i++) begin // bytes 4-7 = data spi_write(0x3a+i,CAN_buffer[i]); // load first 4 data bytes end spi_write(0x30,0x0b); // transmit with highest priority PORTB.2 = 0; while (PINB.0 == 1) { } // wait for interrupt from MCP2515 PORTB.2 = 1; spi_bit_modify(0x2c,0x04 ,0x00); // turn off interrupt spi_write(0x35,0x06); // 6 data bytes for (i = 0; i<6; i++) begin spi_write(0x36+i,CAN_buffer[(char)(i+4)]); // load last 6 data bytes end spi_write(0x30,0x0b); // transmit with highest priority PORTB.2 = 0; while (PINB.0 == 1) { } // wait for interrupt from MCP2515 PORTB.2 = 1; spi_bit_modify(0x2c,0x04,0x00); // turn off interrupt CAN_buffer_full = 0; // clear flag end //********************************************************** void prepare_CAN() begin // Converts 8 10-bit values to 10 8-bit values for transmission over CAN if (CAN_buffer_full == 0) begin CAN_buffer[0] = (char)((ADC_buffer[0]>>2)&0xff); CAN_buffer[1] = ((char)(ADC_buffer[0]<<6)) | ((char)((ADC_buffer[1]>>4)&0x3f)); CAN_buffer[2] = ((char)(ADC_buffer[1]<<4)) | ((char)((ADC_buffer[2]>>6)&0x0f)); CAN_buffer[3] = ((char)(ADC_buffer[2]<<2)) | ((char)((ADC_buffer[3]>>8)&0x03)); CAN_buffer[4] = (char)(ADC_buffer[3]&0xff); CAN_buffer[5] = (char)((ADC_buffer[4]>>2)&0xff); CAN_buffer[6] = ((char)(ADC_buffer[4]<<6)) | ((char)((ADC_buffer[5]>>4)&0x3f)); CAN_buffer[7] = ((char)(ADC_buffer[5]<<4)) | ((char)((ADC_buffer[6]>>6)&0x0f)); CAN_buffer[8] = ((char)(ADC_buffer[6]<<2)) | ((char)((ADC_buffer[7]>>8)&0x03)); CAN_buffer[9] = (char)(ADC_buffer[7]&0xff); CAN_buffer_full = 1; // set flag ADC_buffer_full = 0; // clear flag end end //********************************************************** void get_ADC() begin if(ADC_buffer_full == 0) begin poll_ADC = 0; // clear flag for(i = 0; i<8; i++) begin ADC_buffer[i] = spi_adc(ADC_start[i]); // read each ADC channel end ADC_buffer_full = 1; // set flag end end //********************************************************** interrupt [EXT_INT0] void extint0(void) begin ADC_running = 1; // set flag end //********************************************************** interrupt [TIM0_COMP] void timer0(void) begin // set flag if (ADC_running) poll_ADC = 1; end //********************************************* interrupt [TIM2_COMP] void timer2(void) begin // timestamp increment time2++; if (time2 == 0xffff) begin time2 = 0; time2_extended++; end end //********************************************* void initialize() begin // external int0 on falling edge MCUCR = 0b00000010; GICR = 0b01000000; // SPI ISR disabled, SPI enabled, MSB first, master, SCK = 8MHz SPCR = 0b01010000; SPSR.0 = 1; // timer0 compare match ISR at 500 Hz TCCR0 = 0b00001100; OCR0 = 124; TCNT0 = 0; // timer2 compare match ISR every 1 ms TCCR2 = 0b00001011; OCR2 = 249; TCNT2 = 0; time2 = 0; time2_extended = 0; TIMSK = 0b10000010; // D.2 input for EXT_INT0 DDRD.2 = 0; // B.7 output SCK, B.6 input MISO, B.5 output MOSI, B.4 output CS for CAN, B.3 output CS for ADC, B.0 input for CAN tx complete interrupt DDRB = 0b10111000; // initialize both chip selects high PORTB.4 = 1; PORTB.3 = 1; PORTB.0 = 1; // B.0 pulled up PORTD.2 = 1; // D.2 pulled up // initialize flag ADC_running = 0; #asm("sei") end //**********************************************************