Forum: Compiler & IDEs Brain-Lag die 30ste


von Xilence (Gast)


Lesenswert?

Hi,
ich bastel grad für nen Freund den Code für nen RC-Switch zusammen
Basiert auf nem Tiny85 (hatte ich halt gerade da)
Pinbelegung ist vorgegeben auf Impuls -> PB1 aka. PCINT1
Ausgang ist PB4
war ursprünglich ein ON/OFF switch mit nem Tiny13 (deswegen auch PCINT1, 
da ist beim Tiny13 ja INT0)
wie auch immer

komm aber auf Teufel komm raus mit dem Code nicht weiter
mein hirn sagt mir geht - mein Testaufbau 
(funke+empfänger+testverbraucher in form einer led) sagt geht nicht
(hardware ist ok - wenn ich den pin auf high setze ist die led auch an)
1
/*
2
 * _1Ch_RC_Switch.c
3
 *
4
 * Created: 24.04.2012 17:14:30
5
 *  Author: Xilence
6
 */ 
7
8
#include <stdlib.h>
9
#include <avr/io.h>
10
#include <inttypes.h>
11
#include <avr/interrupt.h>
12
#ifndef F_CPU
13
#define F_CPU 8000000UL
14
#endif
15
16
#ifndef cbi
17
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
18
#endif
19
#ifndef sbi
20
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
21
#endif
22
23
// PB4 Output for PWM
24
// PB1 Input from Receiver 
25
26
27
// Represents the Timer1
28
volatile uint8_t valueFromTimer;
29
// Represents the PWM-Value
30
volatile uint8_t valueForPWM;
31
32
int main(void){
33
  
34
  valueForPWM = 0;
35
  valueFromTimer = 0;
36
  
37
  // set OUT_PIN as Output
38
  sbi(DDRB,PB4);
39
  PORTB = 0;
40
  
41
  // Timer0 - with 1024 Prescaler
42
  sbi(TCCR0B,CS02); sbi(TCCR0B,CS00);
43
  
44
  // Overflow Interrupt enable
45
  sbi(TIMSK,TOIE0); sbi(TIMSK,TOIE1);
46
  
47
  // Set both Timers to 0
48
  TCNT1 = 0;  TCNT0 = 0;
49
   
50
   // activate PinChange-Interrupt
51
  sbi(GIMSK,PCIE);    
52
  // Interrupt at PCINT1
53
  sbi(PCMSK,PCINT1);
54
   
55
//Interrupts on
56
   sei();      
57
58
  while (1){
59
  }
60
}
61
62
// for high and low pwm-cutoff
63
void getPWM(void){
64
  if (valueFromTimer > 250) {
65
    valueForPWM = 255;
66
  } else if (valueFromTimer < 130) {
67
    valueForPWM = 0;
68
  } else {
69
    valueForPWM = (valueFromTimer-125)*2;
70
  }  
71
}
72
73
// pinchange ISR
74
ISR(PCINT0_vect){
75
  if (PORTB & (1<<PCINT1)){
76
    TCCR1 |= ((1<<CS12) | (1<<CS11) | (1<<CS10));
77
  } else {
78
    valueFromTimer = TCNT1;
79
    TCCR1 &= ~((1<<CS10) | (1<<CS11)| (1<<CS12));
80
    TCNT1 = 0;
81
  }
82
}
83
84
// Overflow when signal to long
85
ISR(TIMER1_OVF_vect){
86
  TCCR1 &= ~((1<<CS10) | (1<<CS11)| (1<<CS12));
87
  TCNT1 = 0;
88
}
89
90
// softPWM 
91
ISR(TIMER0_OVF_vect){
92
  getPWM();
93
  if (PORTB & (1<<PB4)) {
94
    cbi(PORTB,PB4);
95
    TCNT0 = valueForPWM;
96
  } else {
97
    if (valueForPWM>0) sbi(PORTB,PB4);
98
    TCNT0 = 255-valueForPWM;
99
  }
100
};

ist wahrscheinlich wieder irgendwas was jeden außenstehenden ins auge 
springt und ich seh's natürlich wieder nicht...

MFG Xilence

von flex (Gast)


Lesenswert?

PCINT0
1
ISR(PCINT0_vect){

oder PCINT1?
1
sbi(PCMSK,PCINT1);

von flex (Gast)


Lesenswert?

Ne, Fehlalarm, das ist richtig.

von Xilence (Gast)


Lesenswert?

der InputPin ist PCINT1
aber die ISR ist doch für alle PinChange-Interrupts PCINT0_vect
mir wird auch im AVR-Studio kein anderer Vektor angezeigt
im DB steht auch nur PCINT_0 in der vector-list

:confused:

von Xilence (Gast)


Lesenswert?

hab - grad auch noch mal mit meinem avr-servotester n durchgang gemacht 
(der geht eigentlich ganz gut - Fahrtregler als auch servos akzeptieren 
den als Input)
geht auch nicht
hab auch mal spaßeshalber die PWM-auskommentiert (on/off statement)
liegt anscheinend aber eher an der Input Analyse
find aber den Fehler nicht...
AVR läuft auf 8MHz (spricht auch mein Multimeter - sry hab kein oszi)
das und der 64er PreScaler im Timer geben mir ein Messfenster von 2,04ms
gut des is vtl. weng knapp aber immerhin bei kurzen Impulsen (1-1,8 ms) 
sollte das ja gehen - machts ja aber auch net

von Simon (Gast)


Lesenswert?

1
[...]
2
    if (PORTB & (1<<PCINT1)){
3
[...]

PINB für das Auslesen verwenden, damit sollte es gehen. Dann würde ich 
die getPWM in die Main-Schleife verschieben (der hat ja zZ sowieso 
nichts zu tun) und wer weiß, vielleicht willst du ja mal ein wneig mehr 
Logik als drei Verzweigungen reinbauen. Ansonsten schaut es auf den 
ersten Blick OK aus, auch wenn sich mir wegen cbi und sbi die Haare 
aufstellen. Wenn du kein gcc 3.4 verwendest kannst du sie dir sparen und 
die _BV() Makros und AND/OR-Masken verwenden, die können das Gleiche wie 
cbi mit dem Bonus, dass der gcc auch noch Opitmieren kann.

von Xilence (Gast)


Lesenswert?

Jo das mit PIN vs. PORT wars
die getPWM hab ich noch mit in die PinChange-ISR gesteckt
geht auch wunderbar

kannst du für die Makros ein Beispiel geben bzw nen Link wo sie 
beschrieben werden?

Achja - woran kann es eigentlich liegen das die PWM bei niedrigen Werten 
anfängt merklich zu flackern. Ist da der AVR so unpräzise das er immer 
in den Cutoff springt?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.