共2条
1/1 1 跳转至页
ZLG 头大了,请ZLG及各位高手帮帮忙
问
我是个CAN初学者,现在在做一个CAN转换通信电路,我将要发送的数据写入发送缓存中后启动发送指令(0x12),让SJA1000工作于自接收测试模式,但是SJA1000一直处于发送状态,死在那里了,中断寄存器也只是只是发送中断,状态寄存器指示SJA1000一直处于发送状态。真搞不懂为什么,现在人都快疯了,烦劳各位大哥给小弟多点指点。
现附上本人的CAN发送程序、及SJA1000初始化程序:
void sja1000_sent(void)
{
unsigned char data j;
EA=0;
SJA1000_ADDRESS=SJA1000_STATE; //指向状态寄存器
temp=*SJA1000_ADDRESS;
do
{
temp=*SJA1000_ADDRESS; //读出当前状态
}
while(temp&SJA1000_RECEIVING); //如正在接收,则等待
do
{
temp=*SJA1000_ADDRESS; //读出当前状态
}
while(!(temp&SJA1000_SENT_OVER)); //则等待先前发送成功
do
{
temp=*SJA1000_ADDRESS; //读出当前状态
}
while(!(temp&SJA1000_SENT_LOCK)); //如发送缓冲区被锁定,则等待释放
SJA1000_ADDRESS=SJA1000_TXBUF;
for(j=0;j<=12;j++) //发送到CAN缓冲区
{
*(SJA1000_ADDRESS+j)=CAN_TXD_BUF[j];
}
SJA1000_ADDRESS=SJA1000_COMMAND; //指向命令寄存器
*SJA1000_ADDRESS=SJA1000_SENT_COMMAND; //发送请求命令
SJA1000_ADDRESS=SJA1000_STATE;
send_succeed=1;
EA=1;
}
void init_sja1000(void)
{
SJA1000_ADDRESS=SJA1000_MODEL; //指向模式寄存器
*SJA1000_ADDRESS=SJA1000_RESET_MODEL; //进入复位模式
while(!(*SJA1000_ADDRESS&SJA1000_RESET_MODEL)); //等待进入复位模式
SJA1000_ADDRESS=SJA1000_CLOCKDIR; //指向时钟分频寄存器
*SJA1000_ADDRESS=SJA1000_CDR_COMMAND; //使用Peli CAN模式,CLOCK使用禁止输出
SJA1000_ADDRESS=SJA1000_ENINTERR; //指向中断使能寄存器
*SJA1000_ADDRESS=SJA1000_IER_COMMAND; //开放接收,数据溢出,错误报警中断
SJA1000_ADDRESS=SJA1000_OUTCONTR; //指向输出控制寄存器
*SJA1000_ADDRESS=SJA1000_OUT_COMMAND; //正常输出模式
SJA1000_ADDRESS=SJA1000_BUSTIME0; //指向总线定时0寄存器
*SJA1000_ADDRESS=BTR0_250Kbps; //选择250Kbps
SJA1000_ADDRESS=SJA1000_BUSTIME1; //指向总线定时1寄存器
*SJA1000_ADDRESS=BTR1_250Kbps; //选择250Kbps
SJA1000_ADDRESS=SJA1000_RBSA; //指向RX缓冲区起始地址寄存器
*SJA1000_ADDRESS=SJA1000_FIFO_ADD; //接收缓冲区FIFO起始为内部RAM的0地址
SJA1000_ADDRESS=SJA1000_AMRRX0; //指向验收屏蔽寄存器,所有位均参加验收
*SJA1000_ADDRESS=AMR_CODE0;(0xff)
SJA1000_ADDRESS=SJA1000_AMRRX1;
*SJA1000_ADDRESS=AMR_CODE1;(0xff)
SJA1000_ADDRESS=SJA1000_AMRRX2;
*SJA1000_ADDRESS=AMR_CODE2;(0xff)
SJA1000_ADDRESS=SJA1000_AMRRX3;
*SJA1000_ADDRESS=AMR_CODE3; (0xff)
SJA1000_ADDRESS=SJA1000_ACRRX0; //指向验收代码寄存器,送ID码
*SJA1000_ADDRESS=ACR_ID0;(0x0)
SJA1000_ADDRESS=SJA1000_ACRRX1;
*SJA1000_ADDRESS=ACR_ID1;(0xa0)
SJA1000_ADDRESS=SJA1000_ACRRX2;
*SJA1000_ADDRESS=ACR_ID2;(0x0)
SJA1000_ADDRESS=SJA1000_ACRRX3;
*SJA1000_ADDRESS=ACR_ID3;(0x0)
SJA1000_ADDRESS=SJA1000_RX_ERR; //指向接收错误寄存器
*SJA1000_ADDRESS=SJA1000_CLEAR_TX_ERR; //清除接收错误
SJA1000_ADDRESS=SJA1000_ALC; //指向仲裁丢失捕捉寄存器
temp=*SJA1000_ADDRESS; //通过读取清除
SJA1000_ADDRESS=SJA1000_ECC; //指向错误代码捕捉寄存器
temp=*SJA1000_ADDRESS; //通过读取清除
SJA1000_ADDRESS=SJA1000_MODEL; //指向模式寄存器
*SJA1000_ADDRESS=SJA1000_WORK_MODEL; //设置双滤波接收,进入工作模式
while(!(*SJA1000_ADDRESS==0)); //等待进入工作模式
}
多谢各位了。 答 1: 写详细点把你的硬件电路给出来,以及一些变量的说明将清楚嘛,这样人家才好看嘛。光写一部分程序,谁知道是不是其他方面的问题了
现附上本人的CAN发送程序、及SJA1000初始化程序:
void sja1000_sent(void)
{
unsigned char data j;
EA=0;
SJA1000_ADDRESS=SJA1000_STATE; //指向状态寄存器
temp=*SJA1000_ADDRESS;
do
{
temp=*SJA1000_ADDRESS; //读出当前状态
}
while(temp&SJA1000_RECEIVING); //如正在接收,则等待
do
{
temp=*SJA1000_ADDRESS; //读出当前状态
}
while(!(temp&SJA1000_SENT_OVER)); //则等待先前发送成功
do
{
temp=*SJA1000_ADDRESS; //读出当前状态
}
while(!(temp&SJA1000_SENT_LOCK)); //如发送缓冲区被锁定,则等待释放
SJA1000_ADDRESS=SJA1000_TXBUF;
for(j=0;j<=12;j++) //发送到CAN缓冲区
{
*(SJA1000_ADDRESS+j)=CAN_TXD_BUF[j];
}
SJA1000_ADDRESS=SJA1000_COMMAND; //指向命令寄存器
*SJA1000_ADDRESS=SJA1000_SENT_COMMAND; //发送请求命令
SJA1000_ADDRESS=SJA1000_STATE;
send_succeed=1;
EA=1;
}
void init_sja1000(void)
{
SJA1000_ADDRESS=SJA1000_MODEL; //指向模式寄存器
*SJA1000_ADDRESS=SJA1000_RESET_MODEL; //进入复位模式
while(!(*SJA1000_ADDRESS&SJA1000_RESET_MODEL)); //等待进入复位模式
SJA1000_ADDRESS=SJA1000_CLOCKDIR; //指向时钟分频寄存器
*SJA1000_ADDRESS=SJA1000_CDR_COMMAND; //使用Peli CAN模式,CLOCK使用禁止输出
SJA1000_ADDRESS=SJA1000_ENINTERR; //指向中断使能寄存器
*SJA1000_ADDRESS=SJA1000_IER_COMMAND; //开放接收,数据溢出,错误报警中断
SJA1000_ADDRESS=SJA1000_OUTCONTR; //指向输出控制寄存器
*SJA1000_ADDRESS=SJA1000_OUT_COMMAND; //正常输出模式
SJA1000_ADDRESS=SJA1000_BUSTIME0; //指向总线定时0寄存器
*SJA1000_ADDRESS=BTR0_250Kbps; //选择250Kbps
SJA1000_ADDRESS=SJA1000_BUSTIME1; //指向总线定时1寄存器
*SJA1000_ADDRESS=BTR1_250Kbps; //选择250Kbps
SJA1000_ADDRESS=SJA1000_RBSA; //指向RX缓冲区起始地址寄存器
*SJA1000_ADDRESS=SJA1000_FIFO_ADD; //接收缓冲区FIFO起始为内部RAM的0地址
SJA1000_ADDRESS=SJA1000_AMRRX0; //指向验收屏蔽寄存器,所有位均参加验收
*SJA1000_ADDRESS=AMR_CODE0;(0xff)
SJA1000_ADDRESS=SJA1000_AMRRX1;
*SJA1000_ADDRESS=AMR_CODE1;(0xff)
SJA1000_ADDRESS=SJA1000_AMRRX2;
*SJA1000_ADDRESS=AMR_CODE2;(0xff)
SJA1000_ADDRESS=SJA1000_AMRRX3;
*SJA1000_ADDRESS=AMR_CODE3; (0xff)
SJA1000_ADDRESS=SJA1000_ACRRX0; //指向验收代码寄存器,送ID码
*SJA1000_ADDRESS=ACR_ID0;(0x0)
SJA1000_ADDRESS=SJA1000_ACRRX1;
*SJA1000_ADDRESS=ACR_ID1;(0xa0)
SJA1000_ADDRESS=SJA1000_ACRRX2;
*SJA1000_ADDRESS=ACR_ID2;(0x0)
SJA1000_ADDRESS=SJA1000_ACRRX3;
*SJA1000_ADDRESS=ACR_ID3;(0x0)
SJA1000_ADDRESS=SJA1000_RX_ERR; //指向接收错误寄存器
*SJA1000_ADDRESS=SJA1000_CLEAR_TX_ERR; //清除接收错误
SJA1000_ADDRESS=SJA1000_ALC; //指向仲裁丢失捕捉寄存器
temp=*SJA1000_ADDRESS; //通过读取清除
SJA1000_ADDRESS=SJA1000_ECC; //指向错误代码捕捉寄存器
temp=*SJA1000_ADDRESS; //通过读取清除
SJA1000_ADDRESS=SJA1000_MODEL; //指向模式寄存器
*SJA1000_ADDRESS=SJA1000_WORK_MODEL; //设置双滤波接收,进入工作模式
while(!(*SJA1000_ADDRESS==0)); //等待进入工作模式
}
多谢各位了。 答 1: 写详细点把你的硬件电路给出来,以及一些变量的说明将清楚嘛,这样人家才好看嘛。光写一部分程序,谁知道是不是其他方面的问题了
共2条
1/1 1 跳转至页
回复
有奖活动 | |
---|---|
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |
打赏帖 | |
---|---|
vscode+cmake搭建雅特力AT32L021开发环境被打赏30分 | |
【换取逻辑分析仪】自制底板并驱动ArduinoNanoRP2040ConnectLCD扩展板被打赏47分 | |
【分享评测,赢取加热台】RISC-V GCC 内嵌汇编使用被打赏38分 | |
【换取逻辑分析仪】-基于ADI单片机MAX78000的简易MP3音乐播放器被打赏48分 | |
我想要一部加热台+树莓派PICO驱动AHT10被打赏38分 | |
【换取逻辑分析仪】-硬件SPI驱动OLED屏幕被打赏36分 | |
换逻辑分析仪+上下拉与多路选择器被打赏29分 | |
Let'sdo第3期任务合集被打赏50分 | |
换逻辑分析仪+Verilog三态门被打赏27分 | |
换逻辑分析仪+Verilog多输出门被打赏24分 |