CAN总线之saj1000与82c250应用源程序.docx
- 文档编号:10324990
- 上传时间:2023-02-10
- 格式:DOCX
- 页数:12
- 大小:20.05KB
CAN总线之saj1000与82c250应用源程序.docx
《CAN总线之saj1000与82c250应用源程序.docx》由会员分享,可在线阅读,更多相关《CAN总线之saj1000与82c250应用源程序.docx(12页珍藏版)》请在冰豆网上搜索。
CAN总线之saj1000与82c250应用源程序
CAN总线之saj1000与82c250应用源程序,基于c8051f340单片机平台。
2009年04月19日星期日10:
58
定义头文件:
s.h
voidCanInit();
voidCanSend(unsignedchar*bufDATA,unsignedchardatalen);
voidPort_IO_Init();
voidOscillator_Init();
voidInit_Device(void);
voidWR_SJA(unsignedcharsja_addr,unsignedcharsja_data);
unsignedcharRD_SJA(unsignedcharsja_addr);
//******SJA1000内部寄存器地址(初始化复位模式)PeliCAN模式的地址表.
//******标准帧格式(SFF)与扩展帧格式(EFF).
#defineSJA_MOD0 /*模式寄存器可以定义过滤模式MOD.3=AFM00H*/
#defineSJA_CMR1 //命令寄存器
#defineSJA_SR 2 //状态寄存器
#defineSJA_IR 3 //中断标志 03
#defineSJA_IER4 /*中断允许04H*/
#defineSJA_BTR06 /*总线定时器0 06H*/
#defineSJA_BTR17 /*总线定时器1 07H*/
#defineSJA_OCR 8 /*输出控制 08H*/
#defineSJA_ALC11 //仲裁丢失捕捉 11
#defineSJA_ECC12 /*错误代码捕捉0CH*/
#defineSJA_EWLR13 //错误报警限制寄存器
#defineSJA_RXERR14 //错误计数寄存器
#defineSJA_TXERR15 /*发送错误记数0FH*/
//以下为复位模式定义
#defineSJA_ACR016 /*验收代码即ID?
16*/
#defineSJA_ACR117 /*验收代码即ID 17*/
#defineSJA_ACR218 /*验收代码即ID 18*/
#defineSJA_ACR319 /*验收代码即ID 19*/
#defineSJA_AMR020 /*验收屏蔽初地址20*/
#defineSJA_AMR121 /*验收屏蔽初地址21*/
#defineSJA_AMR222 /*验收屏蔽初地址22*/
#defineSJA_AMR323 /*验收屏蔽初地址23*/
//SJA1000内部寄存器地址(工作模式)
#defineSJA_EFF16 //RX和TX结构信息扩展帧/标准帧
#defineSJA_ID117 //识别码
#defineSJA_ID218 //识别码
#defineSJA_ID319 //识别码,标准帧无
#defineSJA_ID420 //识别码,标准帧无
#defineSJA_D121 //
#defineSJA_D222
#defineSJA_D323
#defineSJA_D424
#defineSJA_D525
#defineSJA_D626
#defineSJA_D727
#defineSJA_D828 //////////////
单片机程序如下:
#include
#include
#include"s.h"
//模块程序测试--CAN主动发送与中断接收。
//版本号:
V1.2
// c8051f340
// -----------------
//(低有效)led1|P2.0 P3.0|-->P1继电器(低有效)上
// led2|P2.1 P3.1|-->P2继电器 下
// SDA|P2.2I2C |
// SCL|P2.3 |
// | |
// AD0|P1.0 |
// *|* |
//(CAN通信) *|* |
// AD7|P1.7 |
// | |
// CS_CAN|P0.3 |
// ALE|P0.0 |
// RD|P0.1 |
// WR|P2.7 |
// INTCAN|P0.2 |
// | |
//
//
sbitled1 =P2^0;
sbitled2 =P2^1;
sbitSDA =P2^2;
sbitSCL =P2^3;
sbitJ1 =P3^0;
sbitJ2 =P3^1;
sbitst1 =P0^4;
sbitALE_CAN=P0^0;
sbitRD_CAN =P0^1;
sbitINT_CAN=P0^2;
sbitCS_CAN =P0^3;
sbitWR_CAN =P2^7;
#defineWriteDeviceAddress0xa0//地址以及读写方向,本设备中只有一个IIC设备地址为0
#defineReadDviceAddress0xa1
#defineucharunsignedchar
#defineuintunsignedint
#definenop_nop_
ucharc1[16]={0X00,0X01,0X02,0X03,0X04,0X05,0X06,0X07,0X08,0X09,0X0a,0X0b,0X0c,
0X0d,0X0e,0X0f};
ucharc2[16];
ucharc3[8]={0X00,0X01,0X02,0X03,0X04,0X05,0X06,0X07};
unsignedintidataMaxLenCanRxBuf=440;
unsignedcharxdataCanRxBuf[440]; //40个CAN帧缓冲区
unsignedcharidataCanTempBuf[11]; //单个can报文的缓冲区。
unsignedcharidataCanTxData[8]; //CAN发送数据缓冲区
unsignedchardata_flag=0;
unsignedintidataCanRxAddr=0;
unsignedcharCanRxcompleteFlag=0;
unsignedcharidatacfgbuf[32];
unsignedcharSendBufId[2]={0x07,0x20};//这个值要自己设定,现在只是测试程序代码假设的一个值11位标示符的格式,后3位可选值为20,,60,40,80,a0,e0
unsignedcharSendBufInfo;
unsignedintxdatamSendDelay=0;
unsignedchar*h_pointer;
unsignedchar*l_pointer;
unsignedchari=0;
unsignedcharj=0;
uintLedFlag1=0;
voidDelayMs(unsignedintnumber)
{
unsignedinttemp;
for(;number!
=0;number--)
{
for(temp=3066;temp!
=0;temp--);//forc8051
}
}
voiddelay(intnum)
{
intvalue;
unsignedcharjj;
value=num*5;
for(jj=0;jj } voiddelay2(intnum) { unsignedcharjj=0; for(jj=0;jj } /****************************************************************************************************************************************************** *函数名: CanInit(void) *功能描述: CAN的初始化设置,在复位模式下设置CAN为单滤波,正常模式,PeliCAN模式,不屏蔽,8* 字节数据位 *函数说明: 通过ALE,RD,CS的配合控制完成 *调用函数: NONE *全局变量: NONE *输入: *返回: *设计者: ******************************************************************************************************************************************************/ voidCanInit(void) { unsignedchartempMode; unsignedchartemp7=0; unsignedchartemp8=0; tempMode=0x01; //复位模式 tempMode|=0x08; //设置CAN为单滤波,选择单个验收滤波器(32位长度) tempMode|=0x00; //正常模式,这句话貌似没有实际意义? ? WR_SJA(SJA_MOD,tempMode); //模式寄存器进入复位模式 temp7=RD_SJA(SJA_MOD); //设置的变量用来查看前面的写入是否成功。 WR_SJA(SJA_CDR,0x0C8); //时钟分频选择PeliCAN模式终止can输入比较器关闭时钟输出CLKOUT temp8=RD_SJA(SJA_CDR); WR_SJA(SJA_AMR0,0xff); //验收屏蔽位设置,不影响 WR_SJA(SJA_AMR1,0xff); WR_SJA(SJA_AMR2,0xff); WR_SJA(SJA_AMR3,0xff); WR_SJA(SJA_ACR0,0x80); //验收代码位设置扩展祯数据8字节 WR_SJA(SJA_ACR1,0x00); WR_SJA(SJA_ACR2,0x00); WR_SJA(SJA_ACR3,0x00); WR_SJA(SJA_BTR0,0x00); //设置CAN波特率为500k通过波特率计算器可以算出该值 WR_SJA(SJA_BTR1,0x1c); temp7=RD_SJA(SJA_BTR0); temp8=RD_SJA(SJA_BTR1); mSendDelay=1000; WR_SJA(SJA_IER,0x01); //中断允许打开接收中断使能 WR_SJA(SJA_OCR,0x0da); //输出控制驱动上拉正常输出模式 WR_SJA(SJA_MOD,tempMode&0xFE);//模式寄存器退出复位模式 } /****************************************************************************************************************************************************** *函数名: voidcan_rx_isr(void)interrupt0 *功能描述: sja1000CAN接收中断函数 *函数说明: 在响应接收中断的时候,完成数据的接收。 问题是现在sja的数据根本读不出来RD_SJA()函数问题。 *调用函数: NONE *全局变量: NONE *输入: *返回: *设计者: ******************************************************************************************************************************************************/ voidcan_rx_isr(void)interrupt0 //sja1000CAN接收中断 { unsignedchark=0; unsignedcharsja_addr; EA=0; /***! ! ! RD_SJA(SJA_IR)读出来的值为0xff,所以也可以通过进入读环节。 ****************************/ //关CPU中断 if((RD_SJA(SJA_IR)&0x01)==0x01) //IR中断寄存器,当接收FIFO不空和接收中断使能时置位此位 { sja_addr=SJA_EFF; //register17.datastartaddress if(CanRxAddr==MaxLenCanRxBuf)//unsignedintidataMaxLenCanRxBuf=440. CanRxAddr=0; for(k=0;k<11;k++) //完成11位标准帧数据的接收过程。 { CanRxBuf[CanRxAddr+k]=RD_SJA(sja_addr); sja_addr++; } WR_SJA(SJA_CMR,0x04); //释放接收缓冲区 CanRxAddr+=11; CanRxcompleteFlag+=1; //接收完一次完整的数据报文以后该标志位加1. } EA=1;//打开CPU中断 } /****************************************************************************************************************************************************** *函数名: CanSend(unsignedchar*bufDATA,unsignedchardatalen) *功能描述: Can设备数据发送函数 *函数说明: *调用函数: NONE *全局变量: NONE *输入: *返回: *设计者: ******************************************************************************************************************************************************/ voidCanSend(unsignedchar*bufDATA,unsignedchardatalen) { unsignedintsja_addr; unsignedcharj=0; unsignedchartemp; //局部变量 unsignedintn; //CanLedFlag=1; sja_addr=SJA_EFF; //取SJA的ID号的首地址地址,ID0的地址。 SendBufInfo=datalen; //填入数据长度信息 WR_SJA(sja_addr++,SendBufInfo); //以标准帧发送消息 for(j=0;j<2;j++) WR_SJA(sja_addr+j,*(SendBufId+j));//发送两字节的id信息。 for(j=0;j WR_SJA(sja_addr+2+j,*(bufDATA+j));//发送data区数据。 WR_SJA(SJA_CMR,0x03); //打开发送请求位与终止发送位,Send正常发送 for(n=0;n { temp=RD_SJA(SJA_SR); //读取状态寄存器SR.3--TCS发送完毕状态1(完毕) if((temp&0x08)==0x08) //发送完毕 { for(n=0;n<300;n++); //延时 break; } } } /****************************************************************************************************************************************************** *函数名: WR_SJA(unsignedcharsja_addr,unsignedcharsja_data) *功能描述: 完成先准备相应sja_addr地址,再在相应的sja_addr地址操作送sja_data数据的 过程 *函数说明: 通过ALE切换地址与数据位的操作 *调用函数: NONE *全局变量: NONE *输入: *返回: *设计者: ******************************************************************************************************************************************************/ voidWR_SJA(unsignedcharsja_addr,unsignedcharsja_data) { ALE_CAN=1;//置高开启地址锁存允许,将io口的地址数据锁存。 P1=sja_addr; delay2(3); ALE_CAN=0;//置低关闭地址锁存允许,改为发送数据有效。 delay2 (1); CS_CAN=0; WR_CAN=0; P1=sja_data; delay2(4); /******************************************/ WR_CAN=1; CS_CAN=1;//恢复到操作前的状态,避免影响单片机对sja1000误操作。 ALE_CAN=1; /*****************************************/ } /****************************************************************************************************************************************************** *函数名: RD_SJA(unsignedcharsja_addr) *功能描述: 完成先准备相应sja_addr地址,再将该地址的数据读出到sja_data的过程 *函数说明: 通过ALE,RD,CS的配合控制完成 *调用函数: NONE *全局变量: NONE *输入: *返回: *设计者: ******************************************************************************************************************************************************/ /*unsignedcharRD_SJA(unsignedcharsja_addr) { unsignedcharsja_data=0; CS_CAN=0;//使能片选 ALE_CAN=1;//置高开启地址锁存允许,将io口的地址数据锁存。 delay2 (2); P1=sja_addr; ALE_CAN=0;//置低关闭地址锁存允许,改为发送数据有效。 delay2(4); RD_CAN=0;//使能读有效 sja_data=P1; /*********************************************************** ALE_CAN=1; RD_CAN=1;//此处的3个使能一起操作,前面的写地址与写命令一样的原理 CS_CAN=1; /*********************************************************** returnsja_data; }*/ unsignedcharRD_SJA(unsignedcharsja_addr) { unsignedcharsja_data; ALE_CAN=1;//置高开启地址锁存允许,将io口的地址数据锁存。 P1=sja_addr; delay2(3); ALE_CAN=0;//置低关闭地址锁存允许,改为发送数据有效。 delay2 (1); CS_CAN=0;//使能片选 P1=0xFF; //端口初始化 RD_CAN=0;//使能读有效 delay2(4); sja_data=P1; /***********************************************************/ RD_CAN=1;//此处的3
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- CAN 总线 saj1000 82 c250 应用 源程序