Forum: Mikrocontroller und Digitale Elektronik Ein Draht TX DebugTransmitter


von Kahn P. (Gast)


Lesenswert?

Hallo,

ich muss auf dem Atiny85 über eine 1 Draht -Leitung einem
anderen Mikrocontroller an dessen TX Input eine Zeichenkette vor 
tickern.

Dazu verwende ich folgenden primitiven Code, um eine Zeichenkette
bitweise mit einem Zeitschlitz t am PB1 auszugeben:
1
void TxStr(char *p) //zb "Hallo Welt \r\n"
2
{
3
  char n=0;
4
5
  while(*p)
6
  {
7
    for(n=0;n<8;n++)
8
    {
9
      if(*p & (1<<n))
10
       PORTB |= (1 << PB1);//On
11
      else
12
       PORTB &= ~(1 << PB1);//off
13
      
14
                         //wait boud
15
       _delay_loop_2(((F_CPU) / 4e3) / 1); //µs
16
    }
17
18
    p++;
19
  }
20
}

Leider kommt dabei nichts zu Stande außer Datenmüll.
der Baustein läuft auf 16500000 F_CPU = 16.5 Mhz.

Was kann man denn da anpassen .


Danke für Hinweise.
 Lg
  K aus B

von Falk B. (falk)


Lesenswert?

@ Karsten Schulz (kahnsoft)

>ich muss auf dem Atiny85 über eine 1 Draht -Leitung einem
>anderen Mikrocontroller an dessen TX Input eine Zeichenkette vor
>tickern.

Nennt sich SOFT-UART.

>Dazu verwende ich folgenden primitiven Code, um eine Zeichenkette
>bitweise mit einem Zeitschlitz t am PB1 auszugeben:

Wenn das ein UART Signal sein soll, fehlen Start- und Stopbits.

>void TxStr(char *p) //zb "Hallo Welt \r\n"
>{
>  char n=0;

>  while(*p)
>  {
>    for(n=0;n<8;n++)
>    {
>      if(*p & (1<<n))

Hier hätte man sinnvollerweise ein Zwischenvariable nehmen können. 
Möglicherweise macht das die Optimierung des Compilers automatisch.

>       PORTB |= (1 << PB1);//On
>      else
>       PORTB &= ~(1 << PB1);//off

>                         //wait boud
>       _delay_loop_2(((F_CPU) / 4e3) / 1); //µs

Warum nutzt du nicht die normale _delay_us() Funktion? Die funktioniert 
korrekt und ist deutlich besser lesbar.

>Leider kommt dabei nichts zu Stande außer Datenmüll.

Wie gemessen? Was kommt denn raus?

>Was kann man denn da anpassen .

An sich ist der Code korrekt.

von Frickelfritze (Gast)


Lesenswert?

Karsten S. schrieb:
> Leider kommt dabei nichts zu Stande außer Datenmüll.

Aber auch eine 1-Draht Datenverbindung braucht zwei Drähte,
schon klar oder?

von Kahn P. (Gast)


Lesenswert?

Hallo zusammen!

Also nach einigen Verwirrungen bezüglich das das Startbit anfangs Low 
sein muss satt wie in einigen Artikeln high: 
http://www.elektronik-labor.de/RS232/RS232_2-Dateien/image001.jpg

Konnte der atiny85 locker seinen Status an ein terminal über
eindraht Kommunikation absetzen :
1
//Use Atiny85 PB1 as TX DebugTransmitter to emit Strings
2
#define BD300   3333 //300  Baud   3,33 ms
3
#define BD1200  833 //1200  Baud  833 µs
4
#define BD2400   417 //2400  Baud  417 µs
5
#define BD9600   104 //9600  Baud  104 µs
6
#define BD38400   26 //38400 Baud 26,04 µs
7
//9600 8 n 1  1Startbit 8Datenbit 1Stopbit (can use two stop bitslots)
8
void TxStr(unsigned char *p)
9
{
10
    register unsigned char n;
11
  cli();//DisableInterrupt
12
  
13
  do
14
  {
15
    //Startbit   
16
    PORTB &= ~(1 << PB1);
17
    _delay_us(BD9600);
18
19
    for(n=0; n < 8; n++) //Databits
20
     *p&(1<<n)?(PORTB |=  (1 << PB1)):(PORTB &= ~(1 << PB1)),_delay_us(BD9600);//make this slot
21
22
    //Stopbit1  
23
    PORTB |=  (1 << PB1);
24
    _delay_us(BD9600);
25
26
  }while(*p++);
27
28
  sei();//EnableInterrupt
29
}


Das funktioniert sehr gut kann man so empfehlen :
http://www.visiongrid.de/keymandongle.html

Grüße
 Karsten

von Stefan F. (Gast)


Lesenswert?

Schau mal von meiner HelloTiny.zip Vorlage ab, da ist das Timing besser.

http://stefanfrings.de/avr_hello_world/index.html

Ich benutze diesen Code meist mit 9600 Baud und 1 oder 1,2Mhz 
Systemtakt. Habe aber auch schonmal 115200 Baud mit 16Mhz stabil 
getestet.

von Kahn P. (Gast)


Lesenswert?

Hallo Stefan,

ja der Osc wurde getunt, das ganze läuft ja
in einer von V-USB abgelitteten Version: (läuft hier auch mit 16.5Mhz)
1
void  calibrateOscillator(void)
2
{
3
  uchar       step = 128;
4
  uchar       trialValue = 0, optimumValue;
5
  int         x, optimumDev, targetValue = (unsigned)(1499 * (double)F_CPU / 10.5e6 + 0.5);
6
7
    do{
8
        OSCCAL = trialValue + step;
9
        x = usbMeasureFrameLength();    /* proportional to current real frequency */
10
        if(x < targetValue)             /* frequency still too low */
11
            trialValue += step;
12
        step >>= 1;
13
    }while(step > 0);
14
15
    optimumValue = trialValue;
16
    optimumDev = x; /* this is certainly far away from optimum */
17
    for(OSCCAL = trialValue - 1; OSCCAL <= trialValue + 1; OSCCAL++)
18
  {
19
        x = usbMeasureFrameLength() - targetValue;
20
        if(x < 0)
21
            x = -x;
22
23
        if(x < optimumDev)
24
    {
25
            optimumDev = x;
26
            optimumValue = OSCCAL;
27
        }
28
    }
29
    OSCCAL = optimumValue;
30
}

Ich habe dein Scr gesehen, so in etwa läuft das hier auch.
Danke für deinen Tip,
 Grüße
  Karsten#

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.