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

📄 main.c

📁 CAN.rar
💻 C
字号:
/**********************************************************************************
     工程名称:   Can测试
      CPU类型:   LPC2148
     晶振频率:   11.0592Mhz
      作  者 :   武宪明  
      单  位 :   济南大学  控制科学与工程学院  自升0702
	  日  期 :  
	  备  注 :   AD0--------P0.4
           	     AD1--------P0.5
           	     AD2--------P0.6
           	     AD3--------P0.7
           	     AD4--------P0.8
           	     AD5--------P0.9
           	     AD6--------P0.10
           	     AD7--------P0.11
           	     RD/E-------P0.19
           	     WR---------P0.20
           	     ALE/AS-----P0.21
           	     CS --------P0.22
************************************************************************************/
#include "config.h"

/* 定义CAN总线起始的GPIO,即D0对应的GPIO值(P0.4) */
#define  CAN_BUS		4
#define  RD             19
#define  RD_1		IO0SET = 1<<RD
#define  RD_0		IO0CLR = 1<<RD
#define  WR             20
#define  WR_1		IO0SET = 1<<WR
#define  WR_0		IO0CLR = 1<<WR
#define  ALE            21
#define  ALE_1		IO0SET = 1<<ALE
#define  ALE_0		IO0CLR = 1<<ALE
#define  CS             22
#define  CS_1		IO0SET = 1<<CS
#define  CS_0		IO0CLR = 1<<CS
#define  SJA_BTR0   0x01// 总线定时寄存器0
#define  SJA_BTR1   0x1c// 总线定时寄存器1
#define  SJA_ACR    0xaa// 验收代码寄存器
#define  SJA_AMR    0x55// 验收屏蔽寄存器
#define  SJA_OCR    0xaa// 输出控制寄存器
#define  SJA_CDR    0x48// 时钟分频寄存器
#define  LED        12
/* 输出CAN总线数据宏定义 */
#define	 OutData(dat)	IO0CLR = 0xFF<<CAN_BUS; IO0SET = (dat&0xff)<<CAN_BUS
uint8  SJA_workmode=1;  //0:为工作在复位模式   1:为工作在工作模式
uint8  connect_ok=0;
struct CAN_BUFstruct{                  //定义CAN数据结构
                     uint8 CAN_ID_H;   //8位---信息功能码2+节点号6
                     uint8 CAN_ID_L;   //3位---数据场格式3
                     uint8 CAN_RTR;    //1位---RTR
                     uint8 CAN_DLC;    //4位---数据长度
                     uint8 CAN_Data[8];//8位---最多8字节数据
                    }receive_BUF,send_BUF;
/*************************************************************************************
函数名:void delay(uint8 data)
功  能:读取CAN总线数据
输  入:寄存器地址
返  回:8位数据
备  注:
**************************************************************************************/
void delay(uint32 data)
{            
  uint32 i;
  for(;data>0;data--)
   { for(i=5;i>0;i--);
   }
}        
/*************************************************************************************
函数名:uint8 Read_Can(uint8 address)
功  能:读取CAN总线数据
输  入:寄存器地址
返  回:8位数据
备  注:
**************************************************************************************/
void GPIO_init(void)
{
 PINSEL0=0x00000000;
 IO0DIR|=(1<<RD)|(1<<WR)|(1<<ALE)|(1<<CS);
 IO0DIR|=1<<LED;
}
/*************************************************************************************
函数名:uint8 Read_Can(uint8 address)
功  能:读取CAN总线数据
输  入:寄存器地址
返  回:8位数据
备  注:
**************************************************************************************/
uint8 Read_Can(uint8 address)
{
 uint32 dat;
 IO0DIR |=(0xff<<CAN_BUS);      //设置为输出口
 ALE_1; 
 CS_1;
 RD_1;
 WR_1;
 OutData(address);              //写入地址
 delay(100);
 ALE_0; 
 CS_0;
 RD_0;
 delay(1);       //10ns
 IO0DIR&=~(0xff<<CAN_BUS);      //设置为输入口
 dat=IO0PIN;
 dat=dat>>CAN_BUS;              //读取总线数据
 CS_1;
 RD_1;
 return (uint8)dat;
}
/*************************************************************************************
函数名:void  Write_Can(uint8 address,uint8 data)
功  能:写数据
输  入:address:待写入数据的地址
           data:待写入的数据
返  回:无
备  注:
**************************************************************************************/
void  Write_Can(uint8 address,uint8 data)
{
 IO0DIR |=(0xff<<CAN_BUS);    //设置为输出口
 ALE_1; 
 CS_1;
 WR_1;
 RD_1;
 OutData(address);            //写入地址
 ALE_0; 
 CS_0;
 WR_0;
 OutData(data);               //写入数据
 CS_1;
 WR_1;
 ALE_1;
 delay(2);
}
/*************************************************************************************
函数名:void  Can_Test(void)
功  能:测试寄存器
输  入:无
返  回:无
备  注:address:0x09  测试寄存器
           data:0xaa  写入的数据
**************************************************************************************/
void  Can_Test(void)
{
 uint8 i;
 Write_Can(0x09,0xaa);
 i=Read_Can(0x09);
 if(i==0xaa)  connect_ok=1;  //连接正常
 else         connect_ok=0;  //连接失败
}
/*************************************************************************************
函数名:void setting_SJA_resetmode(void)
功  能:设置工作模式为复位模式
输  入:无
返  回:无
备  注:
**************************************************************************************/
void setting_SJA_resetmode(void)
{
 uint8 resetdata=0,i;
 resetdata=Read_Can(0x00);
 resetdata|=0x01;
 Write_Can(0x00,resetdata);
 while(SJA_workmode)
      {
      i=Read_Can(0x00);
      if((i&0x01)==1)   SJA_workmode=0;  //置复位模式成功
      else              SJA_workmode=1;  //置复位模式失败
      }
}
/*************************************************************************************
函数名:void setting_SJA_workmode(void)
功  能:设置工作模式为工作模式
输  入:无
返  回:无
备  注:
**************************************************************************************/
void setting_SJA_workmode(void)
{
 uint8 workdata=0;
 workdata=Read_Can(0x00);
 workdata&=0xfe;
 while(SJA_workmode==0)
      { 
       Write_Can(0x00,workdata);
       if((Read_Can(0x00)&0x01)==1)   SJA_workmode=0; //置工作模式成功
       else                           SJA_workmode=1; //置工作模式失败
      }
}
/*************************************************************************************
函数名:void setting_SJA_rate(void)
功  能:设置数据传输速率
输  入:无
返  回:无
备  注:
**************************************************************************************/
uint8 setting_SJA_rate(void)
{
 uint8 setting_success=0;
 while(SJA_workmode)              //工作模式
      { 
       setting_SJA_resetmode();   //设置SJA工作在复位模式
      }
 Write_Can(0x06,SJA_BTR0);
 Write_Can(0x07,SJA_BTR1);
 if((Read_Can(0x06)==SJA_BTR0)&(Read_Can(0x07)==SJA_BTR1))
   {
      setting_success=1;
   }
 else setting_success=0;
 return (setting_success);
}
/*************************************************************************************
函数名:void setting_SJA_dataselect(void)
功  能:设置接收数据类型
输  入:无
返  回:无
备  注:
**************************************************************************************/
uint8 setting_SJA_dataselect(void)
{
 uint8 setting_success=0;
 while(SJA_workmode)              //工作模式
      { 
       setting_SJA_resetmode();   //设置SJA工作在复位模式
      }
 Write_Can(0x04,SJA_ACR);
 Write_Can(0x05,SJA_AMR);
 if((Read_Can(0x04)==SJA_ACR)&(Read_Can(0x05)==SJA_AMR))
   {
      setting_success=1;
   }
 else setting_success=0;
 return (setting_success);
}
/*************************************************************************************
函数名:void setting_SJA_CLK(void)
功  能:设置输出数据类型
输  入:无
返  回:无
备  注:
**************************************************************************************/
uint8 setting_SJA_CLK(void)
{
 uint8 setting_success=0;
 while(SJA_workmode)              //工作模式
      { 
       setting_SJA_resetmode();   //设置SJA工作在复位模式
      }
 Write_Can(0x08,SJA_OCR);
 Write_Can(31,SJA_CDR);
 if((Read_Can(0x08)==SJA_OCR)&(Read_Can(31)==SJA_CDR))
   {
      setting_success=1;
   }
 else setting_success=0;
 return (setting_success);
}
/*************************************************************************************
函数名:void setting_SJA_CLK(void)
功  能:SJA1000初始化
输  入:无
返  回:无
备  注:
**************************************************************************************/
uint8 CAN_init(void)
{
 while(connect_ok==0)                //检测设备连接
      {
       Can_Test();
      }
while(SJA_workmode)                  //置位复位模式
      {
       setting_SJA_resetmode();
      }
 while(setting_SJA_rate()==0)        //设置数据传输速率
      {
       setting_SJA_rate();
      }
while(setting_SJA_dataselect()==0)   //设置接收数据格式
      {
       setting_SJA_dataselect();
      }
  while(setting_SJA_CLK()==0)        //设置输出数据形式
      {
       setting_SJA_CLK();
      }
}
/*************************************************************************************
函数名:uint8 send_CANBUF(void)
功  能:写发送缓存区
输  入:无
返  回:无
备  注:
**************************************************************************************/
uint8 send_CANBUF(void)
{
 uint8 setting_success=0,i;
 while(SJA_workmode)                  //置位工作模式
      {
       setting_SJA_workmode();
      }
 if((Read_Can(0x02)&0x20)==0)         //发送状态为空
   {     
   if((Read_Can(0x02)&0x04)!=0)       //发送缓存器状态为释放
     {
      Write_Can(10,send_BUF.CAN_ID_H);
      Write_Can(11,(send_BUF.CAN_ID_L<<5)|(send_BUF.CAN_RTR<<4)|(send_BUF.CAN_DLC));
      if(send_BUF.CAN_RTR==0)
        {
         for(i=0;i<send_BUF.CAN_DLC;i++)
            {
             Write_Can(12+i,send_BUF.CAN_Data[i]);
            }
        }
     setting_success=1;
     }
   }
 return setting_success;
}
/*************************************************************************************
函数名:receive_CANBUF(void)
功  能:读接收缓存区
输  入:无
返  回:无
备  注: uint8 CAN_ID_H;   //8位---信息功能码2+节点号6
         uint8 CAN_ID_L;   //3位---数据场格式3
         uint8 CAN_RTR;    //1位---RTR
         uint8 CAN_DLC;    //4位---数据长度
         uint8 CAN_Data[8];//8位---最多8字节数据
**************************************************************************************/
uint8 receive_CANBUF(void)
{
 uint8 setting_success=0,i;
 while(SJA_workmode)                  //置位工作模式
      {
       setting_SJA_workmode();
      }
 if((Read_Can(0x02)&0x01)==0)         //接收缓存器状态为空
   {     
   if((Read_Can(0x02)&0x10)!=0)       //接收状态为空闲
     {
      receive_BUF.CAN_ID_H=Read_Can(20);
      receive_BUF.CAN_ID_L=((Read_Can(21)&0xe0)>>5);
      receive_BUF.CAN_RTR =((Read_Can(21)&0x10)>>4);
      receive_BUF.CAN_DLC =(Read_Can(21)&0x0f);
      if(receive_BUF.CAN_RTR==0)
        {
         for(i=0;i<receive_BUF.CAN_DLC,i<8;i++)
            {
             receive_BUF.CAN_Data[i]=Read_Can(22+i);
            }
        }
     setting_success=1;
     }
   }
 return setting_success;
}
/*************************************************************************************
函数名:int main (void)
功  能:主函数
输  入:无
返  回:无
备  注: uint8 CAN_ID_H;   //8位---信息功能码2+节点号6
         uint8 CAN_ID_L;   //3位---数据场格式3
         uint8 CAN_RTR;    //1位---RTR
         uint8 CAN_DLC;    //4位---数据长度
         uint8 CAN_Data[8];//8位---最多8字节数据
**************************************************************************************/
int main (void)
{
  uint8 Tab[8]={0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08};
  uint8 i,j;
  send_BUF.CAN_ID_H=0x01;
  send_BUF.CAN_ID_L=0x00;
  send_BUF.CAN_RTR=0x00;
  send_BUF.CAN_DLC=0x08;
  for(i=0;i<8;i++)
     {
      send_BUF.CAN_Data[i]= Tab[i];
     }
  GPIO_init();
  CS_0;
 // Can_Test();
 // if(connect_ok==1)  IO0SET=1<<LED;
 // else               IO0CLR=1<<LED;
  CAN_init();
  while(1)
  {
  send_CANBUF();
  Write_Can(0x01,0x01);
  }
  return 0;
}
/*********************************************************************************************************
**                            End Of File
********************************************************************************************************/

⌨️ 快捷键说明

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