Dies ist eigentlich kein besonderes Programm; eher eine Demo für das Messen des Resetpins mit dem ADC.
Weil mir bei einem kleinen 4 X 7 Segment Multiplex Projekt mit ATtiny45 und 74HC595 Schieberegistern die Pins am Tiny knapp wurden, suchte ich noch einen Anschluß für einen Taster zum Betriebsmodus umschalten.
Ein Spannungsteiler und Taster an PB5 (RESET & ADC0) bescherte mir dann den "zusätzlichen" Pin.
Code:5V----o-----o-------------------o------- | | | | R1.-.510 ||100nF | | o | | .-----||-------o |=|> | | | || | | o '-' | | T | | | PB5 __ Vcc | '-----o----)---o| |o-----' | | -o| |o- R2.-.10k| -o| |o- | | o---o|__|o- | | | GND '-' | ATtiny45 | | GND---------o----o----------------------
Mit den Defaulteinstellungen der Fuses ist beim ATtiny45 der PB5 Pin als Reset Pin eingestellt; das sollte auch nicht geändert werden um den Tiny weiter über ISP programmieren zu können. (CKDIV8 Fuse wurde für 8Mhz Systemtakt umgestellt)
Gleichzeitig mit der Resetfunktion funktioniert der PB5 aber auch noch als ADC0 und kann mit dem ADC gemessen werden. Das hatte ich schon mal bei einem Linienfolger ausgenutzt.
Um ein sicheres High zu gewährleisten und um keinen Reset auszulösen muß die Spannung nach Datenblatt mindestens 0,9*Vcc betragen (Bei Vcc=5V: 0,9*5V=4,5V). Der Spannungsteiler mit R1 und R2 soll das gewährleisten. Erst eine viel tiefere Spannung löst einen Reset aus.
In diesem Programm mißt der ADC die Spannung an PB5 (ADC0). Wenn PB5 nahe Vcc gemessen wird, wird auf "Taster betätigt" erkannt und zur Entprellung bzw. gegen mehrfaches Erkennen eines Tastendruckes eine Schutzzeit von ca. einer Sekunde gestartet ohne blockierend zu wirken. In dieser Zeit wird PB5 nicht mehr gemessen und es können keine weiteren Tastendrücke für diese Zeit erkannt werden. Mir reicht das völlig, um zwischen zwei verschiedenen Betriebsmodi umzuschalten.
Hier wird zwischen Anzeige des Meßwertes eines Potis an ADC3 und Meßwert am Resetpin durch Tastendruck umgeschaltet.
Für die Schutzzeitzeitnahme wird die Multiplex ISR mitgenutzt, die alle 4ms durch Timer0 aufgerufen wird. Dort wird dann die Bytevariable "Cmp0a_counter" bis zum Überlauf hochgezählt und gibt das Messen des Resetpins in der Haupschleife wieder frei.
Die Bitmuster sind natürlich abhängig von der Beschaltung der Schieberegister. Nur die wichtige HW für die ADC Messung an PB5 sind gezeichnet und die dafür wichtigen Programmteile im Code hervorgehoben.
Ob man den Resetpin in dieser Art nutzt ist bestimmt von Fall zu Fall unterschiedlich und man muß dem Datenblatt entnehmen, bei welchen µCs das überhaupt möglich ist. Meistens ist es nicht nötig und sollte wohl auch vermieden werden? Der Spannungsteiler zieht etwas Strom und könnte auch noch etwas hochohmiger gemacht werden. Bei mir hat der 510 Ohm Widerstand meinen Parallelport-Selbstbau-ISP-Programmer nicht gestört (Es fließen dann während des Programmierens, wenn Reset auf GND gezogen wird, etwa 10mA über den 510 Ohm Widerstand -man beachte auch den internen Pullup von 30k bis 60k, der parallel zu dem R1 liegt. Drücken des Tasters muß dann vermieden werden um keinen Kurzschluß zu verursachen!!!). Andere Programmer könnten empfindlicher auf den niedrigen Pullup reagieren?
GrußCode:$regfile = "attiny45.dat" $crystal = 8000000 $hwstack = 32 $swstack = 32 $framesize = 32 Dim I As Byte Dim K As Word Dim Show As Word 'value from 0 to 9999 to be displayed Dim Show_old As Word Dim Digit As Byte 'currently selected digit for output to display Dim Digit_pattern As Byte 'Segment Select Pattern for 7 Seg. Dim Digit_sel As Byte 'Digit Select Pattern for 7 Seg Dim Number_ar(4) As Byte 'contains four digits to be multiplexed Dim Index As Byte 'Index for Lookup table Dim Adc_key As Word 'Gets ADC value measured on PB5 Dim Key_pressed As Byte 'Toggles when key is actuated Dim Poti_adc_new As Word 'variables for Poti measurement Dim Poti_adc_old As Word 'variables for Poti measurement Dim Poti_value As Word 'variables for Poti measurement Dim Diff_new_old As Integer 'variables for Poti measurement Dim Cmp0a_counter As Byte 'measure security time for key pressing Serial_clock_pin Alias Portb.0 Config Serial_clock_pin = Output 'SHCP at 74HC595 Serial_data_pin Alias Portb.2 Config Serial_data_pin = Output 'DS at 74HC595 Config Portb.1 = Output 'STCP at 74HC595 Config Adc = Single , Prescaler = Auto , Reference = Avcc Tccr0a = Bits(wgm01) 'CTC (OCR0A as top) Ocr0a = 124 'for 250Hz compare interrupt Tccr0b = Bits(cs02) 'prescale = 256 (start timer) On Compare0a Multiplex Enable Compare0a Enable Interrupts Do 'Hauptschleife If Cmp0a_counter = 0 Then Adc_key = Getadc(0) 'measure PB5(ADC0) If Adc_key > 1000 Then 'If key is pressed then Toggle Key_pressed Cmp0a_counter = 1 'start secure timing End If End If Poti_adc_new = Getadc(3) 'measure Poti setting at ADC3 Diff_new_old = Poti_adc_new - Poti_adc_old If Abs(diff_new_old) > 3 Then 'SW-Hysterese Poti_adc_old = Poti_adc_new Shift Poti_adc_new , Right , 2 'remove unsave bits Poti_value = Poti_adc_new 'result between 0 and 255 End If 'Toggle output to display between Adc value at PB5 and Poti_value by each key push If Key_pressed > 0 Then Show = Adc_key Else Show = Poti_value Gosub Prepare_number_for_output Loop End Multiplex: 'ISR called every 4ms If Cmp0a_counter > 0 Then Incr Cmp0a_counter 'overflow counter for security time Incr Digit Digit_pattern = Lookup(number_ar(digit) , Bitpattern) Select Case Digit Case 1 : Digit_sel = &B1000_0000 Case 2 : Digit_sel = &B0100_0000 Case 3 : Digit_sel = &B0010_0000 Case 4 : Digit_sel = &B0001_0000 Digit = 0 End Select Shiftout Serial_data_pin , Serial_clock_pin , Digit_sel , 1 'serial out to 74HC595 Shiftout Serial_data_pin , Serial_clock_pin , Digit_pattern , 1 'serial out to 74HC595 !sbi pinb,1 'toggle PB1 / STCP at 74hc595 !sbi pinb,1 'toggle PB1 / STCP at 74hc595 Return Prepare_number_for_output: If Show <> Show_old Then K = Show / 1000 'separate decimal digits from word variable into byte array Disable Compare0a 'no output to display while modifying Number_ar() Number_ar(1) = K 'first/leftmost digit on 4*7 Seg. Display K = Show Mod 1000 'separate decimal digits from word variable into byte array K = K / 100 Number_ar(2) = K K = Show Mod 100 'separate decimal digits from word variable into byte array K = K / 10 Number_ar(3) = K K = Show Mod 10 'separate decimal digits from word variable into byte array Number_ar(4) = K 'forth/rightmost digit on 4*7 Seg. Display For I = 1 To 3 If Number_ar(i) = 0 Then Number_ar(i) = 10 Else Exit For 'replace leading zeros with indexes of blank Next I Enable Compare0a Show_old = Show End If Return Bitpattern: Data &B00000011 '0 Data &B10011111 '1 Data &B00100101 '2 Data &B00001101 '3 Data &B10011001 '4 Data &B01001001 '5 Data &B01000001 '6 Data &B00011111 '7 Data &B00000001 '8 Data &B00001001 '9 Data &B11111111 'blank
Searcher







Hoffentlich liegt das Ziel auch am Weg
Zitieren
Lesezeichen