Hallo noch mal Ich habe mir beigefügtes Projekt auf einen TTINY461 geladen geht auch soweit bis ich die Digitalen Eingänge als Port Abfrage. Wenn ich Pullup Wiederstände anklemme geht es aber nicht mit den internen Pullup. Könnte sich einer mal das Projekt AVR Studio ansehen? Ist nicht von mir. Gruß
Gast
#4709647
Dirk H. schrieb: > Wenn ich Pullup Wiederstände anklemme geht es aber nicht mit den > internen hast du die Doku vom 461 gelesen? Der hat extra Register für die PullUps.
Gast
#4709664
Peter II vermutete: > hast du die Doku vom 461 gelesen? > Der hat extra Register für die PullUps. Also ich kann nur ein Bit finden, PUD in MCUCR.
Im projekt sind die Pullup doch aktiviert.
Gast
#4709696
> Wenn ich Pullup Wiederstände anklemme geht es aber > nicht mit den internen Pullup. > Könnte sich einer mal das Projekt AVR Studio ansehen? > Im projekt sind die Pullup doch aktiviert. Da könnte man doch mal das Multimeter hervorholen und im "Projekt AVR Studio" nachmessen, dann sähe man klarer.
hab noch mal alles durchgesehen ........... // Tasten PORTB |= (1<<S1) | (1<<S2) | (1<<PINB6); // Pull up Widerstände an DDRB &= ~(1<<S1) | (1<<S2) | (1<<PINB6); // als Eingänge setzen // Eingänge PORTA |= (1<<E1) | (1<<E2) | (1<<E3) | (1<<E4); // Pull up Widerstände an DDRA &= ~(1<<E1) | (1<<E2) | (1<<E3) | (1<<E4); // als Eingänge setzen geht nicht
Gast
#4709999
Sollte man nicht nach '~' Klammern setzen?
Gast
#4710007
Auf jeden Fall fehlen da Klammern. Es muss heissen: DDRA &= ~((1<<E1) | (1<<E2) | (1<<E3) | (1<<E4)); Hast du eventuell vergessen, den Pin AVCC anzuschließen?
tut mir leid keine Ahnung hab das projekt nur so übernommen ob da klammer hinkommen weis ich nicht ich noch kein c bin dabei zu lernen. ich kann nur flowcode.
avcc ist angschlossen auf 5V kommen überall klammern hin wo mehrere ein und Ausgänge hintereinander stehen ?
Gast
#4710018
ich kein c auch nicht lernen Aber was hindert Sie, Stefan Us zu folgen und das einfach mal auszuprobieren?
Gast
#4710019
Dirk H. schrieb: > tut mir leid keine Ahnung > > hab das projekt nur so übernommen > ob da klammer hinkommen weis ich nicht Gib das Projekt weiter
steht doch oben
/*********************************************************************** **************** Titel: ATtiny TPS Author: Christian Hottum File: ATtiny461A_TPS.c Version: 0.1 Datum: 09.01.2015 Software: AVR-GCC 4.3.3 Target: ATtiny461A DESCRIPTION Firmware für einen Tasten Programierbare Steuerung auf Basis einen ATtiny461A mit 3 Tasten (S1(PB0), S2(PB2) und reset(PB7)), 4 digitale Eingängen (PA0 - PA3), 2 ADC Eingänge (PB4 - PB5), 4 digitale Ausgänge (PA4 - PA7), 2 PWM Ausgänge (PB1, PB3), Freie Pins (PB6), 8 MHZ System Takt ************************************************************************ ***************/ // CPU Frequenz #define F_CPU 8000000UL /* Quarz mit 8 Mhz */ // Include Dateien #include <math.h> #include <avr/io.h> #include <stdint.h> #include <stdlib.h> #include <stdio.h> #include <util/delay.h> #include "TPS_UP.h" #include <avr/eeprom.h> // Variablen // I/O vorbereiten int main(void) { _delay_ms(200); // Ausgänge PORTA &= ~(1<<A1) | (1<<A2) | (1<<A3) | (1<<A4); // alle Ausgänge aus DDRA |= (1<<A1) | (1<<A2) | (1<<A3) | (1<<A4); // als Ausgänge setzen // Tasten PORTB |= (1<<S1) | (1<<S2) | (1<<PINB6); // Pull up Widerstände an DDRB &= ~(1<<S1) | (1<<S2) | (1<<PINB6); // als Eingänge setzen // Eingänge PORTA |= (1<<E1) | (1<<E2) | (1<<E3) | (1<<E4); // Pull up Widerstände an DDRA &= ~(1<<E1) | (1<<E2) | (1<<E3) | (1<<E4); // als Eingänge setzen // ADC's ADCSRA |= (1<<ADEN); // ADC aktivieren ADMUX |= (1<<ADLAR); // ADC Ausgabe left adjusted ADCSRA |= (1<<ADPS2) | (1<<ADPS0); // ADC-Frequenz Clock/32 (verkürzt die Abfrage) // PWM's PORTB &= ~(1<<PB1) | (1<<PB3); // alle Ausgänge aus DDRB |= (1<<PB1) | (1<<PB3); // als Ausgänge setzen TCCR1B |= (1<<CS10); // PWM-Mode setzen TCCR1D |= (1<<WGM10); TCCR1D &= ~(1<<WGM11); TCCR1A |= (1<<PWM1A) | (1<<PWM1B) | (1<<COM1A1) | (1<<COM1B1); // Hauptprogrammschleife while(1) { if (!(PINB & (1<<S2))) // wenn S2 beim einschalten gedrückt ist { // gehe in den Programmier-Modus PROG(); } if (!(PINB & (1<<S1))) // wenn S1 beim einschalten gedrückt ist { // gehe in den Test-Modus TEST(); } AUSF(); // ansonsten gehe in den Ausführen-Modus } return 0; }
/*********************************************************************** **************** Titel: ATtiny TPS Unterprogramme Author: Christian Hottum File: TPS_UP.h Version: 0.1 Datum: 09.01.2015 Software: AVR-GCC 4.3.3 Target: ATtiny461A DESCRIPTION Variablen und Unterprogramme der TPS ************************************************************************ ***************/ // CPU Frequenz #define F_CPU 8000000UL /* Quarz mit 8 Mhz */ // Include Dateien #include <math.h> #include <avr/io.h> #include <stdint.h> #include <stdlib.h> #include <stdio.h> #include <util/delay.h> #include <avr/eeprom.h> // Tasten #define S1 PINB0 #define S2 PINB2 // Eingänge #define E1 PINA0 #define E2 PINA1 #define E3 PINA2 #define E4 PINA3 // Ausgänge #define A1 PINA4 #define A2 PINA5 #define A3 PINA6 #define A4 PINA7 //PWM's #define PWM1 OCR1A #define PWM2 OCR1B //Variablen uint8_t eebyte[256] EEMEM; //Programmspeicher uint8_t byte = 0; //Zwischenspeicher Programmbytes uint8_t addr = 0; //Addresse Programmspeicher uint8_t dat = 0; //Daten Programmspeicher uint8_t kom = 0; //Befehl Programmspeicher uint8_t adrlo = 0; //Adresse Low - unteres Nibble uint8_t adrhi = 0; //Adresse High - oberes Nibble uint8_t adrret = 0; //Rücksprungadresse uint8_t prog = 0; //Programmierschritt uint8_t puffer = 0; //ADC Puffer für ersten Wert uint16_t ff = 0; //Rücksetzt Zähler uint16_t ms = 0; //Zählvariable langes Delay uint8_t A = 0; //Speicher A uint8_t B = 0; //Speicher B uint8_t C = 0; //Speicher C uint8_t D = 0; //Speicher D // Unterprogramme // ADC 1 auslesen uint8_t ADC1(void) { loop_until_bit_is_clear (ADCSRA, ADSC); // warte bis das Bit ADSC gelöscht wird ADMUX = 39; // setze den Mux auf ADC 7 ADCSRA |= (1<<ADSC); // starte die Wandlung loop_until_bit_is_clear (ADCSRA, ADSC); // warte bis das Bit ADSC gelöscht wird return ADCH; // gib den zweiten ADC-Wert zurück } // ADC 2 auslesen uint8_t ADC2(void) { loop_until_bit_is_clear (ADCSRA, ADSC); // warte bis das Bit ADSC gelöscht wird ADMUX = 40; // setze den Mux auf ADC 8 ADCSRA |= (1<<ADSC); // starte die Wandlung loop_until_bit_is_clear (ADCSRA, ADSC); // warte bis das Bit ADSC gelöscht wird return ADCH; // gib den zweiten ADC-Wert zurück } // Größere Delays void long_delay(uint16_t ms) { for(; ms>0; ms--) _delay_ms(1); } // Programm ausführen void AUSF() { addr = 0; do { byte = eeprom_read_byte (&eebyte [addr]); // lese das eebyte-Array an der stelle addr aus dat = byte & 15; // schreibe das unter Nibble in dat und kom = byte / 16; // das obere Nibble in kom addr = addr + 1; // addiere 1 zu addr if (kom == 1) // 1: Direkte Portausgabe { PORTA = dat * 16 & 0xF0; } if (kom == 2) // 2: Wartezeit { if (dat == 0) _delay_ms(1); if (dat == 1) _delay_ms(2); if (dat == 2) _delay_ms(5); if (dat == 3) _delay_ms(10); if (dat == 4) _delay_ms(20); if (dat == 5) _delay_ms(50); if (dat == 6) _delay_ms(100); if (dat == 7) _delay_ms(200); if (dat == 8) _delay_ms(500); if (dat == 9) _delay_ms(1000); if (dat == 10) _delay_ms(2000); if (dat == 11) _delay_ms(5000); if (dat == 12) long_delay(10000); if (dat == 13) long_delay(20000); if (dat == 14) long_delay(30000); if (dat == 15) long_delay(60000); } if (kom == 3) // 3: Sprung - relativ { addr = addr - 1; addr = addr - dat; } if (kom == 4) // 4: A = ... { A = dat; } if (kom == 5) // 5: ... = A { if (dat == 1) B = A; // Variablen if (dat == 2) C = A; if (dat == 3) D = A; if (dat == 4) PORTA = A * 16 & 0xF0; // Port if (dat == 5) // Portbits { if (A == 0) PORTA &= ~(1<<A1); else PORTA |= (1<<A1); } if (dat == 6) { if (A == 0) PORTA &= ~(1<<A2); else PORTA |= (1<<A2); } if (dat == 7) { if (A == 0) PORTA &= ~(1<<A3); else PORTA |= (1<<A3); } if (dat == 8) { if (A == 0) PORTA &= ~(1<<A4); else PORTA |= (1<<A4); } if (dat == 9) PWM1 = A * 16; // PWM if (dat == 10) PWM2 = A * 16; } if (kom == 6) // 6: A = ... { if (dat == 1) A = B; // Variablen if (dat == 2) A = C; if (dat == 3) A = D; if (dat == 4) A = PINA & 15; // Port if (dat == 5) // Portbits { if (!(PINA & (1<<E1))) A = 0; else A = 1; } if (dat == 6) { if (!(PINA & (1<<E2))) A = 0; else A = 1; } if (dat == 7) { if (!(PINA & (1<<E3))) A = 0; else A = 1; } if (dat == 8) { if (!(PINA & (1<<E4))) A = 0; else A = 1; } if (dat == 9) A = ADC1() / 16; // ADC if (dat == 10) A = ADC2() / 16; } if (kom == 7) // 7: A = ... { if (dat == 1) A = A + 1; if (dat == 2) A = A - 1; if (dat == 3) A = A + B; if (dat == 4) A = A - B; if (dat == 5) A = A * B; if (dat == 6) A = A / B; if (dat == 7) A = A & B; if (dat == 8) A = A | B; if (dat == 9) A = A ^ B; if (dat == 10) A = ~A; } if (kom == 8) adrhi = dat; // 8: Oberes Nibble der Adresse if (kom == 9) // 9: Spring absolut 0...255 { addr = adrhi * 16; addr = addr + dat; } if (kom == 10) // 10: C * Spring absolut 0...255 { if (C > 0) { C = C - 1; C = C & 15; addr = adrhi * 16; addr = addr + dat; } } if (kom == 11) // 11: D * Spring absolut 0...255 { if (D > 0) { D = D - 1; D = D & 15; addr = adrhi * 16; addr = addr + dat; } } if (kom == 12) // 12: Skip if ... { if (dat == 1) { if (A > B) addr = addr + 1; } if (dat == 2) { if (A < B) addr = addr + 1; } if (dat == 3) { if (A == B) addr = addr + 1; } if (dat == 4) { if (PINA & (1<<E1)) addr = addr + 1; } if (dat == 5) { if (PINA & (1<<E2)) addr = addr + 1; } if (dat == 6) { if (PINA & (1<<E3)) addr = addr + 1; } if (dat == 7) { if (PINA & (1<<E4)) addr = addr + 1; } if (dat == 8) { if (!(PINA & (1<<E1))) addr = addr + 1; } if (dat == 9) { if (!(PINA & (1<<E2))) addr = addr + 1; } if (dat == 10) { if (!(PINA & (1<<E3))) addr = addr + 1; } if (dat == 11) { if (!(PINA & (1<<E4))) addr = addr + 1; } if (dat == 12) { if (!(PINB & (1<<S1))) addr = addr + 1; } if (dat == 13) { if (!(PINB & (1<<S2))) addr = addr + 1; } if (dat == 14) { if (PINB & (1<<S1)) addr = addr + 1; } if (dat == 15) { if (PINB & (1<<S2)) addr = addr + 1; } } if (kom == 13) // 13: Call Unterprogramm absolut 0...255 { adrret = addr; addr = adrhi * 16; addr = addr + dat; } if (kom == 14) // 14: Return { addr = adrret; } if (kom == 15 ) // 15: EEProm neu schreiben { if ((dat == 15) && (addr < 3)) { ff++; if (ff == 2) { eeprom_write_byte (&eebyte [0], 0x64); eeprom_write_byte (&eebyte [1], 0x51); eeprom_write_byte (&eebyte [2], 0x4E); eeprom_write_byte (&eebyte [3], 0x80); eeprom_write_byte (&eebyte [4], 0xC3); eeprom_write_byte (&eebyte [5], 0x98); eeprom_write_byte (&eebyte [6], 0x82); eeprom_write_byte (&eebyte [7], 0x95); eeprom_write_byte (&eebyte [8], 0x4D); eeprom_write_byte (&eebyte [9], 0x80); eeprom_write_byte (&eebyte [10], 0xC3); eeprom_write_byte (&eebyte [11], 0x9E); eeprom_write_byte (&eebyte [12], 0x82); eeprom_write_byte (&eebyte [13], 0x9A); eeprom_write_byte (&eebyte [14], 0x4B); eeprom_write_byte (&eebyte [15], 0x81); eeprom_write_byte (&eebyte [16], 0xC3); eeprom_write_byte (&eebyte [17], 0x94); eeprom_write_byte (&eebyte [18], 0x83); eeprom_write_byte (&eebyte [19], 0x90); eeprom_write_byte (&eebyte [20], 0x47); eeprom_write_byte (&eebyte [21], 0x81); eeprom_write_byte (&eebyte [22], 0xC3); eeprom_write_byte (&eebyte [23], 0x9A); eeprom_write_byte (&eebyte [24], 0x83); eeprom_write_byte (&eebyte [25], 0x94); eeprom_write_byte (&eebyte [26], 0x43); eeprom_write_byte (&eebyte [27], 0x82); eeprom_write_byte (&eebyte [28], 0xC3); eeprom_write_byte (&eebyte [29], 0x90); eeprom_write_byte (&eebyte [30], 0x84); eeprom_write_byte (&eebyte [31], 0x90); eeprom_write_byte (&eebyte [32], 0x11); eeprom_write_byte (&eebyte [33], 0x28); eeprom_write_byte (&eebyte [34], 0x18); eeprom_write_byte (&eebyte [35], 0x28); eeprom_write_byte (&eebyte [36], 0x34); eeprom_write_byte (&eebyte [37], 0x71); eeprom_write_byte (&eebyte [38], 0x54); eeprom_write_byte (&eebyte [39], 0x59); eeprom_write_byte (&eebyte [40], 0x26); eeprom_write_byte (&eebyte [41], 0x34); eeprom_write_byte (&eebyte [42], 0x69); eeprom_write_byte (&eebyte [43], 0x54); eeprom_write_byte (&eebyte [44], 0x59); eeprom_write_byte (&eebyte [45], 0x26); eeprom_write_byte (&eebyte [46], 0x34); eeprom_write_byte (&eebyte [47], 0xFF); eeprom_write_byte (&eebyte [48], 0x54); eeprom_write_byte (&eebyte [49], 0xCE); eeprom_write_byte (&eebyte [50], 0x71); eeprom_write_byte (&eebyte [51], 0x33); eeprom_write_byte (&eebyte [52], 0x22); eeprom_write_byte (&eebyte [53], 0xCC); eeprom_write_byte (&eebyte [54], 0x32); eeprom_write_byte (&eebyte [55], 0x40); eeprom_write_byte (&eebyte [56], 0x22); eeprom_write_byte (&eebyte [57], 0x71); eeprom_write_byte (&eebyte [58], 0x54); eeprom_write_byte (&eebyte [59], 0xCE); eeprom_write_byte (&eebyte [60], 0x34); eeprom_write_byte (&eebyte [61], 0x39); eeprom_write_byte (&eebyte [62], 0xFF); eeprom_write_byte (&eebyte [63], 0xFF); eeprom_write_byte (&eebyte [64], 0x86); eeprom_write_byte (&eebyte [65], 0xD0); eeprom_write_byte (&eebyte [66], 0x40); eeprom_write_byte (&eebyte [67], 0x71); eeprom_write_byte (&eebyte [68], 0x54); eeprom_write_byte (&eebyte [69], 0x23); eeprom_write_byte (&eebyte [70], 0xCD); eeprom_write_byte (&eebyte [71], 0x34); eeprom_write_byte (&eebyte [72], 0xD8); eeprom_write_byte (&eebyte [73], 0x40); eeprom_write_byte (&eebyte [74], 0x54); eeprom_write_byte (&eebyte [75], 0x3B); eeprom_write_byte (&eebyte [76], 0xFF); eeprom_write_byte (&eebyte [77], 0xFF); eeprom_write_byte (&eebyte [78], 0xFF); eeprom_write_byte (&eebyte [79], 0xFF); eeprom_write_byte (&eebyte [80], 0x4F); eeprom_write_byte (&eebyte [81], 0x93); eeprom_write_byte (&eebyte [82], 0x45); eeprom_write_byte (&eebyte [83], 0x53); eeprom_write_byte (&eebyte [84], 0x19); eeprom_write_byte (&eebyte [85], 0x11); eeprom_write_byte (&eebyte [86], 0x21); eeprom_write_byte (&eebyte [87], 0x19); eeprom_write_byte (&eebyte [88], 0x11); eeprom_write_byte (&eebyte [89], 0x21); eeprom_write_byte (&eebyte [90], 0x19); eeprom_write_byte (&eebyte [91], 0x11); eeprom_write_byte (&eebyte [92], 0x20); eeprom_write_byte (&eebyte [93], 0xB4); eeprom_write_byte (&eebyte [94], 0x10); eeprom_write_byte (&eebyte [95], 0xE0); eeprom_write_byte (&eebyte [96], 0x23); eeprom_write_byte (&eebyte [97], 0xCE); eeprom_write_byte (&eebyte [98], 0x32); eeprom_write_byte (&eebyte [99], 0x23); eeprom_write_byte (&eebyte [100], 0xCC); eeprom_write_byte (&eebyte [101], 0x31); eeprom_write_byte (&eebyte [102], 0xE0); eeprom_write_byte (&eebyte [103], 0xFF); eeprom_write_byte (&eebyte [104], 0x23); eeprom_write_byte (&eebyte [105], 0xCF); eeprom_write_byte (&eebyte [106], 0x32); eeprom_write_byte (&eebyte [107], 0x23); eeprom_write_byte (&eebyte [108], 0xCD); eeprom_write_byte (&eebyte [109], 0x31); eeprom_write_byte (&eebyte [110], 0xE0); eeprom_write_byte (&eebyte [111], 0xFF); eeprom_write_byte (&eebyte [112], 0xCC); eeprom_write_byte (&eebyte [113], 0x31); eeprom_write_byte (&eebyte [114], 0x40); eeprom_write_byte (&eebyte [115], 0x54); eeprom_write_byte (&eebyte [116], 0x23); eeprom_write_byte (&eebyte [117], 0xCE); eeprom_write_byte (&eebyte [118], 0x32); eeprom_write_byte (&eebyte [119], 0xCF); eeprom_write_byte (&eebyte [120], 0xE0); eeprom_write_byte (&eebyte [121], 0xCC); eeprom_write_byte (&eebyte [122], 0x33); eeprom_write_byte (&eebyte [123], 0x71); eeprom_write_byte (&eebyte [124], 0x23); eeprom_write_byte (&eebyte [125], 0xCC); eeprom_write_byte (&eebyte [126], 0x31); eeprom_write_byte (&eebyte [127], 0x3C); ff = 0; } } } } while (!0); } // Programmieren void PROG() { addr = 0; // setze addr und prog auf 0 prog = 0; do // Hauptschleife { // Adresse anzeigen adrlo = addr & 15; // lade das untere Nibble der Adresse in adrlo PORTA = adrlo * 16 & 0xF0; // gib das untere Nibble aus und warte 500 ms _delay_ms(300); PORTA = 0 & 0xF0; // schalte die Anzeige für 250 ms aus _delay_ms(200); byte = eeprom_read_byte (&eebyte [addr]); // lese das eebyte-Array an der stelle addr aus dat = byte & 15; // schreibe das unter Nibble in dat und kom = byte / 16; // das obere Nibble in kom PORTA = kom * 16 & 0xF0; // Befehl anzeigen - gib kom aus loop_until_bit_is_set (PINB, S2); // warte bis die Taste S2 nicht mehr gedrückt wird _delay_ms(40); // Taste entprellen prog = 1; // setze prog = 1 do { if (!(PINB & (1<<S1))) // wenn Taste S1 gedrückt wird, verzweige nach hier { if (prog == 1) // Phase 1: Befehl anzeigen { // wenn prog = 1 dann setzte prog = 2 und kom = 15 prog = 2; kom = 15; } if (prog == 2) // Phase 2: Befehl verändern { // wenn prog = 2 dann addier 1 zu kom und verknüpfe kom = kom + 1; // kom & 15, gib kom aus kom = kom & 15; PORTA = kom * 16 & 0xF0; } if (prog == 3) // Phase 3: Befehl unverändert, Daten ändern { // wenn prog = 3 dann setzte prog = 5 und dat = 15 prog = 5; dat = 15; } if (prog == 4) // Phase 4: Befehl und Daten geändert { // wenn prog = 4 dann setzte prog = 5 und dat = 15 prog = 5; dat = 15; } if (prog == 5) // Phase 5: Daten verändern { // wenn prog = 5 dann addier 1 zu dat und verknüpfe dat = dat + 1; // dat & 15, gib dat aus dat = dat & 15; PORTA = dat * 16 & 0xF0; } _delay_ms(40); // Taste entprellen loop_until_bit_is_set (PINB, S1); // Warte bis die Taste S1 nicht mehr gedrückt wird _delay_ms(40); // Taste entprellen } if (!(PINB & (1<<S2))) // wenn Taste S2 gedrückt wird verzweige hier { if (prog == 3) // nur angezeigt nicht verändert { // wenn prog = 3 dann setzte prog = 7 prog = 7; } if (prog == 1) // wenn prog = 1 dann zeige dat an und setze prog = 3 { PORTA = dat * 16 & 0xF0; prog = 3; } if (prog == 4) // wenn prog = 4 dann zeige dat an u. setze prog = 6 { PORTA = dat * 16 & 0xF0; prog = 6; } if (prog == 2) // wenn prog = 2 dann zeige dat an u. setzte prog = 4 { PORTA = dat * 16 & 0xF0; prog = 4; } if (prog == 6) // nur Befehl wurde verändert { // verknüpfe dat & 15 und nehme kom * 16 dat = dat & 15; // schreibe beides in byte und schreibe das ins eeprom byte = kom * 16; // an die stelle addr ins eebyte-Array byte = byte + dat; eeprom_write_byte (&eebyte [addr], byte); PORTA = 0 & 0xF0; // schalte die Anzeige für 600 ms aus _delay_ms(600); addr = addr + 1; // addiere 1 zu addr und setzte prog = 0 prog = 0; } if (prog == 5) // Daten wurden verändert { // verknüpfe dat & 15 und nehme kom * 16 dat = dat & 15; // schreibe beides in byte und schreibe das ins eeprom byte = kom * 16; // an die stelle addr ins eebyte-Array byte = byte + dat; eeprom_write_byte (&eebyte [addr], byte); PORTA = 0 & 0xF0; // schalte die Anzeige für 600 ms aus _delay_ms(600); addr = addr + 1; // addiere 1 zu addr und setzte prog = 0 prog = 0; } if (prog == 7) // wenn prog = 7 dann addiere 1 zu addr u. setze prog = 0 { addr = addr + 1; prog = 0; } _delay_ms(40); // Taste entprellen loop_until_bit_is_set (PINB, S2); // Warte bis die Taste S2 nicht mehr gedrückt wird _delay_ms(40); // Taste entprellen } } while(!prog == 0); } while (!0); } // Testprogramm void TEST() { do { if (!(PINB & (1<<S1))) // Wenn S1 geschaltet ist dann { // schalte A1 bis A4 an. PORTA |= (1<<A1); _delay_ms(200); PORTA |= (1<<A2); _delay_ms(200); PORTA |= (1<<A3); _delay_ms(200); PORTA |= (1<<A4); _delay_ms(200); } if (!(PINB & (1<<S2))) // Wenn S2 geschaltet ist dann { // schalte A1 bis A4 aus. PORTA &= ~(1<<A1); _delay_ms(200); PORTA &= ~(1<<A2); _delay_ms(200); PORTA &= ~(1<<A3); _delay_ms(200); PORTA &= ~(1<<A4); _delay_ms(200); } if (!(PINA & (1<<E1))) // Wenn E1 geschaltet ist dann { // dann schalte PWM1 und PWM2 _delay_ms(200); // auf 50 und dann auf 100 PWM1 = 50; _delay_ms(200); PWM2 = 50; _delay_ms(200); PWM1 = 100; _delay_ms(200); PWM2 = 100; } if (!(PINA & (1<<E2))) // Wenn E2 geschaltet ist dann { // dann schalte PWM1 und PWM2 _delay_ms(200); // auf 150, 200 und dann auf 250 PWM1 = 150; _delay_ms(200); PWM2 = 150; _delay_ms(200); PWM1 = 200; _delay_ms(200); PWM2 = 200; _delay_ms(200); PWM1 = 250; _delay_ms(200); PWM2 = 250; } if (!(PINA & (1<<E3))) // Wenn E3 geschaltet ist dann { // dann frage ADC1 ab und setzte PWM1 PWM1 = ADC1(); } if (!(PINA & (1<<E4))) // Wenn E4 geschaltet ist dann { // dann frage ADC2 ab und setzte PWM2 PWM2 = ADC2(); } } while (!0); }
Gast
#4710071
Die Klammern sind trotz konkretem Vorschlag immer noch nicht gesetzt. So kommt man nicht weiter! "Ich kann kein C" ist eine Faule Ausrede, denn zwischen den Zeilen bedeutet es: Ich will auch kein C lernen. Lerne es und folge den Ratschlägen. Oder lass es bleiben und übergebe das Projekt an jemanden, der dazu bereit ist.
Ich bin nicht in der Firma Um das zu Testen. Darumm wäre es echt Nett wenn ihr mir sagen könntet ob Bei beiden PORTA |= ((1<<E1) | (1<<E2) | (1<<E3) | (1<<E4)) Und DDRA &= ~((1<<E1) | (1<<E2) | (1<<E3) | (1<<E4)); Und bei allen anderen mehrfachzuweisungen die klammern kommen
Gast
#4710088
Das wird wohl schon so sein. Allerdings frage ich mich zweierlei: Wie hat das jemals funktioniert, bzw. welchen Compiler hat Christian Hottum benutzt? Wenn weitere solcher Merkwürdigkeiten im Programm stecken, wie wollen Sie diese ohne C-Kenntnisse finden?
Ich bin erst voe zwei Tagen mit C angefangen in meinem alter micht mehr so einfach. Im Tutorial steht das manchmal mit und manchmal ohne Doppelklammer. Was soll man da lehrnen? Hat nichts mit Faul zu tun. Wen soll man denn sonst Fragen als hier im Forum? Ansonsten läuft das Programm.
Hier mal der Link zu dem guten Mann. http://www.elektronik-labor.de/Projekte/TPS11.html
Gast
#4710102
Und was mir auch nicht ganz klar ist: S. Landolt schlug vor: > ... Multimeter hervorholen und ... nachmessen Dirk Hartmann bestätigte: > hab noch mal alles durchgesehen ........... Da hätte Ihnen doch ein Unterschied auffallen müssen z.B. zwischen E1 und E2.
Was ich mich frage : List das hier auch einer von Anfang an? Die Schaltung geht ausser Pullup. Also kann es nur an der Programmierung liegen. Da brauch ich nicht messen. Aber echt super Forum. Anfänger werden erst mal runtergemacht. Und für dumm verkauft. Dann verbessert erst mal eure Tutorial wo man ja immer nachschauen soll.
Gast
#4710120
Ich habe sehr wohl von Anfang an gelesen, und als erstes fiel mir auf, dass es mit externen Pullup-Widerständen funktioniert. Durch Nachmessen hätten Sie den Unterschied z.B. zwischen E1 und E2 festgestellt und hätten gezielt im Programm danach suchen können, dann wäre auch aufgefallen, dass vor dem einen '~' steht und vor dem anderen nicht. Das war's jetzt aber auch von meiner Seite, denn, pardon, Ihr Ton gefällt mir ganz und gar nicht.
Ist mir aufgefallen Und? Noch mal ich kann kein C Darum habe ich um Hilfe gebeten. Ich habe die schaltung überprüft Dann habe ich mich hier gemeldet. Weil ein Programmfehler vorliegt Und dann Faul, Probier doch einfach und So kommen wir nicht weiter Einfacher und schneller !!! Mach da und da Klammern weil.... Und man hat was dazugelernt.
Gast
#4710143
S. Landolt schrieb: >> Wenn ich Pullup Wiederstände anklemme geht es aber >> nicht mit den internen Pullup. >> Könnte sich einer mal das Projekt AVR Studio ansehen? >> Im projekt sind die Pullup doch aktiviert. Dies Sprüche sind es: > > Da könnte man doch mal das Multimeter hervorholen und im "Projekt AVR > Studio" nachmessen, dann sähe man klarer. die den TO zu der Aussage kommen lassen: Dirk H. schrieb: > List das hier auch einer von > Anfang an? > > Die Schaltung geht ausser Pullup. > > Also kann es nur an der Programmierung liegen. > > Da brauch ich nicht messen. > > Aber echt super Forum. > > Anfänger werden erst mal > runtergemacht. > Und für dumm verkauft. Damit hat er absolut Recht. Soll er das Multimeter an die Zeilen im Quelltext halten, um zu messen, ob die internen Pullups eingeschltet sind, oder wie? S. Landolt schrieb: > Das war's jetzt aber auch von meiner Seite, denn, pardon, Ihr Ton > gefällt mir ganz und gar nicht. Und tschüß!
Klammern gesetzt immer noch keine pullups
Gast
#4710493
Wegend er Klammern: 1<<4 = Binär: 00010000 (1<<4) | (1<<3) = Binär: 00011000 Ich hoffe, das ist soweit klar. Ansonsten musst du wirklich mal die Grundlagen von C lernen. Eventuell mit einem besseren Tutorial (Empfehlung: http://openbook.rheinwerk-verlag.de/c_von_a_bis_z/029_c_anhang_a_001.htm). Es gibt auch umfangreichere Bücher. Bei dem obigen Ausdruck sind die Klammern sogar optional, weil die Schiebe-Operation vor der Oder-Verknüpfung hat. Ich schreibe die Klammern aber immer, weil der Code so besser lesbar ist und weil ich nicht alle Detauls im Kopf habe. Zuviel Klammern schaden nicht, sicher ist sicher. Achtung: (1<<4) + (1<<3) = Binär: 00011000 Das sieht man auch häufig. Ist ebenfalls korrekt, hier darf man die Klammern aber nicht weglassen! Nun zur Negation: ~15 (Binär: 00001111) = 240 (Binär: 11110000) ~0 = 255 ~255 = 0 Der folgende Ausdruck ist fehlerhaft: DDRA &= ~(1<<E1) | (1<<E2) | (1<<E3) | (1<<E4); Absicht war, alle Bits zu löschen, die auf der rechten Seite Benannt sind. Aber die Negation bezieht sich nur auf E1! E2 E3 und E4 werden nicht negiert. Ich löse den Ausdruck mal Schrittweise auf, dann siehst du, was schief läuft: DDRA &= ~(1<<E1) | (1<<E2) | (1<<E3) | (1<<E4); ergibt DDRA &= ~(1<<PINA0) | (1<<PINA1) | (1<<PINA2) | (1<<PINA3); ergibt DDRA &= ~(1<<0) | (1<<1) | (1<<2) | (1<<3); ergibt DDRA &= ~(1) | (2) | (4) | (8); ergibt DDRA &= 254 | 2 | 4 | 8; Hier sollte der Fehler offensichtlich sein. Siehst du ihn? ergibt DDRA &= 254; (Binär: 11111110) Also wird hier nur der Pin PA0 als Eingang konfiguriert, die anderen bleiben unverändertt. Mit korrekten Klammern passiert das: DDRA &= ~((1<<E1) | (1<<E2) | (1<<E3) | (1<<E4)); ergibt DDRA &= ~((1<<PINA0) | (1<<PINA1) | (1<<PINA2) | (1<<PINA3)); ergibt DDRA &= ~((1<<0) | (1<<1) | (1<<2) | (1<<3)); ergibt DDRA &= ~((1) | (2) | (4) | (8)); ergibt DDRA &= ~(1 | 2 | 4 | 8); ergibt DDRA &= ~(15); ergibt DDRA &= 240; (Binär: 11110000) Also werden hier die Pins PA0, PA1, PA2 und PA3 als Eingang konfiguriert, die anderen bleiben unverändertt. Dieser Fehler kommt in deinem Quelltext dreimal vor: PORTA &= ~(1<<A1) | (1<<A2) | (1<<A3) | (1<<A4); DDRB &= ~(1<<S1) | (1<<S2) | (1<<PINB6); DDRA &= ~(1<<E1) | (1<<E2) | (1<<E3) | (1<<E4); Hast du alle drei Stellen korrigiert? Welche Spannung misst du an den Eingängen, wenn sie High sein sollten?
Gast
#4710519
> Wie hat das jemals funktioniert...
Weil UND mit 0 wieder 0 ergibt, und PORTA, DDRA und DDRB haben als
Reset-Wert eben 0. Liegt der Fehler wohl anderswo.
Gast
#4710545
Dirk H. schrieb: > Wenn ich Pullup Wiederstände anklemme geht es aber nicht mit den > internen Pullup. Die internen Pullups sind relativ hochohmig. Vielleicht reichen diese nicht aus und es geht nur deshalb, weil du externe (mit welchem Wert?), viel niederohmigere angeklemmt hattest. Wie sieht denn die Beschaltung der Eingänge aus?
Ja ich habe alle stellen korrigiert. Keine Veränderung. Die Beschaltung : siehe in diesem Beitrag. http://www.elektronik-labor.de/Projekte/TPS11.html Eingänge schalten 0V auf die Pins Habe extern dann 10k zugeschaltet
Gast
#4710595
In dem verlinkten Projekt sind nur zwei taster angeschlossen, die anderen Eingänge sind nicht belegt. Um welche Eingänge geht es bei deinem Problem?
Gemessen : S1 = 5v S2 = 5v E1-E4 = 0V Bei s1 und s2 gehen die pullups
Es geht um die E1 - E4
Dirk H. schrieb: > Bei s1 und s2 gehen die pullups Dirk H. schrieb: > Es geht um die E1 - E4 Danke für die Info! Warum kommst Du damit erst jetzt? Ich habe mir nämlich gestern im Quellcode einen Wolf gesucht, wo denn das Problem mit PB0 und PB2 (S1 & S2) sein soll und keins gefunden. Jetzt hängst Du bitte mal den aktuellen Quellcode (.c und .h) mitsamt Deiner Korrekturen hier an. Betonung liegt auf Anhängen, nicht hier einfach in den Text kopieren.
Hier die Dateien
Sorry diese
Danke. Und jetzt erklärst Du bitte noch, was da an E1 bis E4 dranhängt. Es kann nämlich durchaus sein, dass die internen Pullup-Widerstände mit ~80kOhm zu schwach sind, um den Pegel hochzuziehen. Kannst Du auch einfach mal selber testen: - E1-E4 offen lassen, also externes Gerät abziehen - An E1 einen Pulldown(!) von 1MOhm anschließen - Spannung an E1 messen. Wenn Du annähernd 5V misst, sind die Pullups aktiv, aber offenbar nicht klein genug, um bei Deiner externen Schaltung zu wirken. Wenn Du annähernd 0V misst, sind die Pullups tatsächlich nicht aktiv. Dieser Test dann auch klären, warum Du mit einem externen 10kOhm-Pullup erfolgreich bist. P.S. Ich habe den Quelltext gerade nochmal geprüft. DDRA wird lediglich an 2 Stellen gesetzt. Und diese Stellen sehen nun korrekt aus. Ich sehe da keinen Konfigurationsfehler. Bleibt eigentlich nur noch die externe Hardware...
Gast
#4710665
Schreib doch mal statt
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
einfach nur mal
1 | |
2 | |
und prüfe dann mal. Sehr seltsam finde ich auch die Einstellungen ADMUX=39; // setze den Mux auf ADC 7 und ADMUX=40; // setze den Mux auf ADC 8 Das wählt nicht ADC7 und ADC8 auf PORTB, sondern eine von mir noch nie genutzte differentielle Variante auf den Ports A0 ... A2. Meiner Ansicht nach müssten den beiden ADMUX-Einstellungen entsprechend des Kommentars die Werte 7 bzw. 8 zugeordnet werden. Ich vermute mal, dass die AD-Kanalzuweisungen einfach deine Ports von der normalen Benutzung durch Pulls abhängt.
Ob man Klammern setzen muß, ergibt sich aus der Rangfolge der Operatoren, z.B.: https://de.wikibooks.org/wiki/C-Programmierung:_Liste_der_Operatoren_nach_Priorit%C3%A4t
Gast
#4710677
> E1-E4 = 0V
Wirklich 0V? Das kann ja nur sein, wenn die entweder
a) Die Eingänge quasi nach GND kurzgeschlossen sind
oder
b) Die Pull-Up's nicht funktionieren.
Welche Spannung misst du an den Eingängen, wenn deine zusätzlichen
externen Pull-Ups vorhanden sind, und welchen Widerstandwert haben die?
So Die E1 und E2 sind offen und werden nur mit einer Drahtbrücke nach 0V aktiviert. Verhalten sich wie die Taster S1 und S2 1M 0V nach E1 = 0V allein wenn ich die Eingänge berühre schalten E1-E4 DDRA = 0x0F; PORTA = 0xF0; hatte ich auch probiert ohne Erfolg Patiene habe ich überprüft keine Fehler ADC einstellungen bin ich leider überfragt.
Gast
#4710689
Dirk H. schrieb: > ADC einstellungen bin ich leider überfragt. dann schreibe mal in den Funktionen ADC1() und ADC2() statt ADMUX=39; // setze den Mux auf ADC 7 und ADMUX=40; // setze den Mux auf ADC 8 neu ADMUX = 7; und ADMUX = 8;
Gast
#4710696
> DDRA = 0x0F; > PORTA = 0xF0; Das ist genau falsch rum. Damit stellst du die Anschlüsse PA0 bis PA3 auf Ausgang mit Low Pegel. Probiere: > DDRA = 0xF0; > PORTA = 0x0F; Und du bist ganz sicher, daß AVCC richtig angeschlossen ist? Könne die LED's leuchten?
Gast
#4710699
Hallo, formal gesehen ist die TPS_UP.h eine TPS_UP.c, da in ihr realer Code steht und keine reinen Definitionen, Prototypen und verweise auf externe Variable. Als logischen Fehler sehe ich das Schreiben in TPS_UP.h von
1 | |
2 | |
3 | |
4 | |
5 | |
Und würde eher PORTXn oder durchgängig PXn schreiben. Wie schon geschrieben, kann man aus
1 | |
nicht direkt die gesetzten, bzw. gelöschten Register ablesen.
1 | |
2 | |
3 | |
4 | |
Besser lesbar wird dies durch die Definition zweier ADC Bitmasken:
1 | |
2 | |
3 | |
4 | |
5 | |
Das erste Abfragen
1 | |
in ADC1() und ADC21() ist überflüssig. Je nach Ausgangsimpendanz deiner Spannungsquelle ist ein delay von 1µs eine mögliche Lösung für das Umschalten und Umladen des Eingangs. In AUSF() ist eine Abfolge von sehr vielen IF ohne eine ELSE. Ich hatte den Code als Switch-Case-Anweisung über den Parameter kom mit inline Procedure aufrufen codiert. Das ist sehr gut lesbar, überprüfbat und schnell änderbar. Stilistisch sehr schön ist
1 | |
Die AVR µC Taktfrequenz im Quellcode festzulegen kann eine Fehlerquelle sein.
1 | |
2 | |
Das wurde schon erschöpfend diskutiert. Besser legt man dies im zugehörigen Makefile global ab.
Gast
#4710700
HildeK schrieb: > Dirk H. schrieb: >> ADC einstellungen bin ich leider überfragt. > > dann schreibe mal in den Funktionen ADC1() und ADC2() statt > ADMUX=39; // setze den Mux auf ADC 7 > und > ADMUX=40; // setze den Mux auf ADC 8 > > neu > ADMUX = 7; > und > ADMUX = 8; Ist nicht richtig, da er nur 8Bit über ADCH zurückgibt.
Habe ich geändert geht aber nicht.
Ich hatte vor einiger Zeit für den PIC16F876 das gleiche Programm in Flowcode geschrieben wobei es keine Probleme gab. Es kann ja nur etwas mit dem PORT A sein weil bei Port B gehen die Pullups ja ordentlich. Ich habe auch mal einen neuen 461 Ausprobiert geht auch nicht.
Gast
#4710732
> Es kann ja nur etwas mit dem PORT A sein Sieht so aus, aber > Ich habe auch mal einen neuen 461 Ausprobiert geht auch nicht. Mit Sicherheit können wir ausschließen, dass der ATtiny461 an Port A keine Pull-Ups hat. Aber vielleicht ein Serienfehler? Hast du beide Chips am selben Tag gekauft? Was ist hiermit?: >> DDRA = 0x0F; >> PORTA = 0xF0; >Das ist genau falsch rum. Damit stellst du die Anschlüsse PA0 bis PA3 >auf Ausgang mit Low Pegel. Probiere: >> DDRA = 0xF0; >> PORTA = 0x0F; >Und du bist ganz sicher, daß AVCC richtig angeschlossen ist? >Können die LED's leuchten?
AVCC Auf 5V LED Leuchten >> DDRA = 0xF0; >> PORTA = 0x0F; Ja meinte ich sorry
Gast
#4710858
Ich kann kein C, aber beim Drüberschauen fällt mir auf, dass in allen drei Unterprogrammen PROG, TEST und AUSF an diversen Stellen die Pullup-Widerstände für E1..4, also PORTA0..3, deaktiviert werden, z.B. "PORTA = dat * 16 & 0xF0" o.ä. Vielleicht kann jemand aus der Runde mehr dazu sagen.
Das wirds sein. Die Profis erwarten allerdings keinen Code in einem *.h-File und haben deshalb dort nicht nach dem Fehler gesucht. Code in einem *.h gehört sich einfach nicht. Wenn man mit Make oder der IDE auf Kriegsfuß steht, dann meinetwegen in ein *.inc.
Gast
#4710913
Stimmt, das *.h file habe ich gar nicht angesehen.
Hört sich ja gut an Was soll ich ändern
Dirk H. schrieb: > Was soll ich ändern Schreibe überall, wo PORTA modifiziert wird mit Maske 0xF0: Alt: PORTA = irgendwas & 0xF0; Neu: PORTA = (irgendwas & 0xF0) | 0x0F; Bespiel: Alt: PORTA = dat * 16 & 0xF0; Neu: PORTA = (dat * 16 & 0xF0) | 0x0F; Die Maske 0xF0 könnte man sogar weglassen, also: PORTA = (dat * 16) | 0x0F; Das ist zwar nicht besonders schön gelöst, aber dieses mit Fehlern gespickte Programm hat es sowieso nicht anders verdient.
Ok hab jetzt Feierabend probiere das morgen Früh aus Und berichte sofort
Hab es eingegeben Bricht aber beim Debug ab Wenn ich es wieder zurückstelle Geht es wieder Das nimmt avr studio an PORTA = (dat * 16) | 0x0F
Guten Morgen Läuft super Vielen Dank für eure Hilfe
Gast
#4711943
Hallo Dirk, bitte veröffentliche zum Abschluss noch das geänderte Programm. Was macht dein Standartprogramm, dass man neu in das EEprom schreiben kann ?
1 | |
2 | |
3 | |
4 | |
Zu Timer1, wenn ich das richtig lesen, wird der Timer1 im 10Bit Modus "Phase & Frequency Correct PWM OCR1C" betrieben. Dabei ist das 10Bit Register OCR1C = 0x000 OCR1A und OCR1B werden nur mit 8Bit Werte beschrieben. Ist das so gewollt ?
Gast
#4712072
Hallo, hier werden die Variable C und D nicht verwendet, was soll der Code machen ?
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
Karl M. schrieb: > hier werden die Variable C und D nicht verwendet Doch, u.a. hier:
1 | |
2 | |
3 | |
4 | |
5 | |
Und:
1 | |
2 | |
3 | |
4 | |
5 | |
Dass diese Variablennamen nur aus einem nichtssagenden Buchstaben bestehen, macht dieses Programm nicht unbedingt lesbarer.
Hallo Ich werde das projekt nachher einstellen. Das Projekt ist eine Tasten programmierbare Steuerung Nachzulesen mit Varianten hier http://www.elektronik-labor.de/Lernpakete/TPS/TPS0.html Eigentlicht recht interessant Gruss
Gast
#4712251
Willst du den Quelltext im Ernst so veröffentlichen? Mach das besser nicht - vor allem, wenn du irgendwo als Programmierer eingestellt werden möchtest. Der Code ist sehr hässlich und würde ein schlechtes Licht auf dich werfen.
Zum Glück bin ich u.a. Programmierer Aber im Bereich der SPS. K.O. ich lass das mit dem Code der ja nicht von mir ist. kann mann ja auch auf der Seite runterladen. was mich noch interresieren würde wie Ihr das Programm umsetzen würdet. Gruß
Gast
#4712320
Hallo Dirk, ja mit dem Link zu http://www.elektronik-labor.de/Projekte/TPS11.html wird alles klarer. Viel Erfolg!
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.