1
\$\begingroup\$

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 USART2_read(void);

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 */
int USART2_read(void) {
    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

enter image description here enter image description here

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;
}
\$\endgroup\$
  • 1
    \$\begingroup\$ 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. \$\endgroup\$ – Chris Stratton Mar 2 at 18:34
  • 1
    \$\begingroup\$ 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. \$\endgroup\$ – Dave Tweed Mar 2 at 19:28
  • \$\begingroup\$ 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 \$\endgroup\$ – Athul Mar 2 at 20:52
  • \$\begingroup\$ 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. \$\endgroup\$ – Chris Stratton Mar 2 at 21:34
  • \$\begingroup\$ @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 \$\endgroup\$ – Athul Mar 3 at 9:28
1
\$\begingroup\$

PA2 and PA3 are connected to some peripherals on the board. In particular PA2, which would be used as USART2_TX in your program, is connected to the output of the L3GD20 motion sensor. Setting the pin as output on the MCU may already have damaged the sensor or the MCU.

The easyest way to find some unused pins is to load the board in STM32CubeMX, and find a port in the pinout view that has no warning sign next to it.

I recall someone having a similar problem some time ago.

\$\endgroup\$
  • 1
    \$\begingroup\$ Okay, CubeMX generated code didn't work for UART2 but it did work for UART5. From CubeMX STM32F429ZI DISC1 pin out, only free pins that have UART capability is PD2 and PC12 (UART5). So far CubeMX code works. I need to check with my code and I will update \$\endgroup\$ – Athul Mar 3 at 11:07
  • \$\begingroup\$ If you had used the examples for this board you would not have had this problem as they would have used free pins for the UART. \$\endgroup\$ – Chris Stratton Mar 3 at 13:59
  • 1
    \$\begingroup\$ @ChrisStratton but now Athul has learned for life to check the board documentation first :) \$\endgroup\$ – berendi Mar 3 at 14:09
  • \$\begingroup\$ @ChrisStrattonI couldn't find example code specific to my board. I could find codes for other board. But if I can't use pins why they provides headers for that pin \$\endgroup\$ – Athul Mar 3 at 17:19
  • 1
    \$\begingroup\$ @Athul the examples for your board are in the STSW-STM32138 download from ST. \$\endgroup\$ – Chris Stratton Mar 3 at 17:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.