📄 uart.c
字号:
#include <mc9s12e64.h> /* derivative information */
#include <hidef.h> /* common defines and macros */
#define NOP {__asm NOP; }
#define SIZE_IN_BUFFER 145 //接收 缓冲区长度
#define FrameHeader 0xF2 //报文帧头 低维---协议 高维---帧头
extern const word vswr1 @0xC004;
extern const word vswr2 @0xC006;
extern const word gate @0xC008;
#pragma CONST_SEG PPAGE MY_ROM
#pragma CONST_SEG DEFAULT
// word *far data1=(word *far)0x3C8004;
// word *far data2=(word *far)0x3C8006;
// word *far data3=(word *far)0x3C8008;
byte RXData[SIZE_IN_BUFFER]; //数据缓冲区
typedef struct serialStruct
{//串口的各种属性
unsigned char status; //当前状态
unsigned char cmd; //命令字
unsigned int length; //报文字节长度
unsigned char checkSum; //检验和
unsigned char inAddr; //接收缓冲区的 存数偏置 serial[1] com -> host's buffer
unsigned char token; //0x00:初始化
//接收标志范围:0x0f:接收缓冲区满
//接收报文标志:0xf8:报文接收中
//0xf0:报文接收完整
//0xff:报文处理完
}Structserial;
Structserial serial[3]; //同时可以接收到的数据队列深度为三
extern word ADC_Conver(byte channel);
void CommInt(void); //串口初始化配置
void CommDeal(void);
void TX_Result(word answer);
void TxByte(unsigned char TxValue);
extern void FlashWrite_RAM(byte *WriteData,word * address,byte page);
byte Cal_CRC(byte *ptr, word len);
extern void ShowVswr(void);//处理驻波比
extern void Write_IIC(byte address,byte data);
//串口通信初始化部分
void CommInt(void) {
SCI2BD_SBR =156; // 设置波特率为9600bps
SCI2CR2_TE =1; // 使能SCI2的发送功能
SCI2CR2_RE =1; // 使能SCI2的接收功能
SCI2CR2_RIE=1; // 使能SCI2的接收中断功能
SCI2CR1 =0x00;
}
//发送子函数
void TxByte(byte TxData) {
byte ReadTemp;
ReadTemp=SCI2CR1;
SCI2DRL = TxData; // 发送一个byte
while(!SCI2SR1_TC) ;
}
//发送一串四位数
void TX_Result(word answer)
{
byte i;
byte target[4];
target[0]=(byte)(answer/1000);
target[1]=(byte)((answer%1000)/100);
target[2]=(byte)((answer%100)/10) ;
target[3]=(byte)(answer%10) ;
for (i=0;i<4;i++)
{
TxByte(target[i]+'0');
}
}
//接收中断函数
void interrupt SCI2Rec(void) {
unsigned char bTemp,ch;
static byte index;
if(SCI2SR1_RDRF) {
ch= SCI2DRL;
bTemp=SCI2SR1;
if (serial[index].token == 0x0F) //在缓冲区不满的情况下,接收数据
{
return;
}
switch (serial[index].status )//解释报文-根据接收到的字节转移状态
{
case 0x00 :
if (ch == FrameHeader)// 如果接收到第一个数据为正确的报头
{
serial[index].status = 0x01;
serial[index].token = 0xF8;//报文接收中
if (serial[index].inAddr >= SIZE_IN_BUFFER) //接收缓冲区 满
{
index=0;
serial[index].status = 0x00;
serial[index].inAddr = 0x00;
}
RXData[serial[index].inAddr++] = ch;
}
else
{
serial[index].status = 0x00;
}
break;
case 0x01 ://接收 报文长度 1byte
RXData[serial[index].inAddr++] = ch;
serial[index].length = ch*256;
serial[index].status = 0x02;
if (serial[index].inAddr >= SIZE_IN_BUFFER) //接收缓冲区 满
{
index=0;
serial[index].status = 0x00;
serial[index].inAddr = 0x00;
}
break;
case 0x02 ://接收 报文长度 1byte
RXData[serial[index].inAddr++] = ch;
serial[index].length = serial[index].length+ch;
//此处可以加上长度判断代码
serial[index].status = 0x03;
if (serial[index].inAddr >= SIZE_IN_BUFFER) //接收缓冲区 满
{
index=0;
serial[index].status = 0x00;
serial[index].inAddr = 0x00;
}
break;
case 0x03 ://接收 CMD 1byte
RXData[serial[index].inAddr++] = ch;
serial[index].cmd = ch;
serial[index].status = 0x04;
if (serial[index].inAddr >= SIZE_IN_BUFFER) //接收缓冲区 满
{
index=0;
serial[index].status = 0x00;
serial[index].inAddr = 0x00;
}
break;
case 0x04 ://接收 报文内容 Xbyte 根据前面接收到的长度
RXData[serial[index].inAddr++] = ch;
if (serial[index].inAddr >= SIZE_IN_BUFFER) //接收缓冲区 满
{
index=0;
serial[index].status = 0x00;
serial[index].inAddr = 0x00;
}
if ( (--serial[index].length) == 2 ) //接收完成后退出
{
serial[index].status = 0x05;
if(index==0)
{
serial[index].length = serial[index].inAddr;
serial[index].inAddr = 0x00;
}
else
{
serial[index].length = serial[index].inAddr-serial[index-1].length-serial[index-1].inAddr;
serial[index].inAddr =serial[index-1].length+serial[index-1].inAddr;//起始位置+长度
}
}
break;
case 0x05 ://接收 报文内容校验和 1byte
serial[index].checkSum=Cal_CRC((RXData+serial[index].inAddr),serial[index].length);
if ( ch == serial[index].checkSum )
{
//置报文接收完整标志
serial[index].token = 0xF0;//收到完整报文
serial[index].status = 0x00;
index++;
if(index==2)
index=0;//接收队列满,重新指向头位置
if(index==0)
serial[index].inAddr=0;
else
serial[index].inAddr=serial[index-1].length+serial[index-1].inAddr;//设置一个初始地址指针
}
else//报文内容校验和出错
{
serial[index].status = 0x00;
if(index==0)
serial[index].inAddr = 0x00;
else
serial[index].inAddr =serial[index-1].length+serial[index-1].inAddr;;
}
break;
default :
//将串口状态重置为 0x00
serial[index].status = 0x00;
if(index==0)
serial[index].inAddr = 0x00;
else
serial[index].inAddr =serial[index-1].inAddr;
break;
}//end switch(_sserial[1].status)
}
}
// CRC8=X8+X5+X4+1 -----0x31
byte Cal_CRC(byte *ptr, word len)
{
word i;
byte crc=0;
while(len--)
{
for(i=0x80; i!=0; i>>=1)
{
if((crc&0x80)!=0) {crc<<=1; crc^=0x31;}
else crc<<=1;
if((*ptr & i)!=0) crc^=0x31;
}
ptr++;
}
return(crc);
}
//处理通信部分
void CommDeal(void)
{
word k,j;
byte i;
// PPAGE=0x3C ;
for( i=0;i<3;i++)
if (serial[i].token == 0xF0) //收到了完整报文
{
switch(serial[i].cmd)
{
case 1 :TxByte('1');break;
case 2 :TxByte('2');
TxByte(':');
k=ADC_Conver(13);
j=ADC_Conver(12);
TX_Result(k);
TxByte(' ') ;
TX_Result(j);
TxByte(' ') ;break;
case 3 :TxByte('3');break;
case 4 :TxByte(':') ;
TX_Result(vswr1);
TxByte(' ') ;
TX_Result(vswr2);
TxByte(' ') ;
TX_Result(gate);
TxByte(':') ;
// TX_Result(vswr_1);
TxByte(' ') ;
// TX_Result(vswr_2);
TxByte(' ') ;
// TX_Result(gate_1);
break;
case 5 :TxByte('5');break;
case 6 :DisableInterrupts;
// FlashWrite_RAM((RXData+serial[i].inAddr),(word *)0x8000,0x3c);
FlashWrite_RAM((RXData+serial[i].inAddr),(word *)0xC000,0x00);
EnableInterrupts;
break;
default:break;
}
serial[i].token=0xFF;
}
}
//CRC_16多项式为0x1021
word cal_crc(byte *ptr, byte len) {
byte i;
word crc=0;
while(len--!=0) {
for(i=0x80; i!=0; i/=2) {
if((crc&0x8000)!=0) {crc*=2; crc^=0x1021;} /* 余式CRC 乘以2 再求CRC */
else crc*=2;
if((*ptr&i)!=0) crc^=0x1021; /* 再加上本位的CRC */
}
ptr++;
}
return(crc);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -