Ik ben bezig met de besturing voor mijn robot. Ik wil met de 16f690 een h-brug aansturen. In de datasheet staat hoe ik dat moet doen. Ik weet al hoe ik de motor de andere kant laat draaien, dat doe je door CC1CON = %01001100 of CCP1CON = %11001100 te veranderen.
Ik heb nu dit stukje code, de bedoeling hiervan is om de 3 seconden de motor van richting te veranderen.
Device 16F690 ;Gebruik een 16F690 type
Config HS_OSC, CP_OFF, PWRTE_ON, MCLRE_OFF
XTAL 20
Dim Duty As Word
; 76543210
TRISC = %00000000 ;(0=uitgang, 1=Ingang)
Duty = 100 ;Duty van 10%
While 1 = 1
GoSub Links ;laat de motor linksom draaien
DelayMS 3000 ;Doe dat voor 3 seconden
GoSub Rechts ;Laat de motor rechtsom draaien
DelayMS 3000 ;Doe dat voor 3 seconden
Wend
End
Links:
CCP1CON = %11001100 ;links instelling
T2CON = %00000110 ;Zet Timer2 aan, Prescale=16
PR2 = 249 ;Zet PR2 om 1.22 kHz er uit te krijgen.
CCP1CON.4 = Duty.0 ;Zet duty naar de register
CCP1CON.5 = Duty.1 ;als een 10-bit word
CCPR1L = Duty >> 2
Return
Rechts:
CCP1CON = %01001100 ;rechts instelling
T2CON = %00000110 ;Zet Timer2 aan, Prescale=16
PR2 = 249 ;Zet PR2 om 1.22 kHz er uit te krijgen.
CCP1CON.4 = Duty.0 ;Zet Duty naar de register
CCP1CON.5 = Duty.1 ;als een 10-Bit Word
CCPR1L = Duty >> 2
Return De code werkt niet goed. Hij stuurt de motor alleen naar links en niet naar rechts aan. Ik denk dat het er aan ligt dat ik de TMR2 niet reset. Maar ik weet niet hoe dat moet, ik heb dit al gebrobeert:
CCP1CON = %00000000
T2CON = %00000000
TMR2 = %00000000Ik heb dat boven GoSub recht, Gusub links gezet maar dat werkt ook niet.
Kan iemand me mischien uitleggen hoe ik dit moet oplossen
Alvast bedankt
Brandon
nonkel_dw
nonkel dw
Geen idee wat er hier gebeurd...
CCP1CON.4 = Duty.0 ;Zet Duty naar de register
CCP1CON.5 = Duty.1 ;als een 10-Bit Word
CCPR1L = Duty >> 2Ik zou gewoon dit doen...
CCP1RL = Duty ; stop de waarde in het pwm register.Wat het clearen van de timer betreft dit gebeurd normaal automatisch.
Als de registers staan ingesteld voor PWM...
Heb ik de register niet goed ingestelt?
Dat (raar) stukje komt uit de samples voor HPWM
Dit ik de stuk code daarvan.
' Demonstrate Hardware PWM
' Output a 1KHz signal with duty cycle sweeping from 20% to 80% once per second
Device 16F877
Declare XTAL 4
Dim Duty As Word ' Duty cycle value (CCPR1L:CCP1CON<5:4>)
TRISC.2 = 0 ' Set PORTC.2 (CCP1) to output
CCP1CON = %00001100 ' Set CCP1 to PWM
T2CON = %00000101 ' Turn on Timer2, Prescale=4
PR2 = 249 ' Set PR2 to get 1KHz out
Duty = 200 ' Set duty cycle to 20%
Loop: CCP1CON.4 = Duty.0 ' Store duty to registers as
CCP1CON.5 = Duty.1 ' a 10-bit word
CCPR1L = Duty >> 2
Duty = Duty + 10 ' Increase duty cycle
DelayMS 17 ' Delayms 1/60 of second
If Duty < 800 Then Loop ' Do it again unless 80% duty cycle
Duty = 200 ' Reset to 20% duty cycle
GoTo Loop ' Do it foreverloopycoaster
Mijn youtube profiel: http://www.youtube.com/user/PicBasicMaster
en het commando HPWM*? Daar hoef je alleen het HPWM-kanaal (1 in dit geval, er is maar 1 HPWM kanaal), duty-cycle, en frequentie in te voeren en de rest gaat vanzelf. Of wil je dat om bepaalde redenen niet gebruiken?
*Daar staat ook een truukje waarmee je met 1 CCP-kanaal een motor 2 kanten op kan laten gaan met HPWM-mogelijkheid.
En als je H-brug een enable heeft kan je de CCP-pin gewoon aan de enable knopen, en met de 2 inputs de richting selecteren
[Bericht gewijzigd door loopycoaster op (14%)]
Dit is mijn schema, zoals u kunt zien heeft mijn schema geen enable.
Wil bij mij ook dat ik maar 1 HPWM kanaal kan bebruiken? Moet ik dan de schema van Beginners(7f) toepassen
Ik wou het zo doen omdat de 16F690 een Full-Bridge PWM mode heeft, en ik dacht dat dat wel makkelijk zou zijn met mijn schema.
loopycoaster
Mijn youtube profiel: http://www.youtube.com/user/PicBasicMaster
hmm...
Ik had de datasheet toen ik mijn vorige post had gestuurd nog niet doorgekeken. nu wel. Volgens mij kan het hardwarematig wel zoals jij zegt.. En als het lukt bespaart het 1 IO, 2 diodes en 2 weerstanden.
Als je dan de gewone CCP, met maar 1 pin, wilt gebruiken:
De CCP zit op PORTC.5, en dan inderdaad met schema 7f (dus een beetje aanpassen voor de 16F690).
Als het kan dan wil ik het hardwarematig doen. Maar heeft u mischien een idee waarom mijn programa het niet doet?
Op blz. 141 van de datasheet staat hoe ik de richting moet omdraaien. Alleen ik niet goed wat ze hier mee bedoelen.
- The modulated outputs (P1B and P1D) are placed
in their inactive state.
- The associated unmodulated outputs (P1A and
P1C) are switched to drive in the opposite
direction.
- PWM modulation resumes at the beginning of the
next period.edit
Ik heb tussen mijn code wat leds gezet:
Device 16F690 ;Gebruik een 16F690 type
Config HS_OSC, CP_OFF, PWRTE_ON, MCLRE_OFF
XTAL 20
ALL_DIGITAL = TRUE
Dim Duty As Word
Symbol Led1 = PORTB.7
Symbol Led2 = PORTC.7
Symbol Led3 = PORTB.6
; 76543210
TRISC = %00000000 ;(0=uitgang, 1=Ingang)
Duty = 100 ;Duty van 10%
High Led1 ;zet alle leds aan
High Led2
High Led3
DelayMS 1000 ;wacht 1 seconden
Low Led1 ;zet led1 uit
GoSub Links ;laat de motor linksom draaien
DelayMS 3000 ;Doe dat voor 3 seconden
Low Led2 ;zet led2 uit
GoSub Rechts ;Laat de motor rechtsom draaien
DelayMS 3000 ;Doe dat voor 3 seconden
Low Led3 ;zet led3 uit
Stop
Links:
CCP1CON = %11001100 ;links instelling
T2CON = %00000110 ;Zet Timer2 aan, Prescale=16
PR2 = 249 ;Zet PR2 om 1.22 kHz er uit te krijgen.
CCP1CON.4 = Duty.0 ;Zet duty naar de register
CCP1CON.5 = Duty.1 ;als een 10-bit word
CCPR1L = Duty >> 2
Return
Rechts:
CCP1CON = %01001100 ;rechts instelling
T2CON = %00000110 ;Zet Timer2 aan, Prescale=16
PR2 = 249 ;Zet PR2 om 1.22 kHz er uit te krijgen.
CCP1CON.4 = Duty.0 ;Zet Duty naar de register
CCP1CON.5 = Duty.1 ;als een 10-Bit Word
CCPR1L = Duty >> 2
Return Ik heb als h-brug eerst even 4 leds gebruikt om te kijken wat hij doet.
Wat er gebeurt:
- Licht alle leds op.
- Led1 gaat uit en laat de leds die voor zorgen dat de motor linksom gaat branden.
- Laat alle leds weer branden.
Wat ik hier uit kan concluderen is dat hij niet eens naar de gosub Rechts gaat. Maar hoe kan dit.
[Bericht gewijzigd door Brandon op (67%)]
Als ik in de laaste programa de delayms 3000 weg haal onder GoSub links dan behandelt hij dat niet en gaat direct naar GoSub rechts. Led1 en Led2 gaan dan ook uit.
Van te voren gaan alle leds aan behalve die op poort C4, daarna doe hij dat stukje van GoSub rechts en dan gaan weer alle leds aan behalve poort C4.
Roches
Domoticz en ESP8266, goede combo!!!
Probeer eens:
In je code na DUTY = 100....
WHILE 1=1
en dan in plaats van STOP
WEND
neer te zetten, en geen STOP of END meer gebruiken!!!
Groetjes
Roche
AC/DrieC
Den Dries www.hulens.be
Je weet ook dat je in je code geen rekening houd met de overgangsfase tussen geleiden en niet geleiden van je mosfets (veronderstel ik) in je H-brug?, die er uiteindelijk aan komt te hangen ? Je switched tussen links en rechts zonder een kleine pauze ertussen. Beter dat je je CCP1CON veranderd nadat je 1 ms je uitgangen laag gemaakt hebt.
Dit is wel niet de oplossing voor je probleem, maar je moet er wel op letten.
@Nonkel DW: Het dutycycle register is 10 bit, waarvan de 2 LSB in CCP1CON staan en de 8MSB in CCPR1L. Dus eerst zet hij de 2 LSB in CCP1CON op plaats 5 en 4, daarna zet hij de rest in CCPR1L.
[Bericht gewijzigd door AC/DrieC op (19%)]
@Roches: Dat werkt helaas niet.
@AC/DrieC: Ik weet dat ik er geen rekening mee hou, ik wil eerst dat ding aan de praat krijgen.
Omdat ik 2 pic16f690 gebruik om de robot te besturen dacht ik: Deze 2 PIC laat ik besturen door een 16F877A. Mischien als ik de 16F877A de 16F690 laat aansturen dat het dan wel wil.
Ik wil ze met SPI elkaar laten comisiren. Ik heb er al een keer eerder mee gewerkt, namelijk met een 74hc595. Alleen nog niet met 2 PICtjes.
Ik heb nu 2 code's, 1 voor de 16F877A en 1 voor de 16F690.
Alleen het werkt niet, ik denk dat ik de verkeerde pinnen er voor gebruik maar ik weet het niet zeker. Of licht het aan de code?
16F877A
Device 16F877A ;We gebruiken een 16F877A type
Config HS_OSC, WDT_OFF, PWRTE_ON, LVP_OFF
ALL_DIGITAL TRUE ;Alle ingangen digitaal
XTAL 20
PORTB_PULLUPS On ;On-chip pull-up weerstanden actief
Symbol DTA = PORTC.5
Symbol CLK = PORTC.3
Symbol Toets1 = PORTB.3
Symbol Toets2 = PORTB.4
Symbol Led1 = PORTB.0
Symbol Led2 = PORTB.1
Symbol Led3 = PORTB.2
; 76543210
PORTC = %00000000 ;Alle niveaus van PORTA eerst laag maken
TRISC = %00000000 ;Alle poorten uitgang
Clear ;Wis alle RAM geheugen
DelayMS 100
High Led1
High Led2
High Led3
While 1 = 1
If Toets1 = 0 Then
Low Led1
SHOut DTA , CLK , msbfirst , [ 10 ]
Else
High Led1
EndIf
If Toets2 = 0 Then
Low Led2
SHOut DTA , CLK , msbfirst , [ 20 ]
PulsOut latch, 1
Else High Led2
EndIf
Wend
End16F690
Device 16F690 ;Gebruik een 16F690 type
Config HS_OSC, CP_OFF, PWRTE_ON, MCLRE_OFF
XTAL 20
ALL_DIGITAL = TRUE ;Alle ingangen digitaal
Symbol Led1 = PORTC.1
Symbol Led2 = PORTB.7
Symbol Led3 = PORTC.7
Symbol CLK = PORTB.6
Symbol DTA = PORTB.4
; 76543210
PORTC = %00000000 ;Alle niveaus van PORTA eerst laag maken
PORTB = %00000000 ;Alle niveaus van PORTB laag.
TRISC = %00000000 ;Alle poorten uitgang
TRISB = %01010000 ;Poort B6 en B4 als ingang SPI
Dim Getal As Byte
High Led1
High Led2
High Led3
While 1 = 1
SHIn DTA , CLK , msbpre , [Getal] ' Shiftin msb-first, pre-clock
If Getal = 10 Then
Low Led1
Else
High Led1
EndIf
If Getal = 20 Then
Low Led2
Else
High Led2
EndIf
Wendloopycoaster
Mijn youtube profiel: http://www.youtube.com/user/PicBasicMaster
je kan niet zomaar shout en shin bij elkaar gebruiken.
Shout en shin zijn beiden master-functies, en bij SPI heb je altijd maar 1 master (en een x aantal slaves).
De master produceert als enige de clockpulsen, wat shout en shin dus beiden doen.In jouw vorige ervaring met een PIC en de 74HC595 was de PIC de master en de 74HC595 de slave.
Je zult dus zelf een subroutinetje moeten schrijven waar je de data ontvangt als shin, maar dan zonder clockpulsen te produceren. Ik kan je wel een beetje op weg helpen als je er niet uitkomt..
Oke, ik heb wat gevonden op het internet.
Read_Data:
Low CS
Low CLK
High DTA ' start bit is high
High CS
PulsOut CLK,1
High SDO ' for clarity only- read if bit is high
PulsOut CLK,1 '
Low SDO ' if low then read data register
PulsOut CLK,1
data_in = SHIn DTA , CLK , 0 , 8 ' get data byte ' MSB first
Low CS
PulsOut CLK,1
ReturnWat niet ingesprongen is, die poorten gebruik ik niet in mijn programa of is dat wel nodig?
Zit ik trouwens wel in de goede richting of zit ik hellemaal verkeert?
P.S. gebruik ik de goede poorten van de 2 pic, denk het haast wel.
Zou iemand me mischien op weg helpen? Ik kom er niet echt uit.
Is I2C ook hiervoor geschikt of is dat moeilijker / onhandig.
' Receive a byte from the I2C bus and place it into variable VAR1.
DIM VAR1 as BYTE ' We'll only read 8-bits
DIM Address as WORD ' 16-bit address required
SYMBOL Control %10100001 ' Target an eeprom
SYMBOL SDA = PORTC.3 ' Alias the SDA (Data) line
SYMBOL SCL = PORTC.4 ' Alias the SSL (Clock) line
Address = 20 ' Read the value at address 20
I2Cin SDA, SCL, Control , Address, [ VAR1 ] ' Read the byte from the eeprom
Dit is een stukje code van help voor I2C en over SDA en SCL moet een pull-up weerstand.
loopycoaster
Mijn youtube profiel: http://www.youtube.com/user/PicBasicMaster
Over de zelfgemaakte Shin:
Volgens mij gaat het inderdaad.... de foute kant op. 
SPI heeft normaalgesproken geen start/stopbits.
Ook is dit stukje programma iets waarmee je iets verzendt (SHOUT dus) en de Clocksignalen worden nog steeds gestuurd.
I²C is net zoals SPI een synchrone communicatiemanier (er zijn clocklijnen die aangeven hoe snel je wilt verzenden), en is dus ongeveer hetzelfde als SPI, maar dan met start/stop/acknowledge-bits.
I²C is dus juist moeilijker.
Kijk eens naar SEROUT/SERIN: http://www.picbasic.nl/huis-automatisering.htm (naar beneden scrollen)
Je vraag ging over HPWM, die stel je zo in. Dit is alleen voor een 16F877, maar je kan zien hoe het moet. Er staat niet veel verklarende text bij, dus ik hoop dat het duidelijk is zo.
Device 16F877 ; processor type
XTAL 10 ; crystal 10 Mhz
Config HS_OSC,_ ; cristal groter dan 4MHz
WDT_OFF,_ ; Watchdog Timer Enable uit
PWRTE_ON,_ ; Power-up Timer Enable aan
BODEN_OFF,_ ; Brown-out Reset Enable uit
LVP_OFF,_ ; Low Voltage Programming uit
CPD_OFF,_ ; Memory Code Protection uit
WRTE_ON,_ ; Program Memory Write Enable aan
DEBUG_ON,_ ; In-Circuit Debugger Mode aan
CP_OFF ; Code Protection uit
ALL_DIGITAL true ; alle poorten digitaal
Symbol On = 1 ; 1 is hoog
Symbol off = 0 ; 0 is laag
Symbol vrijgave = PORTC.0
Symbol frequentie = 15000
Symbol S_1 = PORTA.0
Symbol S_2 = PORTA.1
Declare CCP2_PIN PORTC.1 ; pwm 2 op poort C.1
Declare CCP1_PIN PORTC.2
Declare ADIN_RES = 8 ; resolutie 8 bits
Declare ADIN_TAD = frc ; Set rc osc
Declare ADIN_STIME = 50 ; sample tijd 5
Dim potmeter As Byte
Dim waarde As Byte
Clear ; wis geheugen
DelayMS 2000 ; wacht 2 seconden
;76543210
TRISA = %11111111
;76543210 ; hulp regel poort C
TRISC = %00000000 ; poort C als uitgang
;210 ; hulp regel poort E
TRISE = %111 ; poort E als ingang
ADCON0 = %100 ; analooge ingang 7
start:
If S_1 = On Then GoTo run
vrijgave = off
HPWM 2,0,0
HPWM 1,0,0
GoTo start
run:
potmeter = ADIn 7
waarde = potmeter
vrijgave = On
HPWM 2,waarde,frequentie
HPWM 1,~waarde,frequentie
If S_2 = On Then GoTo start
GoTo run
End
@loopycoaster: Oke, ik zal me daar even over buigen.
@Lambiek: Mijn idee was om met een 16F877A de twee 16F690 aan te sturen, en die stuurt op zijn beurt de h-brug aan. De probleem die ik daar bij had dat de 16f690 zijn programa niet afliep.
@Moderator: Wilt U mischien mijn titel veranderen in:
16F877A -> 16F690 -> H-Brug
Edit
Ik heb het even geprobeert maar het lukt niet 
Dit zijn de codes die ik probeer, zit hier een fout in?
16F690
16F877A
[Bericht gewijzigd door Brandon op (32%)]
Ik heb in dit topic even bekeken. En heb het ook uitgeprobeert. Met 2 16f648A werkt het prefect 
Maar als ik 1 16F648A verandert in een 16F690 dan werkt het weer niet 
Ik gebruik de 16F648A als zender en de 16F690 als ontvanger.
Deze code gebruik ik als zender
Device 16F648A
Config WDT_OFF, PWRTE_ON, LVP_OFF, MCLRE_OFF, HS_OSC ;INTRC_OSC_NOCLKOUT verwijderd
XTAL = 20
HSERIAL_BAUD = 9600
HSERIAL_RCSTA = %10010000
HSERIAL_TXSTA = %00100000
HSERIAL_CLEAR = On
Symbol Led1 = PORTB.4
Symbol Led2 = PORTB.5
High Led1
High Led2
opnieuw:
DelayMS 2000
HRSOut "1"
Low Led1
DelayMS 500
HRSOut "2"
Low Led2
DelayMS 500
High Led1
High Led2
GoTo opnieuwEn deze code gebruik ik als ontvanger
Device 16F690 ;Gebruik een 16F690 type
Config HS_OSC, CP_OFF, PWRTE_ON, MCLRE_OFF, WDT_OFF
ALL_DIGITAL = TRUE ;Alle ingangen digitaal
XTAL = 20 ;Gebruik een kristal van 20MHz
HSERIAL_BAUD = 9600
HSERIAL_RCSTA = %10010000
HSERIAL_TXSTA = %00100000
HSERIAL_CLEAR = On
Dim VAR1 As Byte
Symbol Led1 = PORTC.1
Symbol Led2 = PORTC.2
DelayMS 500
High Led1
High Led2
DelayMS 1000
Low Led1
Low Led2
DelayMS 1000
loop:
VAR1 = HRSin ,{1000, timeout}
Select VAR1 ;Deze SELECT lijst bepaalt wat een ontvangen opdracht gaat doen
Case "1" ;Als de waarde '26' is ontvangen van de bus, dan...
Led1 = ~Led1 ;... de LED aan of uitzetten (togglen)
Clear VAR1
Case "2" ;Als waarde '120' is ontvangen, dan...
Led2 = ~Led2 ;... de LED aanzetten (poort een HOOG niveau geven)
Clear VAR1
End Select
timeout:
Clear VAR1
GoTo loopIk gebruik poort B2 van de 16F648A als TX en poort B5 van de 16F690 als RX, lijkt me goed toch?
Mag ik dit wel gebruiken bij een 16F690:
HRSinAlvast bedankt.
Brandon
Ja poort B5 is goed, wat heb je met poort A3 gedaan pin_4, staan alle configs goed, de zelfde XTALLEN en condensators gebruikt.
Kan je controleren of 16F628 wel zend.
De 16f648a die zend wel, als ik er een led op dan knipert de led even als hij zend.
Ik heb met pin A3 niks gedaan, moet daar een weerstand over.
De xtallen en condensators zijn gelijk.
Ik heb een 10K naar de plus gedaan en dit stukje bij de 16f690 geplakt:
; 76543210
TRISB = %00100000
TRISC = %00000000En dit voor de 16F648A
; 76543210
TRISB = %00000000Maar dit maakt ook niet uit, werkt nog steets niet.
Ik heb de configs toch goed?
Ik heb dat uit de help bestand, dit stukje.
Dus dat lijkt me goed, klopt dit?
Ik weet trouwens zeker dat het niet licht aan de 16f648a omdat ik dat gecontroleert heb met UART tool en Logic tool van PICkit2
XTAL = 4
HSERIAL_BAUD = 9600 ' Set baud rate to 9600
HSERIAL_RCSTA = %10010000 ' Enable serial port and continuous receive
HSERIAL_TXSTA = %00100000 ' Enable transmit and asynchronous mode
HSERIAL_CLEAR = ON ' Optionally clear the buffer before receiving
DIM VAR1 AS BYTE
Loop:
VAR1 = HRSIn , {1000 , Timeout} ' Receive a byte serially into VAR1
PRINT DEC VAR1 , " " ' Display the byte received
GOTO Loop ' Loop forever
Timeout:
CLS
PRINT "TIMED OUT" ' Display an error if HRSIn timed out
STOP