打印

求助,有对KEIL工程设置的同学请进

[复制链接]
2332|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
dzxc_wh|  楼主 | 2021-9-12 10:42 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
最近用到NXP的P89V51RD2做一个关于CAN通讯的小工程,碰到点问题,望大家指点一二。
情况是这样的,所用的KEIL的版本是:

硬件情况是:单片机外扩了一片SJA1000的CAN控制器,SJA1000的片选直接接GND
KEIL\Target设置如下:


意思就是告诉编译器,外扩了RAM
SJA1000的基地址定义为:
#define CAN1                         0x0000                                //cs_c1

其控制寄存器定义为(太长,没复制完全):
//第一片CAN地址/
unsigned char volatile         CAN1_MOD                 _at_         (CAN1+0);                //模式
unsigned char volatile  CAN1_CMR                 _at_        (CAN1+1);                 //命令
unsigned char volatile  CAN1_SR                 _at_        (CAN1+2);                 //状态
unsigned char volatile  CAN1_IR                 _at_        (CAN1+3);                //中断
unsigned char volatile  CAN1_IER                 _at_        (CAN1+4);                 //中断使能
unsigned char volatile  CAN1_BRT0                 _at_        (CAN1+6);                 //总线定时0
//在复位模式中是可以被访问的(读/写),定义波特率预设值和同步跳转宽度
//pelican模式,在工作模式中是只读的
//basic模式中,总是0XFF
unsigned char volatile  CAN1_BRT1                 _at_        (CAN1+7);                 //总线定时1
//在复位模式中是可以被访问的(读/写),定义每个位周期的长度、采样点的位置和在每个采样点的采样数目
//pelican模式,在工作模式中是只读的
//basic模式中,总是0XFF
unsigned char volatile  CAN1_OCR                 _at_        (CAN1+8);                //输出控制
//在复位模式中是可以被访问的(读/写),实现了由软件控制不同输出驱动配置的建立
//pelican模式,在工作模式中是只读的
//basic模式中,总是0XFF

CAN初始化函数:
void can1_ini(void)
{
        unsigned char can1_status;

        EX0=0;                                                                                                //关INT0
        can1_status=can1_interface_test(0x55);                                //a)检测硬件连接是否正确
        if(can1_status==CAN1_INTERFACE_OK)
        {
                while((CAN1_MOD&0x01)!=0x01) CAN1_MOD=0x01;           //b)进入复位状态
                CAN1_CDR=0xc8;                                                                        //c)设置时钟分频寄存器
                CAN1_OCR=0xaa;                                                                        //d)设置输出控制寄存器
                CAN1_BRT0=Can12_BTR0_Rate_250k;                                                //e)设置通讯波特率
                CAN1_BRT1=Can12_BTR1_Rate_250k;                                                //e)设置通讯波特率
                CAN1_ACR0=0x00;                                                                        //f)设置代码验收寄存器
                CAN1_ACR1=0x01;                                                                        //f)设置代码验收寄存器
                CAN1_ACR2=0x00;                                                                        //f)设置代码验收寄存器
                CAN1_ACR3=0x01;                                                                        //f)设置代码验收寄存器
                CAN1_AMR0=0xff;                                                                        //g)设置代码屏蔽寄存器
                CAN1_AMR1=0xff;                                                                        //g)设置代码屏蔽寄存器
                CAN1_AMR2=0xff;                                                                        //g)设置代码屏蔽寄存器
                CAN1_AMR3=0xff;                                                                        //g)设置代码屏蔽寄存器
                CAN1_IER=0xff;                                                                        //j)设置中断使能寄存器

                //CAN1_IER=0x00;                                                                        //j)设置中断使能寄存器

                while((CAN1_MOD&0x01)!=0x00) CAN1_MOD=0x00;                //h)退出复位状态
                                                                                                                //i)设置工作模式,选择两个验收滤波器
                                                                                                               
                //EX0=1;
                LED_run=0;
                DelayMs(1000);
                LED_run=1;
                DelayMs(1000);
                LED_run=0;
                DelayMs(1000);
        }
        else
        {
                //硬件连接不正常,以后再处理
        }
}

CAN发送函数为:
void can_take(unsigned char id,unsigned char temp[8])
{
        unsigned char temp1=0;
        unsigned char temp2=0;
        unsigned char temp3=0;
        unsigned char temp4=0;

        temp1=id;
        temp2=id;
        temp3=temp1>>3;
        temp4=temp1<<5;

        CAN1_CMR=0x0e;                                //清除数据溢出,释放接收缓冲器,中止发送
        CAN1_TXB_0=0x08;                        //FF=0:标准桢 RTR=0:数据桢
        CAN1_TXB_1=temp3;                        //ID.28--ID.21       
        CAN1_TXB_2=temp4&0xe0;                //ID.20--ID.18

        CAN1_TXB_3=temp[0];
        CAN1_TXB_4=temp[1];
        CAN1_TXB_5=0x30;
        CAN1_TXB_6=0x31;
        CAN1_TXB_7=0x33;
        CAN1_TXB_8=0x34;
        CAN1_TXB_9=0x35;
        CAN1_TXB_10=0x36;
       
        CAN1_CMR=0x09;
}

目前的现象是:
初始化函数运行正常,SJA1000能正常发出设定波特率的数据,且发送数据的后6个数据正常(写的是常数),但是前面的2个字节就不受控制了,像是随机数一样

CAN接收端收到的数据是:


正常在主程序里面调用CAN发送部分的程序为:
        can_tr[0] = 0x10;
        can_tr[1] = 0x11;
        can_tr[2] = 0x22;
        can_tr[3] = 0x23;
        can_tr[4] = 0x24;
        can_tr[5] = 0x25;
        can_tr[6] = 0x26;
        can_tr[7] = 0x27;



        while(1)
        {
                can_take(0x38,can_tr);

                //can_tr2[0]=1;
                //can_tr2[1]=3;
                //can_tr2[2]=5;
                //can_tr2[3]=7;
                //can_tr2[4]=9;
                //can_tr2[5]=11;
                //can_tr2[6]=13;
                //can_tr2[7]=15;

                //send_string_com(can_tr2,8);                       
                //send_char_com(0x11);
                //send_char_com(0x18);

                DelayMs(500);
               
                LED_run=~LED_run;
        }

即CAN收到的第一个数据应该是0x10,第2个数据应该是0x11

因为这个CPU不能仿真,只能通过ISP的方式下载调试,所以现在很痛苦,不知道是哪里的问题。

肯定各位有知道,指点一下,谢谢谢谢了

使用特权

评论回复

相关帖子

沙发
dzxc_wh|  楼主 | 2021-9-12 10:46 | 只看该作者

使用特权

评论回复
板凳
dzxc_wh|  楼主 | 2021-9-12 10:51 | 只看该作者
本帖最后由 dzxc_wh 于 2021-9-12 10:54 编辑

没有外扩ROM,外扩了RAM(SJA1000),感觉是片内和片外的RAM之间好像有冲突了,但是具体怎么设置又不太清楚

使用特权

评论回复
地板
xyz549040622| | 2021-9-12 21:50 | 只看该作者
这么古老的芯片和编译器,搞得人很少了,我觉得还是先看手册,弄懂配置的作用再说吧。

使用特权

评论回复
5
datouyuan| | 2021-9-13 09:01 | 只看该作者
dzxc_wh 发表于 2021-9-12 10:51
没有外扩ROM,外扩了RAM(SJA1000),感觉是片内和片外的RAM之间好像有冲突了,但是具体怎么设置又不太清楚
...


不要选xdata

使用特权

评论回复
6
datouyuan| | 2021-9-13 09:08 | 只看该作者
#define CAN1                         0x0000                                //cs_c1

应改为0x1000,错开芯片自带的xdata范围。

使用特权

评论回复
7
dzxc_wh|  楼主 | 2021-9-14 07:57 | 只看该作者
一个关键字搞定,idata unsigned char can_tr[8];
感谢各位回帖的同学

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

23

主题

107

帖子

0

粉丝