📄 ncjp.cpp
字号:
#ifdef __cplusplus
#define __CPPARGS ...
#else
#define __CPPARGS
#endif
void interrupt Can0_ISR(__CPPARGS);
void interrupt Can1_ISR(__CPPARGS);
// SJA1000结构
struct CSJA1000Port {
//...控制.命令.状态.中断.验收.屏蔽..........输出.测试
unsigned char CR ,CMR, SR, IR, ACR, AMR,BTR0,BTR1,OCR, TR; // 寄存器00..09
unsigned char TxDSCR[2],TxData[8]; //发送ID,数据 10..19
unsigned char RxDSCR[2],RxData[8]; //接收ID,数据 20..29
unsigned char XX30,CDR; //31 时钟驱动 30..31
// unsigned char XX32[0x0100-32],RST; //复位控制 0x0100
} *Can0,*Can1;
struct CanFrame {
unsigned char flag; // 标志
unsigned char data[8];
};
//******** 全局变量定义 *********
int FlagRx,FlagTx;
struct CanFrame Can_Receive[48],Can_ParameterBuffer[8],parameter_buffer[8];
int Timer_SelfTest;
unsigned char Timer_CanSet, Timer_CanRemind, Timer_CanDir;
unsigned int OldCanAgreement;
// int Can0_temp,Can1_temp;
int Can0_Work,Can1_Work,Can_Fail=0;
enum { // 发送状态
Can_SendIdle // 发送空闲
,Can_SendSelfTest // 正在发送自诊断信息
,Can_SendParameter // 正在发送设定参数
,Can_Send_Request
,Can_SendKey
,Can_SendRemind
} Can_SendStat;
#include <dos.h>
#include <stdio.h>
#include "lcd_can.h"
#include "lcd_def.h"
/******** CAN procedure ********/
// 500K速率下,每帧约200uS,传输256B的文件数据约>=7mS
// IC卡页擦除&编程>=10mS.
// 写IC卡buffer,每页需15ms.
// 写&校验一页约40ms.
// 经测试,如果不考虑通讯,写&校验512K约80秒.实际转储510K约195秒(LCD2000,数码显示器需190秒).
// CR.4 OIE Overrun Interrupt Enable
// CR.3 EIE Error Interrupt Enable
// CR.2 TIE Transmit Interrupt Enable
// CR.1 RIE Receive Interrupt Enable
// CR.0 RR Reset Request
extern unsigned char BrakeTest;
void Can_EI(int port) // 开放中断
{
if (port) Can1->CR=0x0b;
else Can0->CR=0x0b;
}
void Can_DI(int port) // 关闭中断
{
if (port) Can1->CR=0x00;
else Can0->CR=0x00;
}
void Can_PutCR(int port,BYTE cr) // 置控制
{
if(port) Can1->CR=cr;
else Can0->CR=cr;
}
BYTE Can_GetCR(int port) // 读控制
{
if(port) return Can1->CR;
else return Can0->CR;
}
void Can_PutCMR(int port,BYTE b) // 置命令
{
if(port) Can1->CMR=b;
else Can0->CMR=b;
}
BYTE Can_GetSR(int port) // 读状态
{
if(port) return Can1->SR;
else return Can0->SR;
}
BYTE Can_GetIR(int port) // 读中断
{
if(port) return Can1->IR;
else return Can0->IR;
}
BYTE Can_GetRxIDH(int port)
{
if(port) return Can1->RxDSCR[0];
else return Can0->RxDSCR[0];
}
BYTE Can_GetRxIDL(int port)
{
if(port) return (Can1->RxDSCR[1]&IDLMask)>>IDLShift;
else return (Can0->RxDSCR[1]&IDLMask)>>IDLShift;
}
int Can_TxOK(int port)
{
return Can_GetSR(port)&FlagTCS;
}
void Can_StartTx(int port) // 启动发送
{
if(port) Can1->CMR=FlagTR;
else Can0->CMR=FlagTR;
}
void Can_StopTx(int port) // 中止发送
{
if(port) Can1->CMR=FlagAT;
else Can0->CMR=FlagAT;
}
void Can_ReleaseRx(int port) // 释放接收缓冲区
{
if(port) Can1->CMR=FlagRRB;
else Can0->CMR=FlagRRB;
}
void Can_ClearOver(int port) // 清除超载状态
{
if(port) Can1->CMR=FlagCOS;
else Can0->CMR=FlagCOS;
}
void Can_SetMask(int port,BYTE ac,BYTE am) // 置接收过滤
{
if(port) { Can1->ACR=ac; Can1->AMR=am; }
else { Can0->ACR=ac; Can0->AMR=am; }
}
int Can_InitHW(int port) // initiallize and configure can controller
{
BYTE temp;
// Can_PutCR(port,FlagRR);
// Can_Reset(port);
delay(10);
Can_EI(port);
delay(10);
if (!port) {
Can0->BTR0=BTR0_Data;
Can0->BTR1=BTR1_Data;
if (Can0->BTR0!=BTR0_Data || Can0->BTR1!=BTR1_Data) return EVerify;
Can0->ACR=0x07;
Can0->AMR=0xff; // 开放所有ID
Can0->OCR=0xFA; // 11111010
} else {
Can1->BTR0=BTR0_Data;
Can1->BTR1=BTR1_Data;
if (Can1->BTR0!=BTR0_Data || Can1->BTR1!=BTR1_Data) return EVerify;
Can1->ACR=0x07;
Can1->AMR=0xff; // 开放所有ID
Can1->OCR=0xFA; // 11111010
}
temp=Can_GetIR(port); // 清IR
// Can_PutCR(port,0x00);
return 0;
}
//**********初始化Can控制器***********
Can_Init()
{
BYTE temp;
// reset can controller
Can0=(struct CSJA1000Port *)MK_FP(Can_Segment,0);
Can1=(struct CSJA1000Port *)MK_FP(Can_Segment,0x200);
Can_InitHW(0);
Can_InitHW(1);
// 设置can0中断服务程序
disable();
setvect(CAN0_IntNo,Can0_ISR);
setvect(CAN1_IntNo,Can1_ISR);
enable();
outportb(0x21,0); // 8259_1屏蔽=0
// put Can0,Can1 to Normal mode
temp=Can_GetCR(0);
if (temp&1) Can_PutCR(0,temp&0xfe);
temp=Can_GetCR(1);
if (temp&1) Can_PutCR(1,temp&0xfe);
}
// reset can controller
int Can_Reset( BYTE port) // No use in new pcb board
{
BYTE temp;
if (port) {
Can_InitHW(1);
temp=Can_GetCR(1);
if (temp&1)
Can_PutCR(1,temp&0xfe);
} else {
Can_InitHW(0);
temp=Can_GetCR(0);
if (temp&1) Can_PutCR(0,temp&0xfe);
}
}
void Can_Send_Key(BYTE key,BYTE flag,BYTE voice_flag)
{
if((((Can_Receive[14].data[4]&0x04)>>2)==Local_ID)||(Can_Receive[6].data[6]&0x40)||(Can_Receive[6].data[6]&0x10)||key==0x16||key==0x42)//控制权判断
{
Timer_CanSet=10;
flag=~inportb(KEY_SUB_ADR)&0x33; // Read Assistant Driver button
//for port I
Can0->TxDSCR[0]=0x30; // 显示器地址码=04
Can0->TxDSCR[1]=((Local_ID<<IDLShift)&IDLMask)|2; // 只有2 Byte
Can0->TxData[0]=key;
Can0->TxData[1]=flag;
Can_MasterReceiveOK=0; // clear flag
Can0->CMR=FlagTR; // 启动发送
//for port II
Can1->TxDSCR[0]=0x30; // 显示器地址码=04
Can1->TxDSCR[1]=((Local_ID<<IDLShift)&IDLMask)|2; // 只有2 Byte
Can1->TxData[0]=key;
Can1->TxData[1]=flag;
Can1->CMR=FlagTR; // 启动发送
while (Timer_CanSet&&!Can_MasterReceiveOK); // 等待主机握手
watch_dog(2);
if(Timer_CanSet&&voice_flag) keyboard_play();
// if (Timer_CanSet) beep(500,1);
}
}
void interrupt Can1_ISR(__CPPARGS)
{
int i;
BYTE flag;
BYTE far *s,*d;
BYTE id,frame_no,length;
// disable();
flag=Can_GetIR(1);
if (flag&FlagRI) {
id=Can1->RxDSCR[0];
frame_no=(Can1->RxDSCR[1]&IDLMask)>>IDLShift;
length=Can1->RxDSCR[1]&DLCMask;
switch (id) {
case 0x20: // 主机握手 原0x01
if (Local_ID) // 主机接收本端显示器正常
{
if (Can1->RxData[0]&0x10) Can_MasterReceiveOK=1;
} else {
if (Can1->RxData[0]&0x20) Can_MasterReceiveOK=1;
}
break;
。。。。。。。
Can1->CMR=FlagRRB; // 清除接收缓冲区
Can1_Work=0x10;
} else {
// 错误中断
if(Can1->CR&0x01) // Bus-off
Can1->CR=Can1->CR&0xfe; // 清除复位
else
Can1->CMR=0x08; // 清除数据超载
}
// if (flag&FlagTI)
// {}
outportb(0x20,0x20);
enable();
T
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -