第4步编写代码
我编写的代码见附件
/*** PIN ASSIGNMENTS ON ATMEGA48 PC6 (PCINT14/RESET) PC5 (ADC5/SCL/PCINT13) // I2C时钟输入 PC4 (ADC4/SDA/PCINT12) // I2C数据输入 PC3 (ADC3/PCINT11) //传感器 4 IR 接收器 PC2 (ADC2/PCINT10) PC1 (ADC1/PCINT9) PC0 (ADC0/PCINT8) PB7 (PCINT7/XTAL2/TOSC2) //IR 4 触发 PB6 (PCINT6/XTAL1/TOSC1) //IR 3 触发 PB5 (SCK/PCINT5) PB4 (MISO/PCINT4) PB3 (MOSI/OC2A/PCINT3) //PWM 3 PB2 (SS/OC1B/PCINT2) PB1 (OC1A/PCINT1) PB0 (PCINT0/CLKO/ICP1) PD0 (PCINT16/RXD) PD1 (PCINT17/TXD) PD2 (PCINT18/INT0) PD3 (PCINT19/OC2B/INT1) //PWM 4 PD4 (PCINT20/XCK/T0) PD5 (PCINT21/OC0B/T1) //PWM 2 PD6 (PCINT22/OC0A/AIN0) //PWM 1 PD7 (PCINT23/AIN1) ***/ #define IR_1_ON PORTB |= (1<<4) #define IR_2_ON PORTB |= (1<<5) #define IR_3_ON PORTB |= (1<<6) #define IR_4_ON PORTB |= (1<<7) #define IR_1_OFF PORTB &= ~(1<<4) #define IR_2_OFF PORTB &= ~(1<<5) #define IR_3_OFF PORTB &= ~(1<<6) #define IR_4_OFF PORTB &= ~(1<<7) #define PWM1 6 //PORTD PWM引脚分配 #define PWM2 5 //PORTD #define PWM3 3 //PORTB #define PWM4 3 //PORTD #define F_CPU 8000000UL #include #include #include //#include /****Function Declarations****/ int ADC_read(void); void A2D_Channel_Select(unsigned char channel); void Init_ADC(void); void Init_Timer0(void); void Init_Timer1(void); void Init_Timer2(void); void Delay(void); void Calibrate_Sensors(void); //void Init_I2C_Slave_Rx(void); /****Global Variable Declarations****/ volatile char Sensor_Values_Updated = 0; volatile char Timer1_Overflow = 0; volatile unsigned char channel = 0; volatile int Amb_Sensor_1 = 0, Amb_Sensor_2 = 0, Amb_Sensor_3 = 0, Amb_Sensor_4 = 0; volatile int Sensor_1 = 0, Sensor_2 = 0, Sensor_3 = 0, Sensor_4 = 0; volatile int Initial_1 = 0, Initial_2 = 0, Initial_3 = 0, Initial_4 = 0; volatile int New_PWM1 = 0, New_PWM2 = 0, New_PWM3 = 0, New_PWM4 = 0; volatile int Old_PWM1 = 0, Old_PWM2 = 0, Old_PWM3 = 0, Old_PWM4 = 0; unsigned char buffer = 8; int main(void) { DDRB = 0xff; //make sure IR emitters are turned off, and PWM 3 PORTB &= ~((1 << 7)|(1 << 6)|(1 << 5)|(1 << 4)|(1 << 3)); DDRC = 0x00; DDRD = 0xff; PORTD = 0x00; //使所有PORT D为低 Init_ADC(); sei(); Calibrate_Sensors(); PORTD |= (1 << PWM1); _delay_ms(600); PORTD &= ~(1 << PWM1); Init_Timer0(); Init_Timer2(); //Init_I2C_Slave_Rx(); while(1) { //do something? //. . . } } ISR(TIMER1_OVF_vect) { Timer1_Overflow++; switch(Timer1_Overflow) { case 1: A2D_Channel_Select(0); //select ADC channel 0 Amb_Sensor_1 = ADC_read(); IR_1_ON; //turn on IR 1 LED, PORTB |= (1<<4) Delay(); //delay for the IR receiver to settle Sensor_1 = ADC_read(); //take active ADC reading of IR receiver IR_1_OFF; //turn off IR 1 LED New_PWM1 = (Sensor_1 - Amb_Sensor_1) - Initial_1; //condition readings if(New_PWM1 <= 0) { New_PWM1 = 0; } New_PWM1 = ((7*Old_PWM1)>>3) + (New_PWM1>>3); if(OCR0A >= 1) {DDRD |= (1 << PWM1);} else { DDRD &= ~(1 << PWM1); } New_PWM1 <<= 2; if(New_PWM1 > 255) { New_PWM1 = 255; } OCR0A = New_PWM1; New_PWM1 >>= 2; /***** //Trigger sequence if(New_PWM1 > Initial_1) { DDRD |= (1 << PWM1); if(OCR0A < 255) { OCR0A += (255 - OCR0A)>>2 ; //OCR0A++; } if (New_PWM1 < (Initial_1 + 8)) { Initial_1 = ((7*Initial_1)>>3) + (New_PWM1>>3); } } else if(New_PWM1 < Initial_1) { if(OCR0A > 0) { OCR0A -= (OCR0A >> 4)+1; //OCR0A--; } else if(OCR0A <= 0) { DDRD &= ~(1 << PWM1); } } *****/ Old_PWM1 = New_PWM1; break; case 2: A2D_Channel_Select(1); //select ADC channel 1 Amb_Sensor_2 = ADC_read(); IR_2_ON; //turn on IR 2 LED, PORTB |= (1<<5) Delay(); //delay for the IR receiver to settle Sensor_2 = ADC_read(); //take ADC reading IR_2_OFF; //turn off IR 2 LED New_PWM2 = (Sensor_2 - Amb_Sensor_2) - Initial_2; if(New_PWM2 < 0) { New_PWM2 = 0; } New_PWM2 = ((7*Old_PWM2)>>3) + (New_PWM2>>3); if(OCR0B >= 1) {DDRD |= (1 << PWM2);} else { DDRD &= ~(1 << PWM2); } New_PWM2 <<= 2; if(New_PWM2 > 255) { New_PWM2 = 255; } OCR0B = New_PWM2; New_PWM2 >>= 2; /* if(New_PWM2 > Initial_2) { DDRD |= (1 << PWM2); if(OCR0B < 255) { OCR0B += (255 - OCR0B)>>2 ; //OCR0B++; } if (New_PWM2 < (Initial_2 + 8)) { Initial_2 = ((7*Initial_2)>>3) + (New_PWM2>>3); } } else if(New_PWM2 < Initial_2) { if(OCR0B > 0) { OCR0B -= (OCR0B >> 4)+1; //OCR0B--; } else if(OCR0B <= 0) { DDRD &= ~(1 << PWM2); } } */ Old_PWM2 = New_PWM2; break; case 3: A2D_Channel_Select(2); //select ADC channel 2 Amb_Sensor_3 = ADC_read(); IR_3_ON; //turn on IR 3 LED, PORTB |= (1<<6) Delay(); //delay for the IR receiver to settle Sensor_3 = ADC_read(); //take ADC reading IR_3_OFF; //turn off IR 3 LED New_PWM3 = (Sensor_3 - Amb_Sensor_3) - Initial_3; if(New_PWM3 < 0) { New_PWM3 = 0; } New_PWM3 = ((7*Old_PWM3)>>3) + (New_PWM3>>3); if(OCR2A >= 1) {DDRB |= (1 << PWM3);} else { DDRB &= ~(1 << PWM3); } New_PWM3 <<= 2; if(New_PWM3 > 255) { New_PWM3 = 255; } OCR2A = New_PWM3; New_PWM3 >>= 2; /* if(New_PWM3 > Initial_3) { DDRB |= (1 << PWM3); if(OCR2A < 255) { OCR2A += (255 - OCR2A)>>2 ; //OCR2A++; } if (New_PWM3 < (Initial_3 + 8)) { Initial_3 = ((7*Initial_3)>>3) + (New_PWM3>>3); } } else if(New_PWM3 < Initial_3) { if(OCR2A > 0) { OCR2A -= (OCR2A >> 4)+1; //OCR2A--; } else if(OCR2A <= 0) { DDRB &= ~(1 << PWM3); } } */ Old_PWM3 = New_PWM3; break; case 4: A2D_Channel_Select(3); //select ADC channel 3 Amb_Sensor_4 = ADC_read(); IR_4_ON; //turn on IR 4 LED, PORTB |= (1<<7) Delay(); //delay for the IR receiver to settle Sensor_4 = ADC_read(); //take ADC reading IR_4_OFF; //turn off IR 4 LED New_PWM4 = (Sensor_4 - Amb_Sensor_4) - Initial_4; if(New_PWM4 < 0) { New_PWM4 = 0; } New_PWM4 = ((7*Old_PWM4)>>3) + (New_PWM4>>3); if(OCR2B >= 1) {DDRD |= (1 << PWM4);} else { DDRD &= ~(1 << PWM4); } New_PWM4 <<= 2; if(New_PWM4 > 255) { New_PWM4 = 255; } OCR2B = New_PWM4; New_PWM4 >>= 2; /* if(New_PWM4 > Initial_4) { DDRD |= (1 << PWM4); if(OCR2B < 255) { OCR2B += (255 - OCR2B)>>2 ; //OCR2B++; } if (New_PWM4 < (Initial_4 + 8)) { Initial_4 = ((7*Initial_4)>>3) + (New_PWM4>>3); } } else if(New_PWM1 < Initial_4) { if(OCR2B > 0) { OCR2B -= (OCR2B >> 4)+1; //OCR2B--; } else if(OCR2B <= 0) { DDRD &= ~(1 << PWM4); } } */ Old_PWM4 = New_PWM4; Timer1_Overflow = 0; Sensor_Values_Updated = 1; break; }//end switch }//end ISR /**** ISR(TWI_vect) //to include later when I get this figured out { switch(TWSR) { case TW_SR_SLA_ACK: //0x60 //Own address Rx Byte_Number == 1; break; case TW_SR_DATA_ACK: // 0x80 , data in TWDR switch(Byte_Number) { case 1: Reg_Addr = TWDR; Byte_Number++; break; case 2: Reg_Val = TWDR; Byte_Number = 0; //reset, unless more bytes are coming break; case Max_Bytes_Expected: Reg_Val = TWDR; Byte_Number = 0; //reset, unless more bytes are coming break; } break; case TW_SR_GCALL_DATA_ACK: // 0x90 if(Byte_Number == 1) { Reg_Addr = TWDR; Byte_Number++; } else if(Byte_Number == 2) { Reg_Val = TWDR; Byte_Number = 0; //reset, unless more bytes are coming } break; }//end switch }//end ISR void Init_I2C_Slave_Rx(void) { //Set Device Address in TWAR TWAR = 10; TWCR |= ((1 << TWEA)|(1 << TWEN)); TWCR &= ~((1 << TWSTA)|(1 << TWSTO)); } ****/ void Calibrate_Sensors(void) //establish initial ambient sensor values { char q = 0; Init_Timer1(); for(q=0; q<32; q++) //should take one second-ish { //wait for Sensor cycle to be done, then gather sensors values while(Sensor_Values_Updated == 0) {} Initial_1 += (Sensor_1 - Amb_Sensor_1); //initial difference Initial_2 += (Sensor_2 - Amb_Sensor_2); Initial_3 += (Sensor_3 - Amb_Sensor_3); Initial_4 += (Sensor_4 - Amb_Sensor_4); Sensor_Values_Updated = 0; //reset } //condition Initial Ambient Sensor values, plus a buffer Initial_1 = (Initial_1 >> 5) + buffer; Initial_2 = (Initial_2 >> 5) + buffer; Initial_3 = (Initial_3 >> 5) + buffer; Initial_4 = (Initial_4 >> 5) + buffer; } void Init_ADC(void) { ADMUX |= 1 << REFS0; //AVCC with external capacitor at AREF pin ADMUX |= (1< } void Init_Timer0(void) { //Fast PWM, non-inverting, WGM02-WGM00 == 011, no overflow interrupt TCCR0A |= ((1 << COM0A1)|(1 << COM0B1)|(1 << WGM01)|(1 << WGM00)); TCCR0B |= (1 << CS00); //start clock, no prescale } void Init_Timer1(void) { //no PWM, enable overflow interrupt, //TOP == 0xFFFF == 65536 cycles == roughly 122 overflow interrupts/sec TCCR1B |= (1 << CS10); TIMSK1 |= (1 << TOIE1); } void Init_Timer2(void) //PWM for sensors 3 & 4 { //Fast PWM, non-inverting, WGM22-WGM20 == 011, no overflow interrupt TCCR2A |= ((1 << COM2A1)|(1 << COM2B1)|(1 << WGM21)|(1 << WGM20)); TCCR2B |= (1 << CS20); //start clock, no prescale } int ADC_read(void) /***select ADC channel prior to calling this function***/ { int ADC_value = 0; int ADCsample; char i; ADCSRA |= (1< ADCSRA |= (1< while ((ADCSRA & ADSC)); for (i=0; i<64; i++) { ADCSRA |= (1< while ((ADCSRA & ADSC)); //wait for conversion to finish //change back to ADCL for 10 bit precision, and remove left-shift bit setting ADCsample = ADCH; //ADCsample += (ADCH<<8); ADC_value += ADCsample; //add ADCsample to ADC_sensor } return ADC_value; ADCSRA &= ~(1< void A2D_Channel_Select(unsigned char channel) { switch (channel) { case 0: ADMUX &= ~((1 << 3)|(1 << 2)|(1 << 1)|(1 << 0)); break; case 1: ADMUX &= ~((1 << 3)|(1 << 2)|(1 << 1)); ADMUX |= (1 << 0); break; case 2: ADMUX &= ~((1 << 3)|(1 << 2)|(1 << 0)); ADMUX |= (1 << 1); break; case 3: ADMUX &= ~((1 << 3)|(1 << 2)); ADMUX |= ((1 << 1)|(1 << 0)); break; /* I am not using these for this project case 4: ADMUX &= ~((1 << 3)|(1 << 1)|(1 << 0)); ADMUX |= (1 << 2); break; case 5: ADMUX &= ~((1 << 3)|(1 << 1)); ADMUX |= ((1 << 2)|(1 << 0)); break; */ }//end switch } void Delay(void) { _delay_us(100); }
猜你会喜欢
简单的光线探测器
光线探测器是最普遍的传感器之一,并广泛应...
无线供电的LED旋转时钟
这次的制作结合了无线供电的原理和时钟功能...
发光圣诞树
圣诞节就要来了,你还没有圣诞树么?现在就...
高手打造的智能无线供电台灯
无线供电是一个很吸引人的制作课题,许多电...
世界上最小的DS18B20温度计
DS18B20不少朋友都用过吧,不过似乎...
评 论
选择昵称后请轻按空格键
请勿进行人身攻击,谩骂以及任何违法国家相关法律法规的言论。