Hi,
ich sitze hier vor meinem kleinen Board mit einem STM32F105 drauf. Ich
will jetzt mal meine Peripherie testen und hänge an der USART2. Ich
initialisiere die Schnittstelle wie in reference manual beschrieben. Das
klappt auch alles soweit - nur bekommen ich irgendwie nichts ins
Datenregister. Ich habs händig probiert und mit der DMA, aber keines von
beiden funktioniert. Das Register steht dauerhaft auf 0x00000000 und
dadurch kommt natürlich nichts raus.
Hier mein Code zur USART2:
void Usart2()
{
pUSART2->CR1 = 0x00002000; //Enable USART2: 1 Start bit, 8 bits
pUSART2->CR2 = 0x00002000; //2 stop bits
pUSART2->CR3 = 0x00000180; //RTS + DMA enabled
pUSART2->SR = 0x00000000;
Dma1Init();
pUSART2->BRR = 0x0000001A; //Clock/4=Baud rate
pUSART2->CR1 |= 0x00000009; //Transmission enable
//pUSART2->DR = 0x55;
while (!(pUSART2->SR & 0x00000040))
{
}
}
Und die DMA1 initialisier ich folgendermaßen:
void Dma1Init()
{
pDMA1->CPAR1 = 0x4004404; //Zieladresse Peripherie
pDMA1->CMAR1 = (uint32_t) &pSpeicher; //Zieladresse Speicher
pDMA1->CNDTR1 = 0x000000FF; //8 Daten-Bits
pDMA1->CCR1 = 0x00001010; //Priorität = mittel; vom
Speicher lesen
pDMA1->CCR1 |= 0x00000001; //enable
}
Hat da jemand eine idee was ich hier falsch mache?
Wäre super wenn mir jemand weiterhelfen könnte. Ich häng grad echt total
in der Luft.
Vorneweg die Takte der verwendeten Peripheriemodule einschalten, also USART, DMA, GPIO (=> RCC).
mache ich:
void ClockInit()
{
//Clock control register
pRCC->CR |= 0x00010000; //HSE on
// Wait for HSE
while (!(pRCC->CR & 0x00020000))
{
}
//Clock configuration register
//HSE clock, PLLx4
pRCC->CFGR |= 0x00090000; //PLL on
pRCC->CR |= 0x01000000;
//Wait for PLL
while (!(pRCC->CR & 0x02000000))
{
}
pRCC->CFGR |= 0x06000002;
//Access to RTC and Backup registers enabled
//pPWR->CR |= 0x01010100;
//Peripheral colcks enable registers
pRCC->AHBENR |= 0x00000054; //SRAM-,CRC-, FLITF-clock enable
pRCC->APB2ENR |= 0x0000281C; //Timer-, I/O-ports-, AFIO-clock enable
pRCC->APB1ENR |= 0x1A82003F; //Timer-, Power interface-,backup
interface-,USART2-,USB-,CAN-clock enable
}
Zumindest der GPIOA funktioniert auch einwandfrei. das habe ich
getestet.
Geht du davon aus, dass du (oder ein Debugger) aus dem Datenregister der USART das wieder auslesen kannst, was du vorher reingeschrieben hast? Dann hast du die Arbeitsweise einer U(S)ART und von dessen Datenregister egal welchen Controllers nicht verstanden.
Das mag sein, aber wenn ich das Programm Schritt für Schritt debugge und etwas in das Datenregister schreibe, dann muss ich das doch bevor ich den den nächsten Schritt ausführe dort sehen können. Oder bin ich da jetzt falsch gewickelt? Ich schreibe das doch parallel rein und es wird dann seriell an die Schnittstelle weitergegeben. Aslo muss ich es doch kurzfristig dort sehen können, oder nicht?
Benjamin Norenburg schrieb:
> Oder bin ich da jetzt falsch gewickelt?
Ja.
Das Datenregister gibt es zweimal, eins für Empfang (lesender Zugriff)
und eins für Senden (schreibender Zugriff), aber beide an der gleichen
Adresse. Und zu allem Überfluss verschwindet der Inhalt des ohnehin
nicht auslesbaren Datenregisters fürs Senden sofort im Schieberegister
(wenn frei).
In der Referenz findet man ein Prinzipschaltbild der USART (USART block
diagram), in dem das illustriert wird.
Aso, dass die Daten weitergegeben werden war mir klar. Ich habe nur gedacht, dass ich sie im ersten Moment noch sehen müsste bevor der nächste schritt ausgeführt wird. Ok, dann ist das nicht mein Problem, danke schonmal. Da bleibt die Frage: Was mach ich dann falsch?
Deine einzige bisher gelieferte Fehlerbeschreibung war, dass im DR hinterher nichts steht. Dieser Fall wäre geklärt.
Ja, das war meine vermutung, dass es daran hängt. Du hast mir ja klar gemacht, dass dem nicht so ist. Das Problem aller Probleme ist, dass nicht rauskommt. Kein einziges Bit. Ich Schau nochmal nach ob ich den Takt richtig initialisiert habe, aber ich denke schon.
Sieht gut aus, der Takt müsste da sein. Und ich gehe bei der Initialisierung Schritt für Schritt wie im reference manual beschrieben vor. Keine Ahnung warum das nicht geht. Ich steh grad voll auf dem Schlauch.
Und wie werden die Pins initialisiert? Tip dazu: Hexsalat wie oben werde ich nicht zur Kenntnis nehmen, dafür gibt es Namen.
Die pins werden als alternate funktion output Push-pull mit maximal 50 MHz initialisiert. Habe ich gerade auch nochmal überprüft.
Moment, Komando zurück. jetzt sind Sie alle so konfiguriert. Habe gerade beim TX was falsch gemacht. jetzt klappts. Danke für deine Hilfe. War ein dämlicher Fehler an dem ich ohne deinen Schupser in die richtige Richtung warscheinlich noch einen Tag rumgemacht hätte.
Gast
#1548322
Hi, weißt du was du da damals beim TX falsch gemacht hast? Ich fürchte, ich steh grad vor dem selben Problem - komm aber irgendwie nicht drauf was mir fehlt..
ich glaube ich habe den pin falsch konfiguriert gehabt. überprüf nochmal genau jedes einzele bit im entsprechenden register.
Gast
#1549071
Irgendwie komm ich nicht auf den Fehler... Hab mal meinen Sourcecode angehängt:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
Das komische ist, dass es funktioniert, wenn ich den Kommentar am Ende des Unterprogramms entferne... Die Frage ist nur, warum funktionierts dann? Eigentlich konfiguriere ich PA.9 ja oben schon als AF-Push-Pull..
Gast
#1549714
Der Sende-Interrupt wird angestoßen? Wie erfolgt die Datenübergabe - als ISR?
aso, so weit mit ich garnicht gegangen. ich habe garnicht mit interupts gearbeitet. mein entstand war, dass ich was über die serielle schnittstelle empfange kurz zwischenspeicher und gleich wieder zurück schick. es ging nur ums testen der hardware.
Gast
#1549764
Philipp schrieb:
> Der Sende-Interrupt wird angestoßen?
Er hat Interruptbetrieb gar nicht konfiguriert, sonst müsste TXEIE in
USART1_CR1 gesetzt sein. Ergo reicht gepollter Versand.
@STM32 Neuling:
Du müsstest nach1 | |
2 | |
noch IOPAEN in RCC->APB2ENR anknipsen. Könntest Du evtl. so machen:
1 | |
Da ich meine eigene Lib benutze, weiß ich nicht, ob RCC_APB2ENR_IOPAEN in der ST-Lib die richtige Konstante ist.
Gast
#1549779
> Vorneweg die Takte der verwendeten Peripheriemodule einschalten, also > USART, DMA, GPIO (=> RCC). ... und AFIO nicht vergessen ! VG, /th.
Gast
#1550514
Arne schrieb: > @STM32 Neuling: > Du müsstest nachGPIOA->CRH |= (0x0BUL << 4); // Tx (PA9) alt. out push-pull > GPIOA->CRH |= (0x04UL << 8); // Rx (PA10) in floating > noch IOPAEN in RCC->APB2ENR anknipsen. > Könntest Du evtl. so machen:RCC->APB2ENR |= RCC_APB2ENR_USART1EN | RCC_APB2ENR_IOPAEN; // enable clock for USART1 IOPAEN hab ich angeknipst - siehe 2.Zeile des Unterprogramms. @thorstendb: In der STM32 FAQ hab ich zum Thema AFIO-clock folgendes gefunden: "If the application is mapping USART1 on the default port A, then there is no need to enable the AFIO clock. If the application is remapping the USART1 pins from port A to port B, then the AFIO clock should be enabled." So wie ich das sehe, brauche ich den AFIO-clock nicht, da ich eh den Standard USART1 Port A verwende?
Gast
#1551824
Hat noch jemand nen Tipp? Langsam bin ich echt am Verzweifeln... Ich find das Reference Manual von ST ein bisschen schwach - es werden zwar viele Sachen angeschnitten, aber ne ausführliche Erklärung findet man dann selten - zumindest ist das mein Eindruck.
Gast
#1552525
Naja, es gibt schlimmere Manuals, als das RM0008 von ST ;) Zum Beispiel die zum Coldfire :-O Ansonsten könnte es sein, dass die Reihenfolge der ganzen Enablebits entscheidend ist. Ich kann mich da düster entsinnen, hab meine UART Lib vor ca. 1 Jahr geschrieben. Sonst schau mal im Debugger nach, ob durch den auskommentierten Code ein Enablebit wieder angeknipst wird. Denn mit dem auskommentierten bereich am Ende funktioniert es ja?!? BTW: Du willst erstmal nur senden? Dein terminalprg. am anderen Ende hast Du richtig konfiguriert? Die Baudrate im STM hast Du von den Werten des USART1_BRR Mantissa/Fraction (wie in kap 24.3.4 beschrieben) zurückgerechnet?
Gast
#1553017
Genau, im Moment moecht ich nur mal Daten zum PC uebertragen. Wenn ich den Kommentar am Ende entferne, dann funktionierts. Die Einstellungen im Terminalprogramm passen. Wenn ich daheim bin, werd ich mir mal die Enable-Bits anschauen. Danke fuer den Tipp!
Gast
#1553039
Da ich ja nicht die ST-Lib nutze, habe ich meine Initialisierung hier mal in 'Pseudocode' abgetippt:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
Zum Senden dann: Solange auf dem USART_SR_TXE pollen, bis es 1 ist, dann einen Wert in das USART1_DR poken. Hoffe Du kannst was mit den Bitbezeichnungen anfangen. Welche Entwicklungsumgebung nutzt Du? Keil, IAR, GCC,...?
Gast
#1553046
nachtrag: Muss natürlich...
1 | |
heißen.
Gast
#1556541
Hi Arne, erstmal danke für den Sourcecode Auszug. Ich hab mir den Code von dir jetzt mal mit Hilfe des Reference Manuals durchgeschaut und ein paar Kleinigkeiten übernommen. Wenn ich das Programm nun debugge (ich nutze Keil uVision3 als IDE), dann bekomme ich im "Serial Window" innerhalb der IDE die gesendeten Daten angezeigt. Beende ich nun den Debugmodus und connecte mit einem Terminalprogramm, dann bekomm ich komischerweise keine Daten...(die Baudrate, Start -und Stopbit, sowie Parity sind korrekt eingestellt) Was mach ich falsch?
Gast
#1558933
Die IDE zeigt Dir über JTAG an, was rausgegangen sein sollte? Für Analyse der RS232 PC-seitig setze ich das hier ein: http://www.serial-port-monitor.com/Download/free-serial-port-monitor.exe Der klemmt sich zwischen Anwendung und WindowsTreiber. Ab und an hängt er bei mir die komplette Kiste weg, aber ist halt so :( Ansonsten würde ich mal das Demoboard unter die Lupe nehmen: geht der UART 1 auch auf Pegelwandler? Nicht, daß der TTL ausgibt. Müssen da Lötbrücken (um-)gesetzt werden? Ich kenn Dein Board halt nicht - ich selbst nehme ein IAR-Kit mit IAR IDE.
CRL und CRH sind mit 0x44444444 vorbelegt, nicht mit 0. Daher wird CRH |= ... nicht zum gewünschten Ergebnis führen.
Gast
#1559078
Da hat A.K. vollkommen recht! Ich hab das bei mir in einer Funktion gekapselt, in der ich dann die betreffenden 4 Bits ausnulle, bevor ich eine neue Bitmaske reinschreibe. Hab ich im Pseudocode unterschlagen. Mea culpa ;) Somit muss es heissen:
1 | |
2 | |
3 | |
4 | |
habe hoffentlich keinen neuen Fehler eingebaut.
Arne schrieb:
> habe hoffentlich keinen neuen Fehler eingebaut.
Doch.
Erstens stimmen die Shiftcounts nicht, 4/4/8/8 statt 4/8/4/8 wäre
richtig.
Zweitens kriegst du einen Zwischenzustand von 0 (analog input), der bei
rein digitalen Pins möglicherweise nicht definiert ist. Besser:
CRH = CRH & ~(...) | ...;
Gast
#1559220
@A.K.: da ich weiß, daß Du hier Korrektur liest, muß ich nicht alles beachten ;) Hast natürlich recht ;)
1 | |
2 | |
Das 'Ausnullen' und neu Setzen der vier Bits mache ich in meiner Lib über eine lokale Variable und schreibe die dann komplett als uint32_t am Ende zurück.
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.