Forum: Mikrocontroller und Digitale Elektronik USART Verbindunz zwischen Atmega 32 und Cortex M3 (Stm32)


von xy (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Leute,

ich möchte Daten vom Prozessor A (Atmega32) zu Prozessor B (STM32F10x 
Discovery) übertragen.

Schaltungen im Anhang:

Code Prozessor A:
1
#define F_CPU 16000000UL      //Takt 16MHz
2
3
#include <avr/io.h>
4
#include <avr/interrupt.h>
5
#include <util/delay.h>
6
7
/* Programm Libs */
8
#include "defines.h"
9
10
int main(void)
11
{
12
13
  /* Lokale Variablen: */
14
15
16
  /* Ports as Outputs: */
17
  DDRA=0xFF;
18
  DDRB=0xFF; 
19
  DDRC=0xFF;
20
21
  uart_init();
22
23
 
24
   while (1)
25
   {
26
27
28
    // bei neueren AVRs steht der Status in UCSRA/UCSR0A/UCSR1A, hier z.&nbsp;B. fuer ATmega16:
29
    while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich                   */
30
    {
31
    }
32
 
33
    UDR = 'x';                    /* schreibt das Zeichen x auf die Schnittstelle */
34
35
   }
36
 
37
}
38
39
40
Defines.h:
41
42
#define BIT(x) (1 << (x)) 
43
#define SETBITS(x,y) ((x) |= (y)) //Maskierung
44
#define CLEARBITS(x,y) ((x) &= (~(y))) 
45
#define SETBIT(x,y) SETBITS((x), (BIT((y))))  //Bit SET
46
#define CLEARBIT(x,y) CLEARBITS((x), (BIT((y))))  //Bit RESET
47
48
#define BAUD 9600UL      // Baudrate
49
 
50
// Berechnungen
51
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
52
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
53
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.
54
 
55
#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
56
  #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch! 
57
#endif 
58
59
#include "functions.h"
60
void uart_init(void);
61
62
functions.h:
63
64
void uart_init(void)
65
{
66
  UBRRH = UBRR_VAL >> 8;
67
  UBRRL = UBRR_VAL & 0xFF;
68
 
69
  UCSRB |= (1<<TXEN);  // UART TX einschalten
70
  UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);  // Asynchron 8N1 
71
}

Prozessor B:

Auszug vom Programm:
1
  #define USARTy                   USART1
2
  #define USARTy_GPIO              GPIOA
3
  #define USARTy_CLK               RCC_APB2Periph_USART1
4
  #define USARTy_GPIO_CLK          RCC_APB2Periph_GPIOA
5
  #define USARTy_RxPin             GPIO_Pin_10
6
  #define USARTy_TxPin             GPIO_Pin_9
7
8
int main(void)
9
{
10
  RCC_ClocksTypeDef   Clocks;
11
  GPIO_InitTypeDef   GPIO_InitStruct;
12
  USART_InitTypeDef USART_InitStruct;
13
14
  SystemInit();
15
16
  RCC_GetClocksFreq(&Clocks);
17
  SysTick_Config( Clocks.HCLK_Frequency/1000 - 1 );  // 1000 Hz ( T=1ms)
18
19
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC , ENABLE);
20
    RCC_APB2PeriphClockCmd(USARTy_GPIO_CLK  | RCC_APB2Periph_AFIO, ENABLE);
21
    RCC_APB2PeriphClockCmd(USARTy_CLK, ENABLE); 
22
23
    GPIO_InitStruct.GPIO_Pin    =  GPIO_Pin_8|GPIO_Pin_9;      // TESTLEDS
24
  GPIO_InitStruct.GPIO_Speed  =  GPIO_Speed_10MHz;
25
  GPIO_InitStruct.GPIO_Mode    =  GPIO_Mode_Out_PP;
26
  GPIO_Init(GPIOC, &GPIO_InitStruct);
27
28
    /* Configure USARTy Rx as input floating */
29
    GPIO_InitStruct.GPIO_Pin = USARTy_RxPin;
30
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
31
    GPIO_Init(USARTy_GPIO, &GPIO_InitStruct);
32
33
    /* Configure USARTy Tx as alternate function push-pull */
34
    GPIO_InitStruct.GPIO_Pin = USARTy_TxPin;
35
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
36
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
37
    GPIO_Init(USARTy_GPIO, &GPIO_InitStruct);
38
39
   /* USARTy and USARTz configuration -------------------------------------------*/
40
    /* USARTy and USARTz configured as follow:
41
          - BaudRate = 9600 baud  
42
          - Word Length = 9 Bits
43
          - One Stop Bit
44
          - No parity
45
          - Hardware flow control disabled (RTS and CTS signals)
46
          - Receive and transmit enabled
47
    */
48
    USART_InitStruct.USART_BaudRate = 9600;
49
    USART_InitStruct.USART_WordLength = USART_WordLength_9b;
50
    USART_InitStruct.USART_StopBits = USART_StopBits_1;
51
    USART_InitStruct.USART_Parity = USART_Parity_No;
52
    USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
53
    USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
54
    
55
    /* Configure USARTy */
56
    USART_Init(USARTy, &USART_InitStruct);
57
    /* Enable the USARTy */
58
    USART_Cmd(USARTy, ENABLE);
59
    /* Set the USARTy Address */
60
    USART_SetAddress(USARTy, 0x1);
61
    /* Select the USARTz WakeUp Method */
62
    USART_WakeUpConfig(USARTy, USART_WakeUp_AddressMark);
63
64
  LCD_Init();
65
  RTC_Init();
66
  NVIC_Configuration();
67
    
68
   LCD_Data('H');
69
  LCD_Data('A');
70
   LCD_Data('L');
71
  LCD_Data('L');
72
  LCD_Data('O');
73
//  lcd_string(" POOL 38°C");  
74
75
  while(1)
76
  {
77
    static s32 SysTickHold1000=0;
78
      if(USART_GetFlagStatus(USARTy, USART_FLAG_RXNE) != RESET)
79
      {
80
      GPIO_SetBits  (GPIOC, GPIO_Pin_9);
81
      LCD_Data(USART_ReceiveData(USARTy));
82
    }
83
    else
84
      GPIO_ResetBits  (GPIOC, GPIO_Pin_9);
85
86
     if( (SysTickCnt - SysTickHold1000) >= 1000 )    // 1 Sec
87
    {
88
      SysTickHold1000+=1000;
89
      RTC_Cyclic_1Sec();  //RTC-Cyclik in rtc.c
90
    }
91
  }



Verbindung wurde natürlich überkreuzt angeschlossen.

Es Passiert überhaupt nichts bei der Übertragung, beim System B ist das 
RXNE kurz gesetzt und irgentsoein komisches Zeichen wird empfangen (auch 
ohne Anschluss des 2. Prozesosrs) anschließend wird nichts mehr 
empfangen.

Es ist das erste mal dass ich etwas per USART mache, habe ich irgentwo 
einen Denkfehler, muss ich irgentetwas noch ändern?

Wäre euch sehr dankbar wenn ihr mir Ratschläge und testideen geben 
könntet!

freundliche Grüße

von spontan (Gast)


Lesenswert?

Schon mal ein Oszi an die TX-Pin gehängt und geschaut ob überhaupt etwas 
rauskommt?

Sowohl TX des Prozessors als auch TX nach dem MAX.

von xy (Gast)


Lesenswert?

Leider kein Oszi da, und mit dem DMM werd ich wohl nichts messen...

von xy (Gast)


Lesenswert?

System A: -6,8V am TX

System B: 7V am TX

von xy (Gast)


Lesenswert?

Direkt bei dem Tx mess ich beim Atmega fast 5V mit DMM, also denke ich 
gibt er was aus, und beim Tx vom Cortex messe ich 0, der sendet ja auch 
nichts.

von Strickwettbewerbgewinner (Gast)


Lesenswert?

Du weist ja den RX/TX Pins auf dem STM32 gar nicht den USART zu. Du 
musst bei beiden
> GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
einstellen, und so etwas:
1
GPIO_PinAFConfig (GPIOA, GPIO_PinSource9, GPIO_AF_USART1);
2
GPIO_PinAFConfig (GPIOA, GPIO_PinSource10, GPIO_AF_USART1);
ausführen, damit der USART auch diese Pins verwendet. Kann bei dir aufm 
F1 auch etwas anders sein, ich kenn mich mehr mit dem F4 aus.

von xy (Gast)


Lesenswert?

Übrigens habe ich beim Atmega vors while(1) folgendes gepackt:
1
    while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich                   */
2
    {
3
    }
4
 
5
    UDR = 0x01;                    /* WAKEUP */

Dass der Cortex aufwacht.

von xy (Gast)


Lesenswert?

Strickwettbewerbgewinner schrieb:
> Du weist ja den RX/TX Pins auf dem STM32 gar nicht den USART zu. Du
> musst bei beiden
>> GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
> einstellen, und so etwas:GPIO_PinAFConfig (GPIOA, GPIO_PinSource9, 
GPIO_AF_USART1);
> GPIO_PinAFConfig (GPIOA, GPIO_PinSource10, GPIO_AF_USART1);ausführen, damit der 
USART auch diese Pins verwendet. Kann bei dir aufm
> F1 auch etwas anders sein, ich kenn mich mehr mit dem F4 aus.


Also ich habe das meiste hier aus nem DemoProgramm genommen.

Bei TX ist eh AF_PP configuriert

    /* Configure USARTy Tx as alternate function push-pull */
    GPIO_InitStruct.GPIO_Pin = USARTy_TxPin;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(USARTy_GPIO, &GPIO_InitStruct);

Beim RX muss aber der Mode ein Input Mode sein, also sollte 
GPIO_Mode_IN_FLOATING; doch Passen?


Das mit den anderen Beiden Zeilen klingt Logisch:

 GPIO_PinAFConfig (GPIOA, GPIO_PinSource9, GPIO_AF_USART1);
 GPIO_PinAFConfig (GPIOA, GPIO_PinSource10, GPIO_AF_USART1);

Allerdings gibts die Funktion beim F1 nicht, oder heißt anders und 
GPIO_AF_USART1 gibts auch nicht, muss ich ma nachlesen, was es da so 
gibt!

von xy (Gast)


Lesenswert?

Allerdings auffällig ist dass ich mit dem DMM auch 0V messe am RX Pin 
direkt beim Cortex und vorm Max232 -7V

von spess53 (Gast)


Lesenswert?

Hi

Warum dokterst du an zwei Baustellen herum? Verbinde die Module einzeln 
mit dem PC und teste die Verbindung mit einem Terminalprogramm.

MfG Spess

von xy (Gast)


Lesenswert?

Habe kein Terminalprogramm, und auch keine Com Buchsen auf den 
Bausteinen.

Das ganze sind einfach 2 Steuerungen die dann 15m auseinander sein 
sollen und Daten untereinander Kommunizieren sollen.

Übrigens hab grad etwas merkwürdiges entdeckt, beim RX Spannungsteiler 
liegen 4V an nachm Max232 und in der Mitte 0V. -> ?

von xy (Gast)


Lesenswert?

Also ich könnte evtl eine RS232 Buchse aus ner alten Grafikkarte 
auslöten.

Pins brauche ich eh nur RX,TX, GND und 5V, korrekt?

von xy (Gast)


Lesenswert?

Das mit der Buchse aus Grafikkarte war natürlich Unfug.

Ich hätte ein LPT auf RS232 kabel hier, dass ich nicht zerstören will, 
welche Pins vom LPT müsste ich da verwenden?

von xy (Gast)


Lesenswert?

Hab mir ein Kabel gebaut -> nun testen.

von xy (Gast)


Lesenswert?

So Habe beim LPT zu RS232-Kabel am 25Pol Stecker Pin2 TXD mit dem RXD 
vom Atmega verbunden und PIN3 mit TXD

PIN7 GND mit meiner schaltung verbunden.

Terminalprogramm gestartet, Baudrate eingestellt, aber nichts 
passiert...

von Bastler (Gast)


Lesenswert?

xy schrieb:
> Pins brauche ich eh nur RX,TX, GND und 5V, korrekt?

Hast du einen Plan, wie du das anschließen willst? Zum PC bzw. 
RS-232/USB-Wandler gehen RX, TX und Gnd. 5V haben da eher nichts zu 
suchen?

von xy (Gast)


Lesenswert?

Wieschon gesagt, habe RX, TX und GND angeschlossen, dass mit 5V ist 
jetzt auch klar dass das nicht benötigt wird.

von µC-Bastler (Gast)


Lesenswert?

xy schrieb:
> Habe kein Terminalprogramm
Aber dein Internetanschluß funktioniert? Unter Windo.s wäre HTerm eine 
Möglichkeit.

von xy (Gast)


Lesenswert?

Versuchs gerade mit Hterm, aber empfang nichts.

Anschließen muss man hier wieder Überkreuzt richtig? Also PIN2 TX bei 
mir auf RX?

von xy (Gast)


Lesenswert?

Funktioniert irgentwie bei beiden Boards nicht, beim einen das Senden 
und beim anderen das Empfangen...

von xy (Gast)


Lesenswert?

Test mit Stm32: Also irgentwie geht nichts, empfangen nicht und senden 
auch net. (Ist jetzt mit PC verbunden)
1
  while(1)
2
  {
3
      /* Wait while USART1 TXE = 0 */
4
       while(USART_GetFlagStatus(USARTy, USART_FLAG_TXE) == RESET)
5
      {
6
      }
7
    Delay(1);
8
    USART_SendData(USARTy, 0x33);
9
10
      if(USART_GetFlagStatus(USARTy, USART_FLAG_RXNE) != RESET)
11
      {
12
      GPIO_SetBits  (GPIOC, GPIO_Pin_9);
13
      LCD_Data(USART_ReceiveData(USARTy));
14
    }
15
    else
16
      GPIO_ResetBits  (GPIOC, GPIO_Pin_9);   
17
  }

von xy (Gast)


Lesenswert?

Hat jemand ne idee wie man noch testen könnte, bzw an was es liegen 
könnte? hab mitterweile wieder die 2µCs miteinander verbunden...

von xy (Gast)


Lesenswert?

gerade beim Atmega Board den Atmega rausgenommen und RX TX verbunden, es 
passiert nicht wirklich viel. in Hterm im Received Bereich steht immer 
das gesendete, warum auch immer (is aber immer auch im ausgesteckten 
zustand) aber bei Transmitted Data steht gar nix...

von xy (Gast)


Lesenswert?

Denke dass ich fehler gefunden habe, hatte bisher alles über USB 5V 
versorgt, aber die spannung war nur 4,26V und das war anscheiend etwas 
zu wenig...

von xy (Gast)


Lesenswert?

Nur Funktioniert noch immer nichts, zum test 11 und 12 miteinander 
Verbunden

Spannungen PAssen, PIN2 9V, PIN6 -9V.

Allerdings auf RX und TX messe ich -9V nachdem ich senden drücke in 
Hterm messe ich +1,7V. Hoffe damit kann mir jemand helfen...

von xy (Gast)


Lesenswert?

Niemand ne idee?

von spontan (Gast)


Lesenswert?

Mit einem Multimeter an RX und TX messen, mach nicht wirklich Sinn.
Wenn kein Datenverkehr ist, kann man nur die statischen Pegel messen.
Mit Datenverkehr wirds aber sowas von sinnlos. Oszi her.

von xy (Gast)


Lesenswert?

Wie gesagt ich besitze kein Oszilloskop.

Muss doch eine Möglichkeitgeben die Verbindung zu testen...

von xy (Gast)


Lesenswert?

:D Habe den Atmega wieder reingesteckt, und mit Terminalprogramm 
Terminal v1.9b geschaut und siehe da, die Daten kommen an ;).

von xy (Gast)


Lesenswert?

Am STM32 tut sich leider gar nix beim Max, wenn ich ein Zeichen sende 
steht im Terminal das als Received, is aber das selbe wie wenn ich das 
Kabel ausstecke. Spannungspegel passen. Dis Pegel am Rx und Tx auf RS232 
seite sind annähernd 0 ändern sich minimal bei übertragung...

von xy (Gast)


Lesenswert?

Der Rx Spannungsteiler ist auch Merkwürdig, da hab ich 3,7V am Rx und in 
der Mitte vom Spannungsteiler 0V.

von xy (Gast)


Lesenswert?

Die Ausgangspegel sehen jetzt ganz okay aus, und beim Senden vom 
Terminal kommt auch nix mehr zurück bei Receive, außer wenn man den µC 
Resettet und dann sendet steht einmal <0> im Terminal. Allerdings kommt 
wohl beim Prozessor nix an und umgekehrt auch nicht...

von Bastler (Gast)


Lesenswert?

xy schrieb:
> ..., wenn ich ein Zeichen sende steht im Terminal das als Received,
> is aber das selbe wie wenn ich das Kabel ausstecke.

Dann hast du wohl im Terminalprogramm das lokale Echo aktiviert.

von xy (Gast)


Lesenswert?

Also beim Atmega klappt alles wie schon erwähnt, habe die 2 Max232 auch 
schon vertauscht, also Hardwaremäßig müsste es Passen, allerdings müsste 
ich dan Softwaremäßig einen Fehler haben.

Aktuelle Software (will nur ein Zeichen zum PC Senden erstmal.

1
#include "stm32f10x.h"
2
#include <stdio.h>
3
#include "LCD.h"
4
#include "rtc.h"
5
#include "nvic.h"
6
#include "Util.h"  //UINTToString
7
#include "interrupt.h"
8
9
#define RTCClockOutput_Enable 
10
11
12
void Delay (unsigned long tick);
13
void RTC_Cyclic_1Sec(void);
14
15
volatile int32_t SysTickCnt=0;
16
__IO uint32_t TimeDisplay = 0;
17
18
19
int main(void)
20
{
21
  RCC_ClocksTypeDef   Clocks;
22
  GPIO_InitTypeDef   GPIO_InitStruct;
23
  USART_InitTypeDef USART_InitStruct;
24
  USART_ClockInitTypeDef USART_ClockInitStructure;
25
26
  SystemInit();
27
28
  RCC_GetClocksFreq(&Clocks);
29
  SysTick_Config( Clocks.HCLK_Frequency/1000 - 1 );  // 1000 Hz ( T=1ms)
30
31
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC , ENABLE);
32
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
33
34
35
    GPIO_InitStruct.GPIO_Pin    =  GPIO_Pin_8|GPIO_Pin_9;      // TESTLEDS
36
  GPIO_InitStruct.GPIO_Speed  =  GPIO_Speed_10MHz;
37
  GPIO_InitStruct.GPIO_Mode    =  GPIO_Mode_Out_PP;
38
  GPIO_Init(GPIOC, &GPIO_InitStruct);
39
40
  //Set USART1 Tx (PA.09) as AF push-pull   
41
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;   
42
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;   
43
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;   
44
  GPIO_Init(GPIOA, &GPIO_InitStruct);
45
46
  //Set USART1 Rx (PA.10) as input floating
47
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;   
48
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;   
49
  GPIO_Init(GPIOA, &GPIO_InitStruct);
50
51
USART_ClockStructInit(&USART_ClockInitStructure);
52
USART_ClockInit(USART1, &USART_ClockInitStructure);
53
54
   /* USARTy and USARTz configuration -------------------------------------------*/
55
    /* USARTy and USARTz configured as follow:
56
          - BaudRate = 9600 baud  
57
          - Word Length = 9 Bits
58
          - One Stop Bit
59
          - No parity
60
          - Hardware flow control disabled (RTS and CTS signals)
61
          - Receive and transmit enabled
62
    */
63
    USART_InitStruct.USART_BaudRate = 9600;
64
    USART_InitStruct.USART_WordLength = USART_WordLength_9b;
65
    USART_InitStruct.USART_StopBits = USART_StopBits_1;
66
    USART_InitStruct.USART_Parity = USART_Parity_No;
67
    USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
68
    USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
69
    
70
    /* Configure USARTy */
71
    USART_Init(USART1, &USART_InitStruct);
72
    /* Enable the USARTy */
73
    USART_Cmd(USART1, ENABLE);
74
    /* Set the USARTy Address */
75
//    USART_SetAddress(USARTy, 0x1);
76
    /* Select the USARTz WakeUp Method */
77
//    USART_WakeUpConfig(USARTy, USART_WakeUp_AddressMark);
78
79
  LCD_Init();
80
  RTC_Init();
81
  NVIC_Configuration();
82
    
83
   LCD_Data('H');
84
  LCD_Data('A');
85
   LCD_Data('L');
86
  LCD_Data('L');
87
  LCD_Data('O');
88
//  lcd_string(" POOL 38°C");  
89
90
  while(1)
91
  {
92
    static s32 SysTickHold1000=0;
93
      /* Wait while USART1 TXE = 0 */
94
95
       USART_SendData(USART1, 0x44);
96
      //Loop until the end of transmission
97
      while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET) //Transmission Complete
98
      {
99
      GPIO_SetBits(GPIOC,GPIO_Pin_9);
100
      }
101
      GPIO_ResetBits(GPIOC,GPIO_Pin_9);
102
    Delay(100);
103
104
     if( (SysTickCnt - SysTickHold1000) >= 1000 )    // 1 Sec
105
    {
106
      SysTickHold1000+=1000;
107
      RTC_Cyclic_1Sec();  //RTC-Cyclik in rtc.c
108
    }
109
  }
110
}
111
112
113
void Delay (unsigned long tick) //Delay_ms
114
{  
115
  int32_t SysTickCntHold;
116
     SysTickCntHold = SysTickCnt;  
117
  while((SysTickCnt - SysTickCntHold ) <= tick );   
118
}


Die Testled auf GPIOC 9 Blinkt die ganze zeit, also die Software 
erkennts als Zeichen übertragen.


Hab aber gerade eine Vermutung an was es liegt bekommen...

von xy (Gast)


Lesenswert?

Problem gelöst: Die Display Initialisierung war schuld, habe da den 
ganzen PORTA als ausgang gesetzt, statt nur die nötigen Pins...

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.