0

Having programmed 8-bit AVR MCU's, I bought Blue Pill STM32F103C8 dev board from ebay. It has 8MHz external crystal and I program it with ST-Link on Mac. I saw a lot of options like HAL, etc, but I chose to program using direct access to registers and with core of CMSIS.

My problem is that I am trying to send symbol from MCU to computer. I am using CP2102 module connected to USART1(PB6 and PB7). LEDs are blinking, but I don't get any output in Arduino IDE serial monitor. Here is my code:

#include "stm32f1xx.h"

void delay(unsigned long delay)
{
    while(delay) delay--;
}

int SendChar (int ch)  {
    while (!(USART1->SR & USART_SR_TXE));
    USART1->DR = (ch & 0xFF);
    return (ch);
}

int main(void)
{
    //Enable I2C2 clock
    RCC->APB1ENR |= RCC_APB1ENR_I2C2EN;
    //Enable the clock to PORT B, PORT C, USART1 and AFIO clocks
    RCC->APB2ENR |= RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPCEN |       RCC_APB2ENR_AFIOEN;
    RCC->APB2ENR |= RCC_APB2ENR_USART1EN;

    //use AFIO_MAPR register to remap alternate functions to use USART 1 TX and RX on PB6 and PB7
    //Ref 7.4.2 and 6.3.7 in st manual
    AFIO->MAPR |= AFIO_MAPR_USART1_REMAP;

    //CRL Configures outputs 0 to 7 and CRH 8 to 15, so if you want to configure PC13,
    //you modify GPIOC_CRH register
    GPIOB->CRL |= GPIO_CRL_MODE0_0 | GPIO_CRL_MODE0_1;
    GPIOC->CRH = GPIO_CRH_MODE13_0 | GPIO_CRH_MODE13_1 |
        GPIO_CRH_MODE14_0 | GPIO_CRH_MODE14_1 |
        GPIO_CRH_MODE15_0 | GPIO_CRH_MODE15_1;
    //Set RX as floating in and TX as out push-pull
    GPIOB->CRL &= ~(GPIO_CRL_MODE7_0 | GPIO_CRL_MODE7_1);
    GPIOB->CRL |= GPIO_CRL_MODE7_0 | GPIO_CRL_MODE7_1 | GPIO_CRL_CNF6_0;

    //Enable RX TX
    USART1->CR1 |= (USART_CR1_RE | USART_CR1_TE);  // RX, TX enable
    //Enable USART
    USART1->CR1 |= USART_CR1_UE;
    //Make sure to clear OVER8 bit(15 bit in USART_CR1) to oversample by 16, I dont know if I need this
    USART1->CR1 &= ~(1 << 15);
    ////Configure Baud Rate
    /*USART_BRR = Fck/BAUDRATE*/
    //Set 115200 Baud, 8 MHz crystal
    USART1->BRR = 8000000L/115200L;

    while (1)
    {
        SendChar(35); //Test UART,fingers crossed

        //Toggle led on PB0
        GPIOB->ODR ^= GPIO_ODR_ODR0;

        //Toogle RGB led connected on PC13, PC14 and PC5
        GPIOC->ODR ^= GPIO_ODR_ODR13;
        delay(50000);
        GPIOC->ODR ^= GPIO_ODR_ODR13;
        delay(50000);
        GPIOC->ODR ^= GPIO_ODR_ODR15;
        delay(50000);
    }

    return 0;
}
user112290
  • 151
  • 5
  • 1
    Doing this "the hard way" is hard - there are lots of required steps and any one missing will break it. It would be best if you find (and try) some working code and compare. Read the programmer's manual carefully. It would also be good if you have a scope or even crude USB-based logic analyzer to tell if you are getting any activity, even at the wrong baud rate. – Chris Stratton Mar 25 '18 at 20:49
  • Actually I am getting myselft logic analyzer, it will come next week, so I hope that will help. – user112290 Mar 25 '18 at 20:51
  • So I hooked up both UART pins to logic analyzer and I get absolutely no activity.. – user112290 Mar 27 '18 at 11:26

1 Answers1

4

I have managed to solve problem with the help of cheap USB Logic Analyser and STM32 reference manual. I was setting GPIO pins for USART1 incorrectly, RX needs to be floating input and TX needs to be alternate function output with pull-up/pull-down. So after changing these lines:

 GPIOB->CRL &= ~(GPIO_CRL_MODE7_0 | GPIO_CRL_MODE7_1);
 GPIOB->CRL |= GPIO_CRL_MODE7_0 | GPIO_CRL_MODE7_1 | GPIO_CRL_CNF6_0;

To:

GPIOB->CRL |= GPIO_CRL_MODE6_1 | GPIO_CRL_CNF6_1 | GPIO_CRL_CNF7_0;

I can see character being sent with logic analyzer hooked up and also can observe it on arduino serial monitor.

user112290
  • 151
  • 5