📄 can.c
字号:
#include<XC886CLM.H>
#include<stdio.h>
#include "can.h"
//uchar tmp;
//#define _can_0_
typedef struct can_struct
{
uchar leibie;//侦的类别 0标准 1扩展
ulong signal;
unsigned char length;
unsigned char data0[8];
} can_data;
can_data a,b;
void can_write(uword addr,ulong value)
{
CAN_ADL=(addr>>2)&0xff;
CAN_ADH=(addr>>10)&0x0f;
CAN_DATA0=value&0xff;
CAN_DATA1=(value>>8)&0xff;
CAN_DATA2=(value>>16)&0xff;
CAN_DATA3=(value>>24)&0xff;
CAN_ADCON=0xf1;
while(BSY==1);
//BSY=0;
}
//reg 0 2 4 8 选择写那个寄存器
void can_write_0(uword addr,uchar value,uchar reg)
{
uchar i=1;
CAN_ADL=(addr>>2)&0xff;
CAN_ADH=(addr>>10)&0x0f;
switch (reg)
{
case 0:
V0=1;
CAN_DATA0=value;break;
case 1:
V1=1;
CAN_DATA1=value;break;
case 2:
V2=1;
CAN_DATA2=value;break;
case 3:
V3=1;
CAN_DATA3=value;break;
}
//AUAD=0X01;
RWEN=1;
while(BSY==1);
}
void can_read(uword addr)
{
CAN_ADL=(addr>>2)&0xff;
CAN_ADH=(addr>>10)&0x0f;
RWEN=0;
while(BSY==1);
// BSY=0;
}
//置位
void set_bit(uword addr,uchar bitnum,uchar value)
{
uchar i=1;
//can_read(addr);
CAN_ADL=(addr>>2)&0xff;
CAN_ADH=(addr>>10)&0x0f;
if(bitnum<8) {
if(value)
CAN_DATA0|=(i<<bitnum);
else
CAN_DATA0&=~(i<<bitnum);
V0=1;
}
else if(bitnum>=8&&bitnum<16)
{
if(value)
CAN_DATA1|=(i<<(bitnum-8));
else
CAN_DATA1&=~(i<<(bitnum-8));
V1=1;
}
else if(bitnum>=16&&bitnum<24)
{
if(value)
CAN_DATA2|=(i<<(bitnum-16));
else
CAN_DATA2&=~(i<<(bitnum-16));
V2=1;
}
else if(bitnum>=24&&bitnum<32)
{
if(value)
CAN_DATA3|=(i<<(bitnum-24));
else
CAN_DATA3&=~(i<<(bitnum-24));
V3=1;
}
RWEN=1;
while(BSY==1);
}
//读相应的位
uchar read_bit(uword addr,uchar bitnum)
{
uchar i=1;
//can_read(addr);
CAN_ADL=(addr>>2)&0xff;
CAN_ADH=(addr>>10)&0x0f;
RWEN=0;
while(BSY==1);
if(bitnum<8) {
//V0=1;
return CAN_DATA0&(i<<bitnum) ;
}
else if(bitnum>=8&&bitnum<16)
{
//V1=1;
return CAN_DATA1&(i<<(bitnum-8));
}
else if(bitnum>=16&&bitnum<24)
{
//V2=1;
return CAN_DATA2&(i<<(bitnum-16));
}
else if(bitnum>=24&&bitnum<32)
{
//V3=1;
return CAN_DATA3&(i<<(bitnum-24));
}
}
//写发送数据
void write_send_data(can_data data1)
{
uchar j=0,k=0,p=0;
can_write_0(MOFCR0,data1.length,3);
if(data1.leibie==1)
can_write(MOAR0,((data1.signal)|0x20000000));
else
can_write(MOAR0,(data1.signal<<18)&0XDFFFFFFF);
while(data1.length--)
{
//can_wtrite_0((0X1010+j+k),data1.data0[j],p);
//PORT_PAGE=0;
//P3_DATA=data1.data0[j];
can_write_0((MODATAL0+p),data1.data0[j],j);
j++;
//p++;
if(j>=4)
{
// k=k+0x20;
p++;
}
} //end while
}
//接受报文函数 p458
void receive_message()
{
set_bit(MOSTAT0,MSGVAL,1);
set_bit(MOSTAT0,RXEN,1);
set_bit(MOSTAT0,NEWDAT,0);
//设置接受标识符
can_write(MOAR0,0XF0);
while(read_bit(MOSTAT0,RTSEL)==0);
while(read_bit(MOSTAT0,NEWDAT)!=0&&read_bit(MOSTAT0,RXUPD)!=0);
set_bit(MOSTAT0,NEWDAT,1);
if(read_bit(MOSTAT0,RXPND)==1)
{
set_bit(MOSTAT0,RXPND,0);
//设置p3值
}
}
//PANAR2为列表,panar1为报文对象,pancmd位命令
void write_pancom(uchar pancmd,uchar panar1 ,uchar panar2)
{
CAN_ADL=(PANCTR>>2)&0xff;
CAN_ADH=(PANCTR>>10)&0x0f;
CAN_DATA0=pancmd;
CAN_DATA2=panar1;
CAN_DATA3=panar2;
CAN_ADCON=0XD5;//必须在data数据之后设置
while(BSY==1);
while(read_bit(PANCTR,0X08)!=0);
}
void can1_init()
{
//节点1控制
//漏极开路选择
PORT_PAGE = 0x03;
P1_OD = 0x00;
PORT_PAGE = 0x00;
//1.3out,1.4in
P1_DIR=0x08;
//设置rxsel
set_bit(NCR1,CCE,1);
can_write_0(NPCR1,0X03,0);
PORT_PAGE=0x02;
P1_ALTSEL0 = 0x02;
P1_ALTSEL1 = 0x02; //p477,端口选择
//写面板控制寄存器,静态分配,将报文对象0给节点1
write_pancom(0x02,0x00,0x02);
//位时序控制,CCE置位
can_write(NBTR1,0X3487);
//设置ncr1(p495),使能can1节点
can_write(NCR1,0x0e);
//set_bit(NCR1,CCE,0);
return;
}
//can初始化
/*********选择节点0 ,直接使用复位值(由npcr0控制)
p1.0(in) p1.1(out)
******************************/
void can_init()
{
#ifdef _can_0_
//漏极开路选择
PORT_PAGE = 0x03;
P1_OD = 0x00;
PORT_PAGE = 0x00;
P1_DIR=0xfe;
//设置rxsel
set_bit(NCR0,CCE,1);
can_write_0(NPCR0,0X00,0);
PORT_PAGE=0x02;
P1_ALTSEL0 = 0x02;
P1_ALTSEL1 = 0x02; //p477,端口选择
//写面板控制寄存器,静态分配,将报文对象0给节点1
write_pancom(0x02,0x00,0x01);
//测试是否给list1分配报文对象
/*
can_read(MOSTAT0);
if((CAN_DATA1&0xf0)==0x10)
{
PORT_PAGE=0;
P3_DATA=0x55;
}
if(read_bit(0x0104,24)==0)
{
PORT_PAGE=0;
P3_DATA=0XFF;
}*/
//位时序控制,CCE置位
can_write(NBTR0,0X3487);
//设置ncr0 (p495),使能can0节点
can_write(0x0200,0x0e);
//set_bit(NCR0,CCE,0);
//can_write(NBTR0,0X2240);
#else
can1_init();
#endif
//发送数据写入
a.leibie=0;
a.signal=0x05;
a.length=2;
a.data0[0]=0x01;
a.data0[1]=0x02;
write_send_data(a);
//报文发送请求,数据侦
set_bit(MOCTR0 ,SETDIR,1);
//set_bit(MOCTR0 ,RESDIR,1);
//set_bit(MOCTR0 ,SETMSGVAL,1);
//set_bit(MOCTR0 ,RESNEWDAT,0);
set_bit(MOCTR0 ,SETNEWDAT,1);
set_bit(MOCTR0 ,SETMSGVAL,1);
// set_bit(MOCTR0 ,RESMSGVAL,0);
set_bit(MOCTR0 ,SETTXEN0,1);
//set_bit(MOCTR0 ,RESTXEN0,0);
set_bit(MOCTR0 ,SETTXEN1,1);
//set_bit(MOCTR0 ,RESTXEN1,0);
set_bit(MOCTR0 ,SETTXRQ,1);
//set_bit(MOCTR0 ,RESTXRQ,0);
//set_bit(NSR0,RXOK,1);
//can_write(0x0200,0x004e);
// PORT_PAGE=0;
// P3_DATA=0X01;
//while(read_bit(MOSTAT0,RTSEL)==0);
if(read_bit(MOSTAT0,NEWDAT)!=0)
{
PORT_PAGE=0;
P3_DATA=0X02;}
//while(read_bit(MOSTAT0,RTSEL)==0);
while(read_bit(MOSTAT0,NEWDAT)!=0);
while(read_bit(NSR0,TXOK)==0);
//set_bit(NSR0,TXOK,0);
//set_bit(MOSTAT0,MSGVAL,1);
//set_bit(MOSTAT0,DIR,1);
//set_bit(MOSTAT0,TXEN0,1);
//set_bit(MOSTAT0,TXEN1,1);
//set_bit(MOSTAT0,TXRQ,1);
//set_bit(MOSTAT0,RTSEL,1);
//while(read_bit(MOSTAT0,RTSEL)==0);//RTSEL位1,选中报文对象进行接收
// set_bit(MOSTAT0,NEWDAT,1);
//报文对象发送
// while(read_bit(MOSTAT0,NEWDAT)==1);
}
void main()
{
P3_init();
can_init();
PORT_PAGE=0X00;
P3_DATA=0X21;
while(1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -