Hallo,
Ik ben beginner op het gebied van MCU programmeren, maar ik kom er niet echt uit.
ik heb dus het volgende probleem. Ik krijg 12 digitale inputs via mijn Atmega32. Deze inputs moet ik op een of andere manier verwerken om ze door te sturen via uart. Nu weet ik dat uart maar max 8 bit kan versturen.
Nu zit ik eerst gewoon te testen met 8 bit.
hierbij doe ik het volgende:
uint8_t inputs = PIND >>2; //eerste 6 poorten
inputs += PINB <<6; // laatste 2 poorten
UDR0 = inputs;
ik heb zo'n zelfde soort code getest met arduino en krijg dan gewoon een output bij seria in de vorm van: 11001100 te zien.
alleen nu met de atmega32 en deze code krijg ik eigenlijk een lege output bij serial. maar als ik het meet met de oscilloscoop krijg ik wel netjes de goede output te zien.
hoop dat iemand mij hierbij kan helpen
Op 7 maart 2018 00:57:13 schreef digitsboy:
Maar als ik het meet met de oscilloscoop krijg ik wel netjes de goede output te zien.
Dat betekend dat de 'zender' wel werkt.
Bij uart communicatie moet je altijd even wachten vooraleer je een volgende byte kan versturen. In de praktijk schrijf je naar het seriele buffer SBUF en wacht je tot de bit TI hoog wordt. De eerste byte is nu verzonden en kan je de volgende byte versturen.
Maar het probleem is dus dat jou 'ontvanger' niets binnenkrijgt he ?
Het eerste wat in me opkomt:
Is de txd van de zender verbonden met rxd van de ontvanger ?
Zijn de baudrates, start en stop bits hetzelfde voor zowel zender als ontvanger ?
nou als ik UDR0 = '1' doe dan geeft hij wel continue 1 outputs. dus de aansluitingen en instellingen zijn oke van de ontvanger zijn oke.
Ik denk dus dat het probleem in de code zit, kan ik de pins zo wel optellen? of moet ik ze nog naar iets omzetten om ze goed te kunnen verzenden?
rew
four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
Op 7 maart 2018 00:57:13 schreef digitsboy:
uint8_t inputs = PIND >>2; //eerste 6 poorten
inputs += PINB <<6; // laatste 2 poorten
UDR0 = inputs;
Als je de variabele inputs 16-bits maakt, dan heb je je 12 bits "op een rijtje" in je inputs variabele, mits de laatste 4 inputs op PB2-PB5 zitten.
Ik zou een protocol verzinnen als: hoogstebit = 1 is: eerste groep inputs, hoogstebit=0 is tweede groep.
Dan krijg je:
send_data ( 0x80 | (inputs & 0x7f));
send_data (inputs >> 7);
Dan kan je 14 bits versturen. ZIe maar of je tzt nut hebt voor die laatste twee bits.
Dan "send_data": Dat is in theorie zo simpel als:
void send_data (uint8_t d)
{
UDR0 = d;
}
maar daar moet nog even wat bij. Ik zou het er VOOR zetten: Wacht tot dataregister leeg is. Dat is iets als
while (! (STATUS & TXE)) /* nothing */;
Door het er voor te zetten, kan je programma verderlopen terwijl die ene byte door de hardware verstuurd wordt. Als je dan de nieuwe data verzonnen hebt voordat ie klaar is, dan zal ie inderdaad moeten wachten.
Denk eerder dat TS niet duidelijk is wat een binaire code is en hoe de ascii weergave van een binaire bitreeks moet gebeuren.
rew
four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
Hmm. Het zou kunnen dat je gelijk hebt.
for (i=0;i<8;i++) {
printf ("%d ", data&1);
data = data >> 1;
}
Helpt dit?
roadrunner84
Meep! Meep!
Op 7 maart 2018 00:57:13 schreef digitsboy:
ik heb zo'n zelfde soort code getest met arduino en krijg dan gewoon een output bij seria in de vorm van: 11001100 te zien.
alleen nu met de atmega32 en deze code krijg ik eigenlijk een lege output bij serial. maar als ik het meet met de oscilloscoop krijg ik wel netjes de goede output te zien.
Ik denk dat hier je eerste probleem zit: je instellingen van de seriële uitgang van je microcontroller zijn waarschijnlijk verkeerd.
Je zegt dat je oscilloscoop het wel goed weergeeft, maar je "serial" niet, ik gok dat je je PC daarmee bedoelt. Waarschijnlijk staat de baudrate van je microcontroller niet correct. Heb je gekeken of de lengte van je bits (in ms) op de oscilloscoop klopt?
De suggestie van @rew om het bovenste bit te gebruiken geeft je de ruimte voor 14 bits. Je kunt zelfs "compatible" tot 24 bits gaan door de bovenste twee bits te gebruiken voor indexering van de overige 6 bits. In jouw geval van 12 bits heb je dus aan twee indexes genoeg:
/* een 32-bits getal bevat je (tot) 24 bit input
3322222222221111111111 <-- bit nummer tientallen
10987654321098765432109876543210 <-- bit nummer eenheden
[ niks ][hoogste ...... laagste] <-- 24 bit woord
[0xC0][0x80][0x40][0x00] <-- index waarde
*/
send_data(0x00 | ((inputs >> 00) & 0x3f));
send_data(0x40 | ((inputs >> 06) & 0x3f));
/* de regels hieronder zijn alleen nodig voor 18 resp 24 bits
send_data(0x80 | ((inputs >> 12) & 0x3f));
send_data(0xC0 | ((inputs >> 18) & 0x3f));
*/
[Bericht gewijzigd door roadrunner84 op (10%)]
Dan "send_data": Dat is in theorie zo simpel als:
void send_data (uint8_t d) { UDR0 = d; }
Hoi, bedankt voor de antwoorden. Heb mijn systeem iets aangepast waardoor ik dus maar 10 bit hoef te versturen.
ik shift hierbij de input met 8 dus
uint8_t hi = inputs >> 8;
uint8_t lo = inputs & 0xFF;
Stel ik heb als int value: 1023
dan zou high de waarde 3 hebben en low the waarde 255.
Dit zijn beide 8 bit waardes dus zouden in 1 keer verzonden moeten worden via uart. Heb de instellingen dubbel gecheckt door gewoon
UDR ='8'te versturen. Dit werkt goed!.
Alleen wanneer ik de nieuwe code ga testen krijg ik hele andere waarden.
Het ligt dus denk ik aan de send_data functie die de ints niet goed verstuurd ofzo?
hoe kan ik het beste die 2 uint8_t integers kunnen verzenden via uart?