hoi,
ik wil graag een byte serieel
versturen via pin_b3
(16f628)

ik zal het >> of << moeten gebruiken,
om te shiften, maar hoe selecteer ik nu de eerste bit
(of de laatste)
om die de deur uit te werken?

ik programeer in jal
wie helpt?

Als je shift komt de bit die weggeshift is in de carry bit terecht

Jal heb ik helaas niet zoveel verstand van

[Bericht gewijzigd door Zom-B op ]

de operatie die jij nnoemt is volgens mij bit shifting in het programma. Dus zo schuif je niet uit de pport

dus als ik even bot zou doen wordt het zoiets in C dan even, want JAL heb ik ook verdrongen als zijnde hobby taal



byte x;
byte y;
int i;

for (i = 0, i < 8, i++)  // doorloop deze lus 8x om elk bit te senden
{
  y = x & 1;             // logische AND operatie, je pakt nu dus alleen het 
                         laatste bit en maakt dat dus y 1 of 0
  PORTB = PORTB & (y * 8); // Je vermigvuldigd y met 8 om het op plaats 3 
                          in port B te zetten 
                          in JAL kan je dacht ik op 1 of andere manier 
                          zo pin b3 aanspreken in de AVR doe  ik het zo
  x = x >> 1;              //schuif X even door dat het voglende
                          bit achteraan komt
{

nu zend je het laatste bit (least significatn bit) het eerste door

wil je het omgekeerd?



byte x;
byte y;
int i;

for (i = 0, i < 8, i++)  // doorloop deze lus 8x om elk bit te senden
{
  y = x & 128;             // logische AND operatie, je pakt nu dus alleen het 
                         eerste bit en maakt dat dus y 1 of 0
  PORTB = PORTB & (y * 8);
  x = x << 1; // en je schuift de andere kant op
{

LET OP, HET VERZONDEN BYTE IS NU VERLOREN GEGAAN!!!!

[Bericht gewijzigd door High met Henk op ]

Vergeet niet een start- en een stopbit te versturen! Anders weet de ontvanger niet waar de byte begint! Startbit is meestal 0 en stopbit meestal 1.

Maar waarom maak je geen gebruik van de UART in de 628? Die doet dat allemaal voor je. Je kiest een baudrate en stelt de UART verder in, en dan hoef je alleen nog maar naar het TX-register te schrijven en een bitje te checken of-ie klaar is!

fuzzbass, hij wilde het zo, dus ik heb het zo gedaan, ik weet niet welk protocol hij gebruikt!

ik had iig ook ergens een kloksignaal opgewekt :) Dat zit er bij mij nog niet in :)

maar ik had idd ook een interface gekozen die al in de uC zit hoor, waarschijnlijk bij dit geval de I2C

Heeft er eigenlijk iemand een stuk werkende code in jal (of assembly als het niet anders kan) voor de pic 16f628(A) om seriele data door te sturen (gebruik makend van de UART). Anders mag hij het mij eens opsturen, dank bij voorbaat. :)


;------------------------------------------------------------------
; initialization
;------------------------------------------------------------------
xtal	equ	3686400		;Fxt=3,686400 MHz
BRGHbit	equ	0		;BRGH=0
t4800	equ	(((10*xtal/(64-48*BRGHbit)/4800)+5)/10)-1
t9600	equ	(((10*xtal/(64-48*BRGHbit)/9600)+5)/10)-1

init	bsf	RP0			;bank 1
	movlw	t4800
	movwf	SPBRG
	movlw	B'00100000'+4*BRGHbit
	movwf	TXSTA
	bcf	RP0			;bank 0
	movlf	B'10010000',RCSTA
	movff	RCREG,TXREG             ;kick UART, just in case
	return
;------------------------------------------------------------------
; get character from UART in W
;------------------------------------------------------------------
receive	btfsc	RCSTA,OERR	;overflow error?
	call	overerr		;clear overflow error
	btfsc	RCSTA,FERR	;framing error?
	movf	RCREG,W		;reading rcreg clears FERR flag
	btfss	PIR1,RCIF	;check receive flag
	goto	receive		;if not ready, wait...
	movf	RCREG,W		;get uart data
	return
overerr	bcf	RCSTA,CREN	;pulse CREN off...
	movf	RCREG,W		;flush fifo
	movf	RCREG,W
	movf	RCREG,W
	bsf	RCSTA,CREN	;turn CREN back on.
	return			;then try again...
;------------------------------------------------------------------
; send byte in W
;------------------------------------------------------------------
transmt	btfss	TXSTA,TXIF	;wait for previous TX to clear
	goto	transmt
	movwf	TXREG		;put new byte in TSR
	return
;------------------------------------------------------------------

Een flard uit een programma van mij. Ik heb niet gecheckt of het misschien te specifiek voor mijn applicatie is en het misschien nog aangepast moet worden, maar dit is wel iets dat echt werkt.

ik heb het progje van "henk" omgezet in jal..
werkt uitstekend, afgezien van het feit dat ik "and"
nog niet helemaal snap, maar d aar kom ik wel achter.
het werkt in iedergeval,
ik moet zeggen dat gebruik van een scoop wel aan te raden is
om de (korte) signalen te bekijken.
hartelijk dank hiervoor.
sietse

Een logische (bitwise) AND geeft alleen een 1 als bijde getallen die je AND 1 zijn. dus in een tabel

x y | z
-------
0 0 | 0
1 0 | 0
0 1 | 0
1 1 | 1

x en y worden dus zo ingevult in die forumule
z = x & y;
Ik hoop dat je dit snapt!

Ik snap niet wat henk doet! Henk ff een vraagje:

y = x & 1;
PORTB = PORTB & (y * 8);
x = x >> 1;

Wat doe je in godsnaam met
PORTB = PORTB & (y * 8);
Ik zie de logica niet hoor... moet die AND niet een OR zijn? Nu wordt RB3 alleen hoog als hij al hoog was!

ja, verhelderend..

dank hiervoor,

Ik zal proberen deze code uit te leggen:

y = x & 1;
PORTB = PORTB & (y * 8);
x = x >> 1;

y = x & 1; 

Je pakt alleen het laagst waardige bit:
stel X ziet er in bits zo uit:
10111011 die AND je met 00000001 ( =1 )

76543210 (bit nummer)

10111011 | X
00000001 | 1 ( & )
00000001 | Y

Y heeft dus altijd 7 nullen en bit0 heeft de waarde van bit0 uit X.


PORTB = PORTB & (y * 8);

Dit is een moeilijk stukje:
Y wordt vermenigvuldigt met 8. Maar Y was allemaal nullen behalve de laatste. Dus het is of 0 * 8 of 1 * 8 => 0 of 8. En in bits is dat dus:
00000000 of 00001000 => bit3 is dus een 1 of een 0 afhankelijk van x. (je begint met tellen bij bit0).
Persoonlijk had ik hier (y <<PIN3) neer gezet.
(uC zijn niet zo goed in vermendigvuldigen :D )

Vervolgens wordt idd alle info van portb weggepleurd (en alle andere pinnen worden 0). En overschreven met de uitkomst van y*8

11000111 | PORTB (invoer)
00001000 | (y <<pin3)
00001000 | PORTB (uitkomst

Vervolgens wordt met x = x>>1 de te serializen byte een 1 bit opgeschoven.

In pseudo code:
doe 8x
{
pak laagste bit van je te versturen byte (x & 1)
verplaats deze naar de juist pin (y << PIN3)
zet deze op de uitgang PORTB= PORTb ^ (y <<PIN3)
schuif je originele bit eentje door naar links (x = x>>1)
(zodat je de volgende keer de volgende bit pakt)
}

Ik had persoonlijk dit geschreven:


PORTB = (PORTB & (~(1<<PIN3)) ) | (y <<PIN3)))

Nu blijven de overige bits van PORTB intact.
Je schrijft eerst een 0 op pin3 en vervolgens OR je die 0 met Y.

Ik hoop dat dit helpt (ik weet het, misschien is het een beetje wazig... maar het is ook best lastig)

Dankje voor je uitleg, ik snap wel wat die code doet opzich, maar wat ik niet snap waarom is het een AND (&) het moet toch een OR zijn (|)? Stel je hebt dit op PORTB staan:

0b10110101
en y = 1. Ok je doet dat maar 8 (of bitshiften zou ik ook doen hoor ;)) dan krijg je dit binair
0b00001000
en dan word dit in die code gedaan

0b10110101
0b00001000 (&)
----------
0b00000000

Dus pinB3 blijft 0 terwijl ie volgens y 1 moest worden (dat ik toch de bedoeling?)

uik was ff weg, maar ik begrijp de moeilijkheidsgraad ff niet

uitleg:



bit nr.          7  6  5  4  3  2  1  0
decimale waarde 128 64 32 16 8  4  2  1

De output is 1 of 0 door deze te vermenigvuldigen met 8 beinvloed je dus bit 3

Op 23 oktober 2004 19:34:17 schreef Berry:
Stel je hebt dit op PORTB staan:

0b10110101
en y = 1. Ok je doet dat maar 8 (of bitshiften zou ik ook doen hoor ;)) dan krijg je dit binair
0b00001000
en dan word dit in die code gedaan

0b10110101
0b00001000 (&)
----------
0b00000000

Dus pinB3 blijft 0 terwijl ie volgens y 1 moest worden (dat ik toch de bedoeling?)

Jups, die hele code van Henk werkt idd niet!

