hallo allemaal

ikzelf ben al een tijdje aan het klooien waarom rs232 op een pic en interrupts niet samen willen. ik hoop dat jullie me kunnen helpen.

eerst even wat wel werkt:

alleen rs232 gebruiken:

zenden


DEVICE 16F628A                ;Gebruik een 16F628A type
CONFIG INTRC_OSC_NOCLKOUT, WDT_off, PWRTE_ON, LVP_OFF, MCLRE_OFF
DECLARE XTAL 4

HSERIAL_BAUD = 9600
HSERIAL_RCSTA = %10010000
HSERIAL_TXSTA = %00100000
HSERIAL_CLEAR = On


opnieuw:
DelayMS 2000
HRSOut "0"
DelayMS 500
HRSOut "1"
DelayMS 500
GoTo opnieuw

ontvangen


DEVICE 16F628A                ;Gebruik een 16F628A type
CONFIG INTRC_OSC_NOCLKOUT, WDT_off, PWRTE_ON, LVP_OFF, MCLRE_OFF
DECLARE XTAL 4

HSERIAL_BAUD = 9600
HSERIAL_RCSTA = %10010000
HSERIAL_TXSTA = %00100000
HSERIAL_CLEAR = On


Dim VAR1 As Byte
Dim var2 As Byte

DelayMS 500

Cls 
var2 = 65
loop:




VAR1 = HRSin ,{1000,timeout}


If VAR1 = "1" Then 
High PORTA.1
Clear VAR1
GoTo loop
EndIf


If VAR1 = "0" Then
Low PORTA.1
Clear VAR1
GoTo loop
EndIf



Clear VAR1
GoTo loop
timeout:

GoTo loop

dit werkt. ook heb ik een programma van m'n robot, dat met softwarepwm en een zaagtand met de ne555 de motors regelt:


DEVICE 16F628A                ;Gebruik een 16F628A type
CONFIG INTRC_OSC_NOCLKOUT, WDT_off, PWRTE_ON, LVP_OFF, MCLRE_OFF
DECLARE XTAL 4

	ON_INTERRUPT 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) 



'variables:
dim teller as byte
dim dimwaardelinks as byte
dim dimwaarderechts as byte
; switches:
SYMBOL sl   = PORTb.0         ;Poort a.0 heeft nu de naam Sl
SYMBOL sr   = PORTb.1         ;Poort a.1 heeft nu de naam Sr

   ; h-bruggen:
SYMBOL linksvoor   = PORTb.4         
SYMBOL linksachter = PORTb.5

SYMBOL rechtsvoor   = PORTb.6        
SYMBOL rechtsachter = PORTb.7

symbol uitganglinks  = porta.6 (pin15)
symbol uitgangrechts = porta.7 (pin16)
	
	
	
	
;----------------------------------------------------------------------------------------------------
	
 
	GOTO Over_interrupt			' Jump over the interrupt subroutine 


;---------------------------------------INTERRUPT--------------------------------------------------
Flash: 


;teller voor PWM.. 16hz 100 stappen
 if teller > 100 then 
  teller = 0
 else
  teller = teller + 1
  end if


;vergelijk dimwaarde met teller:

;linker motor:
  If dimwaardelinks <= teller then
	high uitganglinks 
   else 
  	low uitganglinks 
   end if
   
  

;rechter motor:
  If dimwaarderechts <= teller then
	high uitgangrechts 
   else 
	low uitgangrechts 
   end if

	T0IF = 0 			' Clear the TMR0 overflow flag 
	;TMR0 = %00010110
	TMR0 = 0

	
	CONTEXT RESTORE	' Restore the registers and exit the interrupt 

	
;------------------------------------voor interrupt----------------------------------------------------


Over_interrupt: 
;            76543210
	TRISB = %00000000
	TRISA = %00000111
	PORTA = 0	
	PORTB = 0		' Clear PORTB 
	' Initiate the interrupt 
	GIE = 0 			' Turn on global interrupts 
	PSA = 0 			' Koppel prescaler aan TMR0   
	PS0 = 1 			' Set the prescaler 
	PS1 = 0 			' to increment TMR0 
	PS2 = 0 			' every 4th instruction cycle

T0CS = 0 			' Assign TMR0 clock to internal source 
	TMR0 = 256-150  '(= 106) 
	T0IE = 1 			' Enable TMR0 overflow interrupt 
	GIE = 1 			' Enable global interrupts 


;---------------------------------------MAIN PROG----------------------------------------------------
  
Main:


if sl = 1 then
dimwaardelinks = dimwaardelinks + 5
delayms 25
endif

if sr = 1 then
dimwaardelinks = dimwaardelinks - 5
delayms 25 
endif


   if dimwaarderechts > 100 then
     dimwaarderechts = 0
   end if
   
   if dimwaardelinks > 100 then
     dimwaardelinks = 0
    end if


GOTO Main

deze code werkt ook perfect. echter lukt het mij niet om de 2 laatste codes samen in 1 pic te krijgen.

wat ik al heb geprobeerd, maar NIET werkt:


DEVICE 16F628A                ;Gebruik een 16F628A type
CONFIG INTRC_OSC_NOCLKOUT, WDT_off, PWRTE_ON, LVP_OFF, MCLRE_OFF
DECLARE XTAL 4

HSERIAL_BAUD = 9600
HSERIAL_RCSTA = %10010000
HSERIAL_TXSTA = %00100000
HSERIAL_CLEAR = On


	ON_INTERRUPT 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) 





'variables:
dim teller as byte
dim dimwaardelinks as byte
dim dimwaarderechts as byte
; switches:
SYMBOL sl   = PORTb.0         ;Poort a.0 heeft nu de naam Sl
SYMBOL sr   = PORTb.1         ;Poort a.1 heeft nu de naam Sr

   ; h-bruggen:
SYMBOL linksvoor   = PORTb.4         
SYMBOL linksachter = PORTb.5

SYMBOL rechtsvoor   = PORTb.6        
SYMBOL rechtsachter = PORTb.7

symbol uitganglinks  = porta.6 (pin15)
symbol uitgangrechts = porta.7 (pin16)
	
	
	
	
;----------------------------------------------------------------------------------------------------
	
 
	GOTO Over_interrupt			' Jump over the interrupt subroutine 


;---------------------------------------INTERRUPT--------------------------------------------------
Flash: 


;teller voor PWM.. 16hz 100 stappen
 if teller > 100 then 
  teller = 0
 else
  teller = teller + 1
  end if


;vergelijk dimwaarde met teller:

;linker motor:
  If dimwaardelinks <= teller then
	high uitganglinks 
   else 
  	low uitganglinks 
   end if
   
  


;rechter motor:
  If dimwaarderechts <= teller then
	high uitgangrechts 
   else 
	low uitgangrechts 
   end if

	T0IF = 0 			' Clear the TMR0 overflow flag 
	;TMR0 = %00010110
	TMR0 = 0

	
	CONTEXT RESTORE	' Restore the registers and exit the interrupt 

	
;------------------------------------voor interrupt----------------------------------------------------


Over_interrupt: 
;            76543210
	TRISB = %00000000
	TRISA = %00000111
	PORTA = 0	
	PORTB = 0		' Clear PORTB 
	' Initiate the interrupt 
	GIE = 0 			' Turn on global interrupts 
	PSA = 0 			' Koppel prescaler aan TMR0   
	PS0 = 1 			' Set the prescaler 
	PS1 = 0 			' to increment TMR0 
	PS2 = 0 			' every 4th instruction cycle

T0CS = 0 			' Assign TMR0 clock to internal source 
	TMR0 = 256-150  '(= 106) 
	T0IE = 1 			' Enable TMR0 overflow interrupt 
	GIE = 1 			' Enable global interrupts 


;---------------------------------------MAIN PROG----------------------------------------------------
  
Main:
Dim VAR1 As Byte
Dim var2 As Byte

DelayMS 500


loop:




VAR1 = HRSin' ,{1000,timeout}


If VAR1 = "1" Then 
High PORTA.1
Clear VAR1
GoTo loop
EndIf


If VAR1 = "0" Then
Low PORTA.1
Clear VAR1
GoTo loop
EndIf



Clear VAR1
GoTo loop
timeout:

GoTo loop

ik kom er niet uit.. kunnen jullie me verder helpen?
alvast bedankt, Danny

en dan de vraag: wat doet-ie-niet >?

Ik wou het net vragen, maar Jeroen was me voor.

Wat moet het programma doen, en wat doet ie niet.

Verder nog wat slordigheidjes in je prog :

- Als je de interne oscillator gebruikt, hoef je geen xtal meer te declareren.

- Schakel je poorten naar All_digital = true, voorkomt nu en in de toekomst een hoop ellende.

- Er staat een aanhalingsteken na je Hrsin, de timeout zal dus nooit uitgevoerd worden.

- Als er na timeout geen extra commands meer volgen, kan je in je Hrsin net zo goed direct naar loop: jumpen

Theo

[Bericht gewijzigd door ~Galaxy op ]

Volgens mij probeert hij ons duidelijk te maken dat het (bij hem) niet lukt om rs232 en interupts samen te laten werken.

Nu is dat volgens mij goed te doen, zelfs de rs232 op interuptbasis is te doen.

Maar vertel eens, wat gaat je picje uitvoeren en waarvoor rs232 met het zenden van een 1 en weer een 0,... (HRSOut)

Op 13 mei 2007 22:15:21 schreef treinfreak:
Volgens mij probeert hij ons duidelijk te maken dat het (bij hem) niet lukt om rs232 en interupts samen te laten werken.

idd. ik heb op mijn robot nu 1 pic die nu de motors kan regelen. Dat werkt allemaal prima.

nu wil ik een 2e pic als master gebruiken waar de sensors op aangesloten worden en die het denkwerk gaat doen.

die master moet dan via rs232 de snelheid en richting per wiel doorgeven aan de slave pic.

wat hij doet kan ik heel kort over zijn: hij doet helemaal niks. dus geen rs232 en geen interrupt of wat dan ook. lijkt wel dood

Nu is dat volgens mij goed te doen, zelfs de rs232 op interuptbasis is te doen.

als dat kan zou dat super zijn!
alvast bedankt, Danny

Hardware?

Als je HRSin gebruikt, dan werken de signalen geinverteerd.
Een level converter hoeft voor pic2pic communicatie niet, maar wel een inverter.

Verder zou je met ledjes op vrije pins eens kunnen kijken WAAR het programma blijft hangen.

Dit kan in de main zijn, maar ook in de interrupt.

En ja, je kan ook een interrupt genereren op een binnengekomen byte in je USART. Zie datasheet.
Dan moet je wel in je ISR de flags checken WAT de interrupt heeft veroorzaakt. timer0 of USART.

Voorlopig hou ik het erop dat je prog hangt op je HRSin command.

Theo

kijk eens hier naar,
een ISR voor uart, welliswaar voor de PIC18F2550, maar dat is makkelijk om te bouwen naar een PIC16F628 bijvoorbeeld.

http://jeroen.boere-adviseur.nl/show.php?action=show&id=10

O ja, interupt basis.

Het lijkt er op dat je niet al te veel met controllers hebt gewerkt. Zet je de interuptflag wel weer laag :) anders gaat hij de volgende klokslag er gewoon weer in, das iets wat je niet wilt.

hallo, pic's zijn voor mij idd nog aardig nieuw.. maar zal m'n best doen om het te begrijpen.
ik heb wat geprobeert met de link van jeroen boere:


DEVICE 16F628A                ;Gebruik een 16F628A type
CONFIG INTRC_OSC_NOCLKOUT, WDT_off, PWRTE_ON, LVP_OFF, MCLRE_OFF
DECLARE XTAL 4


ALL_DIGITAL true


'76543210 ' bit wise output mask


HSERIAL_BAUD = 9600
HSERIAL_RCSTA = %10010000 ; Enable serial continuous receive
HSERIAL_TXSTA = %00100000 ; Enable transmit asynchronous mode
HSERIAL_CLEAR = On


SYMBOL int_LED = PORTb.4
SYMBOL flash_LED = PORTb.5
symbol ontvangen_led = portb.6
DIM var1 AS BYTE


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
VAR1 = HRSin
PIR1.5 = 0 ' Just to be sure: Clear the Interrupt flag

if var1 = "1" then 
high ontvangen_led
end if
if var1 = "0" then
low ontvangen_led
end if
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!

wat de leds nu doen:
int_led blijft uit
flash_led blijft continu branden

de laatste is wel interressant:
ontvangen_led brand continu, echter als ik het tx/rx draadje tussen beide pic's weghaal gaat deze led uit. plaats ik de draad terug brandt de led weer.
hij reageerd dus wel enigzins.

maar.. hij doet niet wat ie zou moeten doen: knipperen.
(de zender zendt nog steeds beurtelings een "1" of een "0")

en wat ik ook nog niet begrijp is hoe ik hier nu de interrupt zo instel dat ik er pwm mee kan opwekken

wat ik denk: hij loopt vast in de int. en doordat hij daar niet meer uitkomt, komt hij ook niet aan bij het hoofdprogramma dat de led laat knipperen.

Danny

oja @ ~galaxy: m'n eerste programma bovenaan dit topic werkt toch ook zonder inverter? lijkt mij dus niet het probleem

Ik mis de Context Restore in je ISR.
Daardoor vrees ik dat de stack het heel moeilijk gaat krijgen.

Daarnaast ben ik intussen al heel wat frommelprogramma's tegengekomen.

Ik denk dat je eerst eens goed op een rijtje moet zetten wat je nu precies wil, i.p.v. direct willen programmeren.

Wil je een interrupt op een timer, of op de USART ?
Ik zie dat er nu ook weer PWM bij komt kijken. Daar heb je geen interrupt voor nodig. Kwesie van een paar registertjes setten en het pwm-machientje loopt wel.

Theo

iik heb voor mezelf alles al op een rijtje hoe ik het wil hebben op m'n robot:

ik wil de 2 wielen van m'n robot onafhankelijk van elkaar kunnen laten draaien.

hiervoor heb ik 2x pwm nodig voor de motors maar een 16f628a heeft maar 1 hpwm pin.

daarvoor heb ik nu een oplossing:

ik wek met de interrupt een pwm op van 16 hz.
met een externe zaagtand (ne555 circuit) en de comparator van de pic zelf. verhoog ik die frequentoe naar zo'n 20 a 25 Khz

dit hele gebeuren zit al in elkaar en werkt nu perfect. alleen heb ik er niet goed bij nagedacht dat ik nu nog maar een paar pinnen op de pic over heb.

om dit uit te breiden wil ik dus een 2e pic ernaast zetten.
om dan hierop de ir sensors en lijn sensors enz. op aan te sluiten.

dit is wat ik dus wil

Je kunt ook overwegen om over te stappen naar een grotere pic zoals bijv. de 16F877A.
Deze heeft namelijk twee Hpwm kanalen op PortC.1 & 2

ik zit al een aantal avonden te zoeken, proberen en te doen maar kan ook niet 1 voorbeeld oid vinden op internet.

ook is het allemaal blijkbaar toch moeilijker dan ik dacht.
ik leg me er dan ook maar even bij neer en ga ik het anders proberen op te lossen.

ik heb er nog eens over nagedacht en heb nu wat anders uitgedacht: simpelweg tellen.

1 draad als klok en 1 draad voor de pulsjes

dan stuur ik:

1 puls, klok, 2 pulsjes, klok, 5 pulsjes, klok

in totaal krijgt de ontvangende pic dan: 125

wat dan betekend: motor 1, snelheid 25
ik ga dit gewoon eens proberen en zie wel wat het wordt.

groeten danny