STM32 USART Interrupt - FabLabSeoul/WingProject GitHub Wiki

Stm32 Value line discovery ๋ณด๋“œ ์ „์šฉ ๊ธ€์ž…๋‹ˆ๋‹ค.

์‹œ๋ฆฌ์–ผ ํ†ต์‹ (USART)์„ ์ธํ„ฐ๋ŸฝํŠธ ๋ฐฉ์‹์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์„ค๋ช…ํ•œ๋‹ค.

์˜ˆ์ œ๋Š” STM32\stm32vldiscovery_package\Project\Examples\Serial_Interrupt ๊ฒฝ๋กœ์— ์žˆ๋‹ค. ์˜ˆ์ œ๋Š” PA10,9(Rx,Tx)๋ฅผ ์‹œ๋ฆฌ์–ผํ†ต์‹ ํฌํŠธ๋กœ ์„ค์ •ํ•˜๊ณ , ์ปดํ“จํ„ฐ์˜ Serial port terminal ํ”„๋กœ๊ทธ๋žจ๊ณผ ํ†ต์‹ ์„ ์ฃผ๊ณ  ๋ฐ›๋Š”๋‹ค. ์ด ์˜ˆ์ œ๋ฅผ ์‹คํ–‰ํ•ด๋ณด๊ธฐ ์œ„ํ•ด์„œ๋Š” Stm32vldiscovery ๋ณด๋“œ์™€ serial to usb ๋ณด๋“œ, ์‹œ๋ฆฌ์–ผ ํฌํŠธ ํ„ฐ๋ฏธ๋„ ํ”„๋กœ๊ทธ๋žจ์ด ์žˆ์–ด์•ผ ํ•œ๋‹ค. Stm32๋ณด๋“œ์˜ ์‹œ๋ฆฌ์–ผ ํฌํŠธ๋ฅผ serial to usb ๋ณด๋“œ์— ์—ฐ๊ฒฐํ•˜๊ณ  ํ„ฐ๋ฏธ๋„ ํ”„๋กœ๊ทธ๋žจ์„ ์‹คํ–‰ํ•˜๋ฉด, ๋จผ์ € Stm32๋ณด๋“œ๋กœ ๋ถ€ํ„ฐ ๋„˜์–ด์˜จ ์ •๋ณด๊ฐ€ ํ™”๋ฉด์— ํ‘œ์‹œ๋œ๋‹ค. ๊ทธ ํ›„ ํ„ฐ๋ฏธ๋„ ํ”„๋กœ๊ทธ๋žจ์—์„œ ์ •๋ณด๋ฅผ ์†ก์‹ ํ•ด์„œ, ์•ฝ 30๋ฌธ์ž๋ฅผ ๋„˜์–ด์„œ๋ฉด Stm32๋ณด๋“œ์—์„œ ๋ฐ›์€ ๋ฌธ์ž์—ด์„ ๊ทธ๋Œ€๋กœ ํ„ฐ๋ฏธ๋„์—๊ฒŒ ์ „์†กํ•œ๋‹ค.

๋ณธ๋ก ์œผ๋กœ ๋“ค์–ด๊ฐ€๋ฉด, Stm32์—์„œ ์‹œ๋ฆฌ์–ผํ†ต์‹ ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ํฌ๊ฒŒ Polling, Interrupt, DMA ๋ฐฉ์‹์ด ์žˆ๋‹ค. ์ด ๊ธ€์—์„œ๋Š” Interrupt๋ฐฉ์‹์„ ์„ค๋ช…ํ•œ๋‹ค. ์ธํ„ฐ๋ŸฝํŠธ ๋ฐฉ์‹์€ ์‹œ๋ฆฌ์–ผ๋กœ ์ •๋ณด๋ฅผ ์ฃผ๊ณ  ๋ฐ›์„ ๋•Œ๋งˆ๋‹ค ์ธํ„ฐ๋ŸฝํŠธ๋ฅผ ๋ฐœ์ƒ์‹œ์ผœ ์ •๋ณด๋ฅผ ์ฃผ๊ฑฐ๋‚˜ ๋ฐ›๊ฑฐ๋‚˜ ํ•˜๋Š” ๋ฐฉ์‹์„ ๋งํ•œ๋‹ค. ์ต์ˆ™ํ•ด์ง€๋ฉด ๋‹ค๋ฅธ ๋ฐฉ์‹๋ณด๋‹ค ํŽธํ•˜๋‹ค๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค. ์ธํ„ฐ๋ŸฝํŠธ๋Š” ๊ฐ„๋‹จํžˆ ๋งํ•˜๋ฉด, ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋œ๋‹ค.

์‹œ๋ฆฌ์–ผ ํฌํŠธ๋ฅผ ์„ค์ •ํ•˜๋Š” ๊ฒƒ์€ ๊ธฐ์กด ๋ฐฉ์‹๊ณผ ๋˜‘๊ฐ™๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ Stm32 UART ๋ฌธ์„œ๋ฅผ ์ฐธ์กฐํ•˜์ž. ๋‹ค๋ฅธ ์ ์€ ์ธํ„ฐ๋ŸฝํŠธ๋ฅผ ์„ค์ •ํ•ด์ค˜์•ผ ํ•˜๋Š” ๋ถ€๋ถ„์ด๋‹ค. Stm32์—์„œ ์ธํ„ฐ๋ŸฝํŠธ๋ฅผ ๊ด€์žฅํ•˜๋Š” ํŒŒํŠธ๋ฅผ NVIC๋ผ๊ณ  ํ•œ๋‹ค. Nested Vectored Interrupt Controller์˜ ์•ฝ์ž๋‹ค. 60๊ฐœ์˜ ์ธํ„ฐ๋ŸฝํŠธ ํ…Œ์ด๋ธ”์ด ์žˆ๊ณ , ๊ทธ ์ค‘์— USART ์ธํ„ฐ๋ŸฝํŠธ๊ฐ€ ์žˆ๋‹ค. ์ด ํ”Œ๋ž˜๊ทธ๋ฅผ ํ™œ์„ฑํ™” ์‹œํ‚ค๋ฉด, USART์— ๊ด€๋ จ๋œ ์ธํ„ฐ๋ŸฝํŠธ๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค. ์ฝ”๋“œ๋Š” ๊ฐ„๋‹จํ•˜๋‹ค.

/**
  * @brief  Configures the nested vectored interrupt controller.
  * @param  None
  * @retval None
  */
void NVIC_Configuration(void)
{
   NVIC_InitTypeDef NVIC_InitStructure;

  /* 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);
}

Stm32์—์„œ๋Š” USART1_IRQn, USART2_IRQn, USART3_IRQn์˜ ์ธํ„ฐ๋ŸฝํŠธ๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ธํ„ฐ๋ŸฝํŠธ๋Š” ์šฐ์„ ์ˆœ์œ„์— ๋”ฐ๋ผ ๋ฌด์—‡์„ ๋จผ์ € ํ˜ธ์ถœ ํ• ์ง€๋ฅผ ๊ฒฐ์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ NVIC_IRQChannelPreemptionPriority ์—๋Š” ๊ฐ™์€ ๋ถ„๋ฅ˜๋ผ๋ฆฌ ๊ฐ™์€ ๊ฐ’์œผ๋กœ ์„ค์ •ํ•˜๊ณ , NVIC_IRQChannelSubPriority ์—์„œ ์šฐ์„ ์ˆœ์œ„๋ฅผ ์ •ํ•˜๊ฒŒ ๋œ๋‹ค. ์ž‘์€ ๊ฐ’ ์ผ์ˆ˜๋ก ๋จผ์ € ํ˜ธ์ถœ๋œ๋‹ค.

์šฐ์„ ์ˆœ์œ„์— ๊ด€๋ จ๋œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์ด ๊ธ€์„ ์ฐธ์กฐํ•˜์ž.

๊ทธ๋ฆฌ๊ณ , ์‹œ๋ฆฌ์–ผ์„ ๋ณด๋‚ผ ๋•Œ์™€ ๋ฐ›์„ ๋•Œ ๊ฐ๊ฐ ๋”ฐ๋กœ ์ธํ„ฐ๋ŸฝํŠธ๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค. ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

/* Enable USART1 Receive and Transmit interrupts */
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
USART_ITConfig(USART1, USART_IT_TXE, ENABLE);

###์ธํ„ฐ๋ŸฝํŠธ USART1 ์ธํ„ฐ๋ŸฝํŠธ๊ฐ€ ๋ฐœ์ƒ๋˜๋ฉด, void USART1_IRQHandler(void) ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค. USART2 ์ธํ„ฐ๋ŸฝํŠธ๊ฐ€ ๋ฐœ์ƒ๋˜๋ฉด void USART2_IRQHandler(void) ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค. USART3 ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€๋‹ค. ๊ฐœ๋ฐœ์ž๋Š” ์ด ํ•จ์ˆ˜๋ฅผ ๊ทธ๋Œ€๋กœ ๊ตฌํ˜„ํ•˜๋ฉด ๋œ๋‹ค. ๊ฐ„ํ˜น stm32f10x_it.c ํŒŒ์ผ์— ์ด๋ฏธ ํ•จ์ˆ˜๊ฐ€ ๊ตฌํ˜„๋œ ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋Š”๋ฐ, ์ปดํŒŒ์ผ ์˜ค๋ฅ˜๋ฅผ ํ”ผํ•˜๋ ค๋ฉด, ๊ธฐ์กด ์ธํ„ฐ๋ŸฝํŠธ ํ•จ์ˆ˜๋Š” ์ง€์šฐ๊ณ , ์ƒˆ๋กœ ๊ตฌํ˜„ํ•˜๋ฉด ๋œ๋‹ค.

์ธํ„ฐ๋ŸฝํŠธ๋Š” USART_ITConfig()ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ด์„œ ์ธํ„ฐ๋ŸฝํŠธ๋ฅผ ํ™œ์„ฑํ™”ํ•˜๋Š” ์ˆœ๊ฐ„๋ถ€ํ„ฐ, Transmitter ์ธํ„ฐ๋ŸฝํŠธ๋Š” ๋ฐ”๋กœ ํ˜ธ์ถœ๋œ๋‹ค. ๋”์ด์ƒ ์ •๋ณด๋ฅผ ๋ณด๋‚ผ๊ฒŒ ์—†๋‹ค๋ฉด, USART_IT_TXE ์ธํ„ฐ๋ŸฝํŠธ๋Š” ๋„๋Š”๊ฒŒ ์ข‹๋‹ค. ๋ฐ˜๋Œ€๋กœ Receiver ์ธํ„ฐ๋ŸฝํŠธ๋Š” ์ •๋ณด๋ฅผ ๋ฐ›์„ ๋•Œ๋งŒ ํ˜ธ์ถœ๋œ๋‹ค. ๊ทธ๋Ÿฌ๋‹ˆ ํฐ ๋ฌธ์ œ๊ฐ€ ์—†๋‹ค๋ฉด, USART_IT_RXNE ์ธํ„ฐ๋ŸฝํŠธ๋Š” ๊ณ„์† ์ผœ๋†“๋Š”๊ฒŒ ์ข‹๋‹ค.


/**
  * @brief  This function handles USARTy global interrupt request.
  * @param  None
  * @retval None
  */
void USART1_IRQHandler(void)
{
  // ์‹œ๋ฆฌ์–ผ๋กœ ๋ถ€ํ„ฐ ๋ฐ›์€ ์ •๋ณด๋ฅผ ๊ณ„์† ์ €์žฅํ•œ๋‹ค.
  if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
  {
    /* Read one byte from the receive data register */
    RxBuffer[RxCounter++] = USART_ReceiveData(USART1);

    if(RxCounter == NbrOfDataToRead)
    {
        // NbrOfDataToRead ๋งŒํผ ์ •๋ณด๋ฅผ ๋ฐ›์•˜๋‹ค๋ฉด, ๊ทธ๋Œ€๋กœ ์ „์†กํ•œ๋‹ค.
	    SendSerial(RxBuffer, RxCounter);
	    RxCounter = 0;			
    }
  }
  
	// ์‹œ๋ฆฌ์–ผ๋กœ ๋ฐ์ดํƒ€๋ฅผ ๋ชจ๋‘ ๋ณด๋‚ด๋ฉด, ์ธํ„ฐ๋ŸฝํŠธ๋ฅผ ๋ˆ๋‹ค.
  if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET)
  {   
    /* Write one byte to the transmit data register */
    USART_SendData(USART1, TxBuffer[TxCounter++]);

    if(TxCounter == NbrOfDataToTransfer)
    {
      /* Disable the USART1 Transmit interrupt */
      USART_ITConfig(USART1, USART_IT_TXE, DISABLE);
    }    
  }
}

void SendSerial(uint8_t buffer[], uint8_t size)
{
	int i=0;
	
	TxCounter = 0;
	NbrOfDataToTransfer = size;

	for (i=0; i < size; ++i)
	{
		TxBuffer[ i] = buffer[ i];
	}			

	USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
}

USART_GetITStatus(USART1, USART_IT_RXNE) ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•ด ์‹œ๋ฆฌ์–ผํ†ต์‹ ์„ ํ†ตํ•ด ์ •๋ณด๋ฅผ ๋ฐ›์•˜๋Š”์ง€ ํŒ๋‹จ ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ฝ”๋“œ์—์„œ๋Š” ์ •๋ณด๋ฅผ ๋ฐ›์„ ๋•Œ๋งˆ๋‹ค ๋ฒ„ํผ์— ์ €์žฅํ•˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

USART_GetITStatus(USART1, USART_IT_TXE) ํ•จ์ˆ˜๋Š” USART_ITConfig(USART1, USART_IT_TXE, ENABLE) ํ˜ธ์ถœ ๋˜์—ˆ๋‹ค๋ฉด ํ•ญ์ƒ TRUE๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ์ •๋ณด๋ฅผ ๋ชจ๋‘ ์†ก์‹ ํ•˜๋ฉด ์ธํ„ฐ๋ŸฝํŠธ๋ฅผ ๋„๋Š”๊ฒŒ ์ข‹๋‹ค.

main() ํ•จ์ˆ˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

int main()
{
  /* System Clocks Configuration */
  RCC_Configuration();
 
  /* NVIC configuration */
  NVIC_Configuration();

  /* Configure the GPIO ports */
  GPIO_Configuration();	

  // USART1 ์ดˆ๊ธฐํ™”	
  USART_InitStructure.USART_BaudRate = 9600;
  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_Init(USART1, &USART_InitStructure);
	
  /* Enable USART1 Receive and Transmit interrupts */
  USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
  USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
	
  // Enable USART1
  USART_Cmd(USART1, ENABLE);

  while (1)
  {
  }	
}

============================= ###๋ ˆํผ๋Ÿฐ์Šค