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

📄 modbus_ascii.c

📁 44B0的串口接收发送程序 **** 现在共享这样的代码有些过时了
💻 C
字号:
#include "44B.h"
#include "Modbus_ASCII.h"
#include <string.h>


/****************************************************************/
//
//							接收模块
//
/****************************************************************/


static volatile RXDBUF RxdBuf;

//********************************************************************** 
//功 能: 帧读指针加1
//**********************************************************************
static void pFrameRd_Inc(void)
{
	if(RxdBuf.FrameCnt>0)
	{
		if(RxdBuf.pFrameRd == (FRAMEPT *volatile)&RxdBuf.FramePt[FrameBufLen-1])
		{
			RxdBuf.pFrameRd = (FRAMEPT *volatile)&RxdBuf.FramePt[0];
		}
		else
		{
			RxdBuf.pFrameRd++;
		}
	}
}

//********************************************************************** 
//功 能:	以帧的Start指针为指针向接收缓冲区读一字节
//读1字节->清0->Start指针加1
//**********************************************************************
static volatile char FrameState_RdByte(void)
{
	volatile char ch;
	if(RxdBuf.ByteCnt>0)
	{
		ch = (volatile char)*RxdBuf.pFrameRd->Start;
		*RxdBuf.pFrameRd->Start = (volatile char)0;
		if(RxdBuf.pFrameRd->Start == (char *volatile)&RxdBuf.Buf[(RxdBufLen-1)])
		{
			RxdBuf.pFrameRd->Start = (char *volatile)&RxdBuf.Buf[0];
		}
		else
		{
			RxdBuf.pFrameRd->Start++;
		}
		return (ch);
	}
	else
	{
		return (0);
	}
}

//********************************************************************** 
//功 能: 	读一帧数据
//**********************************************************************
int Modbus_GetFrame(char *pBuf)
{
	int i;
	int Len;
	if(RxdBuf.FrameCnt>0)
	{
		Len = RxdBuf.pFrameRd->FrameLen;
		if(*RxdBuf.pFrameRd->Start==FRAME_START && *RxdBuf.pFrameRd->End==FRAME_END)
		{
			for(i=0;i<Len;i++)
			{
				*pBuf++ = FrameState_RdByte();
			}
			RxdBuf.pFrameRd->Start = (char *volatile)0;
			RxdBuf.pFrameRd->End = (char *volatile)0;
			RxdBuf.pFrameRd->FrameLen = (volatile int)0;
			pFrameRd_Inc();
			rINTMSK |= BIT_URXD1;
			RxdBuf.ByteCnt -= Len;
			RxdBuf.FrameCnt--;
			rINTMSK &= ~BIT_URXD1;
			return (1);
		}
		else
		{
			for(i=0;i<Len;i++)
			{
				FrameState_RdByte();
			}
			RxdBuf.pFrameRd->Start = (char *volatile)0;
			RxdBuf.pFrameRd->End = (char *volatile)0;
			RxdBuf.pFrameRd->FrameLen = (volatile int)0;
			pFrameRd_Inc();
			rINTMSK |= BIT_URXD1;
			RxdBuf.ByteCnt -= Len;
			RxdBuf.FrameCnt--;
			rINTMSK &= ~BIT_URXD1;
			return (0);
		}
	}
	else
	{
		return (0);
	}
}

//********************************************************************** 
//功 能: 删除接收缓冲区一字节数据
//删除数据->地址&计数器减1
//**********************************************************************
static void RxdBuf_DelByte(void)
{
	if(RxdBuf.ByteCnt>0)
	{
		*RxdBuf.pWr = (volatile char)0;
		if(RxdBuf.pWr == (char *volatile)&RxdBuf.Buf[0])
		{
			RxdBuf.pWr = (char *volatile)&RxdBuf.Buf[(RxdBufLen-1)];
		}
		else
		{
			RxdBuf.pWr--;
		}
		RxdBuf.ByteCnt--;
	}
}

//********************************************************************** 
//功 能: 向接收缓冲区写一字节数据
//地址加1->写数据->计数器加1
//**********************************************************************
static int RxdBuf_WrByte(const volatile char ch)
{
	if(RxdBuf.ByteCnt<RxdBufLen-1)
	{
		if(RxdBuf.pWr == (char *volatile)&RxdBuf.Buf[(RxdBufLen-1)])
		{
			RxdBuf.pWr = (char *volatile)&RxdBuf.Buf[0];
		}
		else
		{
			RxdBuf.pWr++;
		}
		*RxdBuf.pWr = (volatile char)ch;
		RxdBuf.ByteCnt++;
		return (1);
	}
	else
	{
		return (0);
	}
}


//********************************************************************** 
//功 能: 帧写指针加1
//**********************************************************************
static void pFrameWr_Inc(void)
{
	if(RxdBuf.FrameCnt<FrameBufLen-1)
	{
		if(RxdBuf.pFrameWr == (FRAMEPT *volatile)&RxdBuf.FramePt[(FrameBufLen-1)])
		{
			RxdBuf.pFrameWr = (FRAMEPT *volatile)&RxdBuf.FramePt[0];
		}
		else
		{
			RxdBuf.pFrameWr++;
		}
	}
}

//********************************************************************** 
//功 能: 	串口接收中断处理
//**********************************************************************
static void __irq UART1_ISR_Rxd(void)
{
	int i;
	char ch;
	do
	{
		ch = RdURXH1();
		switch(ch)
		{
			case FRAME_START:
				if( RxdBuf.pFrameWr->Start == (char *volatile)0 )
				{
					RxdBuf.pFrameWr->End = (char *volatile)0;
					RxdBuf.pFrameWr->FrameLen = (volatile int)0;
					if(RxdBuf_WrByte((volatile char)ch))
					{						
						RxdBuf.pFrameWr->FrameLen = (volatile int)1;
						RxdBuf.pFrameWr->Start = (char *volatile)RxdBuf.pWr;
					}
				}
				else
				{
					for(i=0;i<RxdBuf.pFrameWr->FrameLen;i++)
					{
						RxdBuf_DelByte();
					}
					RxdBuf.pFrameWr->Start = (char *volatile)0;
					RxdBuf.pFrameWr->End = (char *volatile)0;
					RxdBuf.pFrameWr->FrameLen = (volatile int)0;
					
					if(RxdBuf_WrByte((volatile char)ch))
					{						
						RxdBuf.pFrameWr->FrameLen = (volatile int)1;
						RxdBuf.pFrameWr->Start = (char *volatile)RxdBuf.pWr;
					}
				}
				break;
			case FRAME_END:
				if( RxdBuf.pFrameWr->Start != (char *volatile)0 )
				{
					if(RxdBuf.FrameCnt<FrameBufLen-1 && RxdBuf.ByteCnt<RxdBufLen-1)
					{
						RxdBuf_WrByte((volatile char)ch);
						RxdBuf.pFrameWr->FrameLen++;
						RxdBuf.pFrameWr->End = (char *volatile)RxdBuf.pWr;
						pFrameWr_Inc();
						RxdBuf.FrameCnt++;
					}
					else
					{
						for(i=0;i<RxdBuf.pFrameWr->FrameLen;i++)
						{
							RxdBuf_DelByte();
						}
						RxdBuf.pFrameWr->Start = (char *volatile)0;
						RxdBuf.pFrameWr->End = (char *volatile)0;
						RxdBuf.pFrameWr->FrameLen = (volatile int)0;
					}
				}
				else
				{
						for(i=0;i<RxdBuf.pFrameWr->FrameLen;i++)
						{
							RxdBuf_DelByte();
						}
						RxdBuf.pFrameWr->Start = (char *volatile)0;
						RxdBuf.pFrameWr->End = (char *volatile)0;
						RxdBuf.pFrameWr->FrameLen = (volatile int)0;
				}
				break;
			default:
				if(RxdBuf.ByteCnt<RxdBufLen-1)
				{
					if(RxdBuf.pFrameWr->Start != (char *volatile)0)
					{
						if(RxdBuf_WrByte((volatile char)ch))
						{
							RxdBuf.pFrameWr->FrameLen++;
						}
					}
				}
				else
				{
					for(i=0;i<RxdBuf.pFrameWr->FrameLen;i++)
					{
						RxdBuf_DelByte();
					}
					RxdBuf.pFrameWr->Start = (char *volatile)0;
					RxdBuf.pFrameWr->End = (char *volatile)0;
					RxdBuf.pFrameWr->FrameLen = (volatile int)0;
				}
				break;
		}
			
	}while( (rUFSTAT1&0xf) >0 );	//若RxD_FIFO计数器为0退出
	rI_ISPC = BIT_URXD1;			//清除中断标志
}

//********************************************************************** 
//功 能: 	Modbus数据接收缓冲区初始化
//**********************************************************************
static void Modbus_RxdBuf_Init(void)
{
	memset((char *)&RxdBuf,0,sizeof(RxdBuf));
	RxdBuf.pWr = (char *volatile)&RxdBuf.Buf[0];
	RxdBuf.pFrameWr = (FRAMEPT *volatile)&RxdBuf.FramePt[0];
	RxdBuf.pFrameRd = (FRAMEPT *volatile)&RxdBuf.FramePt[0];
	RxdBuf.ByteCnt = (volatile int)0;
	RxdBuf.FrameCnt = (volatile int)0;
	RxdBuf.pFrameWr->FrameLen = (volatile int)0;
}



/****************************************************************/
//
//							发送模块
//
/****************************************************************/
static volatile TXDBUF TxdBuf;


//********************************************************************** 
//功 能: 读指针加1
//**********************************************************************
static void TxdBuf_pRd_Inc(void)
{
	if(TxdBuf.ByteCnt>0)
	{
		if(TxdBuf.pRd == (char *volatile)&TxdBuf.Buf[(TxdBufLen-1)])
		{
			TxdBuf.pRd = (char *volatile)&TxdBuf.Buf[0];
		}
		else
		{
			TxdBuf.pRd++;
		}
	}
}


//********************************************************************** 
//功 能: 写指针加1
//**********************************************************************
static void TxdBuf_pWr_Inc(void)
{
	if(TxdBuf.ByteCnt<TxdBufLen-1)
	{
		if(TxdBuf.pWr == (char *volatile)&TxdBuf.Buf[(TxdBufLen-1)])
		{
			TxdBuf.pWr = (char *volatile)&TxdBuf.Buf[0];
		}
		else
		{
			TxdBuf.pWr++;
		}
	}
}

//********************************************************************** 
//功 能: 	从发送缓冲区取一个byte 
//**********************************************************************
static const volatile char TxdBuf_RdByte(void)
{
	volatile char ch;
	if(TxdBuf.ByteCnt>0)
	{
		ch = (volatile char)*TxdBuf.pRd;
		*TxdBuf.pRd = (volatile char)0;
		TxdBuf_pRd_Inc();
		TxdBuf.ByteCnt--;
		return (ch);
	}
	else
	{
		return (0);
	}
}

//********************************************************************** 
//功 能: 向发送收缓冲区写一字节数据
//写数据->地址加1->计数器加1->向串口发送寄存器写一字节->开发送中断
//**********************************************************************
static int TxdBuf_WrByte(const volatile char ch)
{
	if(TxdBuf.ByteCnt<TxdBufLen-1)
	{
		*TxdBuf.pWr = ch;
		TxdBuf_pWr_Inc();
		*TxdBuf.pWr = (volatile char)0;
		TxdBuf.ByteCnt++;
		if( (rINTMSK&BIT_UTXD1) )
		{
			rUTXH1 = TxdBuf_RdByte();
			rINTMSK &= ~BIT_UTXD1;			//开UART0发送中断
		}
		return (1);
	}
	else
	{
		return (0);
	}
}

//********************************************************************** 
//功 能: 	写一帧数据
//**********************************************************************
int Modbus_WrFrame(const volatile char *pBuf)
{
	int StrLen;
	if (!pBuf)
	{
		return (0);
	}
	StrLen = strlen((char *)pBuf);
	if( (*pBuf!=FRAME_START) || (pBuf[StrLen-1]!=FRAME_END) )
	{
		return (0);
	}
	if( (TxdBuf.ByteCnt+StrLen) > (TxdBufLen-1) )
	{
		return (0);
	}
	for (; *pBuf; pBuf++)
	{
		TxdBuf_WrByte(*pBuf);
		if (*pBuf == 0)
		break;
	}
	return (1);
}


//********************************************************************** 
//函 数 名: static void __irq UART0_ISR_Txd(void);
//功 能: 	串口发送中断处理 
//说 明: 
//参 数: 
//返 回 值: 
//**********************************************************************
static void __irq UART1_ISR_Txd(void)
{
	volatile char ch;
	while( !(rUFSTAT1 & 0x200) && (ch=TxdBuf_RdByte()) )   //当TxD FIFO满或者TxLen为0时退出
    {
    	rUTXH1 = ch;
	}
	if(!ch)
	{
		while(1)
		{
			if((rUTRSTAT1 & 0x04) == 0x04)
				break;
		}
    	rINTMSK |= BIT_UTXD1;	//若这里不把中断关掉,TxD FIFO永远为空,也就是说中断永远都会发生!!
	}
	rI_ISPC = BIT_UTXD1;
}


//********************************************************************** 
//功 能: 	Modbus数据发送缓冲区初始化
//**********************************************************************
static void UART1_TxdBuf_Init(void)
{
	memset((char *)TxdBuf.Buf,0,sizeof(TxdBuf.Buf));
	TxdBuf.pWr = (char *volatile)&TxdBuf.Buf[0];
	TxdBuf.pRd = (char *volatile)&TxdBuf.Buf[0];
	TxdBuf.ByteCnt = (volatile int)0;
}



/****************************************************************/
//
//							初始化模块
//
/****************************************************************/


//********************************************************************** 
//功 能: 	串口1中断注册
//**********************************************************************
static void UART1_INT_Init(void)	//中断注册
{    
    pISR_URXD1	= (unsigned) UART1_ISR_Rxd;
    pISR_UTXD1	= (unsigned) UART1_ISR_Txd;
}

/****************************************************************/
//函 数 名: void UART0_Init(int mclk,int baud);
//功 能: 	串口接收中断处理 
//说 明: 
//参 数: 	mclk:系统时钟 	baud:波特率	
//返 回 值: 
/****************************************************************/
void Modbus_Uart1_Init(int mclk,int baud)
{
    rPCONC &= ~(0x0f<<24);
	rPCONC |= (0x0f<<24);						//GPE1 = TxD0,GPE2 = RxD0;
	rPDATC |= (0x03<<12);						//GPE1 = 1,GPE2 = 1;
	rPUPC  |= (0x03<<12); 						//GPE1\GPE2 Disable pull-up
	rULCON1 = 0x03;      						//Normal,No parity,1 bit stop,8 bit data
	rUCON1 = 0x02c5;							//Tx Int->Level;Rx int->Pules;Rx time out enable;
												//Error int enable;Tx mode->int;Rx mode->int;           
	rUFCON1 = 0xe7;								//FIFO enable;RxD FIFO = 12 Bytes;Tx FIFO = 12 Bytes
	rUMCON1 = 0x00;
    rUBRDIV1=( (int)(mclk/16./baud + 0.5) -1 );	//设置波特率;
    UART1_INT_Init();							//初始化串口0中断;
    Modbus_RxdBuf_Init();
    UART1_TxdBuf_Init();
    rI_ISPC = BIT_URXD1;
    rI_ISPC = BIT_UTXD1;
}

⌨️ 快捷键说明

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