Nun, wenn Du normalerweise nicht brauchst, ist's ja ok. Assembler ist aber sehr einfach mit Bascomcode zu mischen und da stellt's 'nen echten Vorteil dar, wenn man's kann.
Druckbare Version
Dann dürfte das noch etwas mehr Ansporn sein:
Edit:Code:'#########
'## EDT ##
'#########
'---------
'TinyRGB
'V1.2
'11.03.2012
'---------
'schaltplan_tinyrgb_v1_0.dsn
'---------
'AtTiny13 @ 9,6 Mhz internal RC-Clock
'Jp1 gesetzt: Modus 0 aktiv
'Jp2 gesetzt: Modus 1 aktiv
'Modus 0: Farbwechsel über alle drei Grundfarben (R-G-B)
'Modus 1: Effekt-Farbwechsel
'---------
'Changelog:
'V1.2: * If-Abfrage zum Rücksetzen der Variable Pwm_count in der Timer-ISR entfernt
' (Variable läuft von selbst nach 0 über)
' * If-Abfragen zur Statusänderung in der Fading-Routine für Modus1 entfernt und über
' else-Statement direkt in den If-Abfragen zum Verändern der C_x-Variablen implementiert;
' einsparen von Flash
'
'V1.1: * If-Abfragen gegen Select-Abfragen getauscht; bessere Code-Lesbarkeit
' * Sprung zu Sub Fading über Flag in der Hauptschleife; spart SRAM und verkürzt die ISR-Handlung
'---------
$regfile = "attiny13.dat"
$crystal = 9600000 '9,6 Mhz
$hwstack = 16
$swstack = 16
$framesize = 24
Const R_Pin = 2
Const G_Pin = 1
Const B_Pin = 0
Const Clr_Mask = Not(2 ^ R_Pin + 2 ^ G_Pin + 2 ^ B_Pin)
Const Div_Preset = 9999
Const Clr_down = 0 ' Bei Ausgangspin Low schaltet die Led ein, bei High aus
Const Clr_up = 1 ' Bei Ausgangspin High schaltet die Led ein, bei Low aus
Const Compare_PWM_mode = Clr_down ' hier festlegen wie sich die PWM verhalten soll
'Const Compare_PWM_mode = Clr_up
PWM_Port Alias PortB
PWM_DIR Alias DDRB
R_Reg Alias R12
G_Reg Alias R13
B_Reg Alias R14
PWM_Cnt_Reg Alias R15
Dim C_r As IRam Byte At 12 'Channel Rot
Dim C_g As IRam Byte At 13 'Channel Grün
Dim C_b As IRam Byte At 14 'Channel Blau
'CONFIG IN/OUT
PWM_DIR = Bits(PB2 , PB1 , PB0)
PWM_Port = Bits(PB4 , PB3) 'Pullup Jp1 JP2 einschalten
'ALIAS
Jp1 Alias Pinb.3
Jp2 Alias Pinb.4
'CONFIG TIMER
Config Timer0 = Timer , Prescale = 1
On Timer0 Isr_timer0 Nosave
Enable Timer0
'VARIABLEN
Dim State As Byte
Dim Div As Word 'Teilervariable
Dim Modus As Byte 'Modus
Dim Flag_a As Byte 'Flag für Sub Fading
'INTERRUPTS EIN
Enable Interrupts
'### HAUPTSCHLEIFE ###
Do
'Jumperabfrage:
If Jp1 = 0 Then Modus = 0
If Jp2 = 0 Then Modus = 1
'Abfrage Flag_a:
If Flag_a = 1 Then Gosub Fading 'Wenn Flag gesetzt, springe zu Sub Fading
Loop
End
Fading:
If Modus = 0 Then
Select Case State
Case 0 :
Incr C_r
Decr C_b
If C_r = 255 Then State = 1
Case 1:
Decr C_r
Incr C_g
If C_g = 255 Then State = 2
Case 2:
Decr C_g
Incr C_b
If C_b = 255 Then State = 0
End Select
End If
If Modus = 1 Then
Select Case State
Case 0:
If C_r < 255 Then Incr C_r Else State = 1
Case 1:
If C_b < 255 Then Incr C_b Else State = 2
Case 2:
If C_g < 255 Then Incr C_g Else State = 3
Case 3:
If C_r > 0 Then Decr C_r Else State = 4
If C_g > 50 Then Decr C_g
If C_b > 0 Then Decr C_b
Case 4:
If C_g < 255 Then Incr C_g
If C_b < 255 Then Incr C_b Else State = 5
Case 5:
If C_g > 0 Then Decr C_g Else State = 0
If C_b > 0 Then Decr C_b
End Select
End If
Flag_a = 0 'Flag zurücksetzen
Return
'ISR TIMER0
Isr_timer0:
!PUSH R25
!push R24
!IN R24, SREG
!push R24
!INC PWM_Cnt_Reg
!IN R24, PWM_Port
!ANDI R24, Clr_Mask
!CP R_Reg, PWM_Cnt_Reg
#IF Compare_PWM_mode = Clr_up
!BRCS No_R
#ELSE
!BRCC No_R
#ENDIF
!SBR R24, 2 ^ R_Pin
No_R:
!CP G_Reg, PWM_Cnt_Reg
#IF Compare_PWM_mode = Clr_up
!BRCS No_G
#ELSE
!BRCC No_G
#ENDIF
!SBR R24, 2 ^ G_Pin
No_G:
!CP B_Reg, PWM_Cnt_Reg
#IF Compare_PWM_mode = Clr_up
!BRCS No_B
#ELSE
!BRCC No_B
#ENDIF
!SBR R24, 2 ^ B_Pin
No_B:
!OUT PWM_Port,R24
!LDS R24, {Div}
!LDS R25, {Div+1}
!SBIW R24, 1
!BRPL Not_Elapsed
!LDI R24, 1
!STS {Flag_a},R24
!LDI R24, lbyte(Div_Preset)
!LDI R25, hbyte(Div_Preset)
Not_Elapsed:
!STS {Div}, R24
!STS {Div+1}, R25
!POP R24
!OUT SREG, R24
!POP R24
!POP R25
Return
Hab' noch 'ne Compileranweisung eingeführt um je nach Anschluss der Leds eine einfache Umschaltung der Polarität zu ermöglichen, ohne ASM kennen zu müssen, damit kann der ISR-Teil universell verwendet werden.
Der Vorteil der Soft-PWM in ASM statt in Basic: es werden nur ca. 45 Takte verbraucht, bei einem Prescaler von 1 und einem 8-Bit Timer0 wird die ISR alle 256 Takte aufgerufen, damit beträgt die Prozessorlast durch die ASM-ISR: 45/256 = 17,6% gegenüber ca. 55% der Basic-ISR. Der Flashverbrauch sank auf 56%.
Die Konstantenbezeichnung orientiert sich an der Syntax von Config PWM.
Hallo!
Die Variante mit etwas mehr Power, von mir wegen des größeren Controllers als eigenständiges Projekt geführt, nennt sich TinyStripeRGB. Es geht primär darum einen RGB-LED-Stripe treiben zu können und etwas mehr Programmspeicher zur Verfügung zu haben.
Hinweis: Die Sicherung F1 ist relativ knapp bemessen, Strombedarf des Led-Stripes beachten!