Stap 3: De code
/***
PIN-TOEWIJZINGEN OP ATMEGA48
PC6 (PCINT14/RESET)
PC5 (ADC5/SCL/PCINT13) / / I2C klok ingang
Pc4 (ADC4/SDA/PCINT12) / / I2C gegevens ingang
PC3 (ADC3/PCINT11) //Sensor 4 IR ontvanger
PC2 (ADC2/PCINT10) //Sensor 3 IR ontvanger
PC1 (ADC1/PCINT9) //Sensor 2 IR ontvanger
PC0 (ADC0/PCINT8) //Sensor 1 IR ontvanger
PB7 (PCINT7/XTAL2/TOSC2) //IR 4 activeren
PB6 (PCINT6/XTAL1/TOSC1) //IR 3 Trigger
Pb5 (SCK/PCINT5) //IR 2 Trigger
PB4 (MISO/PCINT4) //IR 1 activeren
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 pin-toewijzingen
#define PWM2 5 //PORTD
#define PWM3 3 //PORTB
#define PWM4 3 //PORTD
#define F_CPU 8000000UL
#include
#include
#include
#include
/ *** Functioneren verklaringen *** /
int ADC_read(void);
VOID A2D_Channel_Select (unsigned char kanaal);
nietig Init_ADC(void);
nietig Init_Timer0(void);
nietig Init_Timer1(void);
nietig Init_Timer2(void);
nietig Delay(void);
nietig Calibrate_Sensors(void);
nietig Init_I2C_Slave_Rx(void);Alle, maar een van deze variabelen vluchtige wordt verklaard omdat in principe al het werk wordt uitgevoerd
Interrupt service routines
/ *** Globale variabele declaraties *** / unsigned char buffer = 8; int main(void) Sei(); PORTD | = (1 << PWM1); knipperen om aan te geven van einde van kalibratie Init_Timer0(); Init_I2C_Slave_Rx(); while(1) }
vluchtige char Sensor_Values_Updated = 0;
vluchtige char Timer1_Overflow = 0;
kanaal van de vluchtige unsigned char = 0;
vluchtige int Amb_Sensor_1 = 0, Amb_Sensor_2 = 0, Amb_Sensor_3 = 0, Amb_Sensor_4 = 0;
vluchtige int Sensor_1 = 0, Sensor_2 = 0, Sensor_3 = 0, Sensor_4 = 0;
vluchtige int Initial_1 = 0, Initial_2 = 0, Initial_3 = 0, Initial_4 = 0;
vluchtige int New_PWM1 = 0, New_PWM2 = 0, New_PWM3 = 0, New_PWM4 = 0;
vluchtige int Old_PWM1 = 0, Old_PWM2 = 0, Old_PWM3 = 0, Old_PWM4 = 0;
{
DDRB = 0XFF;
Zorg ervoor dat de IR-stralers zijn uitgeschakeld, en PWM 3
PORTB & = ~ ((1 << 7) | () 1 << 6) | (1 << 5) | (1 << 4) | (1 << 3));
DDRC = 0X00; maken van poort C ingangen
DDRD = 0XFF;
PORTD = 0X00; alle PORT D laag ingesteld. zorgt voor
Init_ADC();
Calibrate_Sensors();
_delay_ms(600);
PORTD & = ~ (1 << PWM1);
Init_Timer2();
{
iets doen?
//. . .
}
Met de klok lopen bij ongeveer 8MHz, en Timer 1 tellen tot 65535. De timer zal overlopen ongeveer 122 keer per seconde. Deze ISR zal brand en de timer overloop variabele zal verhogen, en vervolgens de functie SWITCH/CASE kiest de volgende pixel te testen
ISR(TIMER1_OVF_vect)
{
Timer1_Overflow ++; interval timer overloop variabele
switch(Timer1_Overflow)
{
Case 1:
A2D_Channel_Select(0); Selecteer ADC kanaal 0
Amb_Sensor_1 = ADC_read(); Neem ambient IR sensor lezing
IR_1_ON; inschakelen van IR 1 LED, PORTB | = (1 << 4)
Delay(); vertraging bij de IR ontvanger te regelen
Sensor_1 = ADC_read(); het nemen van actieve ADC lezing van IR ontvanger
IR_1_OFF; IR 1 LED uitschakelen
New_PWM1 = (Sensor_1 - Amb_Sensor_1) - Initial_1; voorwaarde lezingen
Als (New_PWM1 < = 0) {New_PWM1 = 0;} voorkomen van negatieve getallen
eenvoudige low-pass filter (87,5% * oude) + (12,5% * New) . Het duurt slechts de oude waarde en gewichten het meer dan de oudere waarde. Heeft hetzelfde effect van het vertragen van de verandering, die is van cruciaal belang bij het verstrekken van vloeibare veranderingen in helderheid
New_PWM1 = ((7*Old_PWM1) >> 3) + (New_PWM1 >> 3);
Als (OCR0A > = 1) {DDRD | = (1 << PWM1);}
else {DDRD & = ~ (1 << PWM1);} LEDs volledig uitschakelen//artificially verhogen de waarde van de sensor lezen, niet volstrekt noodzakelijk is, maar maakt de sensor gevoeliger lijkendoordat helderder vroeg
New_PWM1 << = 2;
if(New_PWM1 > 255) {New_PWM1 = 255;}
OCR0A = New_PWM1;
New_PWM1 >> = 2;
De onderstaande code die volledig is uitgecommentarieerd is een andere helderheid-algoritme. Het is een activerende algoritme dat de LEDs op wanneer iets binnen een drempel komt zal vervagen. En de LEDs zullen fade out langzaam wanneer het object uit de drempel afstand. Dit is handig omdat de operatie zou betrouwbaarder en de fade out tijd kan worden aangepast zeer lang of hoe lang u het wilt. Ik heb deze code niet getest dus ik niet zekere ben wanneer op 100 werkzaamheden zal %
/ *** //Trigger reeks if(OCR0A < 255)
if(New_PWM1 > Initial_1)
{
DDRD | = (1 << PWM1);
{
OCR0A += (255 - OCR0A) >> 2;
OCR0A ++;
}
Als (New_PWM1 < (Initial_1 + 8))
{
Initial_1 = ((7*Initial_1) >> 3) + (New_PWM1 >> 3);
}
}
anders if(New_PWM1 < Initial_1)
{
if(OCR0A > 0)
{
OCR0A-= (OCR0A >> 4) + 1;
OCR0A--;
}
else if (OCR0A < = 0)
{
DDRD & = ~ (1 << PWM1);
}
}
*****/
Old_PWM1 = New_PWM1;
breken;
Case 2:
A2D_Channel_Select(1); selecteert u ADC kanaal 1
Amb_Sensor_2 = ADC_read();
IR_2_ON; inschakelen van IR 2 LED, PORTB | = (1 << 5)
Delay(); vertraging bij de IR ontvanger te regelen
Sensor_2 = ADC_read(); nemen van ADC lezen
IR_2_OFF; IR 2 LED uitschakelen
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);
Als (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 ++;
}
Als (New_PWM2 < (Initial_2 + 8))
{
Initial_2 = ((7*Initial_2) >> 3) + (New_PWM2 >> 3);
}
}
anders if(New_PWM2 < Initial_2)
{
if(OCR0B > 0)
{
OCR0B-= (OCR0B >> 4) + 1;
OCR0B--;
}
else if (OCR0B < = 0)
{
DDRD & = ~ (1 << PWM2);
}
}
*/
Old_PWM2 = New_PWM2;
breken;
Case 3:
A2D_Channel_Select(2); Selecteer ADC kanaal 2
Amb_Sensor_3 = ADC_read();
IR_3_ON; inschakelen van IR 3 LED, PORTB | = (1 << 6)
Delay(); vertraging bij de IR ontvanger te regelen
Sensor_3 = ADC_read(); nemen van ADC lezen
IR_3_OFF; IR 3 LED uitschakelen
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);
Als (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 ++;
}
Als (New_PWM3 < (Initial_3 + 8))
{
Initial_3 = ((7*Initial_3) >> 3) + (New_PWM3 >> 3);
}
}
anders if(New_PWM3 < Initial_3)
{
if(OCR2A > 0)
{
OCR2A-= (OCR2A >> 4) + 1;
OCR2A--;
}
else if (OCR2A < = 0)
{
DDRB & = ~ (1 << PWM3);
}
}
*/
Old_PWM3 = New_PWM3;
breken;
Case 4:
A2D_Channel_Select(3); Selecteer ADC kanaal 3
Amb_Sensor_4 = ADC_read();
IR_4_ON; inschakelen van IR 4 LED, PORTB | = (1 << 7)
Delay(); vertraging bij de IR ontvanger te regelen
Sensor_4 = ADC_read(); nemen van ADC lezen
IR_4_OFF; IR 4 LED uitschakelen
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);
Als (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 ++;
}
Als (New_PWM4 < (Initial_4 + 8))
{
Initial_4 = ((7*Initial_4) >> 3) + (New_PWM4 >> 3);
}
}
anders 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; Reset
Sensor_Values_Updated = 1; nieuwe waarden klaar
breken;
} //end schakelaar
} //end ISR
Dit is iets wat die ik ben gaan uitzoeken later te proberen. Het is niet-geteste elementaire code die kon ik wil de twee Wire Interface (I2C) gebruiken dus verschillende controllers en met elkaar communiceren of één master en een stelletje slaven.
/****
ISR(TWI_vect) //to omvatten later wanneer mij worden zulks postuur uiterlijk
{
switch(TWSR)
{
kast TW_SR_SLA_ACK: //0x60 //Own adres Rx
Byte_Number == 1;
breken;
kast TW_SR_DATA_ACK: / / 0x80, gegevens in TWDR
switch(Byte_Number)
{
Case 1:
Reg_Addr = TWDR;
Byte_Number ++;
breken;
Case 2:
Reg_Val = TWDR;
Byte_Number = 0; herstellen, tenzij meer bytes zijn afkomstig
breken;
Case Max_Bytes_Expected:
Reg_Val = TWDR;
Byte_Number = 0; herstellen, tenzij meer bytes zijn afkomstig
breken;
}
breken;
kast TW_SR_GCALL_DATA_ACK: / / 0x90
if(Byte_Number == 1)
{
Reg_Addr = TWDR;
Byte_Number ++;
}
anders if(Byte_Number == 2)
{
Reg_Val = TWDR;
Byte_Number = 0; herstellen, tenzij meer bytes zijn afkomstig
}
breken;
} //end schakelaar
} //end ISR
VOID Init_I2C_Slave_Rx(void)
{
Apparaatadres instellen in TWAR
TWAR = 10; Misschien maken dit als een argument aan deze functie
TWCR | = ((1 << TWEA) | () 1 << TWEN));
TWCR & = ~ ((1 << TWSTA) | () 1 << TWSTO));
}
****/
ongeldig Calibrate_Sensors(void) //establish eerste ambient sensor-waardes
{
char q = 0;
Init_Timer1();
voor (q = 0; q < 32; q ++) //should nemen een second-ish
{
wacht voor de cyclus van de Sensor worden gedaan, dan verzamelen sensoren waarden
while(Sensor_Values_Updated == 0) {}
Initial_1 += (Sensor_1 - Amb_Sensor_1); eerste verschil
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
} //end voor
//Condition eerste Ambient Sensor-waardes, plus een buffer VOID Init_ADC(void) VOID Init_Timer0(void) //PWM voor sensoren 1 & 2 int ADC_read(void) / *** Selecteer ADC kanaal voorafgaand aan bellen deze functie *** /
Initial_1 = (Initial_1 >> 5) + buffer;
Initial_2 = (Initial_2 >> 5) + buffer;
Initial_3 = (Initial_3 >> 5) + buffer;
Initial_4 = (Initial_4 >> 5) + buffer;
}
{
ADMUX | = 1 << REFS0; AVCC met externe condensator op AREF pin
ADMUX | = (1 <
}
{
Snel PWM, niet-inverterende, WGM02-WGM00 == 011, geen overflow interrupt
TCCR0A | = ((1 << COM0A1) | () 1 << COM0B1) | (1 << WGM01) | (1 << WGM00));
TCCR0B | = (1 << CS00); Start van de klok, geen prescale
}
VOID Init_Timer1(void)
{
geen PWM, inschakelen overflow interrupt,
TOP == 0xFFFF 65536 cycli == == ongeveer 122 overloop interrupts per seconde
TCCR1B | = (1 << CS10);
TIMSK1 | = (1 << TOIE1);
}
VOID Init_Timer2(void) //PWM voor sensoren 3 & 4
{
Snel PWM, niet-inverterende, WGM22-WGM20 == 011, geen overflow interrupt
TCCR2A | = ((1 << COM2A1) | () 1 << COM2B1) | (1 << WGM21) | (1 << WGM20));
TCCR2B | = (1 << CS20); Start van de klok, geen prescale
}
{
int ADC_value = 0;
int ADCsample;
char i;
ADCSRA | = (1 < ADCSRA | = (1 < terwijl ((ADCSRA & ADSC)); Wacht tot de conversie te voltooien, en vergeet over het
//This gebeurt niet meer dan 64 maal, langer en ADC1_value moet groter zijn dan een unsigned int!!!
voor (ik = 0; ik < 64; i ++)
{
ADCSRA | = (1 < terwijl ((ADCSRA & ADSC)); wacht tot de conversie te voltooien
//Change terug naar ADCL voor 10 bits precisie, en verwijderen van shift-links bitinstelling
ADCsample = ADCH;
ADCsample += (ADCH << 8); Links verschuiven de bovenste twee bits 8 plaatsen
ADC_value += ADCsample; toevoegen van ADCsample aan ADC_sensor
}
gemiddeld monster door rechts verschuiven 6 plaatsen, hetzelfde als delen door 64
ADC_value = (ADC_value >> 6);
Return ADC_value;
ADCSRA & ~(1< =
VOID A2D_Channel_Select (unsigned char kanaal)
{
schakelaar (kanaal)
{
geval van 0: //select A2D kanaal 0
ADMUX & = ~ ((1 << 3) | () 1 << 2) | (1 << 1) | (1 << 0));
breken;
geval 1: //select A2D kanaal 1
ADMUX & = ~ ((1 << 3) | () 1 << 2) | (1 << 1));
ADMUX | = (1 << 0);
breken;
geval 2: //select A2D kanaal 2
ADMUX & = ~ ((1 << 3) | () 1 << 2) | (1 << 0));
ADMUX | = (1 << 1);
breken;
Case 3: //select A2D kanaal 3
ADMUX & = ~ ((1 << 3) | () 1 << 2));
ADMUX | = ((1 << 1) | () 1 << 0));
breken;
/ * ik ben niet met behulp van deze voor dit project
geval 4: //select A2D kanaal 4
ADMUX & = ~ ((1 << 3) | () 1 << 1) | (1 << 0));
ADMUX | = (1 << 2);
breken;
geval 5: //select A2D kanaal 5
ADMUX & = ~ ((1 << 3) | () 1 << 1));
ADMUX | = ((1 << 2) | () 1 << 0));
breken;
*/
} //end schakelaar
}
VOID Delay(void)
{
_delay_us(100);
}