Ik heb een PIC 16F1847. Daar wilde ik een timer interrupt instellen voor 1uS.
Echter met de waarden van T2Con Post, Pre, en Pr2 kom ik niet verder dan 2uS.
Is dat een beperking van deze PIC?
Ik dacht in mijn onschuld: interne clock frequentie 32Mhz, 4*PLL enabled.
Volgens de formule: 32.000.000 / 4 / 1 / 2 / 4 = 1.000.000
Maar het wordt 500.000...
'====================================================================================================
Program Test1US 'Test timer interrupt
'====================================================================================================
' Project name: Test1US
' MCU: PIC16F1847
' Oscillator: Internal 32 MHz
'====================================================================================================
'====================================================================================================
Sub procedure Interrupt() iv 0x0004 ics ICS_AUTO
'====================================================================================================
If TMR2If_bit = 1 Then
LATB.3 = Not LATB.3
TMR2If_bit = 0
End If
End Sub
main:
ANSELB = %00000000 'All Port B digital
TRISB = %00000000 '
OSCCON = %11110000 '32 MHz internal, 4X PLL enabled
T2CON = %00001100 'Pre: 1 - Post:2
PR2 = 3
GIE_bit = 1 'Enable timer irq
PEIE_bit = 1
TMR2IE_bit = 1 'Enable Timer1 overflow interrupt
TMR2If_bit = 0 'Clear Timer1 overflow interrupt flag bit
While True Wend
End.SparkyGSX
Een manager is iemand die denkt dat negen vrouwen in één maand een kind kunnen maken
Ik ken deze PIC niet (eigenlijk ken ik nauwelijks PICs), maar bij andere microcontrollers is het vrij gebruikelijk om de deelfactor -1 in te stellen; een instelling van 3 betekend dat een tellertje van 0 tot 3 telt, en dus dat je door 4 deelt. Wellicht gebeurd hier hetzelfde?
Bedenk wel dat een interrupt op die frequentie erg moeilijk gaat zijn, simpelweg omdat je tussen 2 interrupts maar 32 clockcycles hebt om iets te doen, wat al erg weinig is, maar ik meen me te herinneren dat de PIC niet op elke clockcycle een instructie uitvoert (elke 4de cycle?).
Nogmaals, ik ken de PIC niet, dus misschien is dit compleet onzin. In dat geval: succes!
kijk ook eens naar de tijd die het kost om een routine in en uit te springen...
ken de PIC niet, maar had ooit zelf een blokgolf generatortje gemaakt met variabele puls breedte en timing. bij te hoge snelheid (freq) had hij alleen maar tijd om de interrupt routines af te handelen en NIET meer de rest van het programma uit te voeren, met als gevolg dat de knop bediening niet meer werkte...
Arco
Special Member
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Interrupt op 1uS (1MHz!) is veel te snel. 1uS is 8 instruction cycles bij de PIC16 op 32MHz.
4 cycles gaan al verloren door de call/return van interrupt, dus blijven er maar 4 cycles over, veel te weinig om iets nuttigs in te doen.
Dit geldt voor een enhanced 16F1xxx processor, bij een standaard 16Fxxx is de overhead nog veel groter (iets van 16 cycles ivm context save/restore)
(jouw code is al vele malen langer)
_Interrupt:
;Test_irq.mbas,11 :: Sub procedure Interrupt() iv 0x0004 ics ICS_AUTO
;Test_irq.mbas,13 :: If TMR2If_bit = 1 Then
0x0004 0x3180 MOVLP 0
0x0005 0x0020 MOVLB 0
0x0006 0x1C91 BTFSS TMR2IF_bit, BitPos(TMR2IF_bit+0)
0x0007 0x280D GOTO L__Interrupt2
;Test_irq.mbas,14 :: LATB.3 = Not LATB.3
0x0008 0x3008 MOVLW 8
0x0009 0x0022 MOVLB 2
0x000A 0x068D XORWF LATB, 1
;Test_irq.mbas,15 :: TMR2If_bit = 0
0x000B 0x0020 MOVLB 0
0x000C 0x1091 BCF TMR2IF_bit, BitPos(TMR2IF_bit+0)
L__Interrupt2:
;Test_irq.mbas,17 :: End Sub
L_end_Interrupt:
L__Interrupt11:
0x000D 0x0009 RETFIE %s
; end of _Interrupt
De langere tijd tussen interrupts wordt veroorzaakt doordat er interrupts gemist worden om en om: irq is non-reentrant.
digithalys
RobH
Wanneer je enige doel is om pin B3 te laten flip-floppen zou je PWM kunnen gebruiken. Een voorbeeldje in JAL/JALLIB zou kunen zijn:
include 16f1847 -- target PICmicro
--
-- This program uses the internal oscillator at 8 MHz + 4x PLL
pragma target clock 32_000_000 -- oscillator frequency
-- configuration memory settings (fuses)
pragma target OSC INTOSC_NOCLKOUT -- internal oscillator
pragma target WDT disabled -- no watchdog
pragma target MCLR external -- reset externally
pragma target LVP ENABLED -- no LVP
pragma target PLLEN ENABLED -- 4x PLL -> 32 MHz
--
enable_digital_io() -- make all pins digital I/O
--
OSCCON_IRCF = 0b1110 -- set internal oscillator for 8 MHz
-- Configure PWM
pin_ccp1_RB3_direction = output -- make PWM pin output
include pwm_hardware
pwm_set_frequency(1000000)
pwm1_set_dutycycle_percent(50)
pwm1_on()
Nee, mijn doel was een hernieuwde poging om een TV-patroon generatortje te maken met een PIC.
Waarbij ik in eerste instantie dacht per uS aan te kunnen geven waar wat moet komen.
Maar ik kan het anders oplossen door de interrupt lager te zetten zodat mijn kleinste eenheid 4uS is.
Dat werkt wel.
Alleen heb ik nu wat moeite met het testen van de pulsen waarbij ik een logic Analyzer gebruik. Ik gebruik PulseView als software, maar de resultaten zijn raar.
Met name de pulslengte. Hij volgt gewoon wat je boven aan frequentie hebt ingesteld.
Hierbij het voorbeeld:
Hij maakt van de pulslengte 50uS (de echte waarde is 4us, gemeten op de scope).
Die 50us toont hij omdat de frequentie daarboven op 20Khz staat ingesteld. Kies je daar een andere, dan volgt hij die gewoon en past de pulslengte aan aan de gekozen frequentie.
Wat ik wil weten hoe lang die puls écht is.
Ik doe vast iets fout...
Op maandag 15 januari 2024 16:39:51 schreef Bavelt:
Alleen heb ik nu wat moeite met het testen van de pulsen waarbij ik een logic Analyzer gebruik. Ik gebruik PulseView als software, maar de resultaten zijn raar.
Heb je geen digitale scoop?
Arco
Special Member
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Die 50us toont hij omdat de frequentie daarboven op 20Khz staat ingesteld.
Dat klopt toch ook?
Als je de samplefrquentie op 50uS zet (1/20000), dan kun je moeilijk verwachten dat je kortere pulsen kunt meten...
Heel goed, Arco. 
Ja natuurlijk is het dat. Dat had ik over het hoofd gezien. Bij een hogere frequentie gaat het gewoon goed.
Een data analyzer is soms overzichtelijker dan een scope, al helemaal als er hogere en lagere frequenties tegelijk in het signaal zijn.
Arco
Special Member
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
De samplefrequentie altijd op minimaal het dubbele van de te meten frequentie zetten voor een goed resultaat...
Op maandag 15 januari 2024 22:06:02 schreef Arco:
De samplefrequentie altijd op minimaal het dubbele van de te meten frequentie zetten voor een goed resultaat...
Heb ik zojuist gedaan. De uitdaging nu is om de interrupt goed te krijgen. Want het is al snel gebeurd dat deze te druk wordt.
Ik had een bedacht een signaal te maken die iedere 64uS een low geeft van 4uS.
Vervolgens iedere 20ms een Low van 20uS.
En tenslotte een low na 28uS met een lengte van 28uS. En dat alles in een EN-operatie gegooid.
Maar de timing loopt verkeerd. Ze beïnvloeden elkaar.
'====================================================================================================
Program Test1US 'Test timer interrupt
'====================================================================================================
' Project name: Test1US
' MCU: PIC16F1847
' Oscillator: Internal 32 MHz
'====================================================================================================
Dim CntHor As Byte
CntLenHor As Byte
CntVert As Word
CntLenVert As Word
CntSign As Byte
CntLenSign As Byte
i1 As Byte
Flags As Byte
fTim64 As Sbit At Flags.0
fTim50 As Sbit At Flags.1
'====================================================================================================
Sub procedure Interrupt() iv 0x0004 ics ICS_AUTO
'====================================================================================================
If TMR2If_bit = 1 Then
If CntHor > 0 Then
Dec(CntHor)
Else
LATB.1 = 0
CntLenHor = 1
CntHor = 15
End If
If CntLenHor > 0 then
Dec (CntLenHor)
Else
LATB.1 = 1
End If
If CntVert > 0 Then
Dec(CntVert)
Else
LATB.2 = 0
CntLenVert = 5
CntVert = 5000
End If
If CntLenVert > 0 then
Dec (CntLenVert)
Else
LatB.2 = 1
End If
If CntSign > 0 Then
Dec(CntSign)
Else
LATB.3 = 0
CntSign = 7
CntLenSign = 7
End If
If CntLenSign > 0 then
Dec (CntLenSign)
Else
LatB.3 = 1
End If
TMR2If_bit = 0
End If
End Sub
main:
ANSELB = %00000000 'All Port B digital
TRISB = %00000000 '
OSCCON = %11110000 '32 MHz internal, 4X PLL enabled
T2CON = %00011100 'Pre: 1 - Post:4
PR2 = 7
GIE_bit = 1 'Enable timer irq
PEIE_bit = 1
TMR2IE_bit = 1 'Enable Timer1 overflow interrupt
TMR2If_bit = 0 'Clear Timer1 overflow interrupt flag bit
LATB.1 = 1
LATB.2 = 1
LATB.3 = 1
LATB.4 = 1
CntHor = 16 'Preload Cnt to get Horizontal pulse (64 us)
CntVert = 5000 'Preload Cnt to get Vertical pulse (20 ms)
CntLenHor = 0
CntLenVert = 0
CntLenSign = 0
CntSign = 7
CntLenSign = 6
Flags = 0
While True
LATB.4 = LATB.1 and LATB.2 and LATB.3
Wend
End.Toen ik las dat je een patroongenerator wilt maken moest ik aan Otto Tuil z'n project denken. Misschien kun je daar nog ideeën opdoen. Hij gebruikt een CPLD voor de beeldgeneratie. Ik denk dat een PIC te traag is, misschien een andere processor. (Teensy ?)
http://www.gloeidraad.nl/index.php?p=artikelen&sub=artikel-tvbeeld…
Arco
Special Member
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Hoe moet het signaal er precies uit zien? Er is vast wel wat te bedenken, pic is snel genoeg.
(er is ook een 16 MIPS 64MHz versie, en PIC24 zelfs tot 70 MIPS)
Wellicht een tekeningetje van het signaal? In wat voor verhouding tot elkaar zitten die signalen? (4uS/20uS/28uS/64uS/20mS
[Bericht gewijzigd door Arco op (28%)]
Geen idee of een PIC het kan, maar ik heb ooit een 4MHz signaal met een AVR gemaakt door de SPI te "ge"-bruiken.
Al jouw perioden zijn veelvouden van 4uS. Als je een SPI peripheral op 250kHz instelt, en de juiste data tweakt om je gewenste bit-patroon te maken, ben je er dan niet?
Een SPI peripheral op 250kHz heeft slechte elke 32uS een nieuwe data-byte nodig. Dat moet haalbaar zijn in een interrupt, vooral als de data al klaar staat.
Op dinsdag 16 januari 2024 03:28:01 schreef Arco:
Hoe moet het signaal er precies uit zien? Er is vast wel wat te bedenken, pic is snel genoeg.
(er is ook een 16 MIPS 64MHz versie, en PIC24 zelfs tot 70 MIPS)Wellicht een tekeningetje van het signaal? In wat voor verhouding tot elkaar zitten die signalen? (4uS/20uS/28uS/64uS/20mS
Ik dacht aan dit signaal. Let wel: ik weet dat dit geen goed TV-signaal is, maar om te beginnen kom ik wel in de buurt.
SparkyGSX
Een manager is iemand die denkt dat negen vrouwen in één maand een kind kunnen maken
De tijden 5us, 28us, en 64us zijn een beetje ongelukkig, aangezien de grootste gemene deler daarvan 1us is. Ik vind de suggestie van blurp op een SPI bus te gebruiken lang niet gek, maar dat vereist wel dat je geen signalen op andere pinnen hoeft te genereren, want dat gaat natuurlijk niet op die manier.
Arco
Special Member
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Zoiets zou moeten werken: (niet getest)
De 'kludge' met Sub Procedure bij SyncPuls is nodig omdat er een bug in de compiler zit in assembly afhandeling: een assembly call wordt niet uitgevoerd.
'====================================================================================================
Program TestSync 'Test timer interrupt
'====================================================================================================
' MCU: PIC16F1847
' Oscillator: Internal 4 MHz
'====================================================================================================
Dim Cnt As Byte
Cnt2 As Byte
Sub Procedure Init()
ANSELB = %00000000 'All Port B digital
TRISB = %00000000 '
OSCCON = %01101000 '4 MHz internal
End Sub
Sub Procedure SyncPuls()
Asm
MOVLW %11111100
ANDWF LATB, f
NOP
NOP
NOP
BSF LATB,0
GOTO DEL1
DEL1: GOTO DEL2
DEL2: GOTO DEL3
DEL3: BSF LATB,1
MOVLW 8
MOVWF _CNT
CNTLP1: DECFSZ _CNT
GOTO CNTLP1
BCF LATB,1
MOVLW 8
MOVWF _CNT
CNTLP2: DECFSZ _CNT
GOTO CNTLP2
End Asm
End Sub
'==============================================================================
main:
'==============================================================================
Init()
Asm
LOOP2: MOVLW 125
MOVWF _CNT2
CALL _SyncPuls
CALL _SyncPuls
CALL _SyncPuls
CALL _SyncPuls
CALL _SyncPuls
DECFSZ _CNT2
GOTO LOOP2
MOVLW %11111100
ANDWF LATB, f
MOVLW 3
MOVWF _CNT
CNTLP3: DECFSZ _CNT
GOTO CNTLP3
GOTO DEL4
DEL4: GOTO LOOP2
End Asm
End.Met interrupt is het op hogere snelheden moeilijk om exacte timing te garanderen, daarom in-line code.
Het gebruik van words moet je ook voorkomen, dat geeft ook overhead en onverwachte delays...
Op maandag 15 januari 2024 22:06:02 schreef Arco:
De samplefrequentie altijd op minimaal het dubbele van de te meten frequentie zetten voor een goed resultaat...
Had meneer Nyquist daar niet iets mee te maken ?
Op dinsdag 16 januari 2024 16:28:43 schreef Arco:
Zoiets zou moeten werken: (niet getest)
De 'kludge' met Sub Procedure bij SyncPuls is nodig omdat er een bug in de compiler zit in assembly afhandeling: een assembly call wordt niet uitgevoerd.'==================================================================================================== Program TestSync 'Test timer interrupt '==================================================================================================== ' MCU: PIC16F1847 ' Oscillator: Internal 4 MHz '==================================================================================================== Dim Cnt As Byte Cnt2 As Byte Sub Procedure Init() ANSELB = %00000000 'All Port B digital TRISB = %00000000 ' OSCCON = %01101000 '4 MHz internal End Sub Sub Procedure SyncPuls() Asm MOVLW %11111100 ANDWF LATB, f NOP NOP NOP BSF LATB,0 GOTO DEL1 DEL1: GOTO DEL2 DEL2: GOTO DEL3 DEL3: BSF LATB,1 MOVLW 8 MOVWF _CNT CNTLP1: DECFSZ _CNT GOTO CNTLP1 BCF LATB,1 MOVLW 8 MOVWF _CNT CNTLP2: DECFSZ _CNT GOTO CNTLP2 End Asm End Sub '============================================================================== main: '============================================================================== Init() Asm LOOP2: MOVLW 125 MOVWF _CNT2 CALL _SyncPuls CALL _SyncPuls CALL _SyncPuls CALL _SyncPuls CALL _SyncPuls DECFSZ _CNT2 GOTO LOOP2 MOVLW %11111100 ANDWF LATB, f MOVLW 3 MOVWF _CNT CNTLP3: DECFSZ _CNT GOTO CNTLP3 GOTO DEL4 DEL4: GOTO LOOP2 End Asm End.Met interrupt is het op hogere snelheden moeilijk om exacte timing te garanderen, daarom in-line code.
Het gebruik van words moet je ook voorkomen, dat geeft ook overhead en onverwachte delays...
Het blijft lastig om te doorgronden wat hier gebeurt in dat Assembler.
Ik heb hem wel geprobeerd.
Maar er komt niets uit, geen beweging bij geen enkele poort..
fatbeard
Honourable Member
Een goed begin is geen excuus voor half werk; goed gereedschap trouwens ook niet. Niets is ooit onmogelijk voor hen die het niet hoeven te doen.
Kun je niet iets met de twee PWM modules en de data signal module?
PWM's hebben het voordeel van set-and-forget: geen interrupt nodig.
Anders zul je toch wat externe logic moeten gebruiken.
In een grijs en ver berleden (toen Microchip net kwam kijken) heeft een afstudeerder bij het bedrijf waar ik toen werkte een JTAG-module gemaakt met een PIC16C54 op 4MHz en wat externe TTL-logica op 10MHz; weet alleen niet meer hoe het precies in elkaar zat...
Op dinsdag 16 januari 2024 16:28:43 schreef Arco:
Zoiets zou moeten werken: (niet getest)
De 'kludge' met Sub Procedure bij SyncPuls is nodig omdat er een bug in de compiler zit in assembly afhandeling: een assembly call wordt niet uitgevoerd.'==================================================================================================== Program TestSync 'Test timer interrupt '==================================================================================================== ' MCU: PIC16F1847 ' Oscillator: Internal 4 MHz '==================================================================================================== Dim Cnt As Byte Cnt2 As Byte Sub Procedure Init() ANSELB = %00000000 'All Port B digital TRISB = %00000000 ' OSCCON = %01101000 '4 MHz internal End Sub Sub Procedure SyncPuls() Asm MOVLW %11111100 ANDWF LATB, f NOP NOP NOP BSF LATB,0 GOTO DEL1 DEL1: GOTO DEL2 DEL2: GOTO DEL3 DEL3: BSF LATB,1 MOVLW 8 MOVWF _CNT CNTLP1: DECFSZ _CNT GOTO CNTLP1 BCF LATB,1 MOVLW 8 MOVWF _CNT CNTLP2: DECFSZ _CNT GOTO CNTLP2 End Asm End Sub '============================================================================== main: '============================================================================== Init() Asm LOOP2: MOVLW 125 MOVWF _CNT2 CALL _SyncPuls CALL _SyncPuls CALL _SyncPuls CALL _SyncPuls CALL _SyncPuls DECFSZ _CNT2 GOTO LOOP2 MOVLW %11111100 ANDWF LATB, f MOVLW 3 MOVWF _CNT CNTLP3: DECFSZ _CNT GOTO CNTLP3 GOTO DEL4 DEL4: GOTO LOOP2 End Asm End.Met interrupt is het op hogere snelheden moeilijk om exacte timing te garanderen, daarom in-line code.
Het gebruik van words moet je ook voorkomen, dat geeft ook overhead en onverwachte delays...
Uit welke poort had nu het signaal moeten komen?
Arco
Special Member
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Signaal moet uit poort B0 en B1 komen.
Ik weet niet of er in de assemblycalls in Mikrobasic nog een bug zit misschien.
Daarom heb ik het even in assembly geklopt (de aangewezen weg voor timing gevoelige code en maar 57 bytes code...
)
Timing klopt in MPSIM. (alleen wat er bij lijn 312/13 exact gebeurt klopt misschien niet helemaal)
Hexfile ook attached.
;==============================================================================
; TestSync.asm. Clock frequency = 8MHz
;==============================================================================
#include <p16F1847.inc>
__CONFIG _CONFIG1, 0x3FFF & _FOSC_INTOSC & _WDTE_OFF & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _BOREN_OFF
__CONFIG _CONFIG2, 0x3FFF & _LVP_OFF
radix dec
errorlevel -302
cnt equ 0x70
cnt2 equ 0x71
;==============================================================================
; Program start
;------------------------------------------------------------------------------
org 0x000
goto Init
;==============================================================================
; Initialize
;------------------------------------------------------------------------------
org 0x020
Init
banksel trisb ;Port B all output
movlw b'00000000' ;
movwf trisb ;
movlw b'01110000' ;Oscillator 8MHz
movwf osccon ;
banksel anselb ;All pins digital
clrf anselb ;
banksel latb ;
nop ;
clrf latb ;
nop ;
;==============================================================================
loop2 movlw 156 ;156 x 2 = 312 lines
movwf cnt2 ;Loop counter
loop1 call sendline2 ;Run 2 times
call sendline ;
decfsz cnt2, f ;All done?
goto loop1 ;No, next loop
movlw b'11111100' ;Done, add frame sync
andwf latb, f ;
movlw 8 ;Frame sync pulse
movwf cnt ;
cntlp3 decfsz cnt, f ;
goto cntlp3 ;
goto del14 ;All done, new frame
del14 goto loop2 ;
;==============================================================================
sendline goto del0 ;
del0 nop ;
sendline2 nop ;
del1 nop ;
bsf latb, 0 ;Set b0
goto del3 ;Wait 7uS
del3 goto del4 ;
del4 goto del5 ;
del5 goto del6 ;
del6 goto del7 ;
del7 goto del8 ;
del8 nop ;
bsf latb, 1 ;Set b1
movlw 16 ;Wait 26uS
movwf cnt ;
cntlp1 decfsz cnt, f ;
goto cntlp1 ;
nop ;
nop ;
bcf latb, 1 ;Clear b1
movlw 15 ;Wait 26uS
movwf cnt ;
cntlp2 decfsz cnt, f ;
goto cntlp2 ;
goto del11 ;
del11 goto del12 ;
del12 nop ;
bcf latb, 0 ;
retlw 0 ;Done and return
end
SparkyGSX
Een manager is iemand die denkt dat negen vrouwen in één maand een kind kunnen maken
Als je nu een iets modernere controller gebruikt, met een DMA periferal die naar een GPIO poort schrijft op een trigger van een timer, kun je elk willekeurig signaal van 8 (of 16/32) bits breed maken, op 1MHz of nog veel meer, terwijl je CPU dat helemaal niets voor hoeft te doen.
Ik snap niet zo goed waarom je zo hard probeert om de timing signalen te maken, terwijl je nu al weet dat je er geen pixeldata bij kunt maken omdat je PIC hier al 100% druk mee is.
Op woensdag 17 januari 2024 15:38:53 schreef Arco:
Signaal moet uit poort B0 en B1 komen.
Ik weet niet of er in de assemblycalls in Mikrobasic nog een bug zit misschien.Daarom heb ik het even in assembly geklopt (de aangewezen weg voor timing gevoelige code en maar 57 bytes code...
)
Timing klopt in MPSIM. (alleen wat er bij lijn 312/13 exact gebeurt klopt misschien niet helemaal)
Hexfile ook attached.;============================================================================== ; TestSync.asm. Clock frequency = 8MHz ;============================================================================== #include <p16F1847.inc> __CONFIG _CONFIG1, 0x3FFF & _FOSC_INTOSC & _WDTE_OFF & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _BOREN_OFF __CONFIG _CONFIG2, 0x3FFF & _LVP_OFF radix dec errorlevel -302 cnt equ 0x70 cnt2 equ 0x71 ;============================================================================== ; Program start ;------------------------------------------------------------------------------ org 0x000 goto Init ;============================================================================== ; Initialize ;------------------------------------------------------------------------------ org 0x020 Init banksel trisb ;Port B all output movlw b'00000000' ; movwf trisb ; movlw b'01110000' ;Oscillator 8MHz movwf osccon ; banksel anselb ;All pins digital clrf anselb ; banksel latb ; nop ; clrf latb ; nop ; ;============================================================================== loop2 movlw 156 ;156 x 2 = 312 lines movwf cnt2 ;Loop counter loop1 call sendline2 ;Run 2 times call sendline ; decfsz cnt2, f ;All done? goto loop1 ;No, next loop movlw b'11111100' ;Done, add frame sync andwf latb, f ; movlw 8 ;Frame sync pulse movwf cnt ; cntlp3 decfsz cnt, f ; goto cntlp3 ; goto del14 ;All done, new frame del14 goto loop2 ; ;============================================================================== sendline goto del0 ; del0 nop ; sendline2 nop ; del1 nop ; bsf latb, 0 ;Set b0 goto del3 ;Wait 7uS del3 goto del4 ; del4 goto del5 ; del5 goto del6 ; del6 goto del7 ; del7 goto del8 ; del8 nop ; bsf latb, 1 ;Set b1 movlw 16 ;Wait 26uS movwf cnt ; cntlp1 decfsz cnt, f ; goto cntlp1 ; nop ; nop ; bcf latb, 1 ;Clear b1 movlw 15 ;Wait 26uS movwf cnt ; cntlp2 decfsz cnt, f ; goto cntlp2 ; goto del11 ; del11 goto del12 ; del12 nop ; bcf latb, 0 ; retlw 0 ;Done and return end[bijlage]
Deze hex werkt, er komt wat uit:
.
Bo: pulsen van 1,25 uS laag, 14,75 uS hoog
B1: pulsen van 9,5 uS laag, 16 uS hoog.
Verschuiving tussen B0 en B1: 1,75uS
Wat dit de bedoeling dat er uit zou komen?
Arco
Special Member
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Moet in ieder geval wat aanpassen.
Die 1.25uS moet 5uS zijn (vergeten de PLL uit te zetten, die staat default aan)
Kun je de tijden onderling erbij zetten (aangenomen dat 'A' 00:000 uS is, en dan dus de A-B, A-C, A-D, en A-E tijd)
Dan kan ik even kijken of het klopt. (die relatieve tijden erboven zijn me niet helemaal duidelijk)
Ik neem aan dat D0 = B0 en D1 = B1?
Angepaste versie met PLL uit:
;==============================================================================
; SyncTest.asm. Clock frequency = 8MHz
;==============================================================================
#include <p16F1847.inc>
__CONFIG _CONFIG1, 0x3FFF & _FOSC_INTOSC & _WDTE_OFF & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _BOREN_OFF
__CONFIG _CONFIG2, 0x3FFF & _LVP_OFF & _PLLEN_OFF
radix dec
errorlevel -302
cnt equ 0x70 ;Counters/digits
cnt2 equ 0x71
;==============================================================================
; Program start
;------------------------------------------------------------------------------
org 0x000
goto Init
;==============================================================================
; Initialize
;------------------------------------------------------------------------------
org 0x020
Init
banksel trisb ;Port B all output
movlw b'00000000' ;
movwf trisb ;
movlw b'01110000' ;Oscillator 8MHz
movwf osccon ;
banksel anselb ;All pins digital
clrf anselb ;
banksel latb ;
nop ;
clrf latb ;
nop ;
;==============================================================================
loop2 movlw 156 ;156 x 2 = 312 lines
movwf cnt2 ;Loop counter
loop1 call sendline2 ;Run 2 times
call sendline ;
decfsz cnt2, f ;All done?
goto loop1 ;No, next loop
movlw b'11111100' ;Done, add frame sync
andwf latb, f ;
movlw 8 ;
movwf cnt ;
cntlp3 decfsz cnt, f ;
goto cntlp3 ;
goto del14 ;All done, new frame
del14 goto loop2 ;
;==============================================================================
sendline goto del0 ;
del0 nop ;
sendline2 nop ;
del1 nop ;
bsf latb, 0 ;Set b0
goto del3 ;Wait 7uS
del3 goto del4 ;
del4 goto del5 ;
del5 goto del6 ;
del6 goto del7 ;
del7 goto del8 ;
del8 nop ;
bsf latb, 1 ;Set b1
movlw 16 ;Wait 26uS
movwf cnt ;
cntlp1 decfsz cnt, f ;
goto cntlp1 ;
nop ;
nop ;
bcf latb, 1 ;Clear b1
movlw 15 ;Wait 26uS
movwf cnt ;
cntlp2 decfsz cnt, f ;
goto cntlp2 ;
goto del11 ;
del11 goto del12 ;
del12 nop ;
bcf latb, 0 ;
retlw 0 ;Done and return
end
Zie dit docment voor aansluiten weerstanden op RB0 en RB1 (blz 3 en 4)