Hallo zusammen,
bräuchte mal Hilfe, bei einem Programmteil, der mit einem Hallsensor mit
Latch die Drehrichtung und Drehzalt auswerten soll. Drehzahl ist ca.
15-200 U/min und es sind auf einer Kreisscheibe 5 Magnete. Die Variable
Kadenz soll gibt reziprok die Drehzahl aus. Bei Rückwärtslauf und bei
starkem Drehzahlabfall oder Stillstand soll Kadenz=255 gesetzt werden.
Im Vorwartssinn ist das Signal vom Hall am INT (beide Flankenwechsel)
Ruhe = high und bei passieren eines Magnets kurz low. Rückwarts
demenstsprechen lange low und kurz high.
Die Auswertung funktioniert meistens; manchmal beim Rückwartslauf gibt
es kurze Freigaben beim passieren eines Magnets, und noch nicht
nachvollziehbar beim erneuten Vorwärtsgang gibt es keine Ausgabe von
Kadenz<255.
Bin gerade zu festgefahren und seh den Fehler nicht. Erst dachte ich
wenn low relativ gross ist beim Stop, danach nach beim Vergleich
low<high nie aus dem high=0 rauskommt. Wars aber leider nicht.
Also wäre über einen unbefangenen Blick darüber mit resultierenden
Vorschlägen dankbar.
Grüsse Micha
1 | #include <stdio.h>
|
2 | #include <avr/interrupt.h>
|
3 | #include <util/delay.h>
|
4 | //#include "lcd.h"
|
5 | #include <stdlib.h>
|
6 | #include <avr/pgmspace.h>
|
7 | #include <avr/eeprom.h>
|
8 |
|
9 |
|
10 | volatile uint8_t Kadenz=255, K_counter, K_high, K_diff;
|
11 | // TIMER1 OVF INT
|
12 | ISR(TIMER1_COMPA_vect) {
|
13 | K_counter++;
|
14 | if(K_counter > 250) {Kadenz=255; K_high=0; PORTB ^= (1<<5); }
|
15 | if(K_counter > K_diff) {Kadenz=255; K_high=0; PORTB ^= (1<<5); }
|
16 |
|
17 | }
|
18 |
|
19 | void Timer1CTC_Init (void) {
|
20 | // TIMER1 als Zählerbasis für PAS (CTC 27800 macht 255 ticks für 14Kadenz und 17/200) und speed, evtl zeittakt
|
21 | TCCR1B = (1<<WGM12) | (1<<CS10);
|
22 | TIMSK |= (1<<OCIE1A);
|
23 | OCR1A = 27800;
|
24 | }
|
25 |
|
26 |
|
27 | //INT0 PD2 pin4 für PAS
|
28 |
|
29 | ISR(INT0_vect) {
|
30 | static uint8_t K_low, K_state;
|
31 |
|
32 | if((PIND & (1<<PD2)) > K_state) { //steigend
|
33 | if (K_counter >= K_high) K_low= K_counter - K_high;
|
34 | K_counter=0;
|
35 | }
|
36 | else //fallend
|
37 | { K_high=K_counter;
|
38 | //K_counter =0;
|
39 | }
|
40 | K_state = PIND & (1<<PD2);
|
41 | PORTB ^= (1<<PB4);
|
42 | if(K_high > K_low) {
|
43 | Kadenz = K_high + K_low;
|
44 | if(Kadenz > 166) K_diff =255; // bei Drehzahlabfall um x1.5
|
45 | else K_diff = Kadenz + (Kadenz>>1); // im COMPA1 abschalten
|
46 | }
|
47 | else {
|
48 | Kadenz =255;
|
49 | // K_high = 0; TEST- raus wegen probleme beim wiederanfahren - keine Verbesserung
|
50 | }
|
51 | }
|