Ik ben aan het proberen om een rotary encoder werkend te krijgen op een 16f628, als compiler gebruik ik proton lite. Ik heb het topic gevonden waarin videomodulator aangeeft hoe het kan in mikrobasic en een 16f877, zie:
http://www.circuitsonline.net/forum/view/40455/1/rotary+encoder+16f628
Graag zou ik dit omzetten naar proton en 16f628a, maar ik kom er niet helemaal uit. De code van hieronder werkt niet, ik krijg geen foutmeldingen, maar ik zie als temp 4 horizontale lijntjes in 1 karakter.
Iemand een idee hoe ik temp kan laten verhogen en verlagen met behulp van de rotary encoder?
DEVICE 16F628A ;Gebruik een 16F628A type
CONFIG INTRC_OSC_NOCLKOUT, WDT_OFF, PWRTE_ON, LVP_OFF, MCLRE_OFF
PORTB_PULLUPS ON ;On-chip pull-up weerstanden actief
DIM Temp AS BYTE ;Variabelen
TRISB = %11111111 ;Alle poorten ingangen
INTCON = %10001000 ;GIE & RBIE hoog
CLEAR
IF PORTB.0 = 1 THEN
IF PORTB.1 = 1 THEN
Temp = Temp + 1
ELSE
Temp = Temp - 1
ENDIF
ELSE
IF PORTB.1 = 1 THEN
Temp = Temp - 1
ELSE
Temp = Temp + 1
ENDIF
ENDIF
DELAYMS 5 ;Ontdendering
INTCON.0 = 0 ;Interrupt flag clearen
WHILE 1 = 1
DELAYMS 100 ;Lcd initialisatie
PRINT AT 1,1, "Volume="
PRINT AT 2,1, Temp
WEND ;Terug naar WHILE
END
In ieder geval is Temp een BYTE en geen string, zoals 123 niet hetzelfde is als "123" voor de compiler.
Als bij jou Temp de waarde 65 zou krijgen, komt er een A op je display.
Je zal een functie of routine moeten hebben om van bytes strings (- of characters) te maken.
@Henry, bovenste stuk is een ISR?
Een interrupt?
Heb ik me nog niet mee bezig gehouden, had al zitten prakkedenken over INTCON...
Edit: Leest gegeven link.
bytetostr(temp,txt) 'omzetten van getalletje om op LCD te zetten
Ok, dom geblaat van moi.
Toch niet, routine loopt over in de main loop...
[Bericht gewijzigd door Henry S. op ]
Volgens mij, is dat wel de bedoeling. Dan wordt de hoofdlus dus onderbroken en zou het moeten werken. Ik weet echter te weinig van Proton om te zeggen of TS het correct heeft uitgevoerd.
//edit: Ok!
Op 12 februari 2007 18:40:52 schreef Rd12tf:
Je zal een functie of routine moeten hebben om van bytes strings (- of characters) te maken.
Ik kan geen automatische conversie doen van byte naar string aangezien het geen 16 bits processor is.
Als ik alleen het verschil kan zien tussen rechtsom en linksom draaien, dan zou dat ook al voldoende zijn.
Temp is al een getal en wordt ook zo uitgespuugd als je
Print at 2,1,dec Temp
gebruikt.
Maar ik denk ook dat je interrupt vastloopt in de hoofdroutine...
Zie de manual over interrupts, blz 277 ev.
[Bericht gewijzigd door Henry S. op ]
Op 13 februari 2007 08:46:57 schreef Red_Arrow:
[...]Ik kan geen automatische conversie doen van byte naar string aangezien het geen 16 bits processor is.
[...]
Automatisch?! Kan niet?!? Moet je ook zelf maken!
Tip
Splits de cijfers van het te converteren getal 123 ->
a=1
b=2
c=3
(rekenkundig slimmigheidje, zelf uitzoeken!)
Tel bij iedere variabele a,b en c 48 op, en je hebt de ASCII waarden als chars, aan elkaar rijgen en op je display zetten ...
Programmeren is nu eenmaal 1% inspiratie en 99% transpiratie!
Wat henry zegt klopt wel, dus ik vraag me af waarvoor ik de conversie moet doen. Dit stond echter wel in het programma van videomodulator. Maar het gaat mij in eerste instatie om links en rechtsom te kunnen onderscheiden.
Maar het zou dus moeten zijn dat zodra een pin van waarde verandert hij in de interrupt service routine gaat. Doet de PIC dit automatisch als je intcon enabled? Want dan moet ik erachter komen hoe ik hem in die functie kan laten komen.
De manual lezen. En eventueel die van MikroBasic.
@Rd12tf: Omzetten is niet nodig, Temp is al byte en wordt als getal uitgepoept.
[Bericht gewijzigd door Henry S. op ]
Daar gaat het niet om! ...
(Of: Als je ècht wilt leren programmeren, dan moet je daar wat voor doen.)

[Bericht gewijzigd door Rd12tf op ]
Ik heb mijn programma een beetje ingekort, om interrupts onder de knie te krijgen (ook met behulp van de help functie van proton). Maar ik kom er nog niet uit.
DEVICE 16F628A ;Gebruik een 16F628A type
CONFIG INTRC_OSC_NOCLKOUT, WDT_OFF, PWRTE_ON, LVP_OFF, MCLRE_OFF
PORTB_PULLUPS ON ;On-chip pull-up weerstanden actief
DIM Temp AS BYTE ;Variabelen
on_interrupt Flash
TRISB = %11111111 ;Alle poorten ingangen
INTCON = %10001000 ;GIE & RBIE hoog
CLEAR
GOTO test
Flash:
PRINT AT 2,1, "Flash"
DELAYMS 5 ;Ontdendering
INTCON.0 = 0
test:
DELAYMS 100 ;Lcd initialisatie
PRINT AT 1,1, "Vol="
PRINT AT 1,5, DEC Temp
GOTO test
END
Nu krijg ik zonder iets te doen vol=255 en flash in mijn scherm. Dus hij komt gelijk in de interrupt mode. Ook heb in on_interrupt verandert in on_hardware_interrupt, maar dat scheelde ook niet.
Weet iemand wat er fout zit in het programma, of waarom waarom temp op 255 komt te staan?
Frits Kieftenbelt
Ohm sweet Ohm | www.picbasic.nl
Nadat hij in Flash is geweest wandelt hij meteen weer test binnen.
De regel "Flash" zal nu maar 105mSec op het display staan.
(Waarvoor is de 5mSec ontdendering?)
De ontdendering staat ook in het programma van videomodulator (zie link 1e post), dit heb ik dus maar op dezelfde plaats gehouden, ik gebruik een mechanische rotary encoder.
Flash blijft gewoon op het scherm staan.
Nog steeds de interrupt niet als subroutine gedefineerd, die banjert gewoon door.
Is de manual zo onduidelijk? In de laatste gedrukte versie vanaf blz. 281
Op 16 februari 2007 16:16:02 schreef Henry S.:
Nog steeds de interrupt niet als subroutine gedefineerd, die banjert gewoon door.Is de manual zo onduidelijk? In de laatste gedrukte versie vanaf blz. 281
Ik heb als voorbeeld voor het laatste programmatje blz 281 als voorbeeld genomen, maar ik weet niet wat ik van de subroutine mis, op pagina 281 staat alleen nog context restore, maar ik denk dat ik alleen RBIF laag hoef te maken.
Zou iemand misschien iets meer willen vertellen over die subroutine, of mij een beetje op weg helpen?
elmowww
PA0EJE - www.eje-electronics.nl - e.jongerius[aapje]eje-electronics.nl - EJE Electronics - Elektronica/firmware ontwikkeling
Jeroen Boere
IF you can't convince them, then confuse them!
ik gebruik dit (eerder deze week ontwikkeld...) om een interrupt te handlen van een UART
'****************************************************************
'* Name : 20072 - PIC18F2550 COM Receives 3 bytes command *
'* Author : Jeroen Boere *
'* Notice : Copyright (c) 2007 Jeroen Boere *
'* : All Rights Reserved *
'* Date : 14/02/2007 *
'* Version : 1.0 *
'* Notes : XTAL 20MHZ *
'* : PIC18F2550 *
'****************************************************************
DEVICE 18F2550
@CONFIG_REQ
@__config CONFIG1L, PLLDIV_1_1 & CPUDIV_1_1 & USBDIV_1_1
@__config CONFIG1H, FOSC_HS_1 & FCMEM_OFF_1 & IESO_OFF_1
@__config CONFIG2L, PWRT_ON_2 & BOR_OFF_2 & VREGEN_ON_2
@__config CONFIG2H, WDT_OFF_2 & WDTPS_128_2
@__config CONFIG3H, MCLRE_ON_3 & LPT1OSC_OFF_3 & PBADEN_OFF_3 & CCP2MX_OFF_3
@__config CONFIG4L, STVREN_OFF_4 & LVP_OFF_4 & ICPRT_OFF_4 & XINST_OFF_4 & DEBUG_OFF_4
@__config CONFIG5L, CP0_OFF_5 & CP1_OFF_5 & CP2_OFF_5
@__config CONFIG5H, CPB_OFF_5 & CPB_OFF_5
@__config CONFIG6L, WRT0_OFF_6 & WRT1_OFF_6 & WRT2_OFF_6
@__config CONFIG6H, WRTC_OFF_6 & WRTB_OFF_6 & WRTD_OFF_6
@__config CONFIG7L, EBTR0_OFF_7 & EBTR1_OFF_7 & EBTR2_OFF_7
@__config CONFIG7H, EBTRB_OFF_7
ALL_DIGITAL true
XTAL = 20
'76543210 ' bit wise output mask
SPBRG = %00001111 ' Set baud rate to 19200 (=15 dec)
RCSTA = %10010000 ' Enable serial continuous receive
TXSTA = %00100000 ' Enable transmit asynchronous mode
BAUDCON = %00000000 ' no special features
SYMBOL int_LED = PORTC.1
SYMBOL flash_LED = PORTC.0
DIM Rx_Byte[3] AS BYTE
DIM cmd_str AS STRING * 3
START:
INTCON.7 = 1 ' Enable Global Interrupts
INTCON.6 = 1 ' Enable Peripheral Interrupts
PIE1.5 = 1 ' Enable UART Rx Interrupt
ON_INTERRUPT GOTO INT ' If there is UART activity: goto INT
GOTO MAIN ' Skip the ISR, goto main program
INT: ' Begin of the ISR
HIGH int_LED ' Make Interrupt Bit High
HSERIN[STR Rx_Byte] ' Read RCreg and put into byte array
PIR1.5 = 0 ' Just to be sure: Clear the Interrupt flag
cmd_str[0] = Rx_Byte[0] ' Store first byte in string at pos 0
cmd_str[1] = Rx_Byte[1] '
cmd_str[2] = Rx_Byte[2] '
cmd_str[3] = 0 ' Terminate the string
DELAYMS 100 ' Wait 100 ms (just for fun :) )
IF cmd_str = "LRE" THEN HSEROUT["Live Read OK!"] ' If LRE, output string
IF cmd_str = "MRA" THEN HSEROUT["Memory Read OK!"] ' IF MRA, output string
LOW int_LED ' The end of the ISR, clear INT-LED
GOTO START ' Goto start so ISR will be used again
MAIN: ' main programloop
LOW flash_LED ' flashled is off
DELAYMS 500 ' Wait 500 ms
HIGH flash_LED ' flashled is on
DELAYMS 500 ' Wait 500 ms
GOTO MAIN ' Again, begin the loop
END ' End of program!
zie ook http://jeroen.boere-adviseur.nl 
Bedankt voor jullie bijdragen tot nu toe.
Ik heb mijn programma nog wat aangepast namelijk:
DEVICE 16F628A ;Gebruik een 16F628A type
CONFIG INTRC_OSC_NOCLKOUT, WDT_OFF, PWRTE_ON, LVP_OFF, MCLRE_OFF
PORTB_PULLUPS ON ;On-chip pull-up weerstanden actief
DIM Temp AS BYTE ;Variabelen
on_interrupt Flash
TRISB = %11111111 ;Alle poorten ingangen
INTCON = %10001000 ;GIE & RBIE hoog
CLEAR
GOTO test
Flash:
PRINT AT 2,1, "Flash"
INTCON.0 = 0
CONTEXT RESTORE
test:
DELAYMS 100 ;Lcd initialisatie
PRINT AT 1,1, "Vol="
PRINT AT 1,5, DEC Temp
GOTO test
END
on_interrupt goto?
op regel 8 staat on_interrupt flash, dit zou volgens mij moeten zijn wat jij bedoelt, het staat zo tenminste in de manual. Ook heb ik context restore ingevoegd. Helaas werkt het nog steeds niet.
Hij blijft gelijk in de interrupt gaan, wat ik dus niet begrijp, aangezien hij dat pas moet doen als ik aan de rotary encoder draai.
Jeroen Boere
IF you can't convince them, then confuse them!
kijk nog een goed naar de loop uit mijn source....
elke keer als ik een interrupt heb gehad ga ik terug naar start (lijkt wel monopolie...) om de hele ISR opnieuw te initialiseren... en do goto vond ik wat prettiger werken, is wat duidelijke en werkt ook goed....
Op 20 februari 2007 15:32:34 schreef Jeroen Boere:
kijk nog een goed naar de loop uit mijn source....
elke keer als ik een interrupt heb gehad ga ik terug naar start (lijkt wel monopolie...) om de hele ISR opnieuw te initialiseren... en do goto vond ik wat prettiger werken, is wat duidelijke en werkt ook goed....
Opnieuw initialiseren doe ik met de context restore (toch?)
Hieronder het programma uit de manual (daar initialiseren ze 1x en daarna werken ze ook met context restore. Ook staat daar nergens in ON INTERRUPT goto flash, maar alleen bovenin on_interrupt flash:
DEVICE 16F84
ON_HARDWARE_INTERRUPT GOTO Flash
' Assign some Interrupt associated aliases
SYMBOL T0IE = INTCON.5 ' TMR0 Overflow Interrupt Enable
SYMBOL T0IF = INTCON.2 ' TMR0 Overflow Interrupt Flag
SYMBOL GIE = INTCON.7 ' Global Interrupt Enable
SYMBOL PS0 = OPTION_REG.0 ' Prescaler ratio bit-0
SYMBOL PS1 = OPTION_REG.1 ' Prescaler ratio bit-1
SYMBOL PS2 = OPTION_REG.2 ' Prescaler ratio bit-2
SYMBOL PSA = OPTION_REG.3 ' Prescaler Assignment (1=assigned to WDT 0=assigned to oscillator)
SYMBOL T0CS = OPTION_REG.5 ' Timer0 Clock Source Select (0=Internal clock 1=External PORTA.4)
SYMBOL LED = PORTB.1
GOTO Over_interrupt ' Jump over the interrupt subroutine
' Interrupt routine starts here
Flash:
' XOR PORTB with 1, Which will turn on with one interrupt and turn off with the next the LED connected to PORTB.0
PORTB = PORTB ^ 1
T0IF = 0 ' Clear the TMR0 overflow flag
CONTEXT RESTORE ' Restore the registers and exit the interrupt
Over_interrupt :
TRISB = %00000000 ' Configure PORTB as outputs
PORTB = 0 ' Clear PORTB
' Initiate the interrupt
GIE = 0 ' Turn off global interrupts
PSA = 0 ' Assign the prescaler to external oscillator
PS0 = 1 ' Set the prescaler
PS1 = 1 ' to increment TMR0
PS2 = 1 ' every 256th instruction cycle
T0CS = 0 ' Assign TMR0 clock to internal source
TMR0 = 0 ' Clear TMR0 initially
T0IE = 1 ' Enable TMR0 overflow interrupt
GIE = 1 ' Enable global interrupts
Inf:
LOW LED
DELAYMS 500
HIGH LED
DELAYMS 500
GOTO Inf
Jeroen Boere
IF you can't convince them, then confuse them!
maken ze in boeken nooit typ fouten?
heb je al geprobeert wat ik voorgedragen heb?
anders denken en doen kan tot een oplossing leiden...
Ik heb jouw code even als voorbeeld genomen en aangepast naar mijn idee, het ledje knippert wel, maar het interrupt ledje knippert niet als ik aan de rotary encoder draai.
DEVICE 16F628A
CONFIG INTRC_OSC_NOCLKOUT, WDT_OFF, PWRTE_ON, LVP_OFF, MCLRE_OFF
PORTB_PULLUPS ON
ALL_DIGITAL true
TRISB = %00000011
SYMBOL int_LED = PORTA.0
SYMBOL flash_LED = PORTA.1
START:
INTCON.7 = 1 ' Enable Global Interrupts
INTCON.6 = 1 ' Enable Peripheral Interrupts
INTCON.3 = 1 ' Enable RB port change
ON_INTERRUPT GOTO INT ' If there is a interrupt: goto INT
GOTO MAIN ' Skip the ISR, goto main program
INT: ' Begin of the ISR
HIGH int_LED ' Make Interrupt Bit High
PIR1.5 = 0 ' Just to be sure: Clear the Interrupt flag
LOW int_LED ' The end of the ISR, clear INT-LED
GOTO START ' Goto start so ISR will be used again
MAIN: ' main programloop
LOW flash_LED ' flashled is off
DELAYMS 500 ' Wait 500 ms
HIGH flash_LED ' flashled is on
DELAYMS 500 ' Wait 500 ms
GOTO MAIN ' Again, begin the loop
END
Frits Kieftenbelt
Ohm sweet Ohm | www.picbasic.nl