|
本帖最后由 89057445 于 2013-5-12 20:45 编辑
我想通过can接收can总线上的所以数据,固定相ID位0011108A的设备发送数据。不知道是没有正确初始化还是什么原因,不能接收到数据,请大师帮忙,加QQ酬谢:911781291。程序如下:已经核对过,波特率正确,250K,物理连接正确。
#include "C8051F040.h"
#include "can.h"
#include "uart.h"
//CAN接收缓冲区
xdata unsigned char g_ucCanRecvBuff[16]; //CAN接收数据缓冲区
unsigned char g_ucCanSendBuff[16]; //CAN发送数据缓冲区
xdata unsigned char g_ucCanSendId[4]; //存对应发送CAN_ID
char status;
extern unsigned char canflag;
void clear_msg_objects (void)
{
unsigned char i;
SFRPAGE = CAN0_PAGE;
CAN0ADR = IF1CMDMSK; // Point to Command Mask Register 1
CAN0DATL = 0xFF; // Set direction to WRITE all IF registers to Msg Obj
for(i=1;i<33;i++)
{
CAN0ADR = IF1CMDRQST; // Write blank (reset) IF registers to each msg obj
CAN0DATL = i;
}
}
//Initialize Message Object for RX
void init_msg_object_RX (char MsgNum)
{
SFRPAGE = CAN0_PAGE;
CAN0ADR = IF1CMDMSK; // Point to Command Mask 1
CAN0DAT = 0x00B8; // Set to WRITE, and alter all Msg Obj except ID MASK
// and data bits
CAN0ADR = IF1MSK1; // Point to IF1 Mask1 register
CAN0DAT = 0x0000;
CAN0DAT = 0xE000;
CAN0ADR = IF1ARB1; // Point to arbitration1 register
CAN0DAT = 0x0001; // Set arbitration1 ID to "1"
CAN0DAT = 0xC000; // Arb2 high byte:Set MsgVal bit, no extended ID, 扩展ID
// Dir = RECEIVE
CAN0DAT = 0x0488; // Msg Cntrl: set RXIE, remote frame function disabled
CAN0ADR = IF1CMDRQST; // Point to Command Request reg.
CAN0DATL = MsgNum; // Select Msg Obj passed into function parameter list
// --initiates write to Msg Obj
// 3-6 CAN clock cycles to move IF register contents to the Msg Obj in CAN RAM
}
//Initialize Message Object for TX
void init_msg_object_TX (char MsgNum)
{
SFRPAGE = CAN0_PAGE;
CAN0ADR = IF1CMDMSK; // Point to Command Mask 1
CAN0DAT = 0x00B2; // Set to WRITE, & alter all Msg Obj except ID MASK bits
CAN0ADR = IF1ARB1; // Point to arbitration1 register
CAN0DAT = 0x108A; // Set arbitration1 ID to highest priority
CAN0DAT = 0xE011; // Autoincrement to Arb2 high byte: 0xA002; 扩展ID
// Set MsgVal bit, no extended ID, Dir = WRITE
CAN0DAT = 0x0088; // Msg Cntrl: DLC = 1, remote frame function not enabled
CAN0ADR = IF1CMDRQST; // Point to Command Request reg.
CAN0DAT = MsgNum; // Select Msg Obj passed into function parameter list
// --initiates write to Msg Obj
// 3-6 CAN clock cycles to move IF reg contents to the Msg Obj in CAN RAM.
}
/***********************************************
** 函数名 :OpenCanInt
** 函数说明 :打开CAN中断
** 输入 :无
** 输出 :无
** 其它 :无
************************************************/
void OpenCanInt(void) //打开CAN中断
{
EIE2 |= 0x20; //CPU开can中断
}
/***********************************************
** 函数名 :CloseCanInt
** 函数说明 :关闭CAN中断
** 输入 :无
** 输出 :无
** 其它 :无
************************************************/
void CloseCanInt(void) //关闭CAN中断
{
EIE2 &= ~0x20; //CPU关can中断
}
/***********************************************
** 函数名 :Can_Init
** 函数说明 :初始化CAN
** 输入 :baudRate,CAN波特率
** 输出 :无
** 其它 :无
************************************************/
void Can_Init(unsigned int baudRate)
{
SFRPAGE = CAN0_PAGE;
CAN0CN = 0x41; // Configuration Change Enable CCE and INIT
CAN0ADR = BITREG; // Point to Bit Timing register
CAN0DATH = HIGH_WORD(baudRate); //设置CAN波特率
CAN0DATL = LOW_WORD(baudRate); //设置CAN波特率
CAN0ADR = IF1CMDMSK; // Point to Command Mask 1
CAN0DAT = 0x0087; // Config for TX : WRITE to CAN RAM, write data bytes,
// set TXrqst/NewDat, clr IntPnd
// RX-IF2 operation may interrupt TX-IF1 operation
CAN0ADR = IF2CMDMSK; // Point to Command Mask 2
CAN0DATL = 0x1F; // Config for RX : READ CAN RAM, read data bytes,
// clr NewDat and IntPnd
CAN0CN |= 0x06; // Global Int. Enable IE and SIE
CAN0CN &= ~0x41; // Clear CCE and INIT bits, starts CAN state machine
EIE2 |=0x20; //开启CAN中断
}
void start_CAN (void)
{
// Clear CAN RAM
clear_msg_objects();
// Initialize message object to transmit data
init_msg_object_TX (0x02);
// Initialize message object to receive data
init_msg_object_RX (0x01);
// Enable CAN interrupts in CIP-51
EIE2 = 0x20;
//Function call to start CAN
Can_Init(CAN_RATE);
//Global enable 8051 interrupts
EA = 1;
}
void SendCanData (unsigned char MsgNum,unsigned char *sendcmdtocan)
{
SFRPAGE = CAN0_PAGE; // IF1 already set up for TX
CAN0ADR = IF1CMDMSK; // Point to Command Mask 1
CAN0DAT = 0x0087; // Config to WRITE to CAN RAM, write data bytes,
// set TXrqst/NewDat, Clr IntPnd
CAN0ADR = IF1DATA1; // Point to 1st byte of Data Field
CAN0DATH = *(sendcmdtocan+1);
CAN0DATL = *(sendcmdtocan); // Ones signals to turn LED's light ON in data A1 field
CAN0DATH = *(sendcmdtocan+3);
CAN0DATL = *(sendcmdtocan+2);
CAN0DATH = *(sendcmdtocan+5);
CAN0DATL = *(sendcmdtocan+4);
CAN0DATH = *(sendcmdtocan+7);
CAN0DATL = *(sendcmdtocan+6);
CAN0ADR = IF1CMDRQST; // Point to Command Request Reg.
CAN0DATL = MsgNum; // Move new data for TX to Msg Obj "MsgNum"
}
void receive_data (unsigned char MsgNum,unsigned char i)
{
SFRPAGE = CAN0_PAGE; // IF1 already set up for RX
CloseCanInt();
CAN0ADR = IF2CMDRQST;// Point to Command Request Reg.
CAN0DATL = MsgNum; // Move new data for RX from Msg Obj "MsgNum"
// Move new data to a
CAN0ADR = IF2DATA1; // Point to 1st byte of Data Field
g_ucCanRecvBuff[i+1] = CAN0DATH;
g_ucCanRecvBuff = CAN0DATL;
g_ucCanRecvBuff[i+3] = CAN0DATH;
g_ucCanRecvBuff[i+2] = CAN0DATL;
g_ucCanRecvBuff[i+5] = CAN0DATH;
g_ucCanRecvBuff[i+4] = CAN0DATL;
g_ucCanRecvBuff[i+7] = CAN0DATH;
g_ucCanRecvBuff[i+6] = CAN0DATL;
OpenCanInt();
canflag=1;
}
void ISRname (void) interrupt 19
{
unsigned char temp;
temp=SFRPAGE;
SFRPAGE=CAN0_PAGE;
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 (0x01,0); // Up to now, we have only one RX message 注意,目前只接收八个数据
}
if ((status&0x08) != 0)
{ // 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
}
SFRPAGE=temp;
}
/***********************************************
** 函数名 :ComToCan
** 函数说明 :复制上位机命令,发送到角度传感器
** 输入 :n:发送数据的个数
** 输出 :无
** 其它 :无
************************************************/
void CopyComToCan(unsigned char n,unsigned char *comcmd)
{
unsigned char i,j,k;
for(i=0;i<4;i++)
{
g_ucCanSendId=*(comcmd+i);
send_char_com(g_ucCanSendId);
}
if(n<=8) //如果n小于等于8,可以一次发送完
{
j=n;
k=0;
}
else //如果n大于8,要分多次发送
{
j=8;
k=n-8;
}
delay(50);
for(i=0;i<j;i++) //数据拷备
g_ucCanSendBuff=*(comcmd+(i+4));
// k=g_ucCanSendBuff[0];
// send_char_com(j);
// send_char_com(k);
SendCanData (0x02,g_ucCanSendBuff); //第一次发送数据
delay(500);
for(i=0;i<16;i++)
{
g_ucCanSendBuff=0; //清除CAN发送缓冲区
}
}
|
阿莫论坛20周年了!感谢大家的支持与爱护!!
你熬了10碗粥,别人一桶水倒进去,淘走90碗,剩下10碗给你,你看似没亏,其实你那10碗已经没有之前的裹腹了,人家的一桶水换90碗,继续卖。说白了,通货膨胀就是,你的钱是挣来的,他的钱是印来的,掺和在一起,你的钱就贬值了。
|