我也遇到 CAN的发送问题, 数据发送不出去.
以下是我的代码:
CAN 初始化的函数:
void DriverCan0_init(void)
{
//----------------------------
//设置 CAN引脚
//STB(PA0) 为待机控制输入(低电平有效)
DDRA_DDRA0 = 1; // TJA1040_STB#
PORTA_PA0 = 1; // disable standby of TJA1040
DDRM_DDRM0 = 0;//PTM0 输入
DDRM_DDRM1 = 1;//PTM1 输出
PERM_PERM0 = 1; PPSM_PPSM0 = 0;//PTM0 上拉
WOMM_WOMM1=0;
//PTM_PTM0 = 1; PTM_PTM1 = 1;//在PORT M的数据寄存器里PM0,PM1位写1就可以正常收发了. //需要吗?
//----------------------------
//if(CAN0CTL0_INITRQ==0) { // 查询是否进入初始化状态
CAN0CTL0_INITRQ =1; // 进入初始化状态
//}
while (CAN0CTL1_INITAK==0); //等待进入初始化状态
CAN0BTR0_SJW = 0; //设置同步 (1 Tq时钟周期)
CAN0BTR0_BRP = 1; //设置波特率 (分频数 2)
CAN0BTR1 = 0x1C; //设置时段1和时段2的Tq个数 ,总线频率为500kb/s
// 打开滤波器(CAN0IDAC使用默认值,32位接收滤波)
//标准帧的最高3bit为 (101)2
CAN0IDAC_IDAM = 0x0; // Two 32-bit acceptanc filter
CAN0IDMR0 = 0x1F; CAN0IDMR1 = 0xFF;
CAN0IDMR2 = 0x00; CAN0IDMR3 = 0x00;
CAN0IDMR4 = 0x00; CAN0IDMR5 = 0x08;//完全不接收数据
CAN0IDMR6 = 0x00; CAN0IDMR7 = 0x00;
//---------
CAN0IDAR0 = 0xA0; CAN0IDAR1 = 0x00; //标准帧的最高3bit为 (101)2
CAN0IDAR2 = 0x00; CAN0IDAR3 = 0x00;
CAN0IDAR4 = 0x00; CAN0IDAR5 = 0x00;
CAN0IDAR6 = 0x00; CAN0IDAR7 = 0x00;
//-----------------------------
CAN0CTL1 = 0x80; //使能MSCAN模块,设置为一般运行模式、使用振荡器时钟源
CAN0MISC = 0x01; //模块总线脱离,并保持该状态直到用户请求.
CAN0CTL0 = 0x00; //返回一般模式运行
while(CAN0CTL1_INITAK); //等待回到一般运行模式
while(CAN0CTL0_SYNCH==0); //等待总线时钟同步
CAN0RFLG_RXF = 1; //清除 接收标志
CAN0RIER_RXFIE = 1; //使能接收中断
//=====================================
DDRM_DDRM0 = 0;//PTM0 输入
DDRM_DDRM1 = 1;//PTM1 输出
PERM_PERM0 = 1; PPSM_PPSM0 = 0;//PTM0 上拉
WOMM_WOMM1=0;
//PTM_PTM0 = 1; PTM_PTM1 = 1;//在PORT M的数据寄存器里PM0,PM1位写1就可以正常收发了. //需要吗?
}
CAN 发送的函数:
/**************************************************************
* 名称 : DriverCan0_sendMsg
* 功能 : CAN0 发送数据;
*
* 参数 : msg : in : 要发生的CAN数据;
* 返回 : err : 错误标记; 0 : OK; 1:参数错误; others:其他错误;
*
* 备注 : 1.
**************************************************************/
uint8_t DriverCan0_sendMsg(const CAN_MSG_T *pTxMsg)
{
uint8_t send_buf, sp, len;
len = pTxMsg->len;
if(len > 8) { return(1); }// 检查数据长度
if(CAN0CTL0_SYNCH == 0) { return(2); }// 检查总线时钟
send_buf = 0;
do
{ // 寻找空闲的缓冲器
CAN0TBSEL = CAN0TFLG;
send_buf = CAN0TBSEL;
DriverWatchdog_feed();//喂看门狗
}while(!send_buf);
// 写入标识符
CAN0TXIDR0 = (uint8_t)((pTxMsg->id>>3) & 0xFF);
CAN0TXIDR1 = (uint8_t)((pTxMsg->id<<5) & 0xFF);
// 写入数据
for(sp = 0; sp < len; sp++)
{
*((&CAN0TXDSR0)+sp) = pTxMsg->data[sp];
}
CAN0TXDLR = len; // 写入数据长度
CAN0TFLG = send_buf;// 清 TXx 标志 (缓冲器准备发送)
// while ( (CAN0TFLG&send_buf) != send_buf); // Wait for Transmission comple
tion
return(0);
}
调用函数, 好像发送几次, 把 CAN的发送缓存写完后, 就一直在
do
{ // 寻找空闲的缓冲器
CAN0TBSEL = CAN0TFLG;
send_buf = CAN0TBSEL;
DriverWatchdog_feed();//喂看门狗
}while(!send_buf);
里面循环.
不知道是什么原因. 请指导一下.
一周热门 更多>