• 大小: 21KB
    文件类型: .rar
    金币: 1
    下载: 0 次
    发布日期: 2021-05-21
  • 语言: 其他
  • 标签: CAN总线  

资源简介

基于CAN总线的简单发送和接收程序,由此程序可以了解CAN的基本工作原理。对初学者很有帮助,并且可以以此做为模板进行CAN总线收发的编写。

资源截图

代码片段和文件信息

#include 
#define byte unsigned char
#define word unsigned int
#define TIM0  -50000
#define MyAddr  1
#define PtAddr  2
#define READ   ‘R‘
#define WRIT   ‘W‘
#define CAN_PORT P0
sbit CAN_RST = P2^7;
bit TMS;
#define CAN_CR   0    //控制
#define CAN_CMR  1    //命令
#define CAN_SR   2    //状态
#define CAN_IR   3    //中断
#define CAN_ACR  4    //验收
#define CAN_AMR  5    //屏蔽
#define CAN_BTR0 6    //时序0
#define CAN_BTR1 7    //时序1
#define CAN_OCR  8    //输出
#define CAN_TXB  10   //发送缓冲
#define CAN_RXB  20   //接收缓冲
#define CAN_CDR  31   //分频
byte pdata CAN[32] _at_(0);
sbit LED1    = P2^0;
sbit LED2    = P2^1;
sbit KEY1    = P2^2;
sbit KEY2    = P2^3;
sfr  AUX  = 0x8E; //辅助/附加接口
sfr  WDT  = 0xA6; //看门狗
void WDTRST()
{
  EA=0; //关中断
  WDT=0x1e; //看门狗
  WDT=0xe1;
  EA=1; //开中断
}

bit CANBUS;
byte idata TXB[10];//idata表示外部地址
byte idata RXB[10];

//1、data 的数据类型是直接访问;idata的数据类型是间接访问。
//2、data 的类型数据只能存储在低128个字节中,而idata的类型的数据可以
//   存储在256个字节中(低128个字节和高128个字节);idata类型的数据具体
//   的存储位置(低128个字节或高128个字节)编译器会自动分配。


void delay(word p)
{
  while(p--);
}

void CAN_SEND() /*发送数据部分*/
{
 byte ip;
 p=CAN[CAN_SR]; //状态寄存器的内容给p
 if (p&0x04) //检查第三位即发送缓冲器的状态,为1 CPU可以向发送缓冲器写报文
 {
  p=CAN_TXB;        /*p指向发送缓存首址*/
  for(i=0;i<10;i++) CAN[p++]=TXB[i];
  CAN[CAN_CMR]=0x01;     /*请求发送*/
 }
}

void CAN_INT() interrupt 0 using 1/*接收中断*/
{
  byte ip;
  p=CAN[CAN_IR];
  if(p&0x01) //中断寄存器的低一位为一:RXFIFO不空且中断寄存器的RIE(接收中断使能)位置1
  {
    p=CAN_RXB;//接收数据的首地址给p
    for(i=0;i<10;i++)
    {
     RXB[i]=CAN[p++];//读接收的数据
    }
    CAN[CAN_CMR]=0x04;     /*释放接收缓存*/
    CANBUS=1;
  }
}

void CAN_INI()  /*初始化部分*/
{
  CAN[CAN_CR]=0x01;    //进入复位模式,允许访问各个寄存器
  CAN[CAN_ACR]=MyAddr; //验收,表示接收的数据中第一位为1。
  CAN[CAN_AMR]=0x00;    //屏蔽;00表示不屏蔽,8位全有效。
  CAN[CAN_BTR0]=0x07;   //总线时序0
  CAN[CAN_BTR1]=0xff; //总线时序1
  CAN[CAN_OCR]=0x1A;   //0xaa0xd20xfa 输出控制
  CAN[CAN_CR]=0x02;     //接收中断使能,否则不能接收  
  
}

void Timer1() interrupt 1 using 1
{
  TH0=TIM0&0XFF; TL0=TIM0>>8;  TR0=1;
  TM=1;
}

void main() 
{
 byte CMD; AUX=2;//   AUX=2??,实际单片机晶振和原理图不同
 IE=0x83; //打开外部中断0x82为关闭外部中断
 IT0=1;//外中断请求信号方式控制位:1 脉冲方式(后沿负跳有效)0 电平方式(低电平有效)
 TH0=TIM0&0XFF; TL0=TIM0>>8;  TR0=1; //启动0号计数器-50000equsFFFF3CB0;TH0==B0TL0==3C
 KEY1=1;KEY2=1;LED1=0;LED2=0;
 delay(15000);LED1=1;LED2=1;
 CAN_INI();
 while(1)
 {
   if(TM)
   {
     S=!S; TM=0;
     TXB[0]=PtAddr;
     TXB[1]=8;
     TXB[2]=MyAddr; 
 if(S)//判断按键按下?然后发送数据
 {
       TXB[3]=WRIT;
       if(KEY1==0) TXB[4]=0; else TXB[4]=1;
       if(KEY2==0) TXB[5]=0; else TXB[5]=1;
       CAN_SEND();
   }
 else
 {
       TXB[3]=READ;
       CAN_SEND();
 }
  }
   if(CANBUS)
   {
     CANBUS=0;
    CMD=RXB[3]; 
 if(CMD==WRIT)        //WRIT
 {
   if(RXB[4]==0) LED1=0; else LED1=1;
   if(RXB[5]==0) LED2=0; else LED2=1;
 }
 else if(CMD==READ)   //READ
 {
TXB[0]=RXB[2];
    TXB[1]=8;
    TXB[2]

 属性            大小     日期    时间   名称
----------- ---------  ---------- -----  ----

     文件       2771  2010-06-09 10:48  can程序\CAN总线实验板A--2号.C

     文件       3641  2010-06-09 10:48  can程序\CAN总线实验板A--1号.c

     文件    1797366  2010-03-30 23:08  can程序\CAN总线系统大板A2图.bmp

     目录          0  2010-06-09 10:49  can程序

----------- ---------  ---------- -----  ----

              1803778                    4


评论

共有 条评论