cancel
Showing results for 
Search instead for 
Did you mean: 

Can't get anything onto TX line with USART

george
Associate
Posted on February 12, 2016 at 10:18

Hi,

I'm using the STM32L053R8 on a Nucelo (L053R8) board and I can't seem to get anything on the TX line. It doesn't even get pulled high as you'd expect from the USART module before any transmission. I have the pin set correctly (as far as I can tell) but my oscilloscope hooked up to the TX pin has it at 0V at all times. Below is my full code. Note that I'm using MikroC for ARM however, aside from a few GPIO functions everything USART related involves direct register addressing so it should be pretty easy to follow if you aren't used to MikroC. Any help would be greatly appreciated. Cheers.


void main(){


// ------------------------- GPIO Control -------------------------- \\


// Set PORTA as digital output

GPIO_Digital_Output(&GPIOA_BASE, _GPIO_PINMASK_5); //Set LED as output

GPIO_Digital_Output(&GPIOA_BASE, _GPIO_PINMASK_2);

GPIO_Config(&GPIOA_BASE, _GPIO_PINMASK_2, _GPIO_CFG_PULL_UP);


// ------------------------- Clock Control ------------------------- \\


RCC_CR.PLLON = 0; // Disable PLL

RCC_CR.MSION = 1; // Enable MSI clock

// Set MSI clock to 5288 kHz

RCC_ICSCR.MSIRANGE0 = 1;

RCC_ICSCR.MSIRANGE1 = 1;

RCC_ICSCR.MSIRANGE2 = 0;

// Use MSI as system clock

RCC_CFGR.SW0 = 0;

RCC_CFGR.SW1 = 0;

RCC_CFGR.HPRE3 = 0; // AHB Prescaler - System Clock not divided: HCLK = System Clock = MSI = 0.524288 MHz

// Set APB2 prescar to 2: PCLK2 = HCLCK/2 = 0.262144 Mhz

RCC_CFGR.PPRE20 = 0;

RCC_CFGR.PPRE21 = 0;

RCC_CFGR.PPRE22 = 1;

// Set APB1 prescar to 2: PCLK1 = HCLCK/2 = 0.262144 Mhz

RCC_CFGR.PPRE10 = 0;

RCC_CFGR.PPRE11 = 0;

RCC_CFGR.PPRE12 = 1;

// Now enable peripheral clocks

RCC_IOPENR = 0b101; // Enable clock on PORTC & PORTA

RCC_IOPSMEN = 0b100; // Enable clock on PORTC & PORTA during sleep mode

RCC_APB2ENR.SYSCFGEN = 1; // Enable Peripheral Clock on SYSCFGEN (System configuration controller clock) - APB2 (0.262144 Mhz)

RCC_APB1ENR.USART2EN = 1; // Enable clock on USART2 - APB1 (0.262144 Mhz)


// ----------------------------- USART ----------------------------- \\


USART2_CR2 = 0;

USART2_CR3 = 0;


// Set USART2 clock as PCLK1 = 0.262144 Mhz

RCC_CCIPR.USART2SEL0 = 0;

RCC_CCIPR.USART2SEL1 = 0;


//Set USART2 Baudrate to 9600 with oversampling to 16

USART2_BRR = 0x1B; // 262144 / 9600 = 27 = 0x1B

USART2_CR1.OVER8 = 0;


// Set PORTA.2 as USART2-TX - Alternate Function 4

GPIOA_AFRL.AFSEL20 = 0;

GPIOA_AFRL.AFSEL21 = 0;

GPIOA_AFRL.AFSEL22 = 1;

GPIOA_AFRL.AFSEL23 = 0;

// Set PORTA.2 as USART2-RX - Alternate Function 4

GPIOA_AFRL.AFSEL30 = 0;

GPIOA_AFRL.AFSEL31 = 0;

GPIOA_AFRL.AFSEL32 = 1;

GPIOA_AFRL.AFSEL33 = 0;

// Configure USART word length (8), parity (none) and stop bits (1)

USART2_CR1.M0 = 0;

USART2_CR1.M1 = 0;

USART2_CR1.PCE = 0;

USART2_CR2.STOP0 = 0;

USART2_CR2.STOP1 = 0;

//Disable Flow Control

USART2_CR3.CTSE = 0;

USART2_CR3.RTSE = 0;

// Enable USART2 Module

USART2_CR1.UE = 1;

// Enable TX

USART2_CR1.TE = 1;


// Transmit some data

while(USART2_ISR.TXE == 0);

USART2_TDR = 'a';

while(USART2_ISR.TXE == 0);


// ----------------------- Main Program ---------------------------- \\


while(1){

GPIOA_ODR = 0b0000000000100000;

delay_ms(2000);

GPIOA_ODR = 0b0000000000000000;

delay_ms(2000);

}

}

#usart #stm32 #tx #transmission
1 REPLY 1
re.wolff9
Senior
Posted on February 12, 2016 at 10:27

My first thought is that you're forgetting to enable the clock to the GPIO port or forgetting to set the AF for the pin. 

As you are stuffing the bits directly into the registers, your code is difficult to read without having the reference manual next to your keyboard and looking everything up. 

To debug this: try and get a led to blink. i.e. select output PUSHPULL for the tx pin and make the pin high and low and wait 0.5 seconds inbetween. 

Also, read back the values in the registers in the  GPIO port into a variable and view that variable in a debugger. If all values come back zero, you didn't manage to enable the clock. Same for the uart module. 

Also, dumping ALL registers in a peripheral and checking each and every one with the reference manual is useful. Then you'll often find what's wrong.