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

📄 jd1a.c

📁 美国wind river 公司的CAN总线源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
    return 0;
}

/*
********************************************************************************************
**函数原型: bit BCAN_SET_OUTCLK (unsigned char Out_Control,
** unsigned char Clock_Out)
**参数说明: Out_Control:存放输出控制寄存器(OC) 的参数设置;
** Clock_Out:存放时钟分频寄存器(CDR) 的参数设置
**返回值: 0 ;设置成功
** 1 ;设置失败
* *说明: 设置SJA1000 的输出模式和时钟分频该子程序只能用于复位模式
********************************************************************************************
*/
bit BCAN_SET_OUTCLK (unsigned char Out_Control,unsigned char Clock_Out){
    SJA_BCANAdr=REG_OCR ; //访问地址指向输出控制寄存器
    *SJA_BCANAdr=Out_Control; //写入参数
    if(*SJA_BCANAdr != Out_Control) { //校验写入值
       return 1;
    }
    SJA_BCANAdr=REG_CDR; //访问地址指向输出控制寄存器
    *SJA_BCANAdr=Clock_Out; //写入参数
    return 0;
}

/*
********************************************************************************************
**函数原型: bit BCAN_DATA_WRITE(unsigned char *SendDataBuf)
**参数说明: SendDataBuf 特定帧各式的数据
**返回值: 0 表示将数据成功的送至发送缓冲区
** 1 送至发送缓冲区失败
**说明: 注本函数的返回值仅指示将数据正确写入SJA1000 发送缓存区中与否
** 不指示SJA1000 将该数据正确发送到CAN 总线上完毕与否
********************************************************************************************
*/
bit BCAN_DATA_WRITE(unsigned char *SendDataBuf){
    unsigned char TempCount,status;
    SJA_BCANAdr = REG_STATUS; //访问地址指向状态寄存器
    if((*SJA_BCANAdr&0x08) == 0) { //判断上次发送是否完成
       return(1);
    }
    if((*SJA_BCANAdr&0x04)==0) { //判断发送缓冲区是否锁定
       return(1);
    }
    SJA_BCANAdr = REG_TxBuffer1; //访问地址指向发送缓冲区1
    if((SendDataBuf[1]&0x10)==0) { //判断RTR 从而得出是数据帧还是远程帧
       TempCount =(SendDataBuf[1]&0x0f)+2; //输入数据帧
    }
    else{
       TempCount =2; //远程帧
    }
    memcpy(SJA_BCANAdr,SendDataBuf,TempCount);
    return 0;
}
/**函数原型: bit BCAN_DATA_RECEIVE(unsigned char *RcvDataBuf)
**参数说明: RcvDataBuf,存放微处理器保存数据缓冲区
**返回值: 0;接收成功
** 1;接收失败
**说明: CAN 控制器接收数据,仅限于接收数据
********************************************************************************************
*/
bit BCAN_DATA_RECEIVE(unsigned char *RcvDataBuf) {
    unsigned char TempCount;
    SJA_BCANAdr = REG_STATUS; //访问地址指向状态寄存器
    if((*SJA_BCANAdr&0x01)==0) { //判断报文是否有效
        return 1;
    }
    SJA_BCANAdr = REG_RxBuffer2; //访问地址指向接收缓冲区2
    if((*SJA_BCANAdr&0x10)==0) { //如果是数据帧
        TempCount=(*SJA_BCANAdr&0x0f)+2; //计算报文中数据的个数
    }
    else{
        TempCount=2;
    }
    SJA_BCANAdr = REG_RxBuffer1; //访问地址指向接收缓冲区1
    memcpy(RcvDataBuf,SJA_BCANAdr,TempCount); //读取接收缓冲区的报文
    return 0;
}

/**函数原型: bit BCAN_CMD_PRG(unsigned char cmd)
**参数说明: cmd:sja1000 运行的命令字
**返回值: 0 ; 表示命令执行成功
** 1; 表示命令执行失败
**说明: 执行sja1000 命令
********************************************************************************************
*/
bit BCAN_CMD_PRG(unsigned char cmd) {
    SJA_BCANAdr=REG_COMMAND; //访问地址指向命令寄存器
    *SJA_BCANAdr=cmd; //启动命令字
    switch(cmd){
        case TR_CMD: //发送请求命令
             return 0;
             break;
        case AT_CMD: //夭折发送命令
             SJA_BCANAdr = REG_STATUS; //访问地址指向状态寄存器
             if((*SJA_BCANAdr & 0x20)==0) { //判断是否正在发送
                return 0;
             }
             else{
                return 1;
             }
             break;
        case RRB_CMD: //释放接收缓冲区
             SJA_BCANAdr = REG_STATUS; //访问地址指向状态寄存器
             if((*SJA_BCANAdr & 0x01)==1) { //判断是否释放成功
                return 1;
             }
             else{
                return 0;
             }
             break;
        case COS_CMD: //清除超载状态
             SJA_BCANAdr = REG_STATUS; //访问地址指向状态寄存器
             if((*SJA_BCANAdr & 0x02)==0) { //判断清除超载是否成功
               return 0;
             }
             else{
               return 1;
             }
             break;
        case GTS_CMD: //进入睡眠状态命令
             return 0;
             break;
        default:
             return 1;
             break;
     }
}


// 串行口 ************************************************************************
// Trax string via SBUFF untill s[i]==0
void traxstring(unsigned char *s)
{
  unsigned char i=0;

  while(s[i])
  {
    SBUF=s[i];
    do{
        _nop_();
      }
      while(!TI);
    TI=0;
    i++;
  }
}

//Interrupt function of the serial com
void ints(void) interrupt 4 using 3
{
    unsigned char ich;

    ES=0;
    RI=0;

    ich=SBUF;

    if(ich=='$')
    {
        buff[0]=ich;
        comnum=1;
        ROK=0;
    }
    else if(ich==10)				//Receive until SBUF==10
    {
        buff[comnum]=0;
        ROK=1;
        comnum=0;
    }
    else
    {
        buff[comnum]=ich;
        comnum++;
        ROK=0;
    }

    if(comnum>108)		//Receive until comnum>108
      {
        ROK=0;
        comnum=0;
      }

    ES=1;
}
void i2hex2(unsigned char ch,unsigned char *s)
{
    unsigned char i;
    i=(ch>>4) & 0x0f;
    if(i<10) s[0]=i+'0';
    else s[0]=i-10+'A';

    i=ch & 0x0f;
    if(i<10) s[1]=i+'0';
    else s[1]=i-10+'A';

    s[2]=0;
}
//将十六进制的字符串转换为数字
int hex2i(unsigned char *s)
{
    unsigned char i,len,ch;
    unsigned int ii;
    len=strlen(s);
    ii=0;
    for(i=0;i<len;i++)
    {
        ii<<=4;
        if(s[i]>='0' && s[i]<='9')
          ii=ii+s[i]-'0';
        else if(s[i]>='a' && s[i]<='f')
          ii=ii+10+s[i]-'a';
        else if(s[i]>='A' && s[i]<='F')
          ii=ii+10+s[i]-'A';
    }
    return(ii);
}

void delayms(unsigned int n)  //delay for n ms
{
  unsigned int i,j;

  for(i=0;i<n;i++){
     for(j=0;j<101;j++)    //   @11.0592MHz  229@22.1184MHz
     {
        _nop_();
     }
  }
}

//我的子程序结束*******************************************************************************


// LCD 12864 显示屏 函数  ******************************************************************************
//显示一个字符或发送一个命令  20050426
void w_cd(unsigned char dat,unsigned char cd_type)   /* type=0(instruction), type=1(data) */
{
   int i;

   LCDCS=1;
   SID=1;  SCLK=0;
   for(i=0;i<5;i++)
   { SCLK=1;SCLK=0;}

   SID=0;SCLK=1;SCLK=0; //RW=0;

   if(!cd_type)
     { SCLK=1;SCLK=0;SCLK=1;SCLK=0;}
   else
     { SID=1;SCLK=1;SCLK=0;SID=0;SCLK=1;SCLK=0;}

   for(i=0;i<4;i++)
   {
      if(dat & 0x80) SID=1;
      else SID=0;    // SID=serdat[i];
      dat<<=1;
      SCLK=1;SCLK=0;
   }
   for(i=0;i<4;i++)
   { SID=0;SCLK=1;SCLK=0;}

   for(i=0;i<4;i++)
   {
      if(dat & 0x80) SID=1;
      else SID=0;
      dat<<=1;
      SCLK=1;SCLK=0;
   }
   for(i=0;i<4;i++)
   { SID=0;SCLK=1;SCLK=0;}
   LCDCS=1;

   if(!cd_type)   delayms(5);
}
//初始化12864LCD显示屏
void LCDInit()
{
	w_cd(0x38,0);
	w_cd(0x01,0);   //清屏
	w_cd(0x06,0);   //进入点设置
	w_cd(0x0c,0);   //显示状态开关
}

//清屏 12864 LCD
void LCDClear()
{
    int i;
    w_cd(0x80,0);
    for(i=0;i<16;i++)
	{
		w_cd(0xA1,1);w_cd(0xA0,1);
    }
    w_cd(0x90,0);
    for(i=0;i<16;i++)
	{
		w_cd(0xA1,1);w_cd(0xA0,1);
    }
}
//显示 LCDBuff 中的数据
void LCDDisplay(unsigned char x,unsigned char y,unsigned char *LCDBuff)
{
	unsigned char i;
        unsigned char code pos[4]={0x80,0x90,0x88,0x98};
	w_cd(pos[x]+y,0);
	for(i=0;i<16-2*y;i++)
        {
            if(LCDBuff[i]==0) break;
	    w_cd(LCDBuff[i],1);
	}
}

//ADC0832有关函数  修改于 2002-01-19 ********************************************************
unsigned char ADC0832(bit ch)
{
   unsigned char i,result;
   ADCS=1;
   ADCLK=0;

   ADCS=0;
   ADDI=1;      //起始位
   ADCLK=1;
   ADCLK=0;
   ADDI=1;      //单极性方式
   ADCLK=1;
   ADCLK=0;
   if(ch==0) ADDI=0;     //信号通道号
   else ADDI=1;
   ADCLK=1;
   ADCLK=0;
   ADCLK=1;     //再来一个时钟脉冲
   ADCLK=0;

   for(i=0;i<8;i++)  //循环读取数据
   {  result<<=1;
      ADCLK=1;
      if(ADDO) result=result|0x01;
      else result=result&0xfe;
      nop=1;
      ADCLK=0;
      nop=1;
   }
   ADCS=1;
   return result;
}

bit ICclock();
//24C64基本操作函数 ***************************
//I2C 器件开始操作
void ICstart()
{
  ICSDA=1;
  ICSCL=1;
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  ICSDA=0;
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  ICSCL=0;
}

//I2C 器件停止操作
void ICstop()
{
  ICSDA=0;
  ICSCL=1;
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  ICSDA=1;
}

//应答
void ICack()
{
 ICSDA=0;
 ICclock();
}

//无应答
void ICnack()
{
 ICSDA=1;
 ICclock();
}

//从 I2C 器件读入 1 个字节
unsigned char ICinbyt()
{
 unsigned char i,ch;
 bit b;

 ch=0;
 ICSDA=1;
 for(i=0;i<8;i++){
   b=ICclock();
   ch<<=1;
   if(b) ch|=0x01;
   else ch&=0xfe;
 }
 return ch;
}

//向 I2C 器件输出 1 个字节
void ICoutbyt(unsigned char ch)
{
unsigned char i;
 for(i=0;i<8;i++){
   if(ch&0x80) ICSDA=1;
   else ICSDA=0;
   ch<<=1;
   ICclock();
 }
}

//I2C 器件 ICclock
bit ICclock()
{
  bit b;

  _nop_();
  ICSCL=1;
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  b=ICSDA;
  ICSCL=0;
  return b;
}

unsigned char Read8574()
{
  unsigned char ch;
  ICstart();
  ICoutbyt(0x41);
  ICack();
  ch=ICinbyt();
  ICnack();
  ICstop();
  return  ch;
}


//DS18B20 温度传感器 有关函数
//延时
void delay(unsigned int useconds)
{
   for(;useconds>0;useconds--);
}

//复位
unsigned char ow_reset(void)
{
   unsigned char presence;
   DQ = 0; //pull DQ line low
   delay(29); // leave it low for 480us
   DQ = 1; // allow line to return high
   delay(3); // wait for presence
   presence = DQ; // get presence signal
   delay(25); // wait for end of timeslot
   return(presence); // presence signal returned
} // 0=presence, 1 = no part

//从 1-wire 总线上读取一个字节
unsigned char read_byte(void)
{
   unsigned char i;
   unsigned char value = 0;
   for (i=8;i>0;i--)
   {
      value>>=1;
      DQ = 0; // pull DQ low to start timeslot
      DQ = 1; // then return high
      delay(1); //for (i=0; i<3; i++);
      if(DQ)value|=0x80;
      delay(6); // wait for rest of timeslot
   }
   return(value);
}

//向 1-WIRE 总线上写一个字节
void write_byte(char val)
{
   unsigned char i;
   for (i=8; i>0; i--) // writes byte, one bit at a time
   {
      DQ = 0; // pull DQ low to start timeslot
      DQ = val&0x01;
      delay(5); // hold value for remainder of timeslot
      DQ = 1;
      val=val/2;
   }
   delay(5);
}

//读取温度
int Read_Temperature(void)
{
   union{
     unsigned char c[2];
     int x;
   } temp;

   ow_reset();
   write_byte(0xCC); // Skip ROM
   write_byte(0xBE); // Read Scratch Pad
   temp.c[1]=read_byte();
   temp.c[0]=read_byte();
   ow_reset();
   write_byte(0xCC); //Skip ROM
   write_byte(0x44); // Start Conversion
   return temp.x;    //return temp.x/2;
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -