cancel
Showing results for 
Search instead for 
Did you mean: 

RX and reTX from USART1 with dma (Stm32f100B)

Gigli.Dario
Associate II
Posted on February 07, 2013 at 01:53

Hi,

excuse me for my bad english,I'm new in the microcontrollers field, so I've some uncertainty on the use of the dma to read and write from USART. At the moment I'm interfacing the stm32f100B with a medical module that trasmittes continuosly datas, so I need reading these datas and to retransmit it by USART1.

I have written a code that reads the datas from USART and retransmittes it, this code works but it is without dma.

But now I need to use the dma to read and write data from USART, so I have written another code with dma but I don't understand where is the error and if I use dma in correct mode, because I don't receive nothing. 

My code is this:

#include ''stm32f10x_conf.h'' 

#include ''stm32f10x.h''

#include ''stm32f10x_dma.h''

#include ''stm32f10x_dma.c''

#include ''stm32f10x_usart.h''

#include ''stm32f10x_usart.c''

#include ''stm32f10x_rcc.c''

#include ''platform_config.h''

uint8_t buffer;

int k=0;

void board_init(void) {

    RCC->APB2ENR = 0

                   // Turn on USART1

                   | RCC_APB2ENR_USART1EN

                   // Turn on IO Port A

                   | RCC_APB2ENR_IOPAEN;

    // Put PA9  (TX) to alternate function output push-pull at 50 MHz

    // Put PA10 (RX) to floating input

    GPIOA->CRH = 0x000004B0;

    // Configure BRR by deviding the bus clock with the baud rate

    USART1->BRR = 8000000/9600;

    // Enable the USART, TX, and RX circuit

    USART1->CR1 = USART_CR1_UE | USART_CR1_TE | USART_CR1_RE;

}

// DMA_configuration

void DMA_Configuration(void)

{

  DMA_InitTypeDef DMA_InitStructure;

  /* USARTy TX DMA1 Channel (triggered by USARTy Tx event) Config */

  DMA_DeInit(USARTy_Tx_DMA_Channel);  

  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART1->DR;

  DMA_InitStructure.DMA_MemoryBaseAddr =buffer;

  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;

  DMA_InitStructure.DMA_BufferSize = 1;

  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;

  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;

  DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;

  DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;

  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

  DMA_Init(USARTy_Tx_DMA_Channel, &DMA_InitStructure);

  /* USARTy RX DMA1 Channel (triggered by USARTy Rx event) Config */

  DMA_DeInit(USARTy_Rx_DMA_Channel);  

  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART1->DR;

  DMA_InitStructure.DMA_MemoryBaseAddr = buffer;

  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;

  DMA_InitStructure.DMA_BufferSize = 1;

  DMA_Init(USARTy_Rx_DMA_Channel, &DMA_InitStructure);

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

   /* Enable USARTy TX DMA1 Channel */

  DMA_Cmd(USARTy_Tx_DMA_Channel, ENABLE);

  /* Enable USARTy RX DMA1 Channel */

  DMA_Cmd(USARTy_Rx_DMA_Channel, ENABLE);

    /* Enable USARTy DMA Rx and TX request */

  /* Enable USARTy DMA Rx and TX request */

  USART_DMACmd(USARTy, USART_DMAReq_Rx | USART_DMAReq_Tx, ENABLE);

}

//

/**

 * Receive a single byte from USART1.

 */

int usartdma_rec(void) {

/* Wait until USARTy RX DMA1 Channel Transfer Complete */

  while (DMA_GetFlagStatus(USARTy_Rx_DMA_FLAG) == RESET);

    // read RX data, combine with DR mask (we only accept a max of 9 Bits)

    return USART1->DR & 0x1FF;

}

//Send a single byte by USART1. 

void usartdma_snd(int data) {

    USART1->DR = data;

/* Wait until USARTy TX DMA1 Channel Transfer Complete */

  while (DMA_GetFlagStatus(USARTy_Tx_DMA_FLAG) == RESET);

}

  

int main(void) {

    board_init();

DMA_Configuration();

    for(;;) {

      int rec=usartdma_rec();

      buffer=rec;

  

usartdma_snd(buffer);

  

    }

}

12 REPLIES 12
Posted on February 07, 2013 at 03:14

You must enable the clock on the DMA unit BEFORE you program it. Synchronous devices need clocks else they don't function.

Bunch of defines not expressed so can't determine if they look right or not.

The buffering looks totally bogus, the address is &buffer not buffer, doing a single byte is pointless, you'd need to setup the DMA transfer every time, and it would be less efficient than just using interrupts. Ideally you'd get DMA to TX dozens of bytes.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Gigli.Dario
Associate II
Posted on February 07, 2013 at 10:26

Thank you for your immediate response, I have tried to use a buffer with a single byte only to see if it working or not, but I know that this mode is inefficient. So I have done the corrections that you say me, and I hope to have understood well. But it doesn't reTX nothing , and there is a Warning:

Warning[Pe047]: incompatible redefinition of macro ''FLAG_Mask'' (declared at line 64 of ''C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.4...

Moreover now I use a buffer of 6 byte, and the code modified is this:

#include ''stm32f10x_conf.h'' 

#include ''stm32f10x.h''

#include ''stm32f10x_dma.h''

#include ''stm32f10x_dma.c''

#include ''stm32f10x_usart.h''

#include ''stm32f10x_usart.c''

#include ''stm32f10x_rcc.c''

#include ''platform_config.h''

#define BufferSize   6

char buffer[6];

int k=6;

void board_init(void) {

    RCC->APB2ENR = 0

                   // Turn on USART1

                   | RCC_APB2ENR_USART1EN

                   // Turn on IO Port A

                   | RCC_APB2ENR_IOPAEN;

    // Put PA9  (TX) to alternate function output push-pull at 50 MHz

    // Put PA10 (RX) to floating input

    GPIOA->CRH = 0x000004B0;

    // Configure BRR by deviding the bus clock with the baud rate

    USART1->BRR = 8000000/9600;

    // Enable the USART, TX, and RX circuit

    USART1->CR1 = USART_CR1_UE | USART_CR1_TE | USART_CR1_RE;

}

// DMA_configuration

void DMA_Configuration(void)

{

  

      RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

   

  DMA_InitTypeDef DMA_InitStructure;

  /* USARTy TX DMA1 Channel (triggered by USARTy Tx event) Config */

  DMA_DeInit(USARTy_Tx_DMA_Channel);  

  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART1->DR;

  DMA_InitStructure.DMA_MemoryBaseAddr =(uint32_t) &buffer;

  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;

  DMA_InitStructure.DMA_BufferSize = BufferSize;

  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;

  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;

  DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;

  DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;

  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

  DMA_Init(USARTy_Tx_DMA_Channel, &DMA_InitStructure);

  /* USARTy RX DMA1 Channel (triggered by USARTy Rx event) Config */

  DMA_DeInit(USARTy_Rx_DMA_Channel);  

  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART1->DR;

  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;

  DMA_InitStructure.DMA_MemoryBaseAddr =(uint32_t) &buffer;

  DMA_InitStructure.DMA_BufferSize = BufferSize ;

  DMA_Init(USARTy_Rx_DMA_Channel, &DMA_InitStructure);

/* Enable USARTy TX DMA1 Channel */

  DMA_Cmd(USARTy_Tx_DMA_Channel, ENABLE);

  /* Enable USARTy RX DMA1 Channel */

  DMA_Cmd(USARTy_Rx_DMA_Channel, ENABLE);

    /* Enable USARTy DMA Rx and TX request */

  /* Enable USARTy DMA Rx and TX request */

  USART_DMACmd(USARTy, USART_DMAReq_Rx | USART_DMAReq_Tx, ENABLE);

}

//

/**

 * Receive a single byte from USART1. This call blocks

 */

int usartdma_rec(void) {

/* Wait until USARTy RX DMA1 Channel Transfer Complete */

  while (DMA_GetFlagStatus(USARTy_Rx_DMA_FLAG) == RESET);

    // read RX data, combine with DR mask (we only accept a max of 9 Bits)

    return USART1->DR & 0x1FF;

}

//Receive a single byte from USART1. This call blocks

void usartdma_snd(int data) {

    USART1->DR = data;

/* Wait until USARTy TX DMA1 Channel Transfer Complete */

  while (DMA_GetFlagStatus(USARTy_Tx_DMA_FLAG) == RESET);

}

  

int main(void) {

    board_init();

DMA_Configuration();

    for(;;) {

      int rec=usartdma_rec();  

if (k<=6)        

{buffer[k]=rec;

k++;

}

     else

    

    {       

    

      for (int f=0; f<=6 ; f++ )

    {usartdma_snd(buffer[f]);}

      k=0;

            buffer[k]=rec;

            k++;

    }

  

    }

}

Thank you for your help, but I'm very down because I have been tried to do it for 2 day and I need to it working because this is a part of the my Degree's argument.

Posted on February 07, 2013 at 13:11

For an array either buffer or &buffer[0] ie the address of element zero

DMA_InitStructure.DMA_MemoryBaseAddr =(uint32_t) &buffer[0];

for ''char buffer;'' then DMA_InitStructure.DMA_MemoryBaseAddr =(uint32_t) &buffer;

for ''char *buffer;'' then DMA_InitStructure.DMA_MemoryBaseAddr =(uint32_t) buffer;

for ''char buffer[1];'' then DMA_InitStructure.DMA_MemoryBaseAddr =(uint32_t) buffer; // or &buffer[0]

Review C pointers

usartdma_rec() and usartdma_snd() are just all wrong, you shouldn't be touching USARTx->DR. DMA doesn't work like this, and the transfer needs to be set up each time you repeat it.

There is a code pasting tool, see ''paint brush [<>]'' icon, this also can enable line numbering. I can't see defines you don't provide. Using the correct channels is critical.

I posted this F1 USART DMA Tx example a while back

https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=https%3a//my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/STM32%20USART2%20per%20DMA%20Problem&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B&currentviews=114...

Using DMA for RX is beyond your level at this point. What are the drivers for using DMA here, say vs interrupts?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Gigli.Dario
Associate II
Posted on February 07, 2013 at 21:03

Thank you for your patience, I'm very confused on the dma so I have to study it before to use it. So I have tried to use USART with interrupt for the same purpose, rx in a buffer e after tx when the buffer is full or when a terminator character arrives. This is the code:

#include ''stm32f10x_conf.h'' 

#include ''stm32f10x.h''

#include ''misc.h''

#include ''misc.c''

#include ''stm32f10x_usart.h''

#include ''stm32f10x_usart.c''

#include ''stm32f10x_rcc.h''

#include ''stm32f10x_gpio.h''

#include ''stm32f10x_rcc.c''

#include ''stm32f10x_gpio.c''

#define MAX_STRLEN 12 // this is the maximum string length of our string in characters

volatile char received_string[MAX_STRLEN+1]; // this will hold the recieved string

void Delay(__IO uint32_t nCount) {

  while(nCount--) {

  }

}

/* This funcion initializes the USART1 peripheral

 *

 * Arguments: baudrate --> the baudrate at which the USART is

 *   supposed to operate

 */

void init_USART1(uint32_t baudrate){

GPIO_InitTypeDef GPIO_InitStruct; // this is for the GPIO pins used as TX and RX

USART_InitTypeDef USART_InitStruct; // this is for the USART1 initilization

NVIC_InitTypeDef NVIC_InitStructure; // this is used to configure the NVIC (nested vector interrupt controller)

/* enable APB2 peripheral clock for USART1

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

/* enable the peripheral clock for the pins used by

* USART1, PA9 for TX and PA10 for RX

*/

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

/* This sequence sets up the TX and RX pins

* so they work correctly with the USART1 peripheral

*/

GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; // Pins 9 (TX) and 10 (RX) are used

GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;

GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;

        GPIO_Init(GPIOA, &GPIO_InitStruct);

/* The RX and TX pins are now connected to their AF

   

I don't undestand this block

* so that the USART1 can take over control of the

* pins

*/

//GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1); //

 

//GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);

USART_InitStruct.USART_BaudRate = baudrate; // the baudrate is set to the value we passed into this init function

USART_InitStruct.USART_WordLength = USART_WordLength_8b;// we want the data frame size to be 8 bits (standard)

USART_InitStruct.USART_StopBits = USART_StopBits_1; // we want 1 stop bit (standard)

USART_InitStruct.USART_Parity = USART_Parity_No; // we don't want a parity bit (standard)

USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // we don't want flow control (standard)

USART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; // we want to enable the transmitter and the receiver

USART_Init(USART1, &USART_InitStruct); // again all the properties are passed to the USART_Init function which takes care of all the bit setting

/* Here the USART1 receive interrupt is enabled

* and the interrupt controller is configured

* to jump to the USART1_IRQHandler() function

* if the USART1 receive interrupt occurs

*/

USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); // enable the USART1 receive interrupt

  NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);   

NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;

// we want to configure the USART1 interrupts

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;// this sets the priority group of the USART1 interrupts

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // this sets the subpriority inside the group

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // the USART1 interrupts are globally enabled

NVIC_Init(&NVIC_InitStructure); // the properties are passed to the NVIC_Init function which takes care of the low level stuff

USART_Cmd(USART1, ENABLE);

}

/* This function is used to transmit a string of characters via

 * the USART specified in USARTx.

 *

 * It takes two arguments: USARTx --> can be any of the USARTs e.g. USART1, USART2 etc.

 *   (volatile) char *s is the string you want to send

void USART_puts(USART_TypeDef* USARTx, volatile char *s){

while(*s){

// wait until data register is empty

while( !(USARTx->SR & 0x00000040) );

USART_SendData(USARTx, *s);

*s++;

}

}

int main(void) {

  init_USART1(9600); // initialize USART1 @ 9600 baud

  USART_puts(USART1, ''Init complete! Hello World!''); // just send a message to indicate that it works

  while (1){

  

  }

}

// this is the interrupt request handler (IRQ) for ALL USART1 interrupts

void USART1_IRQHandler(void){

// check if the USART1 receive interrupt flag was set

if( USART_GetITStatus(USART1, USART_IT_RXNE) ){

static uint8_t cnt = 0; // this counter is used to determine the string length

char t = USART1->DR; // the character from the USART1 data register is saved in t

/* check if the received character is not the LF character (used to determine end of string)

* or the if the maximum string length has been been reached

*/

if( (t != 'n') && (cnt < MAX_STRLEN) ){

received_string[cnt] = t;

cnt++;

}

else{ // otherwise reset the character counter and print the received string

cnt = 0;

USART_puts(USART1, received_string);

}

}

}

I think that the GPIO structure is wrong because I don't undestand the block

GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1); .....

I can to receive the string

''Init complete! Hello World!'', but after if I send characters by Serial I don't receive nothing. Where Do I err??

THANK YOU FOR YOUR HELP!

DARIO

Posted on February 07, 2013 at 21:51

GPIO_PinAFConfig() is something specific to L1, F2, F4 families of STM32 parts, it is not used for the F1 series, ie the F100B you are using.

The Pin configurations doesn't look quite right, the RX needs to be an INPUT, please look at the code I cited.

For an interrupt example review the post I made about 1/3 down the page.

[DEAD LINK /public/STe2ecommunities/mcu/Lists/STM32Discovery/Flat.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/STM32Discovery/STM32F100%20UART%20problem&FolderCTID=0x01200200770978C69A1141439FE559EB459D75800084C20D8867EAD444A5987D47BE638E0F&currentviews=317]https://my.st.com/public/STe2ecommunities/mcu/Lists/STM32Discovery/Flat.aspx?RootFolder=%2Fpublic%2FSTe2ecommunities%2Fmcu%2FLists%2FSTM32Discovery%2FSTM32F100%20UART%20problem&FolderCTID=0x01200200770978C69A1141439FE559EB459D75800084C20D8867EAD444A5987D47BE638E0F¤tviews=317

Calling a multi-byte send routine from the interrupt probably is something I would avoid.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Gigli.Dario
Associate II
Posted on February 07, 2013 at 23:56

Thank you for your help. I have read the example that you advised me, I loaded it on my stm32f100b , and with a converter ttl -rs232 I tried to see what happening with a ''MicroRidge Com Serial'', but I didn't see nothing. Is it right? I don't understend how the interrupt happens if there isn't a external event like for example data sendes by external module to USART.

Can you help me how I have to revise the code for receive characters by Serial and resend when the buffer is full? I have been tried for many hours but I don't really understand what I forget to do.

The code that you give me is this, how do I have to modified it?

#include ''stm32f10x_conf.h'' 

#include ''stm32f10x.h''

#include ''misc.h''  

#include ''misc.c''

#include ''stm32f10x_usart.h''

#include ''stm32f10x_usart.c''

#include ''stm32f10x_rcc.h''

#include ''stm32f10x_gpio.h''

#include ''stm32f10x_rcc.c''

#include ''stm32f10x_gpio.c''

volatile char StringLoop[] = ''The quick brown fox jumps over the lazy dog\r\n'';

 

/**************************************************************************************/

 

void RCC_Configuration(void)

{

  /* Enable GPIO clock */

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

 

  /* Enable UART clock */

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

}

 

/**************************************************************************************/

 

void GPIO_Configuration(void)

{

    GPIO_InitTypeDef GPIO_InitStructure;

 

  /* Configure USART Tx as alternate function push-pull */

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;  // PA.09 USART1.TX

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_Init(GPIOA, &GPIO_InitStructure);

 

  /* Configure USART Rx as input floating */

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; // PA.10 USART1.RX

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

  GPIO_Init(GPIOA, &GPIO_InitStructure);

}

 

/**************************************************************************************/

 

void USART_Configuration(void)

{

  USART_InitTypeDef USART_InitStructure;

 

  /* USART resources configuration (Clock, GPIO pins and USART registers) ----*/

  /* USART configured as follow:

        - BaudRate = 115200 baud

        - Word Length = 8 Bits

        - One Stop Bit

        - No parity

        - Hardware flow control disabled (RTS and CTS signals)

        - Receive and transmit enabled

  */

  USART_InitStructure.USART_BaudRate = 115200;

  USART_InitStructure.USART_WordLength = USART_WordLength_8b;

  USART_InitStructure.USART_StopBits = USART_StopBits_1;

  USART_InitStructure.USART_Parity = USART_Parity_No;

  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

 

  /* USART configuration */

  USART_Init(USART1, &USART_InitStructure);

 

  /* Enable the USART1 */

  USART_Cmd(USART1, ENABLE);

 

  USART_ITConfig(USART1, USART_IT_TXE, ENABLE);

  USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

}

 

/**************************************************************************************/

 

void NVIC_Configuration(void)

{

  NVIC_InitTypeDef NVIC_InitStructure;

 

  /* Configure the NVIC Preemption Priority Bits */

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);

 

  /* Enable the USART1 Interrupt */

  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  NVIC_Init(&NVIC_InitStructure);

}

 

/**************************************************************************************/

 

void USART1_IRQHandler(void)

{

  static int tx_index = 0;

  static int rx_index = 0;

 

  if (USART_GetITStatus(USART1, USART_IT_TXE) != RESET) // Transmit the string in a loop

  {

    USART_SendData(USART1, StringLoop[tx_index++]);

 

    if (tx_index >= (sizeof(StringLoop) - 1))

    {tx_index = 0;}

  }

 

  if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) // Received characters modify string

  {

    StringLoop[rx_index++] = USART_ReceiveData(USART1);

 

    if (rx_index >= (sizeof(StringLoop) - 1))

    {rx_index = 0;}

  }

}

 

/**************************************************************************************/

 

int main(void)

{

  RCC_Configuration();

 

  GPIO_Configuration();

 

  NVIC_Configuration();

 

  USART_Configuration();

  while(1);

}

 

/**************************************************************************************/

 

#ifdef  USE_FULL_ASSERT

/**

  * @brief  Reports the name of the source file and the source line number

  *         where the assert_param error has occurred.

  * @param  file: pointer to the source file name

  * @param  line: assert_param error line source number

  * @retval None

  */

void assert_failed(uint8_t* file, uint32_t line)

{

  /* User can add his own implementation to report the file name and line number,

     ex: printf(''Wrong parameters value: file %s on line %d\r\n'', file, line) */

 

  /* Infinite loop */

  while (1)

  {

  }

}

#endif

Today I have been learning many things, thanks you.

 

Posted on February 08, 2013 at 01:28

The project construction is odd, you wouldn't normally #include C files, but rather have them in the project itself.

Makes me wonder if you have suitable startup file to set the interrupt vectors and program the chip to run faster than 8 MHz.

My code is not running at 9600 baud, so you might need to adjust that in the code or in the terminal.

The interrupt is going to occur whenever the TXE asserts, which is going to happen about every 10 bit times. In this case it will happen repeatedly as it outputs the string over and over. The RXNE interrupt will occur whenever bytes are received.

If you are not seeing interrupt I'd suggest you break out a debugger, look at the vector table, and if the vector table address SCB->VTOR points to the flash base.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Gigli.Dario
Associate II
Posted on February 08, 2013 at 17:06

Thank you. I tried to undestand why I don't see nothing even if there are interrupts tx e rx. So I have done the debug of the code and I have noted that after the instruction :

  USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

is generated a infinite loop and if I press the command break I see that it is on BUSFAULT_HANDLES. WHY?

So to understand something I have eliminated the interrupt tx e I have  tried to manage only the rx interrupt. I run it in debug mode, so before it sends the string ''Init complete! Hello World!'', 

and I see it by the ''ComTestSerial'', if I don't send by Terminal any string it stays in the While(1). Then  if I send a single character by terminal the rx interrupt happens but it enters in a infinite loop like

the previus case, and if I break it I see that it is on BUSFAULT_HANDLES.   The code is this:

void RCC_Configuration(void)

{

  /* Enable GPIO clock */

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

 

  /* Enable UART clock */

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

}

 

/**************************************************************************************/

 

void GPIO_Configuration(void)

{

    GPIO_InitTypeDef GPIO_InitStructure;

 

  /* Configure USART Tx as alternate function push-pull */

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;  // PA.09 USART1.TX

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_Init(GPIOA, &GPIO_InitStructure);

 

  /* Configure USART Rx as input floating */

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; // PA.10 USART1.RX

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

  GPIO_Init(GPIOA, &GPIO_InitStructure);

}

 

/**************************************************************************************/

 

void USART_Configuration(void)

{

  USART_InitTypeDef USART_InitStructure;

 

  /* USART resources configuration (Clock, GPIO pins and USART registers) ----*/

  /* USART configured as follow:

        - BaudRate = 115200baud

        - Word Length = 8 Bits

        - One Stop Bit

        - No parity

        - Hardware flow control disabled (RTS and CTS signals)

        - Receive and transmit enabled

  */

  USART_InitStructure.USART_BaudRate = 115200;

  USART_InitStructure.USART_WordLength = USART_WordLength_8b;

  USART_InitStructure.USART_StopBits = USART_StopBits_1;

  USART_InitStructure.USART_Parity = USART_Parity_No;

  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

 

  /* USART configuration */

  USART_Init(USART1, &USART_InitStructure);

 

  /* Enable the USART1 */

  USART_Cmd(USART1, ENABLE);

   

  

}

 

/**************************************************************************************/

 

void NVIC_Configuration(void)

{

  NVIC_InitTypeDef NVIC_InitStructure;

 

  /* Configure the NVIC Preemption Priority Bits */

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);

 

  /* Enable the USART1 Interrupt */

  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  NVIC_Init(&NVIC_InitStructure);

}

 

/**************************************************************************************/

void USART_puts(USART_TypeDef* USARTx, volatile char *s){

while(*s){

// wait until data register is empty

while( !(USARTx->SR & 0x00000040) );

USART_SendData(USARTx, *s);

*s++;

}

}

/**************************************************************************************/

int main(void)

{

  RCC_Configuration();

 

  GPIO_Configuration();

 

  NVIC_Configuration();

 

  USART_Configuration();

  USART_puts(USART1, ''Init complete! Hello World!\r''); // just send a message to indicate that it works

  while(1){

  }

  

}

 

/**************************************************************************************/

void USART1_IRQHandler(void)

{

    if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)

    {

        USART_ReceiveData(USART1); // Clear RXNE

        USART_puts(USART1, ''\r\n==BITE ME==\r\n'');

    }

}

 

Why does it happen? I tried also to use another stm32f100b but nothing. I use IAR , I think that I err some initialization . 

 

I dont' know what I have to do more . Please , Can you give me the .zip with the main and the file.h and .c  of the previus program??? 

THANK YOU

Posted on February 08, 2013 at 17:55

It sounds like it's hard faulting, likely because the vector table isn't set up right in the start up code, or the interrupt handler isn't being linked correctly.

In a correctly formed IAR project using the ST / CMSIS libraries it should be calling SystemInit() in system_stm32f10x.c prior to calling main. This should set up the clock, PLL and the vector table address. The vector code and the start up calls should be in startup_stm32f10x_xx.s

You should perhaps get a current release of the firmware library (STM32F1 v3.5.0 or VL-Discovery), and experiment with the template projects for IAR. Once you understand the project construction you can create your own. I'm not a licensee of the IAR tool chain.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..