2014-07-28 05:07 AM
Good afternoon, I am trying to init UART5 on STM32L152 and it is work wrong.
In the end of thesw_uart5_init
function0xAA (0b10101010) value issent to the UART5 data register. The transmission result, registred with osciloscope not same as value sent to the data register. Can you find a mistake in the code or give me some workaround how to solve this problem?
I'm really appreciate your help. PS. The same deal with DMA, corrupted data.void
sw_uart5_init(
void
)
{
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC|RCC_AHBPeriph_GPIOD, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5, ENABLE);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource12, GPIO_AF_UART5);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource2, GPIO_AF_UART5);
// Configure GPIO pin : PD0 -> WS-VEN; PD1 -> WS-FC
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_400KHz;
GPIO_Init(GPIOD, &GPIO_InitStruct);
//PC12 ------> UART5_TX
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_40MHz;
GPIO_Init(GPIOC, &GPIO_InitStruct);
//PD2 ------> UART5_RX
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOD, &GPIO_InitStruct);
USART_InitTypeDef USART_InitStruct;
USART_InitStruct.USART_BaudRate = 1200;
USART_InitStruct.USART_WordLength = USART_WordLength_8b;
USART_InitStruct.USART_StopBits = USART_StopBits_1;
USART_InitStruct.USART_Parity = USART_Parity_No ;
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(UART5, &USART_InitStruct);
USART_Cmd(UART5, ENABLE);
while
(USART_GetFlagStatus(UART5, USART_FLAG_TC) == RESET);
USART_SendData(UART5,0xaa);
}
#stm32l152 #uart
2014-07-28 06:27 AM
Doesn't look unreasonable, there is a START bit, and the data is sent LSB first.
You are measuring two bit times. If that's wrong review how you are clocking the device, the external crystal, and HSE_VALUE definition. You should wait on TXEwhile
(USART_GetFlagStatus(UART5, USART_FLAG_TXE) == RESET);
2014-07-29 03:33 AM
2014-07-29 05:10 AM
Just move the I/O pin initialization lines after the UART initialization.
While the UART is in reset it keeps its output signal in zero, so connecting the I/O MUX at this stage sends this zero to the output pin.
2014-07-29 05:58 AM
void
uart5_init(
void
)
{
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC|RCC_AHBPeriph_GPIOD, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5, ENABLE);
USART_InitTypeDef USART_InitStruct;
USART_InitStruct.USART_BaudRate = 115200;
USART_InitStruct.USART_WordLength = USART_WordLength_8b;
USART_InitStruct.USART_StopBits = USART_StopBits_1;
USART_InitStruct.USART_Parity = USART_Parity_No ;
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(UART5, &USART_InitStruct);
USART_Cmd(UART5, ENABLE);
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;
// PD0 -> WS-VEN; PD1 -> WS-FC
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_400KHz;
GPIO_Init(GPIOD, &GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12;
//PC12 ------> UART5_TX
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_40MHz;
GPIO_Init(GPIOC, &GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2;
//PD2 ------> UART5_RX
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOD, &GPIO_InitStruct);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource12, GPIO_AF_UART5);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource2, GPIO_AF_UART5);
while
(USART_GetFlagStatus(UART5, USART_FLAG_TXE) == RESET);
USART_SendData(UART5, 170 );
}
2014-07-29 06:25 AM
void uart5_init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC|RCC_AHBPeriph_GPIOD, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5, ENABLE);
USART_InitTypeDef USART_InitStruct;
USART_InitStruct.USART_BaudRate = 115200;
USART_InitStruct.USART_WordLength = USART_WordLength_8b;
USART_InitStruct.USART_StopBits = USART_StopBits_1;
USART_InitStruct.USART_Parity = USART_Parity_No ;
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(UART5, &USART_InitStruct);
USART_Cmd(UART5, ENABLE);
while (USART_GetFlagStatus(UART5, USART_FLAG_TXE) == RESET);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource12, GPIO_AF_UART5);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource2, GPIO_AF_UART5);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1; // PD0 -> WS-VEN; PD1 -> WS-FC
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_400KHz;
GPIO_Init(GPIOD, &GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2; //PD2 ------> UART5_RX
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOD, &GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12; //PC12 ------> UART5_TX
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_40MHz;
GPIO_Init(GPIOC, &GPIO_InitStruct);
while (USART_GetFlagStatus(UART5, USART_FLAG_TXE) == RESET);
USART_SendData(UART5, 170 );
}
2014-07-31 12:39 AM
Thanks, fail start delay twisting less and the byte looks good by the oscilloscope.
The problem of receiving bytes on the receiver side was solved by changing HSE_VALUE variable in the ''stm32l1xx.h'' file, simply a real baudrate was wrong. By default it was 8MHz, now it fixed. I have initialized DMA on TX direction from memory to peripherial, and it works, but looks wrong - from array of 10 elements only 8 can be transferred. The last two bytes just lost. I can to create an array with size+2 and all good, but can it work normally? (I have to transfer 185 bytes, so to use interrupt routine is not a good way. )#include ''stm32l1xx.h''
#include ''stm32l1xx_gpio.h''
#include ''stm32l1xx_rcc.h''
#include ''stm32l1xx_tim.h''
#include ''stm32l1xx_dma.h''
#include ''stm32l1xx_usart.h''
#define sw_wsBuff_Size 10
uint8_t sw_vsBuffer[sw_wsBuff_Size];
void
uart5_init(
void
)
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC|RCC_AHBPeriph_GPIOD, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5, ENABLE);
USART_InitTypeDef USART_InitStruct;
USART_InitStruct.USART_BaudRate = 9600;
USART_InitStruct.USART_WordLength = USART_WordLength_8b;
USART_InitStruct.USART_StopBits = USART_StopBits_1;
USART_InitStruct.USART_Parity = USART_Parity_No ;
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(UART5, &USART_InitStruct);
USART_Cmd(UART5, ENABLE);
USART_DMACmd(UART5, USART_DMAReq_Tx, ENABLE);
while
(USART_GetFlagStatus(UART5, USART_FLAG_TXE) == RESET);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource12, GPIO_AF_UART5);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource2, GPIO_AF_UART5);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;
// PD0 -> WS-VEN; PD1 -> WS-FC
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_400KHz;
GPIO_Init(GPIOD, &GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2;
//PD2 ------> UART5_RX
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOD, &GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12;
//PC12 ------> UART5_TX
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_40MHz;
GPIO_Init(GPIOC, &GPIO_InitStruct);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = DMA2_Channel1_IRQn ;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = DMA2_Channel2_IRQn ;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);
DMA_InitTypeDef dma;
DMA_DeInit(DMA2_Channel1);
dma.DMA_PeripheralBaseAddr = (uint32_t)&UART5->DR;
dma.DMA_MemoryBaseAddr = (uint32_t)&sw_vsBuffer;
dma.DMA_DIR = DMA_DIR_PeripheralDST;
dma.DMA_BufferSize = 10;
dma.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
dma.DMA_MemoryInc = DMA_MemoryInc_Enable;
dma.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
dma.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
dma.DMA_Mode = DMA_Mode_Normal;
dma.DMA_Priority = DMA_Priority_VeryHigh;
dma.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA2_Channel1, &dma);
// Enable DMA Stream Transfer Complete interrupt
DMA_ITConfig(DMA2_Channel1, DMA_IT_TC, ENABLE);
// Enable the USART Tx DMA request
USART_DMACmd(UART5, USART_DMAReq_Tx, ENABLE);
// Enable the DMA RX Stream
DMA_Cmd(DMA2_Channel1, ENABLE);
}
void
DMA2_Channel1_IRQHandler(
void
)
{
if
(DMA_GetITStatus(DMA2_IT_TE1))
{
DMA_ClearITPendingBit( DMA2_IT_TE1 );
DMA_ITConfig(DMA2_Channel1, DMA_IT_TC, DISABLE);
DMA_ITConfig(DMA2_Channel1, DMA_IT_HT, DISABLE);
DMA_ITConfig(DMA2_Channel1, DMA_IT_TE, DISABLE);
DMA_DeInit(DMA2_Channel1);
USART_DeInit(UART5);
}
if
(DMA_GetITStatus(DMA2_IT_TC1))
{
DMA_ClearITPendingBit( DMA2_IT_TC1);
DMA_ITConfig(DMA2_Channel1, DMA_IT_TC, DISABLE);
DMA_ITConfig(DMA2_Channel1, DMA_IT_HT, DISABLE);
DMA_ITConfig(DMA2_Channel1, DMA_IT_TE, DISABLE);
DMA_DeInit(DMA2_Channel1);
USART_DeInit(UART5);
}
if
(DMA_GetITStatus(DMA2_IT_HT1))
{
DMA_ClearITPendingBit( DMA2_IT_HT1);
}
}
2014-07-31 01:22 AM
Now all works good. All bytes is sent propertly. The mistake was in UART5 deinitialization from interrupt, it can stop UART before last data sent .
#include ''stm32l1xx.h''
#include ''stm32l1xx_gpio.h''
#include ''stm32l1xx_rcc.h''
#include ''stm32l1xx_tim.h''
#include ''stm32l1xx_dma.h''
#include ''stm32l1xx_usart.h''
#define UART5_BAUDRATE 9600
#define UART5_DR_ADDRESS ((uint32_t)0x40005004)
#define sw_wsBytesToSend 8
#define sw_wsBuff_Size sw_wsBytesToSend+2
uint8_t sw_vsBuffer[sw_wsBuff_Size];
void
uart5_init(
void
)
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC|RCC_AHBPeriph_GPIOD, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5, ENABLE);
USART_InitTypeDef USART_InitStruct;
USART_InitStruct.USART_BaudRate = UART5_BAUDRATE;
USART_InitStruct.USART_WordLength = USART_WordLength_8b;
USART_InitStruct.USART_StopBits = USART_StopBits_1;
USART_InitStruct.USART_Parity = USART_Parity_No ;
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(UART5, &USART_InitStruct);
USART_Cmd(UART5, ENABLE);
USART_DMACmd(UART5, USART_DMAReq_Tx, ENABLE);
while
(USART_GetFlagStatus(UART5, USART_FLAG_TXE) == RESET);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource12, GPIO_AF_UART5);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource2, GPIO_AF_UART5);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;
// PD0 -> WS-VEN; PD1 -> WS-FC
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_400KHz;
GPIO_Init(GPIOD, &GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2;
//PD2 ------> UART5_RX
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOD, &GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12;
//PC12 ------> UART5_TX
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_40MHz;
GPIO_Init(GPIOC, &GPIO_InitStruct);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = DMA2_Channel1_IRQn ;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = DMA2_Channel2_IRQn ;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);
DMA_InitTypeDef dma;
DMA_DeInit(DMA2_Channel1);
dma.DMA_PeripheralBaseAddr = (uint32_t)&UART5->DR;
dma.DMA_MemoryBaseAddr = (uint32_t)&sw_vsBuffer;
dma.DMA_DIR = DMA_DIR_PeripheralDST;
dma.DMA_BufferSize = sw_wsBuff_Size;
dma.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
dma.DMA_MemoryInc = DMA_MemoryInc_Enable;
dma.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
dma.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
dma.DMA_Mode = DMA_Mode_Normal;
dma.DMA_Priority = DMA_Priority_VeryHigh;
dma.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA2_Channel1, &dma);
// Enable DMA Stream Transfer Complete interrupt
DMA_ITConfig(DMA2_Channel1, DMA_IT_TC, ENABLE);
// Enable the USART Tx DMA request
USART_DMACmd(UART5, USART_DMAReq_Tx, ENABLE);
// Enable the DMA RX Stream
DMA_Cmd(DMA2_Channel1, ENABLE);
}
void
DMA2_Channel1_IRQHandler(
void
)
{
if
(DMA_GetITStatus(DMA2_IT_TE1))
{
DMA_ClearITPendingBit( DMA2_IT_TE1 );
DMA_ITConfig(DMA2_Channel1, DMA_IT_TC, DISABLE);
DMA_ITConfig(DMA2_Channel1, DMA_IT_HT, DISABLE);
DMA_ITConfig(DMA2_Channel1, DMA_IT_TE, DISABLE);
DMA_DeInit(DMA2_Channel1);
}
if
(DMA_GetITStatus(DMA2_IT_TC1))
{
DMA_ClearITPendingBit( DMA2_IT_TC1);
DMA_ITConfig(DMA2_Channel1, DMA_IT_TC, DISABLE);
DMA_ITConfig(DMA2_Channel1, DMA_IT_HT, DISABLE);
DMA_ITConfig(DMA2_Channel1, DMA_IT_TE, DISABLE);
DMA_DeInit(DMA2_Channel1);
}
if
(DMA_GetITStatus(DMA2_IT_HT1))
{
DMA_ClearITPendingBit( DMA2_IT_HT1);
}
}
2014-07-31 09:37 AM
Now all works good. All bytes is sent propertly. The mistake was in UART5 deinitialization from interrupt, it can stop UART before last data sent.
Glad you got it all figured out. Yes, TC on the DMA says it gave last byte to UART, you'd need to wait for TC on the UART to know when the last bit hit the wire.