Maar..... het moet ook geen OR zijn ;).
Want als er dan een 1 staat blijft er een 1 staan :D

0b10111101
0b00000000 ( | )
----------
0b10111101

Dus eerst dat bitje naar een bekend stadium brengen (0 of 1) en vervolgens wijzigen met respectievelijk een OR of een AND.

Op 22 oktober 2004 16:42:46 schreef Rip7:
Heeft er eigenlijk iemand een stuk werkende code in jal (of assembly als het niet anders kan) voor de pic 16f628(A) om seriele data door te sturen (gebruik makend van de UART).

Zie de Wisp628 firmware op mijn site.

Voor bit-banged asynch in Jal: zie de asynch library.

Voor bit-banged asych in assembler: zie bv de WISP firmware.

Op 25 oktober 2004 11:31:56 schreef Wutje:
[...]

Jups, die hele code van Henk werkt idd niet!

Maar..... het moet ook geen OR zijn ;).
Want als er dan een 1 staat blijft er een 1 staan :D

0b10111101
0b00000000 ( | )
----------
0b10111101

Dus eerst dat bitje naar een bekend stadium brengen (0 of 1) en vervolgens wijzigen met respectievelijk een OR of een AND.

sorry, je hebt gelijk, vergis me daar wel vaker in. Kom je met het debuggen snel genoeg achter :)
Maar idd eerst naar 0 schrijven is niet echt een oplossing daar hij aan de andere kant uitgelezen wordt. je moet dus testen of hij op 1 staat en dan kijken of je hem erin moet schrijven. Komt dus stukkie code bij :)

Op 25 oktober 2004 15:02:12 schreef High met henk:
[...]

Maar idd eerst naar 0 schrijven is niet echt een oplossing daar hij aan de andere kant uitgelezen wordt. je moet dus testen of hij op 1 staat en dan kijken of je hem erin moet schrijven. Komt dus stukkie code bij :)

Ehmm... volgens mijn is er nog een klein denk foutje:
Ergens in het geheugen maak je een 0... je schrijft dus niet meteen aan de poort een nul, maar in het geheugen.
De uC doet eerst PORTB & 11110111 dat pleurt hij ergens in een register of geheugen.
En vervolgens doet hij die uitkomst | 0000X000.
En die stored hij vervolgens in PORTB.
Dus aan de uitgang merk je er helemaal niks van.

zoals je ziet doe ik een echo op portb. dus ik gebruik portB als een variabele, als ik op de plek van bit3 in portb een 0 schrijf, is pinb3 echt laag hoor!!!

tenminste bij een AVR / ATmega wel!!

Op 27 oktober 2004 00:29:35 schreef High met henk:
zoals je ziet doe ik een echo op portb. dus ik gebruik portB als een variabele, als ik op de plek van bit3 in portb een 0 schrijf, is pinb3 echt laag hoor!!!

Het is wel te hopen ja! ;)

Maar volgens mij heb je mijn punt (alweer) gemist. Ik schrijf geen nul naar de poort maar ergens in het geheugen:


PORTB = (PORTB & (~(1<<PIN3)) ) | (y <<PIN3) 

Je compiler vertaalt dit naar:


temp1 = y<<PIN3 
temp2 = 11110111b & PORTB
PORTB = temp1 & temp2 

Waar "schrijf" ik dus een nul?
In temp2! En komt temp2 aan de uitgang? Nee!
Dus aan de uitgang komt er niet eerst een nul, maar de waarde die jij daar graag wil hebben. Bovendien blijft de rest van PORTB intact.

tenminste bij een AVR / ATmega wel!!

Ik hoop voor Mircochip dat hun pic'jes ook op die manier werken! ;)

jij ast dus een extra variabele in. dat kan idd wel, maar dat had ik dus niet gelezen. dan gaat het idd wel

Op 27 oktober 2004 00:29:35 schreef High met henk:
zoals je ziet doe ik een echo op portb. dus ik gebruik portB als een variabele

Dit moet je bij een PIC niet doen (althans, niet bij een 12 of 14 bit PIC, het kan wel bij een 16 bit (18F) als je een LAT register gebruikt). Reden: als je bij een PIC een poort leest, dan lees je de pinnen, niet wta je er heen geschreven hebt. Bij een stevige en/of capacitieve belasting kan dit verschil maken.

bij een AVR/atmega heeft me dit nooit problemen opgeleverd en het spaart meteen geheugen uit :)

Op 27 oktober 2004 13:24:41 schreef High met henk:
bij een AVR/atmega heeft me dit nooit problemen opgeleverd

Ik zei ook alleen dat dit voor bepaalde PICs geldt. Overigens, ieder nadeel hep z'n voordel: AVR/atmega fan, hoe lees je bij die chips de *externe* waarde op een pin die als uitgang is geconfigureed?