📄 uart.c
字号:
/**************************************************************************
**
** 文件: UART.c
** 描述: 该文件完成串口的初始化、与传感器串口的数据交互、通过串口中断为EPA网络提供信息分发数据
**
**************************************************************************/
//include library files
#include <iom128v.h>
#include <macros.h>
//include user defined files
#include "Extern_Function.h"
#include "UART.h"
static uchar Cmd_Buf[350];//串口命令数据
static struct DPT_t_OBJECT *DPT_Buf=(struct DPT_t_OBJECT *)Cmd_Buf;
static uchar CMD_DATA_SIZE[DPT_CMD_NUMBER]={59,22,28,30,4,4,4,4,4,4,2,2,8,8,8,1,1,2,2,7,7,1,1,4,1,60,13,13};
/* sending */
static uchar UART_TxSize;
static uchar UART_TxBuf[UART_TXBUFFER_SIZE];
static uchar UART_TxPos;
//标志量
static uchar UART_WatchDogFlag;
static uchar UART_DPTInitFlag;
static uchar UART_RecvEndFlag; //串口接收结束标志
static uchar CoffFlag; //for CMD161
static uchar resp;
/* receiving */
static uchar UART_RxBuf[UART_RXBUFFER_SIZE] ;
static uchar UART_DNCmdWr=0xFF;
static uchar UART_DNCmdRd=0xFF;
static uchar UART_DNCmdAux=1;
static uchar cmdindex=0xFF;
/*DPT_CMD_NUMBER=28,point to the data address and length of every cmd*/
static UART_t_CmdData UART_CmdData[DPT_CMD_NUMBER];
static uchar UART_WatchDogTimer;
static uchar UART_RespTimer; /* wait the end of a new msg */
static uchar UART_ReSendCount;
static int CMDTOINDEX[] = {0, 128, 138, 1, 11, 21, 23, 12, 22, 24, 14, 25, 34, 35, 36, 71, 72, 150, 151,
133, 149, 173, 174, 165, 163, 161, 162, 79};//161-162只查找用,不留空间
//UART_Init();
void UART_ToReady( void ) //初始化相关的缓冲器、标志位
{
UART_DPTInitFlag = 0;
UART_WatchDogTimer = 0x00;
UART_WatchDogFlag = FALSE;
CoffFlag = 0;
UART_DNCmdWr = 0xFF;
UART_DNCmdRd = 0xFF;
UART_ReSendCount = 0x00;
UART_RespTimer = 0xFF;
}
void UART1_UartInitiate( void )//串口1初始化
{
UCSR1B=0x00;
UBRR1L = UBRR_L; //fosc=8M,BAUD=9.6kbps
UBRR1H = UBRR_H;
UCSR1B=(1<<RXEN1)|(1<<TXEN1)|(1<<RXCIE1)|(1<<TXCIE1);//使能发送和接收,使能发送和接收中断
UCSR1C=0x36; //异步,奇检验,8位数据,1位停止位
}
void UART_Init(void)
{
uchar i;
uchar size;
uchar * pb;
UART1_UartInitiate();
pb = Cmd_Buf;
for (i=0; i <DPT_CMD_NUMBER; i++) //DPT_CMD_NUMBER=28
{
size = CMD_DATA_SIZE[i];
UART_CmdData[i].addr = pb;
UART_CmdData[i].size = size;
pb += size;
}
UART_ToReady();
}
//发送与接收中断服务程序
uchar GetChar(void)
{
while(!(UCSR1A&(1<<RXC1)));
return UDR1;
}
#pragma interrupt_handler uart1_rx_isr:iv_USART1_RXC
void uart1_rx_isr(void) //接收中断服务程序
{
uchar UART_RxPos;
UART_RxBuf[0] = UDR1;
if(UART_RxBuf[0]==0xFF)
{
for(UART_RxPos=0;UART_RxPos<3;UART_RxPos++)
{
UART_RxBuf[1+UART_RxPos]=GetChar();
if(UART_RxBuf[1+UART_RxPos]!=0xFF)
break;
}
if(UART_RxPos==3)
{
UART_RxBuf[4]=GetChar();
if((UART_RxBuf[4]==0x55)||(UART_RxBuf[4]==0xAA))
{
UART_RxBuf[5]=GetChar();
UART_RxBuf[6]=GetChar();
if(UART_RxBuf[6]<70)
{
for(UART_RxPos=0;UART_RxPos<=UART_RxBuf[6];UART_RxPos++)//最后一位为校验和
{
UART_RxBuf[7+UART_RxPos]=GetChar();
}
}
if(UART_RxBuf[5]!=1)
{
UCSR1B&=~(1<<RXEN1); //接收禁止
UCSR1B&=~(1<<RXCIE1); //禁止接收中断
}
UART_RecvEndFlag=0x01;
Send_Distribute(UART_RxBuf+7,UART_RxBuf[6]);//见Application.c
}
}
}
}
#pragma interrupt_handler uart1_tx_isr:iv_USART1_TXC
void uart1_tx_isr(void) //发送中断服务程序
{
UART_TxPos++;
if (UART_TxPos < UART_TxSize)
UDR1 = UART_TxBuf[UART_TxPos];
else
{
UART_TxSize = 0x00;
UART_TxPos = 0;
}
}
//UART_Main();
uchar UART_CalCode(uchar *pd, uchar length) //由所有字节异或值组成
{
uchar calcode = 0x00;
uchar i;
for (i=0; i<length; i++)
{
calcode ^= *pd++;
}
return calcode;
}
void UART_MsgCreat(uchar cmdid, uchar cmdtype, uchar resp1, uchar resp2)//构造命令帧与响应帧,并发送
{
uchar i,isize;
//index = Cmd2Index(cmdid);
if(cmdindex != 0xFF)
{
if(cmdtype==UART_RESPONSE) //响应 0,128,138,1
{
UART_TxBuf[0]=cmdtype;
UART_TxBuf[1]=cmdid;
UART_TxBuf[2]=2; //晢时字节计数
UART_TxBuf[3]=resp1;
UART_TxBuf[4]=resp2;
if (cmdid == 1) //确定响应数据和字节数
isize = 2;
else
{
for (i=0; i<UART_CmdData[cmdindex].size; i++)
{
UART_TxBuf[5+i] = *(UART_CmdData[cmdindex].addr + i);
}
isize = UART_TxBuf[2]= (2+UART_CmdData[cmdindex].size);
}
}//end of response
/*SENDING CMD- UART_REAUEST */
else if(cmdtype==UART_REQUEST)
{
UART_TxBuf[0]=cmdtype;
if((cmdid == 128)||(cmdid == 138))
cmdid = (resp1==1)?(++cmdid):cmdid;
UART_TxBuf[1]=cmdid;
if(resp1==0) //read cmd
{
if (cmdid == 161)
{
isize = 1;
UART_TxBuf[3]=UART_DNCmdAux++;
CoffFlag=1;
}
else
isize = 0;
}
else //write cmd
{
isize = UART_CmdData[cmdindex].size;
}
resp1=0;
UART_TxBuf[2]= isize;
}//end of command
UART_TxBuf[isize+3] = UART_CalCode((&UART_TxBuf[0]), isize+3);
UART_TxSize = isize + 4;
/* start sending */
UART_TxPos = 0;
UDR1 = UART_TxBuf[UART_TxPos]; //UDR1 串口数据缓冲区
}
}
uchar Cmd2Index(uint CMD)
{
uchar i;
for (i = 0 ;i < sizeof(CMDTOINDEX)/sizeof(int) ;i++)
{
if(CMD==CMDTOINDEX[i])
return i;
}
return 0xff;
}
static uchar count=0;
void UART_Main(void)
{
uchar i,length,startid;
uchar respcode1 = 0x00;
uchar respcode2 = 0x00;
uchar icalcode,cmd=0xff;
if (UART_RecvEndFlag)//串口接收完毕
{
UART_WatchDogTimer = 0x00;
UART_WatchDogFlag = FALSE;
UART_RecvEndFlag = 0;
startid = UART_RxBuf[4];
cmd = UART_RxBuf[5];
length = UART_RxBuf[6];
icalcode = UART_RxBuf[length+7];
if((cmd == 129)||(cmd == 139)||(cmd == 162))
cmd-=1;
cmdindex = Cmd2Index(cmd);// for data buffer
if(cmdindex!=0xFF)
{
if(cmd == 0x01)
UART_DPTInitFlag = 1; //已经完成初始化过程
// request command from 430 //0,128,138,1
if ((startid == UART_REQUEST)&&(UART_CmdData[cmdindex].size==length))
{
/* check message */
if (icalcode == UART_CalCode(&UART_RxBuf[4], (length+3)))
{
/*save data */
for (i=0; i<length; i++)
{
*(UART_CmdData[cmdindex].addr+i) = UART_RxBuf[7+i];
}
count++;
}
else // check sum error
respcode2 |= 0x08;
/* if no command from DN, later the response msg would be send */
}//end of request
// response from 430 //读、写命令的响应
else if ((startid== UART_RESPONSE)&&((UART_CmdData[cmdindex].size==length-2)||(cmd == 161)))
{
respcode1 = UART_RxBuf[7];
respcode2 = UART_RxBuf[8];
/* check message, save data*/
if(((respcode1|respcode2)==0)&&(icalcode == UART_CalCode(&UART_RxBuf[4], (length+3))))
{
if (cmd == 161) // for 161,162, nine coef
{
if((UART_RxBuf[9]&3)==1)
{
respcode2=UART_RxBuf[9]-1;
for (i=0; i<4; i++)
{
*(UART_CmdData[cmdindex].addr+respcode2+i) = UART_RxBuf[10+i];
*(UART_CmdData[cmdindex].addr+12+respcode2+i) = UART_RxBuf[14+i];
}
}
respcode2=((UART_RxBuf[9]-1)<<2);
for (i=0; i<4; i++)
{
*(UART_CmdData[cmdindex].addr+24+respcode2+i) = UART_RxBuf[18+i];
}
UART_DNCmdRd = (CoffFlag==1)?161:UART_DNCmdRd;
}//end of cmd161
else // for general write-response */
{
for (i=0; i<(length-2); i++) //updata
{
*(UART_CmdData[cmdindex].addr+i) = UART_RxBuf[9+i];
}
}
}
/* clear resp code */
respcode1 = 0x00;
respcode2 = 0x00;
}//----------UART_RESPONSE
else
{
respcode2 |= 0x80; // communation error
}
UCSR1B|=((1<<RXEN1)|(1<<RXCIE1));
}//cmdindex!=0xFF
/* send command */
if(UART_DPTInitFlag == 1)
{
if(UART_DNCmdAux>9)
{
CoffFlag = 0;
UART_DNCmdRd=0xff;
UART_DNCmdAux=1;
}
if (UART_DNCmdWr != 0xFF) // creat request message
{ //借用resp1代表写命令
UART_MsgCreat(UART_DNCmdWr, UART_REQUEST, 0x01, 0x00);
UART_DNCmdWr = 0xFF;
}
else if (UART_DNCmdRd != 0xFF)
{
UART_MsgCreat(UART_DNCmdRd, UART_REQUEST, 0x00, 0x00);
UART_DNCmdRd=0xFF;
}
}
/* send response */
if ((startid == UART_REQUEST)&&(cmd != 0x01)&&(count == 2)) //1号命令暂不响应
{
UART_MsgCreat(cmd, UART_RESPONSE, respcode1, respcode2);
count=0;
}
}//end of RecvEndFlag
}
//UART_CheckTimer();
void UART_CheckTimer(void) //刷新定时器
{
/* after request, wait for response from 430 */
if (UART_WatchDogTimer < UART_WATCHDOG_TIME)
{
UART_WatchDogTimer ++;
if (UART_WatchDogTimer>=UART_WATCHDOG_TIME)
{
UART_WatchDogFlag = TRUE;
}
}
/* wait new msg */
if (UART_RespTimer)
{
UART_RespTimer --;
}
}
/******************* End Of File **********************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -