📄 usart.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 + -