IR-diod
Enligt databladet klarar den max 100mA, dock klarar inte pinnarna på en AVR mer än 40mA. Så säg 20mA ?
Spänningen över ir-dioden är enligt databladet ca 1.3 volt. Jag gissar att du driver AVR med 5 volt. Då blir det 3.7 volt över motståndet.
3.7 volt / 0.020 ampere = 185 ohm
Standardmotstånd är på 180 ohm och 220 ohm, så något i den trakten borde duga.
Spänningen över ir-dioden är enligt databladet ca 1.3 volt. Jag gissar att du driver AVR med 5 volt. Då blir det 3.7 volt över motståndet.
3.7 volt / 0.020 ampere = 185 ohm
Standardmotstånd är på 180 ohm och 220 ohm, så något i den trakten borde duga.
[b]Ny fråga[/b]
Jag har nu kopplat in dioden och har suttit ett tag med att försöka skriva ett program som skickar en signal till min stereo. Det funkar tyvärr inte alls. Vad kan det vara för fel??
Jag vill skicka en signal med 38kHz bärvåg med hjälp av timer1. Om nån kan hitta något i koden som verkar vara fel får denne gärna hojta till:) Eller är det nåt som är otydligt i koden är det oxå bara att fråga...
Jag vill skicka en signal med 38kHz bärvåg med hjälp av timer1. Om nån kan hitta något i koden som verkar vara fel får denne gärna hojta till:) Eller är det nåt som är otydligt i koden är det oxå bara att fråga...
Kod: Markera allt
#include <avr/io.h>
int main(void){
TCCR1A=0x00;
TCCR1B=0x09;
OCR1A=13;
DDRD=0x20;
unsigned int i,j;
unsigned char switch_zero;
unsigned char one_or_zero;
unsigned int volume_down=0x50AF;
void send_one(void){
for(j=0;j<500;j++){
TCCR1A=0x40;
}
for(j=0;j<1800;j++){
TCCR1A=0x00;
}
}
void send_zero(void){
for(j=0;j<500;j++){
TCCR1A=0x40;
}
for(j=0;j<600;j++){
TCCR1A=0x00;
}
}
void send_startbit(void){
for(i=0;i<9000;i++){
TCCR1A=0x40;
}
for(i=0;i<4600;i++){
TCCR1A=0x00;
}
for(i=0;i<8;i++){
send_zero();
}
for(i=0;i<8;i++){
send_one();
}
}
void check_one_or_zero(unsigned int one_or_zero){
if(one_or_zero==1){
send_one();
}
else{
send_zero();
}
}
while(1){
switch_zero = PINB & 0x01; //0000 0001
if(switch_zero==0){
send_startbit();
for(i=15;i>0;i--){
one_or_zero=volume_down>>i;
one_or_zero &= 0x0001;
check_one_or_zero(one_or_zero);
}
one_or_zero = volume_down & 0x0001;
check_one_or_zero(one_or_zero);
for(i=0;i<10000;i++){
}
}
}
}
Senast redigerad av Luckan 18 mars 2007, 23:12:46, redigerad totalt 2 gånger.
Jag ser inte hur du har tänkt att utnyttja timer1. Du har inte ha någon interruptrutin som tar hand om räknaravbrott.
Sen är jag inte riktigt med på dina for-loopar typ:
Vad har du tänkt att göra här?
Sen så har du inte kommenterat något av koden vilket gör det mycket svårare att följa.
Sen är jag inte riktigt med på dina for-loopar typ:
Kod: Markera allt
void send_zero(void){
for(j=0;j<500;j++){
TCCR1A=0x40;
}
for(j=0;j<600;j++){
TCCR1A=0x00;
}
}
Sen så har du inte kommenterat något av koden vilket gör det mycket svårare att följa.
- MicaelKarlsson
- Inlägg: 4669
- Blev medlem: 18 juni 2004, 09:16:07
- Ort: Aneby
- Kontakt:
"Att försöka fixa det med for-loopar för att få rätt "timing" är dömt att misslyckas. "
Håller med!
I detta fall så är det säkert lättare att använda en delayfunktion, om det nu är så att pulserna skall vara 600μs. Då ser jag två alternativ:
- Använda delayfunktion. För WinAVR: _delay_us(delay_time);
- Använda t.ex. timer2
Tänk på:
EDIT:
"Jag har nu kopplat in dioden och har suttit ett tag med att försöka skriva ett program som skickar en signal till min stereo."
Har du kopplat den direkt till din AVR? Om du drar mer ström än vad din AVR klarar så kan ju det ställa till det för dig.
Har du kollat att du får ut det du vill?
Håller med!
I detta fall så är det säkert lättare att använda en delayfunktion, om det nu är så att pulserna skall vara 600μs. Då ser jag två alternativ:
- Använda delayfunktion. För WinAVR: _delay_us(delay_time);
- Använda t.ex. timer2
Tänk på:
Detta är hämtat från delay.hThe maximal possible delay is 768 us / F_CPU in MHz.
The maximal possible delay is 262.14 ms / F_CPU in MHz.
EDIT:
"Jag har nu kopplat in dioden och har suttit ett tag med att försöka skriva ett program som skickar en signal till min stereo."
Har du kopplat den direkt till din AVR? Om du drar mer ström än vad din AVR klarar så kan ju det ställa till det för dig.
Har du kollat att du får ut det du vill?
Tack för alla svar! Har insett nu efter mätning med flukemetern att mina for-loopar var helt uppe på läktaren och införskaffade korv med mos...
Men om jag då istället använder tex TIMER2, hur ska den användas? För att t.ex. skicka en logisk etta vill jag sända en 38kHz våg i cirka 500us, vilket sedan skall följas av "ingenting" i cirka 600us. Kan jag göra det genom att helt enkelt först nollställa TIMER2 och sedan låta den räkna upp till 500 och sedan nollställa igen och räkna upp till 600?
![Shock :shock:](./images/smilies/26.gif)
Men om jag då istället använder tex TIMER2, hur ska den användas? För att t.ex. skicka en logisk etta vill jag sända en 38kHz våg i cirka 500us, vilket sedan skall följas av "ingenting" i cirka 600us. Kan jag göra det genom att helt enkelt först nollställa TIMER2 och sedan låta den räkna upp till 500 och sedan nollställa igen och räkna upp till 600?
När jag har gjort IR-sändere (i och för sig med en PIC, men det är
ingen principiell skillnad), så har jag konfigurerat PWM modulen
för att generera bärvågen (t.ex 38 Khz). Sedan genererade jag
signalen (d.v.s *moduleringen* av bärvågen) genom att helt enkelt
stänga av/på PWM modulen. På en PIC är det en enda bit som
ska sättas/clearas, borde vara något liknande på en AVR...
Timingen av signalen (d.v.s de 600 us pulserna) fixade jag via en
*annan* timer (än den som styr PWM modulen).
ingen principiell skillnad), så har jag konfigurerat PWM modulen
för att generera bärvågen (t.ex 38 Khz). Sedan genererade jag
signalen (d.v.s *moduleringen* av bärvågen) genom att helt enkelt
stänga av/på PWM modulen. På en PIC är det en enda bit som
ska sättas/clearas, borde vara något liknande på en AVR...
Timingen av signalen (d.v.s de 600 us pulserna) fixade jag via en
*annan* timer (än den som styr PWM modulen).
du använder t.ex. timer0 för att skapa interrupts (CTC-mode) med en frekvens på 38kHz. Vid varje interrupt så flippar du utsignal så du får 1-0-1-0-1-.... För att bestämma när du ska flippa utsignalen och när du ska ha den låg använder du timer1.
Hoppas du blir något klokare utav mitt försök till förklaring
Hoppas du blir något klokare utav mitt försök till förklaring
- MicaelKarlsson
- Inlägg: 4669
- Blev medlem: 18 juni 2004, 09:16:07
- Ort: Aneby
- Kontakt:
Luckan: for-lopen glömde väl inte senapen?
Skämt åsido!!
Sedan kan du köra timer0 som "togglar" en pinne
Om du inte får rätt frekvens kan du använda:
TCNTx för att sätta ett startvärde för räknaren så du får 38kHz.
Edit: mke, tycker det var en bra förklaring!![Smile :)](./images/smilies/icon_smile.gif)
![Laughing :lol:](./images/smilies/lol.gif)
Skämt åsido!!
Kod: Markera allt
// Setup timer0 and timer2
TIMSK |= (1 << TOIE0)|(1 << TOIE2); // Enable timer0 & 2 overflow nterupt.
TCCR0 |= (1 << CS00); // timer0 CLK = internal clock
TCCR2 |= (1 << CS22)|(1 << COM20); // timer2 CLK = internal clock/64
Kod: Markera allt
#define bit_flip(p,m) ((p) ^= (m))
ISR(TIMER0_OVF_vect)
{
bit_flip(PORTB,1);
}
TCNTx för att sätta ett startvärde för räknaren så du får 38kHz.
Edit: mke, tycker det var en bra förklaring!
![Smile :)](./images/smilies/icon_smile.gif)
Har skrivit lite ny kod men det vill fortfarande inte fungera...
Nedan följer en liten del av programmet. Nån som ser något som inte borde vara där eller något som borde vara där
Nedan följer en liten del av programmet. Nån som ser något som inte borde vara där eller något som borde vara där
![Very Happy :D](./images/smilies/biggrin.gif)
Kod: Markera allt
void send_one(void){ //metod som sänder etta
TCCR0|=(1 << COM00); //Toggle OC0 on compare match
TCNT1=0x00; //Nollställ timer1
while(TCNT1<=540){ //delay 540us
}
TCNT1=0x00; //Nollställ timer1
TCCR0 &= 0xEF; // OC0 disconnected
while(TCNT1<=1800){ //delay 1800us
}
}
- MicaelKarlsson
- Inlägg: 4669
- Blev medlem: 18 juni 2004, 09:16:07
- Ort: Aneby
- Kontakt:
Luckan: Vad vill du att koden skall göra? Jag tror att du bör sätta dig och skriva ner lite pseudokod eller möjligen ett detaljerat flödesschema och sedan när det är klart skriva koden.
"Någon speciell anledning att du dels gör exakt som alla har sagt att
du *INTE* ska göra samt inte gör på något av de sätt som du har
blivit rekomendera *ATT* göra ?? "
Skulle jag också vilja ha svar på.
"Någon speciell anledning att du dels gör exakt som alla har sagt att
du *INTE* ska göra samt inte gör på något av de sätt som du har
blivit rekomendera *ATT* göra ?? "
Skulle jag också vilja ha svar på.