Changeset 573 for trunk/electronics/avr
- Timestamp:
- 10/15/09 23:45:44 (2 years ago)
- Location:
- trunk/electronics/avr/i2c_irboard/i2c_slave
- Files:
-
- 1 added
- 1 modified
-
I2C_Slave.c (modified) (3 diffs)
-
I2C_Slave.hex (added)
Legend:
- Unmodified
- Added
- Removed
-
trunk/electronics/avr/i2c_irboard/i2c_slave/I2C_Slave.c
r559 r573 32 32 33 33 #include <avr/io.h> 34 #include <avr/eeprom.h> 34 35 #include <avr/interrupt.h> 35 36 #include <avr/pgmspace.h> … … 39 40 #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) 40 41 42 // i2c commands 43 #define RAW_ADC ( 1 ) 44 #define DISTANCE ( 2 ) 45 #define SETADDR ( 3 ) 46 #define READADDR ( 4 ) 47 #define SET_CORR ( 5 ) 48 #define ERROR ( 0 ) 49 41 50 uint16_t ADCIN(void); 42 uint16_t value; 43 uint16_t analog; 51 uint8_t EEMEM slaveaddr = 0x26; 52 uint16_t EEMEM EE_m = 6787; 53 uint8_t EEMEM EE_b = 3; 54 uint8_t EEMEM EE_k = 4; 44 55 45 46 /* Brief: This section determines what format to return the value in. */ 47 48 enum { DATA1, DATA2, RAW }; 49 50 //----------------------------------------------------------------------------- 51 52 /* This section allows you to select between three different modes. In this sample 53 each return the value of the analog at different levels just to give an idea of how 54 it can be used. */ 55 56 void mode(uint8_t mode, uint8_t on) 57 { 58 analog = ADCIN(); 59 switch (mode) 60 { 61 case DATA1: if (on) (value = analog * 2); break; 62 case DATA2: if (on) (value = analog / 10); break; 63 case RAW: if (on) (value = analog); break; 64 } 56 uint8_t distance(uint16_t k, uint8_t m, uint8_t b) { 57 uint16_t analog = ADCIN(); 58 uint16_t distance = (m / (analog - b)) - k; 59 if(distance > 255) distance = 255; 60 if(distance < 0) distance = 0; 61 // http://www.acroname.com/robotics/info/articles/irlinear/irlinear.html 62 return analog; 65 63 } 66 64 67 /* Brief: The main function.68 * The program entry point. Initates TWI and enters eternal loop, waiting for data.69 */70 65 int main(void) 71 66 { 72 u nsigned char slaveAddress,temp;73 67 uint8_t temp; 68 uint16_t value; 74 69 sei(); 75 70 … … 83 78 cbi(DDRB, DDB1); // pb1 set up as input 84 79 cbi(DDRB, DDB3); // pb3 set up as input 85 // cbi(DDRB, DDB5); // pb5 set up as input (use only in production, wipes out reset pin)86 80 sbi(PORTB, PB1); // Set pb1 internal pullup 87 81 sbi(PORTB, PB3); // Set pb3 internal pullup 88 // sbi(PORTB, PB5); // (use only in production, wipes out reset pin)89 90 slaveAddress = 0x26; // This can be change to your own address91 82 92 83 93 usiTwiSlaveInit(slaveAddress); 84 uint16_t m = eeprom_read_word(&EE_m); 85 uint8_t b = eeprom_read_byte(&EE_b); 86 uint8_t k = eeprom_read_byte(&EE_k); 94 87 95 // This loop runs forever. If the TWI Transceiver is busy the execution will96 // just continue doing other operations. 88 usiTwiSlaveInit(eeprom_read_byte(&slaveaddr)); 89 97 90 for(;;) 98 91 { 99 100 101 92 if(usiTwiDataInReceiveBuffer()) 102 93 { 94 value = 1; 103 95 temp = usiTwiReceiveByte(); 104 96 switch (temp) 105 { 106 case 1: mode(DATA1, 1); break; // the case is selected by a single 107 case 2: mode(DATA2, 1); break; // digit in the master code. (1,2 or 3) 108 case 3: mode(RAW, 1); break; 109 } 97 { 98 case RAW_ADC: 99 value = ADCIN() << 2; 100 break; 101 case SETADDR: 102 eeprom_write_byte(&slaveaddr, usiTwiReceiveByte()); 103 value = eeprom_read_byte(&slaveaddr); 104 break; 105 case DISTANCE: 106 value = distance(k, m, b); 107 break; 108 case READADDR: 109 value = eeprom_read_byte(&slaveaddr); 110 break; 111 case SET_CORR: 112 while(!usiTwiDataInReceiveBuffer()); 113 m = usiTwiReceiveByte(); 114 m = m << 8; 115 while(!usiTwiDataInReceiveBuffer()); 116 m = m | usiTwiReceiveByte(); 117 eeprom_write_word(&EE_m, m); 118 while(!usiTwiDataInReceiveBuffer()); 119 b = usiTwiReceiveByte(); 120 eeprom_write_byte(&EE_b, b); 121 while(!usiTwiDataInReceiveBuffer()); 122 k = usiTwiReceiveByte(); 123 eeprom_write_byte(&EE_k, k); 124 default: 125 value = ERROR; 126 break; 127 } 110 128 111 129 usiTwiTransmitByte(value); 112 130 } 113 131 114 // Do something else while waiting for the TWI transceiver to complete.132 asm volatile ("NOP" ::); // stall while waiting for the TWI transceiver to complete 115 133 116 asm volatile ("NOP" ::);117 134 } 118 135 } 119 120 /*121 * ADCIN122 *123 * Read the specified Analog to Digital Conversion channel124 *125 */126 136 127 137 uint16_t ADCIN(void)

