STM8S 带缓冲区 串口中断 使用心得

#include "UART.H"

/*-------------------------串口初始化函数------------------------*/

/***********************************************************
*	函数名称:void UART2_Init(void)
*
*	功能描述:UART2初始化函数
*
*	参数列表:无
*						
*	返回结果:无
***********************************************************/
void UART2_Init(void)
{	
	UART2_CR1=0x00;
	UART2_CR2=0x00;
	UART2_CR3=0x00;

	UART2_BRR2=0x0B;
	UART2_BRR1=0x08;
	
	UART2_CR2=0x2c;		//允许接收,发送,开接收中断
	_asm("rim");			//开全局中断
}

/*-------------------------串口接收相关函数------------------------*/

unsigned char RNUM;		   		//定义接收变量
u8 rx_buffer[RX_BUFFER_SIZE];	//接收缓冲区

#if RX_BUFFER_SIZE <= 256
	u8 rx_wr_index = 0, rx_rd_index = 0, rx_counter;	//接收写指针,接收读指针,接收字符个数
#else
	u16 rx_wr_index = 0, rx_rd_index = 0, rx_counter;	//接收写指针,接收读指针,接收字符个数
#endif

#if RX_BUFFER_SIZE < 256
	u8 rx_counter;	//接收字符个数
#else
	u16 rx_counter;	//接收字符个数
#endif

_Bool rx_buffer_overflow; 			//接收缓冲区溢出标志

/***********************************************************
*	函数名称:@far @interrupt void UART2_Rec_HandledInterrupt(void)
*
*	功能描述:接收中断函数
*
*	参数列表:无
*
*	返回结果:无
***********************************************************/
@far @interrupt void UART2_Rec_HandledInterrupt(void)
{ 
    if (UART2_SR & 0X0F)
	{
		RNUM = UART2_SR;
		RNUM = UART2_DR;	//读取数据
	}
    else
    {
        RNUM = UART2_DR;	//读取数据
    }	

	rx_buffer[rx_wr_index++] = RNUM;	//把数据写入接收缓冲区 接收写指针++
    
	#if RX_BUFFER_SIZE == 256
		if (++rx_counter == 0) rx_buffer_overflow = 1;  //溢出标志置位
	#else
		if (rx_wr_index == RX_BUFFER_SIZE)  rx_wr_index = 0;	//如果写入指针等于 缓冲区大小 写入指针指向第一位	
		if (++rx_counter == RX_BUFFER_SIZE)
		{
			rx_counter = 0;
			rx_buffer_overflow = 1;
		}	
	#endif
}

/***********************************************************
*	函数名称:char getchar(void)
*
*	功能描述:从接收缓冲区获取一字节数据
*
*	参数列表:无
*
*	返回结果:获取到的数据
***********************************************************/
char getchar(void)
{
	char data;
	while (rx_counter == 0);    //如果接收数据个数为0 则等待
	data = rx_buffer[rx_rd_index++];
	
	#if RX_BUFFER_SIZE != 256
		if (rx_rd_index == RX_BUFFER_SIZE)  rx_rd_index = 0;
	#endif		
		
	_asm("sim"); 	//关总中断
	--rx_counter;
	
	_asm("rim");	//开总中断
	return data;
}

/***********************************************************
*	函数名称:int getStr(char *Buf,int count)
*
*	功能描述:从接收缓冲区获取一帧数据
*
*	参数列表:*Buf  存储收到的数据 数组
*			  count 要获取的数据长度
*
*	返回结果:返回获取到的数据长度
***********************************************************/
int getStr(char *Buf,int count)
{
	int i = 0;
	for (i=0; i<count; i++)
	{ 
		Buf[i] = getchar();
	}    
		
	Buf[i] = '\0';
	return i;
}                           

/*-------------------------串口发送相关函数------------------------*/

//发送相关变量
u8 tx_buffer[TX_BUFFER_SIZE];		//接收缓冲区

#if TX_BUFFER_SIZE <= 256
	u8 tx_wr_index = 0, tx_rd_index = 0;//发送写指针,发送读指针
#else
	u16 tx_wr_index = 0, tx_rd_index = 0;//发送写指针,发送读指针	
#endif

#if TX_BUFFER_SIZE < 256
	u8 tx_counter = 0;				//发送字符个数
#else
	u16 tx_counter = 0;				//发送字符个数
#endif

/***********************************************************
*	函数名称:@far @interrupt void UART2_Txc_HandledInterrupt(void)
*
*	功能描述:发送中断函数
*
*	参数列表:无
*
*	返回结果:无
***********************************************************/
@far @interrupt void UART2_Txc_HandledInterrupt(void)
{
	UART2_SR &= ~(1<<6); //清除送完成状态位
    
	if (tx_counter > 0)	//发送队列还有未发送完成的数据
	{		
		UART2_DR = tx_buffer[tx_rd_index];		//把要发送的数据移入发送寄存器	
		--tx_counter;	//未发送数据-1
		
		#if TX_BUFFER_SIZE != 256
			if (++tx_rd_index == TX_BUFFER_SIZE) 		//如果发送读指针等于发送缓冲区个数 
                tx_rd_index = 0;						//指针指向第一个数据
		#endif
	}
	else
	{
		UART2_CR2 &= ~(1 << 7);  //关闭发送完成中断
	}
}

/***********************************************************
*	函数名称:void putchar(unsigned char data)
*
*	功能描述:仿CVAVR发送一字节数据
*
*	参数列表:data:要发送的数据
*
*	返回结果:无
***********************************************************/
void putchar(u8 c)
{
	while (tx_counter == TX_BUFFER_SIZE);		//如果发送队列满,则等待
	_asm("sim"); 	//关总中断
	
	if (tx_counter || ((UART2_SR & 0X80) == 0))	
	{	
										//如过还有未发送完成的数据 		
		tx_buffer[tx_wr_index] = c;		//将现有的数据放入队列后面
        
		#if TX_BUFFER_SIZE != 256
			if (++tx_wr_index == TX_BUFFER_SIZE) tx_wr_index = 0;	//调整写指针
		#endif
		++tx_counter;	//发送个数+1
	}
	else						//发送寄存器为空,直接发送
		UART2_DR = c;
		while((UART2_SR & 0X80) == 0);				//等待发送完成
	
	_asm("rim");	//开总中断
}

/***********************************************************
*	函数名称:void putStr(char *buf,int len,int br)
*
*	功能描述:发送一帧数据
*
*	参数列表:*buf:要发送的数据数组	
*			   len:要发送数据的长度
*			    br:是否在结束添加空格回车
*
*	返回结果:无
***********************************************************/
void putStr(char *buf, int len, char br)
{   
	int i = 0;
	for (i=0; i<len; i++)
	{
		putchar(buf[i]);   
	}  
	if (br == 1)
	{
		putchar(0x0d); 
		putchar(0x0a);    
	}
} 
 
 
 
 
/***********************************************************
*	Copyrighe(C) 2017-2100 Demon
*	All rights reserved
*	
*	文件名称UART.H
*	简要描述:UART初始化、收发函数
*
*	当前版本:V1.0
*	作者/修改者:Demon
*	完成日期:
*	修订说明:
*	
***********************************************************/

#ifndef _UART_H_
#define _UART_H_

#include "MAIN.H"


/***********************串口2收发相关变量**************************/
extern unsigned char RNUM;		//定义UART发送和接收变量
//接收相关
#define RX_BUFFER_SIZE 64				//定义接收缓冲区大小
extern unsigned char rx_buffer[RX_BUFFER_SIZE];	//接收缓冲区数组

#if RX_BUFFER_SIZE <= 256
	extern	unsigned char rx_wr_index,rx_rd_index,rx_counter;	//接收写指针,接收读指针,接收字符个数
#else
	extern	u16 rx_wr_index,rx_rd_index;	//接收写指针,接收读指针,
#endif

#if RX_BUFFER_SIZE < 256
	extern unsigned char rx_counter;		//接收字符个数
#else
	extern u16 rx_counter;  	//接收字符个数
#endif

extern _Bool rx_buffer_overflow; //接收缓冲区溢出标志

//发送相关
#define TX_BUFFER_SIZE 8							//定义发送缓冲区大小
extern unsigned char tx_buffer[TX_BUFFER_SIZE];		//接收缓冲区

#if TX_BUFFER_SIZE <= 256
	extern unsigned char tx_wr_index,tx_rd_index;	  //发送写指针,发送读指针
#else
	extern u16 tx_wr_index,tx_rd_index;	//发送写指针,发送读指针	
#endif

#if TX_BUFFER_SIZE < 256
	extern unsigned char tx_counter;								//发送字符个数
#else
	extern u16 tx_counter;								//发送字符个数
#endif	



void UART2_Init(void);						//串口2初始化函数
//void putStr(u8 *p, u8 len);			    //发送一帧数据函数
void putchar(unsigned char c);				//发送一个字节函数;
void putStr(char *buf, int len, char br);	//发送一帧数据

char getchar(void);							//从接收缓冲区获取一个字节函数
int getStr(char *Buf,int count);			//从接收缓冲区获取一帧数据函数




#endif 		//_UART_H_


 
 


猜你喜欢

转载自blog.csdn.net/cyx416676411/article/details/80262810