⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ncjp.cpp

📁 对CAN的SJA1000的初始化
💻 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 + -