# STM32F429ZI DISC1 Register level code USART

I'm learning to program STM32F4 micro-controller using a UDEMY course. It covers GPIO, SPI, I2C and and UART register level programming. So far I have only been able to make GPIO code work. For communication protocols like SPI & I2c it uses two development board. The course is done on STM32F407 DISCovery board.

I am using a different board than the one used in the course, STM32F429ZI DISC1

Both controller have same Reference manual. Only difference i could find is pins, and RCC control register. So code developed for STM32F407 should work in STM32F429ZI controller with little difference. But I couldn't make SPI code work in my board. So i decided to write UART code , so that I can use it on SPI code for debugging. But UART code is also not working.

Google drive contains all the documents and code that I developed for SPI and UART. Once I could figure out why UART is not working I think I could use that in SPI code to figure out the issue.

I also tried following code that I found online, it also use STM32F4xx series controller but not the same as mine. It is not working too.

/* p4_5.c C library Console I/O using USART2 at 9600 Baud
*
* This program demonstrates the use of C library console I/O.
* The functions fputc() and fgetc() are implemented using
* USART2_write() and USART2_read() for character I/O.
* In the fgetc(), the received character is echoed and if a '\r'
* is received, a pair of '\r', '\n' is echoed.
* In fputc() and fgetc(), the file descripter is not checked. All
* file I/O's are directed to the console.
*
* By default, the clock is running at 16 MHz.
* The USART is configured for 9600 Baud.
* PA2 - USART2 TX (AF7)
* PA3 - USART2 RX (AF7)
* Use Tera Term on the host PC to send keystrokes and observe the display
* of the characters echoed.
*
* This program was tested with Keil uVision v5.24a with DFP v2.11.0
*/
#include "stm32F4xx.h"
#include <stdio.h>

void USART2_init(void);
void delayMs(int);
void USART2_write(int c);

int main(void) {
int n;
char str[80];

USART2_init();
USART2_write('c');

while (1) {

}
}

/* initialize USART2 to transmit at 9600 Baud */
void USART2_init (void) {
RCC->AHB1ENR |= 1;          /* Enable GPIOA clock */
RCC->APB1ENR |= 0x20000;    /* Enable USART2 clock */

/* Configure PA2, PA3 for USART2 TX, RX */
GPIOA->AFR[0] &= ~0xFF00;
GPIOA->AFR[0] |=  0x7700;   /* alt7 for USART2 */
GPIOA->MODER  &= ~0x00F0;
GPIOA->MODER  |=  0x00A0;   /* enable alt. function for PA2, PA3 */

USART2->BRR = 0x0683;       /* 9600 baud @ 16 MHz */
USART2->CR1 = 0x000C;       /* enable Tx, Rx, 8-bit data */
USART2->CR2 = 0x0000;       /* 1 stop bit */
USART2->CR3 = 0x0000;       /* no flow control */
USART2->CR1 |= 0x2000;      /* enable USART2 */
}

/* Write a character to USART2 */
void USART2_write (int ch) {
while (!(USART2->SR & 0x0080)) {}   // wait until Tx buffer empty
USART2->DR = (ch & 0xFF);
//return ch;
}

/* Read a character from USART2 */
while (!(USART2->SR & 0x0020)) {}   // wait until char arrives
return USART2->DR;
}


I am using this USB TTL to connect b/m board and PC and mobaXterm as terminal

these are the terminal settings and connection diagram. I checked the working of USB ttil by using AVR code

IDE: Keil uVision 5.27

EDIT:

Following code transmit a single byte of data UART5

/* UART5 at 9600 Baud
* By default, the clock is running at 16 MHz.
* The USART is configured for 9600 Baud.
* PC12 - UART5 TX (AF8)
* PD2 - UART5 RX (AF8)

*/
#include "stm32F429xx.h"
#include <stdio.h>

void UART5_init(void);
void UART5_write(int c);

int main(void) {
int n;
char str[80];

UART5_init();
//USART2_write('c');

while (1) {
UART5_write('c');
for(int i = 0; i < 500000; i++);
}
}

/* initialize UART5 to transmit at 9600 Baud */
void UART5_init (void) {
RCC->AHB1ENR |= ( (1 << 2) | (1 << 3) );          /* Enable GPIOC & GPIOD clock */
RCC->APB1ENR |= (1 << 20);    /* Enable UART5 clock */

/* Configure PA2, PA3 for USART2 TX, RX */
GPIOC->AFR[1] &= ~((0xF) << 16);
GPIOC->AFR[1] |=  ((0x8) << 16);   /* alt8 for UART5 */
GPIOC->MODER  &= ~((0x3) << 24);
GPIOC->MODER  |=  ((0x2) << 24);   /* enable alt. function for PC12 */

GPIOD->AFR[0] &= ~((0xF) << 8);
GPIOD->AFR[0] |=  ((0x8) << 8);   /* alt8 for UART5 */
GPIOD->MODER  &= ~((0x3) << 4);
GPIOD->MODER  |=  ((0x2) << 4);   /* enable alt. function for PD2 */

UART5->BRR = 0x0683;       /* 9600 baud @ 16 MHz */
UART5->CR1 = 0x000C;       /* enable Tx, Rx, 8-bit data */
UART5->CR2 = 0x0000;       /* 1 stop bit */
UART5->CR3 = 0x0000;       /* no flow control */
UART5->CR1 |= 0x2000;      /* enable UART5 */
}

/* Write a character to USART2 */
void UART5_write (int ch) {
while (!(UART5->SR & 0x0080)) {}   // wait until Tx buffer empty
UART5->DR = (ch & 0xFF);
//return ch;
}

• Sorry, but "not working" and a link to code somewhere does not meet the requirements for a question here. You should probably first test the setup with an STM32 HAL based example for your specific board, then spend enough time going through the actual HAL sources to understand what that is doing differently from your bare register code. You do likely need a build for your specific board - things like clock ranges and which peripherals and how much memory is present changes across the family and chip variant. – Chris Stratton Mar 2 '19 at 18:34
• You need to provide an MCVE, as well as explain exactly what the difference is between what you expect to happen and what actually happens. – Dave Tweed Mar 2 '19 at 19:28
• I have compiled and uploaded the code in the post(not from the Driver link) to the development board, but it is not transmitting any data to terminal. I also tried to debug the code using stlink, and from my limited knowledge, when I opened the UART2 peripheral in the debug window and checked the contents of data register, it's not changing. As you can see in the added code. I'm just trying to transmit a single byte – Athul Mar 2 '19 at 20:52
• At the least move the transmit into the while loop so it repeats. And if you refuse to try HAL code first you are going to have to pour through the reference manual yourself to figure out what you missed, and find a scope to see if you might be generating some outpu but with wrong details. You shouldn't expect to see much with a debugger unless perhaps that execution is getting stuck somewhere unexpected. – Chris Stratton Mar 2 '19 at 21:34
• @ChrisStratton I have tried a CubeMX code from this video. video is done for some other board of same family. Only difference I made is Baud rate 9600, Internal RX oscillator and USART2. I tried to send one character as shown in the video, it's not working as well – Athul Mar 3 '19 at 9:28