📄 serial.c
字号:
#include "typedef.h"
#include "f2407regs_c.h"
#include "global.h"
extern uchar pcdata[Len];
extern uchar status_rx;
extern uchar len_rx;
extern uchar p_rx;
extern uchar b_com_success;
extern uint cfgdata[128];
void interrupt GISR1();
void serialPortInit();
void serialPortOutput1byte(uchar c);
void setSNT(void);
void clrSNT(void);
void send_resp(void);
void testSerialOutput();
/////////////////////////////////////////////////////
void simInit(void);
void delay17us(void);
void delay26us(void);
void delay34us(void);
void delay52us(void);
void delay104us(void);
void simOutput1byte(uchar byte);
extern uchar simdata[50]; //模拟串口数据
extern uchar sim_begin;
extern uchar sim_end;
extern uint cfgdata[128];
#define frameHeader 0x7e
#define frameEnd 0x0d
#define sc2_snt_0 MCRC &= 0xfdff;PFDATDIR |= 0x0200;PFDATDIR &= 0xfffd
#define sc2_snt_1 MCRC &= 0xfdff;PFDATDIR |= 0x0202
#define simRxdIn MCRB &= 0xffef;PCDATDIR &= 0xefff,PCDATDIR |= 0x10
#define simTxdout1 MCRB &= 0xffdf;PCDATDIR |= 0x2020
#define simTxdout0 MCRB &= 0xffdf;PCDATDIR &= 0xffdf
//////////////////////////////////////////////////////////////////////
/**********************************************/
//////////////////////////////////////////////////////////////////////////////////
void serialPortInit()
{
uchar baud,form;
baud = cfgdata[17] >>8;
form = cfgdata[17] & 0x03; //get parity
switch (baud)
{
case 0x06: { SCIHBAUD = 0x02;SCILBAUD = 0x08; break; }//9600
case 0x07: { SCIHBAUD = 0x01;SCILBAUD = 0x03; break; }//19200
case 0x08: { SCIHBAUD = 0x00;SCILBAUD = 0x81; break; }//38400
case 0x09: { SCIHBAUD = 0x00;SCILBAUD = 0x56; break; }//57600
case 0x0a: { SCIHBAUD = 0x00;SCILBAUD = 0x2a; break; }//115200
default : { SCIHBAUD = 0x00;SCILBAUD = 0x81; break; }//38400
}
if(form==0) { SCICCR = 0x07; } //no parity
else if(form ==1){ SCICCR = 0x67; } //even parity
else if(form ==2){ SCICCR = 0x27; } //odd parity
else { SCICCR = 0x07; } //no parity
SCICTL1 = 0x03; /*发送器接收器使能*/
SCICTL2 = 0x02; /*使能接收中断 */
SCICTL1 |= 0x20; /*sw reset*/
SCIPRI &= 0x87; /* high priority*/
MCRA |= 0x3; // configure iopa0,iopa1 as SCITXD,SCIRXD
IMR |= 0x01;
IFR = 0xffff; //clr all flag
pcdata[0] = 0x05;pcdata[1] = 0x44; /*测试数据*/
pcdata[2] = 0x33;pcdata[3] = 0x22;
pcdata[4] = 0x11;
status_rx = 0;
testSerialOutput(); //test Serial Output
}
/////////////////////////////////////////////////////////////////////////////////////////
void testSerialOutput() // initial serial port testing
{
uchar i;
for(i=0;i<pcdata[0];i++)
serialPortOutput1byte(pcdata[i]);
}
void serialPortOutput1byte(uchar c)
{
setSNT();
b_com_success = 1;
SCITXBUF = c;
while((SCICTL2 & 0x40) == 0);
// while((SCICTL2 & 0xc0) == 0);
clrSNT();
}
void setSNT(void)
{
MCRB &= 0xfffe;
PCDATDIR |= 0x0101; //IOPC0设置为输出方式,置为1,send out
}
void clrSNT(void)
{
MCRB &= 0xfffe;
PCDATDIR |= 0x0100;
PCDATDIR &= 0xfffe; //IOPC0设置为输出方式置为0,receive
}
void send_resp(void)
{
uchar i;
uint j;
i = pcdata[0] - 2;
j = crc16Calculate(pcdata,i);
j = ~j;
pcdata[i] = (j&0xff); //crc LSByte
pcdata[i+1] = (j>>8); //crc MSByte
for(i=0;i<pcdata[0];i++)
serialPortOutput1byte(pcdata[i]);
}
static uchar simConter = 0;
void interrupt GISR1()
{
uchar rec = 0,temp;
uchar i;
uint simSerial;
simSerial = cfgdata[18] >> 8;
switch( PIVR)
{
case 0x0006:
{
b_com_success = 1;
if(status_rx == 0 )
{
len_rx = SCIRXBUF;
if((len_rx > 4)&&(len_rx <188)) //接收数至少要有5个字节
{
p_rx = 0;
pcdata[0] = len_rx;
status_rx = 1;
len_rx --;
p_rx ++;
}
}
else if(status_rx == 1)
{
pcdata[p_rx] = SCIRXBUF;
p_rx ++;
len_rx--;
if(len_rx == 0)
{
status_rx = 2;
}
}
else{rec=SCIRXBUF;} //read to clear RXRDY flag
IFR |= 0x01;
break;
}
case 0x0001: //高优先级模式的外部引脚1中断
{
if(simSerial == 0x06)delay52us(); //取电平的中间位置
else if(simSerial == 0x07)delay26us();
else if(simSerial == 0x08)delay17us();
else delay26us();
for(i=0;i<8;i++)//读取一个字节
{
if(simSerial == 0x06)delay104us(); //位与位之间宽度
else if(simSerial == 0x07)delay52us();
else if(simSerial == 0x08)delay34us();
else delay52us();
switch(i)
{
case 0:{if( (PCDATDIR&0x10) == 0x10 )rec |= 0x01;break;}
case 1:{if( (PCDATDIR&0x10) == 0x10 )rec |= 0x02;break;}
case 2:{if( (PCDATDIR&0x10) == 0x10 )rec |= 0x04;break;}
case 3:{if( (PCDATDIR&0x10) == 0x10 )rec |= 0x08;break;}
case 4:{if( (PCDATDIR&0x10) == 0x10 )rec |= 0x10;break;}
case 5:{if( (PCDATDIR&0x10) == 0x10 )rec |= 0x20;break;}
case 6:{if( (PCDATDIR&0x10) == 0x10 )rec |= 0x40;break;}
case 7:{if( (PCDATDIR&0x10) == 0x10 )rec |= 0x80;break;}
}
}
if(rec == frameHeader)//判断帧头
{
sim_begin = 1;
sim_end = 0;
simConter = 0;
simdata[simConter] = rec;
simConter ++;
}
else if(rec == frameEnd)//判断帧尾
{
simdata[simConter] = rec;
sim_begin = 0;
sim_end = 1;
simConter = 0;
}
if( (sim_begin==1) && (sim_end==0) )
{
simdata[simConter] = rec;
simConter ++;
}
XINT1CR |= 0x8000; //清除xint1 flag
}
default: { break;}
}
}
void simInit(void)
{
MCRA |= 0x0004; // iopa2 as xint1
XINT1CR &= 0xfff9; //下降沿产生中断,高优先级
XINT1CR |= 0x0001; //使能外部中断
simRxdIn; // 输入信号
sc2_snt_0; //接收使能
}
void simOutput1byte(uchar byte)//模拟串口输出一个字节
{
uchar i,temp;
uint simSerial;
simSerial = cfgdata[18] >> 8;
sc2_snt_1; //发送时打开发送使能
simTxdout1; // txd =1;
simTxdout0;
if(simSerial == 0x06)delay104us(); //开始位
else if(simSerial == 0x07)delay52us();
else if(simSerial == 0x08)delay34us();
else delay52us();
temp = 0x01;
for(i=0;i<8;i++) //8位数据位
{
if( byte&temp ){simTxdout1;}
else {simTxdout0;}
if(simSerial == 0x06)delay104us();
else if(simSerial == 0x07)delay52us();
else if(simSerial == 0x08)delay34us();
else delay52us();
temp = temp << 1;
}
simTxdout1;
if(simSerial == 0x06)delay104us(); //停止位
else if(simSerial == 0x07)delay52us();
else if(simSerial == 0x08)delay34us();
else delay52us();
delay104us(); //字节与字节之间延时
sc2_snt_0; //关闭发送使能
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -