1
\$\begingroup\$

I was trying USART on STM32F103RC,baud 115200, sysclk 72MHz, 1 stop bit, no parity and i connected my stm with usb to serial to look my output on terminal. At first i did polling of RX and TX and send command from terminal to stm like "led on" to turn on led and "led off" to turn off led and it worked perfectly with the response i have send from stm. rx and tx worked fine

Next what i did was i configured rx as interrupt and tx as polling.when i did that my rx is working fine but my Tx stopped working.

My code looks like this

USART1 IRQ

 /** @breif: USART1 IRQ
     * @param: None
     * @retVal: None
   */
 void USART1_IRQHandler(void)
 {
     if(USART1->SR & USART_SR_RXNE)
     {
            rx_data[datapos] = USART1->DR;
            datapos++;
            if (datapos > 255 )
            {
                datapos = 0;
                Clear_Buffer(rx_data);
            }
   }  
 }

USART INITIALIZATION

 void USART_Init()
 {
     /*Enable Clock for USART port and USART1 */
     RCC->APB2ENR |=  RCC_APB2ENR_IOPAEN | RCC_APB2ENR_USART1EN;
     /*Rx,Tx setup GPIOA->CRH = 0x000004B0*/
     GPIOA->CRH |= GPIO_CRH_MODE9;          // Tx Mode- 11: Output mode, max speed 50 MHz.
     GPIOA->CRH |= GPIO_CRH_CNF9_1;         // Tx CNF - 10: Alternate function output Push-pull
     GPIOA->CRH &= ~(GPIO_CRH_MODE10);  // Rx Mode- 00: Input mode (reset state)
     GPIOA->CRH |= GPIO_CRH_CNF10_0;    // Rx CNF - 01: Floating input (reset state)
     /* Baud rate set 72MHz/115200 */
     USART1->BRR = SYSCLK/BAUD;
     /*Enable Rx, Enable Tx, Enable USART*/
     USART1->CR1 = USART_CR1_RE | USART_CR1_TE | USART_CR1_UE;
     USART1->CR1 |= USART_CR1_RXNEIE;  //enable rx interrupt
 }

USART TRANSMIT

 /** @breif: Transmit a String
     * @param: the string to be transmitted
     * @retVal: None
   */
 void Transmit_String(char *str)
 {
     while(*str != '\0')
     {
         Transmit_Char(*str);
         str++;
     }
 }

 /** @breif: Transmit a character
     * @param: the character to be transmitted
     * @retVal: None
   */

void Transmit_Char(char data)
{
    while (!(USART1->SR & USART_SR_TXE));
    USART1->DR = data;
}

MAIN

 int main(void)
 {
     Led_Init();
     USART_Init();
     NVIC_Init();
     datapos = 0;
     while(1)
     {
         if(strstr(rx_data,"led on\r"))
         {
                RESET_GPIO_BIT_PORTD(2);                        //Make Led High
                Transmit_String("\nLED is ON\r\n");
              datapos = 0;
              Clear_Buffer(rx_data);
         }
         else if(strstr(rx_data,"led off\r"))
         {
                SET_GPIO_BIT_PORTD(2);                      //Make Led Low
                Transmit_String("\nLED is OFF\r\n");
              datapos = 0;
              Clear_Buffer(rx_data);
         }
         Delay(1000);
     }
 }

With this code led is turned on and off perfectly but Nothing is transmitted on terminal. I guess it's something with IRQ as IRQ is for USART1 and not mentioned anything about either it's for RX or TX.

But i want to poll for Tx and Take interrupt for Rx and just not getting the correct procedure to do that. Any suggestion would be helpful.

Thanks in advance.

P.S I can provide full source code if required.

\$\endgroup\$
  • \$\begingroup\$ I think it is the NVIC priority issue. The problem could lie in conflict with main loop and IRQ_loop (which is in blocking mode)! Why not transfer the main while loop code to IRQ Handle? Note, IRQ works in blocking mode but your code is very small so you don't need to worry about it! \$\endgroup\$ – charansai Feb 15 '18 at 8:38
  • \$\begingroup\$ my NVIC initialization goes like this NVIC_EnableIRQ(USART1_IRQn); NVIC_SetPriority(USART1_IRQn, 0); \$\endgroup\$ – Devjeet Mandal Feb 15 '18 at 8:44
  • \$\begingroup\$ transferring the while loop code to irq doesn't change anything. \$\endgroup\$ – Devjeet Mandal Feb 15 '18 at 8:46
  • \$\begingroup\$ Have you tried lowering the priority for usart? \$\endgroup\$ – charansai Feb 15 '18 at 8:50
  • \$\begingroup\$ have you literally transferred complete main while loop code to IRQ loop or are you checking for rx_data strings to match with led_on, led_off and executing the commands accordingly?? \$\endgroup\$ – charansai Feb 15 '18 at 8:58
0
\$\begingroup\$

This is the correct answer. Thanks to Everyone

/* Project: USART(Interrupt RX)
 * Author : Devjeet Mandal   
 * Date   : 15/2/2018       11:48
 * 
 */

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include <string.h>

/* Private define ------------------------------------------------------------*/
#define SYSCLK   72000000
#define BAUD            115200

#define LED_PORT_EN()           ( RCC->APB2ENR |= RCC_APB2ENR_IOPDEN )
#define LED_PORT                    GPIOD

#define LED_MODE_BIT1           8
#define LED_MODE_BIT2           9
#define LED_CNF_BIT1            10
#define LED_CNF_BIT2            11

/* Private macro -------------------------------------------------------------*/
#define CNF_SET_PORTD(BIT1,BIT2)            (   LED_PORT->CRL &= ~((1<<BIT1) | (1<<BIT2)) )                 //General purpose output push-pull
#define MODE_SET_PORTD(BIT1,BIT2)           ( LED_PORT->CRL |=  (1<<BIT1) | (1<<BIT2) )                     //Output mode, max speed 50 MHz.

#define SET_GPIO_BIT_PORTD(BIT)             ( LED_PORT->BSRR =  (1 << BIT) )                                            //For setting the Bit   
#define RESET_GPIO_BIT_PORTD(BIT)           ( LED_PORT->BSRR =  ( (1 << BIT) << 16 )    )                       //For Resseting Bit

/* Private function prototypes -----------------------------------------------*/
 void Delay(int ms);
 void Led_Init(void);
 void Blink_Led(int ms);
 void Transmit_Char(char data);
 void Transmit_String(char *str);
 void USART_Init(void);
 void NVIC_Init(void);
 void USART1_IRQHandler(void);
 void Clear_Buffer(char *str);

 /* Private variables ---------------------------------------------------------*/
 __IO uint16_t datapos;
 char rx_data[255];


 int main(void)
 {
     Led_Init();
     USART_Init();
     NVIC_Init();
     datapos = 0;
     while(1)
     {
         if(strstr(rx_data,"led on\r"))
         {
                RESET_GPIO_BIT_PORTD(2);                        //Make Led High
                Transmit_String("\nLED is ON\r\n");
              datapos = 0;
              Clear_Buffer(rx_data);
         }
         else if(strstr(rx_data,"led off\r"))
         {
                SET_GPIO_BIT_PORTD(2);                      //Make Led Low
                Transmit_String("\nLED is OFF\r\n");
              datapos = 0;
              Clear_Buffer(rx_data);
         }
         Delay(1000);
     }
 }

 /** @breif: Clear Buffer
     * @param: Buffer to be cleared
     * @retVal: None
   */
 void Clear_Buffer(char *str)
 {
     while (*str != '\0')
     {
         *str = 0;
         str++;
     }
 }


 /** @breif: USART1 IRQ
     * @param: None
     * @retVal: None
   */
 void USART1_IRQHandler(void)
 {
     if(USART1->SR & USART_SR_RXNE)
     {
            rx_data[datapos] = USART1->DR;
            datapos++;
            if (datapos > 255 )
            {
                datapos = 0;
                Clear_Buffer(rx_data);
            }
   }  
 }

 /** @breif: Initialize setting for NVIC
     * @param: None
     * @retVal: None
   */
 void NVIC_Init()
 {
     NVIC_EnableIRQ(USART1_IRQn);
     NVIC_SetPriority(USART1_IRQn, 0);
 }

 /** @breif: Initialize setting for Usart
     * @param: None
     * @retVal: None
   */

 void USART_Init()
 {
     /*Enable Clock for USART port and USART1 */
     RCC->APB2ENR |=  RCC_APB2ENR_IOPAEN | RCC_APB2ENR_USART1EN;
     /*Rx,Tx setup GPIOA->CRH = 0x000004B0*/
     GPIOA->CRH |= GPIO_CRH_MODE9;          // Tx Mode- 11: Output mode, max speed 50 MHz.
     GPIOA->CRH |= GPIO_CRH_CNF9_1;         // Tx CNF - 10: Alternate function output Push-pull
     GPIOA->CRH &= ~(GPIO_CRH_CNF9_0);

     GPIOA->CRH &= ~(GPIO_CRH_MODE10);  // Rx Mode- 00: Input mode (reset state)
     GPIOA->CRH |= GPIO_CRH_CNF10_0;    // Rx CNF - 01: Floating input (reset state)*/
     /* Baud rate set 72MHz/115200 */
     USART1->BRR = SYSCLK/BAUD;
     /*Enable Rx, Enable Tx, Enable USART*/
     USART1->CR1 = USART_CR1_RE | USART_CR1_TE | USART_CR1_UE;
     USART1->CR1 |= USART_CR1_RXNEIE;  //enable rx interrupt
 }


  /** @breif: Transmit a String
     * @param: the string to be transmitted
     * @retVal: None
   */
 void Transmit_String(char *str)
 {
     while(*str != '\0')
     {
         Transmit_Char(*str);
         str++;
     }
 }

 /** @breif: Transmit a character
     * @param: the character to be transmitted
     * @retVal: None
   */

void Transmit_Char(char data)
{
    while (!(USART1->SR & USART_SR_TXE));
    USART1->DR = data;
}


/** @breif: For wait and doing nothing i.e for delay
     * @param: delaya time
     * @retVal: None
   */


    void Delay(int ms)
    {
        int i,j; 
        for (i = 0; i < ms; ++i) {
            for (j = 0; j < 1000; ++j);
            }
    }


 /** @breif: Initalize GPIO For Led
     * @param: None
     * @retVal: None
   */


    void Led_Init()
    {
        LED_PORT_EN();                                                              //Enable RCC for Led Port
        CNF_SET_PORTD(LED_CNF_BIT1,LED_CNF_BIT2);           //SET CNF       General purpose output push-pull
        MODE_SET_PORTD(LED_MODE_BIT1,LED_MODE_BIT2);    //SET MODE  Output mode, max speed 50 MHz. 
    }


 /** @breif: Blink Led Placed in PORT D Pin 2
     * @param: Delay for each state(ON/OFF)
     * @retVal: None
   */


    void Blink_Led(int ms)
    {
        RESET_GPIO_BIT_PORTD(2);                        //Make Led High
        Delay(ms);                                                  //wait
        SET_GPIO_BIT_PORTD(2);                          //Make Led Low
        Delay(ms);                                                  //wait
    }
\$\endgroup\$
  • \$\begingroup\$ Add the configuration that you have changed and what caused the problem \$\endgroup\$ – charansai Feb 15 '18 at 10:28

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.