📄 inout.c
字号:
// general input/output dispose
//中断实现载波红外接收
void interrupt isr(void)
{
static bank1 unsigned char byte, loop, CS;
static bank1 unsigned char frameCS;
if((TMR1IE) && (TMR1IF))
{
TMR1H += c_10MsTimeH; //timer1每10ms中断一次
TMR1IF = 0;
v_msCont++; //系统定时
Buff485Mark.otc++; //485接收超时
BuffPLCMark.otc++;
}
if((RBIE) && (RBIF))
{
//RB电平变化中断
if(_RXD == 0) //先判断载波
{
T2CON = c_T2con9600; //默认载波接收
v_RecPort = c_Port_Plc; //标志接收端口
//载波接收
TMR2 = c_SimBaud*3/4; //延时1/4 bit开始采样
TMR2IF = 0;
TMR2ON = 1; //开始计时
while(TMR2IF == 0)
{} //等待时间到达
TMR2IF = 0;
if(_RXD == 1) //再次判断起始位
{
NOP();
goto IntErr; //接收错误
}
//开始接收数据
loop = 8;
CS = 0; //用于计算校验位
while(loop--)
{
byte >>= 1;
while(TMR2IF == 0)
{} //等待时间到达
TMR2IF = 0;
if(_RXD == 1)
{
byte |= 0b10000000; //置1
CS++;
}
}
//校验位检测
while(TMR2IF == 0)
{} //延时1bit
TMR2IF = 0;
_PLCRXD = 0;
_PLCRXD = 1;
if(_RXD == 1)
{
if((CS & 0b00000001) != 1)
{
goto IntErr;
}
}
else
{
if((CS & 0b00000001) != 0)
goto IntErr;
}
//判断停止位
// while(TMR2IF == 0)
// {} //延时1bit
// TMR2IF = 0;
// if(_RXD == 1)
// {
goto IntDataSave;
// }
// else
// {
// goto IntErr;
// }
}
else if(_IrfTXD == 0)
{
if((BuffPLCMark.Sta != c_Free) && (v_RecPort == c_Port_Plc))
{
goto IntReturn;
}
T2CON = c_T2con1200; //红外接收波特率
v_RecPort = c_Port_Irf; //标志接收端口
//红外接收
TMR2 = c_SimBaud*3/4; //延时1/4 bit开始采样
TMR2IF = 0;
TMR2ON = 1; //开始计时
while(TMR2IF == 0)
{} //等待时间到达
TMR2IF = 0;
if(_IrfTXD == 1) //再次判断起始位
{
goto IntErr; //接收错误
}
//开始接收数据
loop = 8;
CS = 0; //用于计算校验位
while(loop--)
{
byte >>= 1;
while(TMR2IF == 0)
{} //等待时间到达
TMR2IF = 0;
if(_IrfTXD == 1)
{
byte |= 0b10000000; //置1
CS++;
}
}
//校验位检测
while(TMR2IF == 0)
{} //延时1bit
TMR2IF = 0;
if(_IrfTXD == 1)
{
if((CS & 0b00000001) != 1)
{
goto IntErr;
}
}
else
{
if((CS & 0b00000001) != 0)
goto IntErr;
}
//判断停止位
while(TMR2IF == 0)
{} //延时1bit
TMR2IF = 0;
if(_IrfTXD == 1)
{
goto IntDataSave;
}
else
{
goto IntErr;
}
}
else
{
goto IntReturn;
}
//数据放入缓冲区
IntDataSave:
if(BuffPLCMark.Sta == c_Free)
{
if(byte != 0x68)
{
goto IntErr; //扔掉无效字符
}
}
if(BuffPLCMark.ptr>=(BuffPLC+c_BuffMax))//防止溢出
{
goto IntErr;
}
BuffPLCMark.otc = 0; //用于判断字节间超时
*BuffPLCMark.ptr++ = byte; //保存数据
BuffPLCMark.len++; //数据长度+1
BuffPLCMark.Sta = c_RecNow; //接收状态
if(BuffPLCMark.len < c_OffsetL+1)
{
goto IntReturn; //正常返回
}
if(BuffPLCMark.len == c_OffsetL+1)
{
if(0x68 == BuffPLC[c_Offset68_2])
{
v_PLClen = byte + 2; //645数据长度
goto IntReturn;
}
goto IntErr;
}
else
{
//数据域按长度接收
if(--v_PLClen == 0)
{
BuffPLCMark.Sta = c_RecEnd;
frameCS = 0;
}
goto IntReturn;
}
IntErr:
BuffPLCMark.len = 0;
BuffPLCMark.ptr = BuffPLC;
BuffPLCMark.Sta = c_Free;
frameCS = 0;
_Show485 = 0;
IntReturn:
asm("movf _PORTB, w"); //清除标志位
asm("movf _PORTB, w"); //清除标志位
RBIF = 0;
}
}
//485缓冲区检测
void Buff485Rec(void)
{
unsigned char byte;
static unsigned char frame485CS;
if(Buff485Mark.Sta == c_Send) //正在发送退出
{
return;
}
if(OERR) //错误检测
{
CREN = 0;
CREN = 1;
asm("movf _RCREG, w");
asm("movf _RCREG, w");
}
if(RCIF == 0) return; //没有接收
// _Show485 = 1; //数据指示灯
byte = RCREG;
if(Buff485Mark.Sta == c_WaitRec)
{
if(byte != 0x68)
{
frame485CS = 0;
Buff485Mark.ptr = Buff485;
Buff485Mark.len = 0;
// _Show485 = 0;
return; //扔掉无效字符
}
}
if(Buff485Mark.ptr>=(Buff485+c_BuffMax-6)) //防止溢出
{
goto Buff485RecErr;
}
Buff485Mark.otc = 0; //用于判断字节间延时
Buff485Mark.Sta = c_RecNow;
*Buff485Mark.ptr++ = byte;
frame485CS += byte;
Buff485Mark.len++;
if(Buff485Mark.len < c_OffsetL+1)
{
goto Buff485RecEnd; //正常返回
}
else if((0x68 != Buff485[0]) || (0x68 != Buff485[c_Offset68_2]))
{
goto Buff485RecErr;
}
if(Buff485Mark.len == c_OffsetL+1)
{
v_485len = byte + 2; //645数据长度
}
else
{
//数据域按长度接收
if(0 == --v_485len)
{
Buff485Mark.Sta = c_RecEnd;
_Show485 = 0;
}
}
Buff485RecEnd:
//
return;
Buff485RecErr:
Buff485Mark.ptr = Buff485;
Buff485Mark.Sta = c_Free;
frame485CS = 0;
highmemset(Buff485, 0x00, c_BuffMax);
Delay1msx(300u); //异常延时300ms后再通信
}
//载波数据发送
void BuffPLCSend(void)
{
if(BuffPLCMark.Sta == c_Send)
{
if(v_RecPort == c_Port_Plc)
{
putCharPLC(*BuffPLCMark.ptr);
}
else if(v_RecPort == c_Port_Irf)
{
putCharIrf(*BuffPLCMark.ptr);
}
BuffPLCMark.ptr++;
if(--BuffPLCMark.len == 0)
{
BuffPLCMark.Sta = c_Free;
BuffPLCMark.ptr = BuffPLC;
}
}
}
//485数据发送
void Buff485Send(void)
{
if(TRMT == 0) return; //上一字节没有发送完,退出
if(Buff485Mark.Sta == c_Send)
{
// _Show485 = 1; //485通信指示
TXSTA = c_TXsta; //设置485通信参数
RCSTA = c_RCsta;
if(_frame_07 == v_frame_mark)
{
SPBRG = c_Baud_2400;
}
else
{
SPBRG = c_Baud_1200;
}
//处理前导符fe
if(Buff485Mark.feCont!= 0)
{
if(Buff485Mark.feCont > 2) //判断防止过大
{
Buff485Mark.feCont = 2; //默认2
}
//发送fe
TX9D = 1; //偶校验位1
TXREG = 0xfe; //发送fe
Buff485Mark.feCont--;
return;
}
//处理645帧
if(EvenParity(*Buff485Mark.ptr))//计算偶校验位
{
TX9D = 1;
}
else
{
TX9D = 0;
}
TXREG = *Buff485Mark.ptr;
Buff485Mark.ptr++;
Buff485Mark.otc = 0;
if(--Buff485Mark.len == 0)
{
Buff485Mark.Sta = c_WaitRec; //等待接收
Buff485Mark.ptr = Buff485;
CREN = 0;
CREN = 1;
asm("movf _RCREG, w");
asm("movf _RCREG, w");
}
// _Show485 = 0; //485通信指示
}
}
//////////////////////////////////////////
////put one byte to PLC
////intput byte
//////////////////////////////////////////
void putCharPLC(unsigned char byte)
{
unsigned char loop = 8;
unsigned char ver = 0;
GIE = 0; //关闭中断
_Show485 = 1; //通信指示
T2CON = c_T2con9600; //设置发送波特率
TMR2 = 0; //延时1bit开始发送
TMR2IF = 0;
TMR2ON = 1; //开始计时
while(TMR2IF == 0)
{;} //等待时间到达
TMR2IF = 0;
//start bit
_PLCRXD = 0; //起始位
while(TMR2IF == 0)
{;} //等待时间到达
TMR2IF = 0;
//data bit
while(loop--)
{
if(byte & 0b00000001)
{
_PLCRXD = 1;
ver++; //校验
}
else
{
_PLCRXD = 0;
}
while(TMR2IF == 0)
{;} //等待时间到达
TMR2IF = 0;
byte >>= 1; //数据右移
}
//parity bit
if(ver & 0b00000001)
{
_PLCRXD = 1;
}
else
{
_PLCRXD = 0;
}
while(TMR2IF == 0)
{} //等待时间到达
TMR2IF = 0;
_Show485 = 0; //通信指示
GIE = 1; //打开中断
//tail bit
_PLCRXD = 1;
while(TMR2IF == 0)
{;} //等待时间到达
TMR2IF = 0;
}
//////////////////////////////////////////
////put one byte to infrared
////intput byte
//////////////////////////////////////////
void putCharIrf(unsigned char byte)
{
unsigned char loop = 8;
unsigned char ver = 0;
GIE = 0; //关闭中断
T2CON = c_T2con38kHz; //enable timer2
CCP1CON = 0x0f & c_CCP1con; //enable PWM out
Delay1200bit();
//start bit
_IrfRXD = 0; //起始位
Delay1200bit(); //等待时间到达
//data bit
while(loop--)
{
if(byte & 0b00000001)
{
_IrfRXD = 1;
ver++; //校验
}
else
{
_IrfRXD = 0;
}
Delay1200bit();
byte >>= 1; //数据右移
}
//parity bit
if(ver & 0b00000001)
{
_IrfRXD = 1;
}
else
{
_IrfRXD = 0;
}
Delay1200bit();
//tail bit
_IrfRXD = 1;
asm("movf _PORTB, w"); //清除标志位
asm("movf _PORTB, w"); //清除标志位
RBIF = 0;
GIE = 1; //打开中断
Delay1200bit();
CCP1CON = 0xf0 & c_CCP1con; //close PWM out
}
//把内存中的一串数写入EEPROM(MC24LC256)
//////////////////////////////////////////
// put string to external EEPROM
//////////////////////////////////////////
unsigned char
putStrFM(unsigned int EEPROMAddr, bank2 unsigned char *src, unsigned char n)
{
unsigned char w_wait;
v_IntRunFlag = c_putStrFM;
safeCheck();
reStart:
GIE = 0; //关闭中断
_FMWP = 0; //使能写入
for(w_wait=0; w_wait<64; w_wait++)
{
I2CStart();
if(_TRUE == I2CByteTX(0xa0)) //发送器件地址
{
break;
}
I2CStop();
Delay1msx(1);
}
if(w_wait >= 64)
{
_FMWP = 1;
GIE = 1;
return _FALSE;
}
if(_FALSE == I2CByteTX((unsigned char)(EEPROMAddr/0x100))) //发送逻辑地址,高字节
{
_FMWP = 1;
GIE = 1; //中断
return _FALSE;
}
if(_FALSE == I2CByteTX((unsigned char)(EEPROMAddr))) //发送逻辑地址,低字节
{
_FMWP = 1;
GIE = 1; //中断
return _FALSE;
}
//发送数据
while(n--)
{
ClrWdt();
if(_FALSE == I2CByteTX(*src++))
{
_FMWP = 1;
GIE = 1; //中断
return _FALSE;
}
EEPROMAddr++; //地址标志+1,判断是否跨越边界
if((EEPROMAddr%c_eepage) == 0)
{
break; //结束本次写入循环,跨页处理
}
}
//停止位
I2CStop();
GIE = 1; //中断
if(n != 0xff)
{
goto reStart;
}
_FMWP = 1;
return _TRUE;
}
unsigned char
putStrFMlow(unsigned int EEPROMAddr, unsigned char *src, unsigned char n) //n不能大于64
{
unsigned char w_wait;
v_IntRunFlag = c_putStrFM;
safeCheck();
reStart:
GIE = 0; //关闭中断
_FMWP = 0; //使能写入
for(w_wait=0; w_wait<64; w_wait++)
{
I2CStart();
if(_TRUE == I2CByteTX(0xa0)) //发送器件地址
{
break;
}
I2CStop();
Delay1msx(1);
}
if(w_wait >= 64)
{
_FMWP = 1;
GIE = 1;
return _FALSE;
}
if(_FALSE == I2CByteTX((unsigned char)(EEPROMAddr/0x100))) //发送逻辑地址,高字节
{
_FMWP = 1;
GIE = 1; //中断
return _FALSE;
}
if(_FALSE == I2CByteTX((unsigned char)(EEPROMAddr))) //发送逻辑地址,低字节
{
_FMWP = 1;
GIE = 1; //中断
return _FALSE;
}
//发送数据
while(n--)
{
ClrWdt();
if(_FALSE == I2CByteTX(*src++))
{
_FMWP = 1;
GIE = 1; //中断
return _FALSE;
}
EEPROMAddr++; //地址标志+1,判断是否跨越边界
if((EEPROMAddr%c_eepage) == 0)
{
break; //结束本次写入循环,跨页处理
}
}
//停止位
I2CStop();
GIE = 1; //中断
if(n != 0xff)
{
goto reStart;
}
_FMWP = 1;
return _TRUE;
}
//////////////////////////////////////////
// 外部存储器,一定区域写入相同数据
//////////////////////////////////////////
unsigned char
FMSet(unsigned int EEPROMAddr, unsigned char data, unsigned char n)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -