#include <io.h> 
#include <interrupt.h> 
#include <avr/signal.h> 
#include <eeprom.h> 

#define F_CPU            4000000      /* 4Mhz */ 
#define UART_BAUD_RATE      9600      /* 9600 baud */ 

#define EEPROM_SIZE (E2END+1) 
#define UART_BAUD_SELECT (F_CPU/(UART_BAUD_RATE*16l)-1) 

typedef unsigned char  u08; 
typedef          char  s08; 
typedef unsigned short u16; 
typedef          short s16; 

u16 read_counter; 
u16 write_counter; 

SIGNAL(SIG_UART_RECV)      { 
    register u08 ee_write; 
    ee_write = inp(UCSRA);                            
     outp(~ee_write, PORTD);                    
    eeprom_wb(write_counter, ee_write);        
    if (++write_counter >= EEPROM_SIZE)                
    write_counter = 0;                    
} 

SIGNAL(SIG_UART_TRANS)  { 
    register u08 ee_read; 
    ee_read = eeprom_rb(read_counter);                
    outp(ee_read, UCSRA);                              
    if (++read_counter >= write_counter)             
    read_counter = 0; 
} 


int main(void) 
{ 
    outp(0xff ,DDRD);      /* PortD output */ 
    outp(0x00, PORTD);     /* switch LEDs on */ 

    outp((1<<RXCIE)|(1<<TXCIE)|(1<<RXEN)|(1<<TXEN),UCSRB);        
    outp(UART_BAUD_SELECT, UBRR);  
    sei();                  
    read_counter  = 0;      
    write_counter = 0;      
    outp('#', UCSRA);        

    for (;;) {}           } 

Beste,

Bovenstaand staat een programma wat werkt met UART. Ik weet inmiddels wel hoe UART werkt, maar dit is in het algemeen. Ik weet niet hoe ik dit nu moet programmeren. Moet ik alles zelf programeren en opdracht geven tot zenden? of doet hij dit automatisch? hoe gaat dit in zijn werk?

vandaar dat ik een voorbeeldprogramma heb opgezocht wat volgens mij niet te ingewikkeld is. Maar ik begrijp er nog niet echt van. Zou iemand mij kunnen uitleggen wat hierboven gebeurt?

Het is de bedoeling dat ik dit programma ga ombouwen tot een programma dat het volgende doet:
Ik werk met een STK500 bordje met daarop de AT90s4433. Zodra ik knopje0 indruk moet op het andere bordje led0 gaan branden. Dus op bordje 1 druk ik knopje 0 in. Op bordje 2 gaat dan ledje 0 branden.

Hoe en waar moet ik nu beginnen? Kan iemand mij hierin tips geven?

Ik heb al enkele tutorials doorgelezen, maar hierin wordt alleen de werking van UART uitgelegd, niet hoe ik het nu moet programmeren.

alvast bedankt.

Ik denk dat je dan toch eens naar de datasheet moet kijken. Lijkt me sterk dat daar niets in staat. Of zoek eens op avrfreaks voor wat code.

[edit] ff verkeerd geklikt...
Smerige code. ff kort er doorheen scannend wordt er iets met EEPROM data naar de UART en omgekeerd gedaan. Waarom? Hoop dat jij het weet... jij komt met die code aan :-)

[/edit]

[Bericht gewijzigd door Marco69 op ]

nou ik weet het dus niet..... ik vraag dus aan alle mensen wie op dit forum rondzwerven, of dit een goed programma is om mee te gaan zenden naar een andere micro..... (zie mijn eerste post).

in de datasheet kan ik geen oefenprogramma's of een help ontdekken voor het opstellen van zo'n programma. Wel weet ik welke registers ik moet openzetten enzo om te kunnen zenden/ontvangen. Dat kan ik wel uit de datasheet halen. Maar hoe nu te zenden weet ik dus nog niet.

[Bericht gewijzigd door noppwes op ]

Inderdaad smerige code. Wat dit programma ongeveer doet, volgens mij:

Het stelt de UART in op versturen en ontvangen, en zet het verstuur en ontvang interrupt aan. Daarna gaat ie wachten op interrupts.

Bij het ontvang interrupt, dat optreedt wanneer er iets ontvangen is, wordt het ontvangen byte in het eeprom geschreven.

Bij het verstuur interrupt, dat optreedt wanneer het versturen klaar is, wordt een byte uit het eeprom gelezen, en verstuurd.

Alleen wat niet zo netjes is aan dit programma is dat hierin naar UCSRA geschreven wordt. Voor zover mij bekend is dit niet het dataregister van de UART, maar dat zal de schrijver wel expres ergens aangepast hebben. In principe stuurt de UART al, als je een byte in het UDR schrijft. Ontvangen doet hij ook vanzelf, als het interrupt komt, kun je het ontvangen byte lezen in het UDR

Op 15 maart 2005 19:19:58 schreef ka_bonthond:
In principe stuurt de UART al, als je een byte in het UDR schrijft. Ontvangen doet hij ook vanzelf, als het interrupt komt, kun je het ontvangen byte lezen in het UDR

Hetgeen ongetwijfeld in de datasheet staat...

Maar noppes... Wat verwacht je dan? Dat ze in de datasheet de code al voor je zetten? Er staat per register beschreven wat het doet, zo spannend is de rest dan niet meer...

Kijk hier eens in

http://www.atmel.com/dyn/resources/prod_documents/doc2547.pdf

Kijk hier

http://www.mikrocontroller.net/tutorial/

