贴一个c8051f040的CAN自测程序(已验证,相关现象在后有说明)
#include<c8051f040.h>#include<stdio.h>
// CAN Protocol Register Index for CAN0ADR, from TABLE 18.1 of the C8051F040
// datasheet
////////////////////////////////////////////////////////////////////////////////
#define CANCTRL 0x00 //Control Register
#define CANSTAT 0x01 //Status register
#define ERRCNT 0x02 //Error Counter Register
#define BITREG 0x03 //Bit Timing Register
#define INTREG 0x04 //Interrupt Low Byte Register
#define CANTSTR 0x05 //Test register
#define BRPEXT 0x06 //BRP Extension Register
////////////////////////////////////////////////////////////////////////////////
//IF1 Interface Registers
////////////////////////////////////////////////////////////////////////////////
#define IF1CMDRQST 0x08 //IF1 Command Rest Register
#define IF1CMDMSK 0x09 //IF1 Command Mask Register
#define IF1MSK1 0x0A //IF1 Mask1 Register
#define IF1MSK2 0x0B //IF1 Mask2 Register
#define IF1ARB1 0x0C //IF1 Arbitration 1 Register
#define IF1ARB2 0x0D //IF1 Arbitration 2 Register
#define IF1MSGC 0x0E //IF1 Message Control Register
#define IF1DATA1 0x0F //IF1 Data A1 Register
#define IF1DATA2 0x10 //IF1 Data A2 Register
#define IF1DATB1 0x11 //IF1 Data B1 Register
#define IF1DATB2 0x12 //IF1 Data B2 Register
////////////////////////////////////////////////////////////////////////////////
//IF2 Interface Registers
////////////////////////////////////////////////////////////////////////////////
#define IF2CMDRQST 0x20 //IF2 Command Rest Register
#define IF2CMDMSK 0x21 //IF2 Command Mask Register
#define IF2MSK1 0x22 //IF2 Mask1 Register
#define IF2MSK2 0x23 //IF2 Mask2 Register
#define IF2ARB1 0x24 //IF2 Arbitration 1 Register
#define IF2ARB2 0x25 //IF2 Arbitration 2 Register
#define IF2MSGC 0x26 //IF2 Message Control Register
#define IF2DATA1 0x27 //IF2 Data A1 Register
#define IF2DATA2 0x28 //IF2 Data A2 Register
#define IF2DATB1 0x29 //IF2 Data B1 Register
#define IF2DATB2 0x2A //IF2 Data B2 Register
////////////////////////////////////////////////////////////////////////////////
//Message Handler Registers
////////////////////////////////////////////////////////////////////////////////
#define TRANSREQ1 0x40 //Transmission Rest1 Register
#define TRANSREQ2 0x41 //Transmission Rest2 Register
#define NEWDAT1 0x48 //New Data 1 Register
#define NEWDAT2 0x49 //New Data 2 Register
#define INTPEND1 0x50 //Interrupt Pending 1 Register
#define INTPEND2 0x51 //Interrupt Pending 2 Register
#define MSGVAL1 0x58 //Message Valid 1 Register
#define MSGVAL2 0x59 //Message Valid 2 Register
sfr16 CAN0DATA=0xd8;
void IO_ini(void);
void oscx_ini(void);
void clear_msg_objects(void);
//void init_msg_object_tx(void);
//void init_msg_object_rx(void);
void start_CAN(void);
sbit switch1=P2^0;
void inter_CAN(void);
unsigned int a, b;
extern void delay_50us(int n);
void main(){
WDTCN = 0xde;
WDTCN = 0xad;
IO_ini();
oscx_ini();
// init_msg_object_tx();
// init_msg_object_rx();
EIE2 = 0x20;//允许can0中断
while(switch1==1);
start_CAN();
EA = 1;
//CANSIE=0;
// init_msg_object_tx();
clear_msg_objects();
//TXOK=0;
while(1);
}
void IO_ini(void){
SFRPAGE=CONFIG_PAGE;
P2MDOUT=0Xff;
P2=0X0f;
XBR3|=0X80;
XBR2=0X40; //该处可设定弱上拉使能
}
void oscx_ini(void){
SFRPAGE=CONFIG_PAGE;
OSCXCN|=0X67;
delay_50us(20);
while((OSCXCN&0x80)==0);
CLKSEL|=0x01;
}
void clear_msg_objects(void){
unsigned char i, IDL=4,j;
unsigned short data_temp=0x0101;
SFRPAGE=CAN0_PAGE;
CANINIT=1;
CAN0ADR=IF1CMDMSK;
CAN0DATL=0Xf3;
for(i=1;i<=8;i++){
CAN0ADR=IF1MSK1;
CAN0DATA=0X0000;
CAN0DATA=0X0000; //需要修改IDE过滤
CAN0ADR=IF1ARB2;
CAN0DATH=0Xa0;
CAN0DATL=IDL;
IDL += 4;
CAN0DATA=0X0088; //IF1MSGC
/* CAN0ADR=IF1DATA1;
for(j=1;j<=4;j++){
CAN0DATA=data_temp;
data_temp+=257;
}*/
CAN0ADR=IF1CMDRQST;
while((CAN0DATH & 0X80) == 1);
CAN0DATL=i;
}
IDL=0x04;
for(;i<=16;i++){
CAN0ADR=IF1MSK1;
CAN0DATA=0XFFFF;
CAN0DATA=0X1FFF; //需要修改IDE过滤
CAN0ADR=IF1ARB2;
CAN0DATH=0XA0;
CAN0DATL=IDL;
IDL += 4;
CAN0DATA=0X1080; //可设定newdata引发intpnd
CAN0ADR=IF1CMDRQST;
while((CAN0DATH & 0X80) == 1);
CAN0DATL=i;
}
CANINIT=0;
CAN0ADR=IF1CMDMSK;
CAN0DATL=0X87; //87控制位等不改
for(i=1;i<=8;i++){
CAN0ADR=IF1DATA1;
for(j=1;j<=4;j++){
CAN0DATA=data_temp;
data_temp+=257;
}
CAN0ADR=IF1CMDRQST;
CAN0DATL=i; //这里发送
// delay_50us(55);
}
}
/*void init_msg_object_rx(void){
SFRPAGE=CAN0_PAGE;
CAN0ADR=IF1CMDMSK;
CAN0DATL=0XA3;
CAN0ADR=IF1ARB1; //关于寄存器地址可能存在问题
CAN0DATA=0X0000;
CAN0DATA=0X0000;
CAN0DATA=0X0401;
CAN0ADR=IF1CMDRQST;
while((CAN0DATH&0X80)!=0);
CAN0DATL=0X01;*/
/*void init_msg_object_tx(){
SFRPAGE=CAN0_PAGE;
CAN0ADR=IF1CMDMSK;
CAN0DATL=0XA3;
CAN0ADR=IF1ARB1; //关于寄存器地址可能存在问题
CAN0DATA=0X0000;
CAN0DATA=0X0000;
CAN0DATA=0X0801;
CAN0ADR=IF1DATA1;
CAN0DATL=0XAA;
CAN0ADR=IF1CMDRQST;
while((CAN0DATH&0X80)!=0);
CAN0DATL=0X11;
while((CAN0DATH&0X80)!=0);
CAN0ADR=IF1CMDMSK;
CAN0DATL|=0X04;
}
*/
void start_CAN(){
SFRPAGE=CAN0_PAGE;
CAN0CN|=0X00C1; // 开测试和bt设置
CAN0CN&=0XFFd7; //自动重发开启错误中断禁止
CAN0ADR=CANTSTR;
CAN0DATL|=0X10;
CAN0ADR=BITREG;
CAN0DATA=0X2640;
CAN0CN|=0X0006;
CAN0CN&=0XFFBE;
}
void delay_50us(int n){
unsigned char l;
for( ;n>0;n--)
for(l=19;l>0;l--);
}
void inter_CAN(void) interrupt 19
{
/*SFRPAGE=CAN0_PAGE;
CAN0ADR=IF1CMDMSK;
CAN0DATL=0XFF;
TXOK=0;*/
unsigned int can_interrupt, i;
unsigned int status;
// temp_page=CAN0ADR;
//temp_data=CAN0DATA;
SFRPAGE= CAN0_PAGE;
CAN0ADR= INTREG; //只读的中断寄存器
can_interrupt = CAN0DATA;
CAN0ADR=NEWDAT1;
i=CAN0DATA;
if(0){SFRPAGE=CONFIG_PAGE;
P5MDOUT=0xff;
P5&=0xf0;
SFRPAGE=CAN0_PAGE;
}
if(can_interrupt==0x8000) //status interrupt
{
status = CAN0STA; //读状态寄存器
if ((status&0x10) != 0)
{ // RxOk is set, interrupt caused by reception
// CAN0STA = (CAN0STA&0xEF)|0x07; // Reset RxOk, set LEC to NoChange
/* read message number from CAN INTREG */
// receive_data (); // Up to now, we have only one RX message
}
if ((status&0x08) != 0)
{
SFRPAGE=CONFIG_PAGE;
P5MDOUT=0x0f;
P5=0x0f;
SFRPAGE=CAN0_PAGE; // TxOk is set, interrupt caused by transmision
// CAN0STA = (CAN0STA&0xF7)|0x07; // Reset TxOk, set LEC to NoChange
}
if (((status&0x07) != 0)&&((status&0x07) != 7))
{ // Error interrupt, LEC changed
/* error handling ? */
CAN0STA = CAN0STA|0x07; // Set LEC to NoChange
}
}
/* CAN0ADR=NEWDAT1;
temp_data=CAN0DATA;
CAN0ADR= IF2CMDMSK;
CAN0DATA= 0x007f;
CAN0ADR= IF2CMDRQST;
CAN0DATL=9;
CAN0ADR=IF1DATA1;
for(i=0;i<=7;i++)
a=CAN0DATA;
CAN0ADR=NEWDAT1;
temp_data=CAN0DATA;
CAN0ADR= IF2CMDMSK;
CAN0DATA= 0x007f;
CAN0ADR= IF2CMDRQST;
CAN0DATL=0x10;
CAN0ADR=IF1DATA1;
for(i=0;i<=7;i++)
b=CAN0DATA;*/
// CAN0DATA=temp_data;
// CAN0ADR=temp_page;
/*CAN0ADR=IF1CMDMSK;
CAN0DATL=0X0C;
CAN0ADR=IF1CMDRQST;
CAN0DATL=0X09;
CAN0ADR=IF1CMDRQST;
CAN0DATL=0X10;*/
}
该程序运用ID滤波RTR与IDE均不参与过滤
按键按下后才开始发送数据(便于之后两块板的正常通信调试)且正常发送时P5低四位的灯亮起指示
程序还不是非常的完善望大家指出我也好学习学习^-^ http://cache.amobbs.com/bbs_upload782111/files_44/ourdev_665871CIEOQC.jpg
完整点附上switch1的接线图 (原文件名:按键.jpg)
http://cache.amobbs.com/bbs_upload782111/files_44/ourdev_665872PAZ931.jpg
这是灯部分的接线与040的P5口连 (原文件名:灯.jpg) 正好在做040的can,学习一下,汲取经验! 楼上的能留下联系方式么?我也刚开始做这个。不知道怎么弄。 楼主有C8051F040的串口程序吗,我用的是内部时钟,串口能发出数据但是格式和数据为全不对,估计是波特率没算好,你能传给我一个串口程序吗,使用外部晶振的也可以
页:
[1]