?? modbus_ascii.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指針為指針向接收緩沖區(qū)讀一字節(jié)
//讀1字節(jié)->清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);
}
}
//**********************************************************************
//功 能: 讀一幀數(shù)據(jù)
//**********************************************************************
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);
}
}
//**********************************************************************
//功 能: 刪除接收緩沖區(qū)一字節(jié)數(shù)據(jù)
//刪除數(shù)據(jù)->地址&計(jì)數(shù)器減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--;
}
}
//**********************************************************************
//功 能: 向接收緩沖區(qū)寫一字節(jié)數(shù)據(jù)
//地址加1->寫數(shù)據(jù)->計(jì)數(shù)器加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計(jì)數(shù)器為0退出
rI_ISPC = BIT_URXD1; //清除中斷標(biāo)志
}
//**********************************************************************
//功 能: Modbus數(shù)據(jù)接收緩沖區(qū)初始化
//**********************************************************************
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;
}
/****************************************************************/
//
// 發(fā)送模塊
//
/****************************************************************/
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++;
}
}
}
//**********************************************************************
//功 能: 從發(fā)送緩沖區(qū)取一個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);
}
}
//**********************************************************************
//功 能: 向發(fā)送收緩沖區(qū)寫一字節(jié)數(shù)據(jù)
//寫數(shù)據(jù)->地址加1->計(jì)數(shù)器加1->向串口發(fā)送寄存器寫一字節(jié)->開發(fā)送中斷
//**********************************************************************
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發(fā)送中斷
}
return (1);
}
else
{
return (0);
}
}
//**********************************************************************
//功 能: 寫一幀數(shù)據(jù)
//**********************************************************************
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);
}
//**********************************************************************
//函 數(shù) 名: static void __irq UART0_ISR_Txd(void);
//功 能: 串口發(fā)送中斷處理
//說 明:
//參 數(shù):
//返 回 值:
//**********************************************************************
static void __irq UART1_ISR_Txd(void)
{
volatile char ch;
while( !(rUFSTAT1 & 0x200) && (ch=TxdBuf_RdByte()) ) //當(dāng)TxD FIFO滿或者TxLen為0時退出
{
rUTXH1 = ch;
}
if(!ch)
{
while(1)
{
if((rUTRSTAT1 & 0x04) == 0x04)
break;
}
rINTMSK |= BIT_UTXD1; //若這里不把中斷關(guān)掉,TxD FIFO永遠(yuǎn)為空,也就是說中斷永遠(yuǎn)都會發(fā)生!!
}
rI_ISPC = BIT_UTXD1;
}
//**********************************************************************
//功 能: Modbus數(shù)據(jù)發(fā)送緩沖區(qū)初始化
//**********************************************************************
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;
}
/****************************************************************/
//函 數(shù) 名: void UART0_Init(int mclk,int baud);
//功 能: 串口接收中斷處理
//說 明:
//參 數(shù): mclk:系統(tǒng)時鐘 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 ); //設(shè)置波特率;
UART1_INT_Init(); //初始化串口0中斷;
Modbus_RxdBuf_Init();
UART1_TxdBuf_Init();
rI_ISPC = BIT_URXD1;
rI_ISPC = BIT_UTXD1;
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -