ein Atmega 328 schafft bei 8 MHz per hw-spi rund 220 kbyte/sec. Mit
usart spi geht es hoch auf 407 kbyte/s - jewels gemessen an einem
spi-tft. Der Code:
1 | int init_usart_spi(void)
|
2 | {
|
3 |
|
4 | DDRD &=~(1<<PD0);//rx-miso
|
5 | DDRD |= (1<<PD1);//tx-mosi
|
6 | // 1. Set baud Rate Register to 0
|
7 | UBRR0 = 0x0000;
|
8 | // 2. Set XCK line to output mode
|
9 | // DDRB = (1<<PB0); // XCK0 ATMega644
|
10 | DDRD |= (1<<PD4); // XCK0 ATMega328
|
11 | // 3. Select Master SPI Mode (UMSELn1:0 = 11)
|
12 | UCSR0C = (1<<UMSEL01) | (1<<UMSEL00);// | (1<<UCSZ01) | (1<<UCSZ00);
|
13 | // 4. Set UCPOLn and UCPHAn to required SPI mode
|
14 | UCSR0C |=(1<<UCPHA0)|(1<<UCPOL0);
|
15 | //5. Enable Transmitter and Receiver
|
16 | UCSR0B = (1<<RXEN0) | (1<<TXEN0);
|
17 | //6. Set Baud Rate Register to required value
|
18 | UBRR0 = 0x0000; // 8Mbps @16Mhz F_CPU
|
19 | // UBRR1 = 0x0001; // 4Mbps
|
20 | // UBRR1 = 0x0002; // 2.66Mbps
|
21 | // UBRR1 = 0x0003; // 2Mbps
|
22 | // UBRR0 = 0x0007; // 1Mbps
|
23 | }
|
24 |
|
25 | /*atme avr317
|
26 | // 1. UDR empty?
|
27 | while ( !( UCSR0A & (1<<UDRE0)) );
|
28 | // 2. Copy value to UDR
|
29 | UDR0 = dat;
|
30 | // 3. Transmit Complete?
|
31 | while ( !(UCSR0A & (1<<RXC0)) );//15,6
|
32 | // 4. Return value from UDR
|
33 | return UDR0;
|
34 | */
|
35 |
|
36 |
|
37 | write_usart_spi(u8 dat){
|
38 | //while ( !( UCSR0A & (1<<UDRE0)) );
|
39 | UDR0 = dat;
|
40 | while ( !(UCSR0A & (1<<RXC0)) );//15,6
|
41 | UDR0;//rx_buffer leeren
|
42 | }
|
43 |
|
44 |
|
45 | ....
|
46 | #if (zucAVR && use_usart_spi==0) || lcd_bitbang==1
|
47 |
|
48 | for( index = 0; index < ((uint32_t)lcd_max_width*lcd_min_width); index++ ) {
|
49 | lcd_write_2x8bit_only(Color);
|
50 | }
|
51 | #endif
|
52 |
|
53 | #if zucAVR && use_usart_spi==1 && lcd_bitbang==0
|
54 | for( index = 0; index < ((uint32_t)lcd_max_width*lcd_min_width); index++ ) {
|
55 | UDR0 = Color>>8;
|
56 | while ( !(UCSR0A & (1<<UDRE0)) );//15,6
|
57 | UDR0;//rx_buffer leeren
|
58 | UDR0 = Color;
|
59 | while ( !(UCSR0A & (1<<UDRE0)) );//15,6
|
60 | UDR0;//rx_buffer leeren
|
61 | }
|
62 | UDR0; //<==?????????
|
63 | lcd_cs_high;
|
64 |
|
65 | #endif
|
Das ganze funktioniert, aber die Flag-Abfrage scheint mir noch nicht
optimal zu sein. Was ich nicht verstehe ist, warum nach der for-Schleife
noch einmal der rx-buffer mit UDR0 geleert werden muss. Lässt man dies
weg, ist danach keine Anzeige auf dem TFT mehr möglich. Warum?