(Ist Deutsch..... :+)

Of hier (Met CTRL-F zoeken op UART)

http://www.atmel.com/dyn/products/app_notes.asp?family_id=607

en tik eens bij Google UART Atmel in... Kijkt en
huivert....

Robert

Goed,

Ik heb de aanwijzingen opgevolgt en ben ook op een ander programma gestapt. Ik vond een mooie tutorial waarin het zenden en ontvangen apart werd behandeld. Nu heb ik nog wel ff 1 klein vraagje. Kan ik het signaal wat verzonden wordt door onderstaand programma ook meten?

en: wat betekent deze regel? wat doet deze? het is een array wie de naam "a" meekrijgt, maar na de [] begrijp ik het ff niet meer


char a[] __attribute__((progmem)) = "This is a test message!";

het programma:


#include <io.h>
#include <interrupt.h>
#include <avr\signal.h>
#include <progmem.h>
char a[] __attribute__((progmem)) = "This is a test message!";
uint8_t pos=0;
SIGNAL(SIG_UART_TRANS)
{
if (pos++ < 23)
outp(PRG_RDB(&a[pos]), UDR);
}
int main(void)
{
outp((1<<TXCIE)|(1<<TXEN),UCSRB); /* enable TX interrupt */
outp(25, UBRR); /* init transfer speed */
sei(); /* enable interrupts */
outp(PRG_RDB(&a[pos]), UDR); /* write byte to data buffer */
for(;;){}
}

Hier tref je een overzicht aan van AVRGCC specifieke zaken

http://jubal.westnet.com/AVR/doc/avr-libc-user-manual/

(Ga er even vanuit dat je AVR-GCC gebruikt).

Die hele riedel achter a[] zorgt ervoor dat de
tekst in de flash wordt gezet voor zover ik weet.
Kost het je geen RAM. Hendig voor menuutjes op
display oid....

PRG_RDB zal wel zoeiets zijn als ProgrammemoryReadByte..

BTW, dit is ook weer kromme tenen code :+

outp(25, UBRR); /* init transfer speed */

Dit is dus prut, ander kristal is zoek maar nieuwe waarde.
Gewoon #define BAUDRATE of zo gebruiken die wordt
berekend als in eeste stuk code ipv harde waarden..

Robert

hmmmm gebruik AVR-Studio en ProgrammersNotepad. Dit wordt altijd al gebruikt op school. Alleen is dit een project en wij worden geacht d.m.v. zelfstudie de stof ons eigen te maken.

ik hoop dat dit geen verschil oplevert. zal eens even gaan zoeken op de aangegeven site.

ProgrammersNotePad is de shell waarbinnen
AVRGCC zit....

Een leuke 'shell' waarbinnen AVRGCC ook goed draait
is deze, http://www.eclipse.org/ ,
Menige Megabytes downloaden, maar ziet er wel gelikt
uit en werkt best prettig, o.a. code completion. Alleen
nogal traag ....

Zo zullen er nog wel meer van die editors zijn...

Wat betreft uitpluizen, GOOGLE....

Suc6,

Robert

toch heb ik nog steeds geen duidelijk antwoord kunnen vinden wat dit nu precies doet. Ook kan ik er niet achterkomen waarom de regel:


outp(PRG_RDB(&a[pos]), UDR);

er 2x instaat.

Ook moet ik dit programma uitleggen zodat mensen na mij het programma wle snappen (na mijn uitleg) Dit is de uitleg voor zover ik hem nu heb. Zouden jullie misschien hier even naar willen kijken? Goede tips of verbeteringen zijn altijd welkom.

Nu een voorbeeldprogramma:


#include <io.h>
#include <interrupt.h>
#include <avr\signal.h>
#include <progmem.h>

Dit is de initalisatie van de verschillende bibliotheken welke gebruikt worden in het programma.


char a[] __attribute__((progmem)) = "UUUUUUUU";

Hier maak je een array aan in welke de regel UUUUUUU geschreven word.


uint8_t pos=0;

de pointer wordt bij de eerste positie gezet. Vanaf hier begint het programma straks te lezen om de regel te verzenden


SIGNAL(SIG_UART_TRANS)
{
  if (pos++ < 23)
  outp(PRG_RDB(&a[pos]), UDR);
}

Hier wordt ingesteld dat de regel niet meer als 23 karakters mag bevatten. Hetgeen wat gelezen wordt, zet het programma in het UDR register. Dit is het register van UART, wat als een zendbuffer dient.


int main(void)
 {

Aanhef van het hoofdprogramma


  for(;;){

Dit zorgt ervoor dat het programma in een oneindige lus komt. Dus de regel welke in de array staat wordt continu verzonden.


               outp((1<<TXCIE)|(1<<TXEN),UCSRB); 

De registers welke de microcontroller vertellen dat hij moet gaan zenden worden 1 gemaakt. Dus ze worden actief gemaakt


               outp(25, UBRR); 

Het instellen van de baudrate.


               sei(); 

Het instellen van interrupts.


               outp(PRG_RDB(&a[pos]), UDR); 

het register UDR wordt gevuld met de waarde van de array.


              }
  }

Afsluiting van het programma

http://jubal.westnet.com/AVR/doc/avr-libc-user-manual/group__avr__pgms…

Staat op die pagina dat PRG_RDB vervangen wordt door
ander commando.

Als eerder gezegd, PRG_RDB leest gewneste data uit
het programmageheugen.....

Tik eens PRG_RDB in in Google... Komen nog
wat hits te voorschijn..

Robert