UART per USI

OP #2600777
Lesenswert?

Hallo,

im Anhang ist meine Routine um das Universal Serial Interface der 
diversen AVRs zum UART-Daten (8N1) versenden zu überreden. Im Moment 
läuft es wunderschön auf einem ATTiny25.
Wäre super wenn ihr es euch anschauen bzw. Testen würdet. Wenn keine 
Fehler auftauchen / alles Optimiert wurde, würde ich es in die 
Codesammlung stellen.

Gruß
--Daniel

[Mod: defekte Version im Anhang zu diesem Beitrag entfernt. Korrigierte 
Version im folgenden Beitrag.]
#2601522
Lesenswert?

Mir ist das mit dem USI viel zu aufwendig.
Ich mach das einfach mit Delay:
1
#define F_CPU           8e6
2
#define BAUD            9600
3
#define STX_PORT        PORTB
4
#define STX_BIT         0
5

6
#include <util/delay.h>
7
#include <avr/io.h>
8

9
void sputchar( uint8_t c )
10
{
11
  c = ~c;
12
  STX_PORT &= ~(1<<STX_BIT);            // start bit
13
  for( uint8_t i = 10; i; i-- ){        // 10 bits
14
    _delay_us( 1e6 / BAUD );            // bit duration
15
    if( c & 1 )
16
      STX_PORT &= ~(1<<STX_BIT);        // data bit 0
17
    else
18
      STX_PORT |= 1<<STX_BIT;           // data bit 1 or stop bit
19
    c >>= 1;
20
  }
21
}


Das erzeugte Assemblerlisting sieht dann so aus:
1
void sputchar( uint8_t c )
2
{
3
  c = ~c;
4
  22:   80 95           com     r24
5
  STX_PORT &= ~(1<<STX_BIT);            // start bit
6
  24:   c0 98           cbi     0x18, 0 ; 24
7
  26:   9a e0           ldi     r25, 0x0A       ; 10
8
    milliseconds can be achieved.
9
 */
10
void
11
_delay_loop_2(uint16_t __count)
12
{
13
        __asm__ volatile (
14
  28:   e0 ed           ldi     r30, 0xD0       ; 208
15
  2a:   f0 e0           ldi     r31, 0x00       ; 0
16
  2c:   31 97           sbiw    r30, 0x01       ; 1
17
  2e:   f1 f7           brne    .-4             ; 0x2c <sputchar+0xa>
18
  for( uint8_t i = 10; i; i-- ){        // 10 bits
19
    _delay_us( 1e6 / BAUD );            // bit duration
20
    if( c & 1 )
21
  30:   80 ff           sbrs    r24, 0
22
  32:   02 c0           rjmp    .+4             ; 0x38 <__CCP__+0x4>
23
      STX_PORT &= ~(1<<STX_BIT);        // data bit 0
24
  34:   c0 98           cbi     0x18, 0 ; 24
25
  36:   01 c0           rjmp    .+2             ; 0x3a <__CCP__+0x6>
26
    else
27
      STX_PORT |= 1<<STX_BIT;           // data bit 1 or stop bit
28
  38:   c0 9a           sbi     0x18, 0 ; 24
29

30
void sputchar( uint8_t c )
31
{
32
  c = ~c;
33
  STX_PORT &= ~(1<<STX_BIT);            // start bit
34
  for( uint8_t i = 10; i; i-- ){        // 10 bits
35
  3a:   91 50           subi    r25, 0x01       ; 1
36
  3c:   11 f0           breq    .+4             ; 0x42 <__SREG__+0x3>
37
    _delay_us( 1e6 / BAUD );            // bit duration
38
    if( c & 1 )
39
      STX_PORT &= ~(1<<STX_BIT);        // data bit 0
40
    else
41
      STX_PORT |= 1<<STX_BIT;           // data bit 1 or stop bit
42
    c >>= 1;
43
  3e:   86 95           lsr     r24
44
  40:   f3 cf           rjmp    .-26            ; 0x28 <sputchar+0x6>
45
  42:   08 95           ret


Peter

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren