Beste CO'ers,
Vanalles geprobeerd, maar ik kom er niet uit...
Mijn code:
Device 18F4431 ;microcontroller
Xtal = 20
All_Digital TRUE ;Alle ingangen digitaal
Hserial_Baud = 115200 ;Transmissiesnelheid van de data over de bus
Hserial_RCSTA = %10010000
SPBRG = 1
TRISB = %00000000 ' PWM0,1,2,3,4,5 outputs
TRISC = %11000000
TRISD = %00000000 ' PWM0,1,2,3,4,5 outputs
TRISE.0 = 0
' PCPWM init
DTCON = %00000101 ' ~500nS dead-time (for complementary outputs only)
PTCON0 = %00001100 ' 1:1 postscale, Fosc/4 1:1 prescale, free running mode
' PTCON0 = %00000100 would give 19.45kHz/4
PTPERL = 0 '
PTPERH = 1 ' PTPER = $0100 or 256d for ~19.45kHz
' PWM4,5 independent, PWM0,1,2,3 complementary
PWMCON0 = %01011111 ' PWM[5:0] outputs enabled
PWMCON1 = 1 ' updates enabled, overrides sync w/timebase
PTCON1 = %10000000 ' PWM time base is ON, counts up
SSPCON.5 = 0
FLTCONFIG.4 = 0
FLTCONFIG.0 = 0
INTCON.7 = 1 ;GIE (Global Interrupt Enable) activeren
INTCON.6 = 1 ;PEIE (PEripheral Interrupt Enable) activeren
PIE1.5 = 1
Dim RGB_R As Word
Dim RGB_G As Word
Dim RGB_B As Word
Dim RGB_W As Word
Dim Serieel As Byte
Dim Ontv_Data As Word
Dim Byte_1 As Byte
Dim Byte_2 As Byte
Dim Temp As Word
Init:
DelayMS 100
On_Interrupt GoTo InterruptAfhandeling ;Spring naar label als data is ontvangen door de USART
Clear
PDC0L = RGB_R.LowByte
PDC0H = RGB_R.HighByte
PDC1L = RGB_G.LowByte
PDC1H = RGB_G.HighByte
PDC2L = RGB_B.LowByte
PDC2H = RGB_B.HighByte
PDC3L = RGB_W.LowByte
PDC3H = RGB_W.HighByte
Main:
GoSub Test
GoTo Main
Test:
For Temp = 0 To 1024
RGB_R = Temp
GoSub Update_RGBW
DelayMS 1
Next Temp
For Temp = 1024 To 0 Step -1
RGB_R = Temp
GoSub Update_RGBW
DelayMS 1
Next Temp
For Temp = 0 To 1024
RGB_G = Temp
GoSub Update_RGBW
DelayMS 1
Next Temp
For Temp = 1024 To 0 Step -1
RGB_G = Temp
GoSub Update_RGBW
DelayMS 1
Next Temp
For Temp = 0 To 1024
RGB_B = Temp
GoSub Update_RGBW
DelayMS 1
Next Temp
For Temp = 1024 To 0 Step -1
RGB_B = Temp
GoSub Update_RGBW
DelayMS 1
Next Temp
For Temp = 0 To 1024
RGB_W = Temp
GoSub Update_RGBW
DelayMS 1
Next Temp
For Temp = 1024 To 0 Step -1
RGB_W = Temp
GoSub Update_RGBW
DelayMS 1
Next Temp
Return
Update_RGBW:
PDC0L = RGB_R.LowByte
PDC0H = RGB_R.HighByte
PDC1L = RGB_G.LowByte
PDC1H = RGB_G.HighByte
PDC2L = RGB_B.LowByte
PDC2H = RGB_B.HighByte
PDC3L = RGB_W.LowByte
PDC3H = RGB_W.HighByte
Return
InterruptAfhandeling: ;Uitlezen en leegschuiven van buffer gebeurt in hoofdprogramma
HSerIn 1, Verder, [Ontv_Data]
Serieel = 1
Verder:
Context Restore
Return
EndDeze code was eerst veel groter, maar gestript om probleem te achterhalen.. Probleem is dat er de eerste 30 seconden niets gebeurt, daarna gaan netjes 4 ledjes 1 voor 1 faden.. Naast dat moet er via de UART nieuwe data binnen komen en verwerkt worden.. Daar is de interupt voor. Echter nu werkt dat niet lekker.. Als het programma eenmaal draait hoef ik maar de RX pin aan te raken en hij is alweer van slag voor +/- 30 seconden... Ook de RX pin aan de 0 verandert niets.. Duurt nog steeds 30 seconden voordat ie opstart..
Echter als ik de code:
HSerIn 1, Verder, [Ontv_Data] weg laat doet hij het in 1 keer prima.. Dus lijkt het daarin te zitten.. Maar ik kom er dus echt niet uit.. Op voorgaande pic ( 16F690 ) werd dezelfde code gebruikt, maar had ie niet deze rare fratsen..
Extern cristal zit goed met 2 20pf condensators, en aan de mclr pin hangt weerstand naar de +..
Wie o wie....
Bob
Arco
Special Member
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Ik weet niet of die compiler ook error-checking doet op de serieele verbinding.
MikroBasic niet, daar had ik iets soortgelijks. (Verbinding liep regelmatig vast)
Je moet na iedere receive de error flags testen (FERR en OERR)
If PIR1.RC1IF Then 'Data received
RxData = RCREG1
If RCSTA1.FERR = 1 Then RxByte = RCREG1 End If 'Framing error, dummy read
If RCSTA1.OERR = 1 Then 'Overrun error, re-enable receiver
RCSTA1.CREN = 0
RCSTA1.CREN = 1
End If
PIR1.RC1IF = 0
End If
Bart Hiddink
Bart Hiddink is Ideetron; electronics and projects, http://www.ideetron.nl. LoRaWAN Nutcase.
Vaak is het idd een overflow.
Die ontstaat als je de UART niet even stopt als het programma iets anders doet.
De UART krijgt dan 2 bytes binnen, terwijl je de eerste niet hebt opgehaald.
Dat stopt de UART en set de OERR flag.
Oplossen door de UART uit te zetten als je gaat verwerken of de routine om te verwerken af en toe onderbreken om te testen of je een byte uit het UART buffer moet halen.
Je hoeft alleen een interupt flag te testen.
hadv
Just find out what you like and let it kill you
Wat Arco zegt klopt.
Wat ik mis in je programma is de naam van PIE.5. Ik weet niet uit mijn hoofd wat dat betekent en heb ook geen zin het op te zoeken.
Verder leg je ook niet uit wat je HSERIAL_RCSTA doet.
Ik zie wel een paar malligheden:
- SPBRG = 1. Waarom doe je dit? Proton rekent zelf alle benodigde variabelen uit, je zou dat nu zomaar kunnen verstoren.
- de afhandeling van de interrupt routine werkte wellicht met een 16F, maar voor een 18F zijn wat andere zaken nodig. Lees de manual er even op na!
- ik betwijfel of het opnemen van een HSERIN in de interrupt routine uberhaupt wel goed kan werken. Houd er rekening mee dat tijdens de afhandeling van een interrupt INTCON.GIE op 0 wordt gezet zodat er geen nieuwe interrupts worden toegelaten. Ik weet 1 ding zeker en dat is dat HSERIN met interrupts werkt.
Nu jullie zo over overflow's begonnen, ben ik er uit denk ik... De variabele om de byte in te ontvangen was gedeclareerd als een Word.. Nu veranderd in een byte en nu lijkt het in 1 keer goed en ongevoelig te werken... Toch apart want ik meende dat er een 2 byte buffer was .. Ook bij de 16F690, maar de datasheet lijkt nu toch ook slechts een 1 byte buffer te zien.....
So far, so good... Thanx !
Arco
Special Member
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Zowiezo moet je de OERR flag altijd testen.
Als die eenmaal geset wordt, stopt de serieele communicatie totdat de USART receiver is gereset.