• 16.jpg
  • 17.jpg
  • 18.jpg
  • 19.jpg
  • 20.jpg

第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);
    }


下一步上一步

评 论

e

选择昵称后请轻按空格键

提 交

请勿进行人身攻击,谩骂以及任何违法国家相关法律法规的言论。

信息

41640

浏览
5
foooy007

作者:foooy007

分享:17

更多的去看、听、想、做,以及更多的去总结。 >>

关键词: 传感器 atmega led

猜你会喜欢

简单的光线探测器

光线探测器是最普遍的传感器之一,并广泛应...

无线供电的LED旋转时钟

这次的制作结合了无线供电的原理和时钟功能...

发光圣诞树

圣诞节就要来了,你还没有圣诞树么?现在就...

高手打造的智能无线供电台灯

无线供电是一个很吸引人的制作课题,许多电...

世界上最小的DS18B20温度计

DS18B20不少朋友都用过吧,不过似乎...