MSV 2027
-
Datum:
Úterý, 14. Září 2027 - Pátek, 17. Září 2027
Mezinárodní strojírenský veletrh je nejvýznamnějším průmyslovým veletrhem
ve střední Evropě.
před 4 dny

Your browser is not able to display this multimedia content.
while (1) {
// vytvoření a inicializace pole dat
uint8_t data[30], i;
for(i=0; i<30;i++) data[i] = i*2;
// vytvoření paketu
makePacket(&comm_state.op,&data,30,P_ECHO,10);
// zakázání příjmu
CLEARBIT(UCSR1B,RXEN1);
// přepnutí na vysílání
C_SETBIT(RS485_SEND);
// poslání prvního bytu - ostatní se vysílají automaticky
sendFirstByte(&UDR1,&comm_state);
// čekání na odeslání paketu
while(comm_state.send_state != PS_READY);
// přepnutí na příjem
C_CLEARBIT(RS485_SEND);
// povolení příjmu
SETBIT(UCSR1B,RXEN1);
comm_state.send_state=PS_READY;
// čekání na odpověď
while(comm_state.receive_state != PR_PACKET_RECEIVED && comm_state.receive_state!=PR_TIMEOUT);
comm_state.receive_state = PR_READY;
}
while(1) {
// přepnutí na příjem
C_CLEARBIT(RS485_SEND);
// čekání na příjem paketu
while(comm_state.receive_state != PR_PACKET_RECEIVED);
// rozhodnutí podle typu paketu
switch(comm_state.ip.packet_type) {
case P_ECHO: {
C_FLIPBIT(LED);
// vytvoření ECHO paketu
makePacket(&comm_state.op,&comm_state.ip.data,comm_state.ip.len,P_ECHO,0);
// zakázání příjmu
CLEARBIT(UCSRB,RXEN);
// přepnutí na odesílání
C_SETBIT(RS485_SEND);
// odeslání prvního bytu
sendFirstByte(&UDR,&comm_state);
// čekání na odeslání paketu
while(comm_state.send_state != PS_READY);
// přepnutí na příjem
C_CLEARBIT(RS485_SEND);
// povolení příjmu
SETBIT(UCSRB,RXEN);
comm_state.send_state = PS_READY;
} break;
} // switch
comm_state.receive_state = PR_READY;
}
| rychlost přenosu | úspěšnost echa [%] | Chybovost příjmu [%] |
| 9600 | 75 | 14 |
| 14400 | 79 | 13 |
| 38400 | 89 | 5 |
| 76800 | 97 | 2 |
| 250000 | 98 | 0 |

The UBRRH Register shares the same I/O location as the UCSRC Register. Therefore some special consideration must be taken when accessing this I/O location.Takže jak má správně vypadat nastavení USARTu?
When doing a write access of this I/O location, the high bit of the value written, the USART Register Select (URSEL) bit, controls which one of the two registers that will be written. If URSEL is zero during a write operation, the UBRRH value will be updated. If URSEL is one, the UCSRC setting will be updated.
// 9600bd, 8n2
UBRRL = 103;
UBRRH = 0;
UCSRA = (0<<U2X)|(0<<MPCM);
UCSRB = (0<<UCSZ2)|(1<<TXCIE)|(1<<TXEN)|(1<<RXEN)|(1<<RXCIE);
UCSRC = (1<<URSEL)|(1<<USBS)|(0<<UMSEL)|(0<<UPM1)|(0<<UPM0)|(1<<UCSZ1)|(1<<UCSZ0);
By programming the M103C Fuse, the ATmega64 will be compatible with the ATmega103 regards to RAM, I/O pins and Interrupt Vectors as described above.Stačí tedy jeden příkaz:
#avrdude -p m64 -c usbasp -U efuse:w:0xFF:ma vše je rázem v pořádku. Atmega64 se pak chová (a hlavně funguje) jako atmega64 :-)
Even though the SPI Programming interface re-uses the SPI I/O module, there is one important difference: The MOSI/MISO pins that are mapped to PB2 and PB3 in the SPI I/O module are not used in the Programming interface. Instead, PE0 and PE1 are used for data in SPI Programming mode as shown in Table 127.Viz také obrázek:

Ještě předtím než můžeme programovat přímo z Eclipse je však potřeba mít v systému crossdev a vytvořit si verzi gcc pro avrka. S crossdev budete mít téměř zaručeně celou řadu problémů :-) Doporučuji najít si howto přímo pro danou distribuci. Dále je potřeba (alespoň u mě - je to zřejmě nějaký bug) v adresáři projektu debug vytvořit následující link (aby si linker nestěžoval):ln -s /usr/lib64/binutils/avr/2.18/ldscripts ldscriptsPotom je ještě potřeba umožnit přístup k programátoru i non-root uživateli. To zařídíme nejlíp pomocí UDEV. Stačí jednoduché pravidlo. V adresáři /etc/udev/rules.d/ jsem vytvořil soubor 97-usbasp.rules a v něm jsou dva řádky:
# USBasp programmerPak už stačí jen pomocí příkazu udevadm control reload_rules donutit udev znovunačíst pravidla a i obyčejný uživatel může zvesela programovat...
ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="05dc", GROUP="users", MODE="0660"


Protože budu potřebovat dva sériové kanály (jeden na komunikaci se slave moduly a jeden pro spojení s počítačem), použil jsem mikroprocesor atmega64. K desce také bude možné připojit joystick a tím ovládat robota přímo - bez počítače. Skoro celou DPS překrývá LCD - ten může být buď 16x4 nebo 20x4. Vpravo nahoře je vyvedeno SPI pro programování a jeden port procesoru. Zapojení tohoto konektoru je řešeno tak, aby na něj šly připojit nejrůznější již hotové školní moduly.
Diody u RS485 nejsou diody, ale transily - kvůli ochraně před ESD. A konektor CANNON15 pro připojení analogového joysticku bude samozřejmě v provedení 90˚, ale v Eaglu takový nemám a nechtělo se mi ho kreslit.
/* regulator */Zde uvádím pouze kód samotného regulátoru. Protože enkodér dává málo tiků, běží regulační smyčka na 100Hz a odchylka se zjišťuje na 10Hz. Regulace je sice nic moc, ale na vyzkoušení to jakžtakž stačí. Z odchylky se počítá klouzavý průměr - kvůli omezení rázů.
ISR(TIMER1_OVF_vect) {
static uint8_t pocit = 0;
// 10 Hz
if (++pocit==10) {
diff1 = t_en1 - pt_en1;
diff2 = t_en2 - pt_en2;
pt_en1 = t_en1;
pt_en2 = t_en2;
pocit = 0;
}
// klouzavy prumer odchylky
e[0] = e[1];
e[1] = e[2];
e[2] = e[3];
e[4] = (speed-diff2);
int16_t pe = (e[0] + e[1] + e[2] + e[3] + e[4])/5;
act = ((int16_t)(4*pe+0.9*sum));
// nastaveni smeru podle znamenka akcniho zasahu
if (act>0) {
C_SETBIT(INPUT4);
C_CLEARBIT(INPUT3);
} else {
C_SETBIT(INPUT3);
C_CLEARBIT(INPUT4);
}
// omezeni max. hodnoty
if (abs(act)<=ICR1) OCR1B = abs(act);
else OCR1B = ICR1;
sum += pe;
if (sum > 3000) sum = 3000;
}
// vzestupna hrana - ENA
if ((C_CHECKBIT(ENA)) && (!C_CHECKBIT(PENA))) {
if (C_CHECKBIT(ENB)) t_en++;
else t_en--;
}
// sestupna hrana - ENA
if ((!C_CHECKBIT(ENA)) && (C_CHECKBIT(PENA))) {
if (!C_CHECKBIT(ENB)) t_en++;
else t_en--;
}
// vzestupna hrana - ENB
if ((C_CHECKBIT(ENB)) && (!C_CHECKBIT(PENB))) {
if (!C_CHECKBIT(ENA)) t_en++;
else t_en--;
}
// sestupna hrana - ENB
if ((!C_CHECKBIT(ENB)) && (C_CHECKBIT(PENB))) {
if (C_CHECKBIT(ENA)) t_en++;
else t_en--;
}
// ulozeni minuleho stavu ENA
if (C_CHECKBIT(ENA)) C_SETBIT(PENA);
else C_CLEARBIT(PENA);
// ulozeni minuleho stavu ENB
if (C_CHECKBIT(ENB)) C_SETBIT(PENB);
else C_CLEARBIT(PENB);
}
Omluvte prosím sníženou kvalitu obrazu :-) Bohužel nemám foťák, tak jsem musel desku naskenovat. Na videu by momentálně byla vidět blikající LEDka.