⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usart.c

📁 stm32初级例程
💻 C
字号:
/**************************************************************
**  精英STM32开发板
**  版本:V1.0
**  功能:	不断查询串口状态,看串口是否收到数据
			串口1配置如下
			 115200,8,N,1
			本串口程序是接收到什么字符就返回什么字符
			使用我提供的串口调试工具,选择【串口超级终端】波特率设置115200
***************************************************************/

#include <stm32f10x_lib.h>                        // STM32F10x Library Definitions
#include <stdio.h>
#include "STM32_Init.h"                           // STM32 Initialization


/*----------------------------------------------------------------------------
  Notes:
  The length of the receive and transmit buffers must be a power of 2.
  Each buffer has a next_in and a next_out index.
  If next_in = next_out, the buffer is empty.
  (next_in - next_out) % buffer_size = the number of characters in the buffer.
 *----------------------------------------------------------------------------*/
#define TBUF_SIZE   256      /*** Must be a power of 2 (2,4,8,16,32,64,128,256,512,...) ***/
#define RBUF_SIZE   256      /*** Must be a power of 2 (2,4,8,16,32,64,128,256,512,...) ***/

/*----------------------------------------------------------------------------
 *----------------------------------------------------------------------------*/
#if TBUF_SIZE < 2
#error TBUF_SIZE is too small.  It must be larger than 1.
#elif ((TBUF_SIZE & (TBUF_SIZE-1)) != 0)
#error TBUF_SIZE must be a power of 2.
#endif

#if RBUF_SIZE < 2
#error RBUF_SIZE is too small.  It must be larger than 1.
#elif ((RBUF_SIZE & (RBUF_SIZE-1)) != 0)
#error RBUF_SIZE must be a power of 2.
#endif

/*----------------------------------------------------------------------------
 *----------------------------------------------------------------------------*/
//数据缓冲队列
struct buf_st
{
   unsigned int in;// Next In Index    下一个数据输入指针
   unsigned int out;// Next Out Index  下一个数据输出指针
   char buf[RBUF_SIZE];// Buffer  数据缓冲队列
};

//声明1个接收数据缓冲队列
static struct buf_st rbuf =
{
   0, 0, 
};
#define SIO_RBUFLEN ((unsigned short)(rbuf.in - rbuf.out))

//声明1个发送数据缓冲队列
static struct buf_st tbuf =
{
   0, 0, 
};
#define SIO_TBUFLEN ((unsigned short)(tbuf.in - tbuf.out))

static unsigned int tx_restart = 1;               // NZ if TX restart is required

/*----------------------------------------------------------------------------
  USART1_IRQHandler
  Handles USART1 global interrupt request.
  串口中断函数
 *----------------------------------------------------------------------------*/
void USART1_IRQHandler(void)
{
   volatile unsigned int IIR;
   struct buf_st* p;

   //读取串口状态
   IIR = USART1->SR;
   //串口接收中断
   if (IIR & USART_FLAG_RXNE) // read interrupt
   {
      //必须清除中断标志
      USART1->SR &= ~USART_FLAG_RXNE;            // clear interrupt

      p = &rbuf;
      //接收数据缓冲未满继续放数据进缓冲区
      if (((p->in - p->out) & ~(RBUF_SIZE - 1)) == 0)
      {
         p->buf[p->in & (RBUF_SIZE - 1)] = (USART1->DR & 0x1FF);
         p->in++;
      }
   }
   //串口发送中断
   if (IIR & USART_FLAG_TXE)
   {
      //必须清除中断标志
      USART1->SR &= ~USART_FLAG_TXE;             // clear interrupt

      p = &tbuf;
      //发送数据缓冲还有数据继续从发送缓冲区取数据
      if (p->in != p->out)
      {
         USART1->DR = (p->buf[p->out & (TBUF_SIZE - 1)] & 0x1FF);
         p->out++;
         tx_restart = 0;
      }
      else//发送数据缓冲空表示数据发送结束      {
         tx_restart = 1;
         USART1->CR1 &= ~USART_FLAG_TXE;           // disable TX interrupt if nothing to send
      }
   }
}

/*------------------------------------------------------------------------------
  buffer_Init
  initialize the buffers
  初始化接收缓冲、发送缓冲
 *------------------------------------------------------------------------------*/
void buffer_Init(void)
{
   tbuf.in = 0;                                    // Clear com buffer indexes
   tbuf.out = 0;
   tx_restart = 1;

   rbuf.in = 0;
   rbuf.out = 0;
}

/*------------------------------------------------------------------------------
  SenChar
  transmit a character
  发送1个字节数据
 *------------------------------------------------------------------------------*/
int SendChar(int c)
{
   struct buf_st* p = &tbuf;

   // If the buffer is full, return an error value
   //如果发送缓冲满,直接返回
   if (SIO_TBUFLEN >= TBUF_SIZE)
      return (-1);
   // Add data to the transmit buffer. 
   //向发送缓冲填充数据                                               
   p->buf[p->in & (TBUF_SIZE - 1)] = c;           
   p->in++;
   //If transmit interrupt is disabled, enable it
   //如果发送中断禁止,那么开启发送中断
   if (tx_restart)
   {
      tx_restart = 0;
      // enable TX interrupt
      USART1->CR1 |= USART_FLAG_TXE;
   }

   return (0);
}

/*------------------------------------------------------------------------------
  GetKey
  receive a character
  接收1个字节
 *------------------------------------------------------------------------------*/
int GetKey(void)
{
   struct buf_st* p = &rbuf;

   if (SIO_RBUFLEN == 0)
      return (-1);

   return (p->buf[(p->out++) & (RBUF_SIZE - 1)]);
}


/*----------------------------------------------------------------------------
  MAIN function
 *----------------------------------------------------------------------------*/
int main(void)
{
   // init RX / TX buffers
   //初始化接收发送缓冲
   buffer_Init();                                  
   // STM32 setup 初始化串口
   stm32_Init();
   //串口实验开始
   printf("Interrupt driven Serial I/O Example\r\n\r\n");

   while (1)
   {
      // Loop forever
      unsigned char c;
      //提示从串口输入1个字符
      printf("Press a key. ");
      //从串口接收1个字符
      c = getchar();
      //从串口输出回车换行
      printf("\r\n");
      //从串口输出接收到的字符
      printf("You pressed '%c'.\r\n\r\n", c);
   } // end while
} // end main

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -