dzxc_wh 发表于 2021-9-12 10:42

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

最近用到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 volatileCAN1_CMR                 _at_        (CAN1+1);               //命令
unsigned char volatileCAN1_SR                 _at_        (CAN1+2);                 //状态
unsigned char volatileCAN1_IR                 _at_        (CAN1+3);                //中断
unsigned char volatileCAN1_IER                 _at_        (CAN1+4);                 //中断使能
unsigned char volatileCAN1_BRT0                 _at_        (CAN1+6);                 //总线定时0
//在复位模式中是可以被访问的(读/写),定义波特率预设值和同步跳转宽度
//pelican模式,在工作模式中是只读的
//basic模式中,总是0XFF
unsigned char volatileCAN1_BRT1                 _at_        (CAN1+7);                 //总线定时1
//在复位模式中是可以被访问的(读/写),定义每个位周期的长度、采样点的位置和在每个采样点的采样数目
//pelican模式,在工作模式中是只读的
//basic模式中,总是0XFF
unsigned char volatileCAN1_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)
{
        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;
        CAN1_TXB_4=temp;
        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 = 0x10;
        can_tr = 0x11;
        can_tr = 0x22;
        can_tr = 0x23;
        can_tr = 0x24;
        can_tr = 0x25;
        can_tr = 0x26;
        can_tr = 0x27;



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

                //can_tr2=1;
                //can_tr2=3;
                //can_tr2=5;
                //can_tr2=7;
                //can_tr2=9;
                //can_tr2=11;
                //can_tr2=13;
                //can_tr2=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

这么古老的芯片和编译器,搞得人很少了,我觉得还是先看手册,弄懂配置的作用再说吧。

datouyuan 发表于 2021-9-13 09:01

dzxc_wh 发表于 2021-9-12 10:51
没有外扩ROM,外扩了RAM(SJA1000),感觉是片内和片外的RAM之间好像有冲突了,但是具体怎么设置又不太清楚
...


不要选xdata

datouyuan 发表于 2021-9-13 09:08

#define CAN1                         0x0000                              //cs_c1
应改为0x1000,错开芯片自带的xdata范围。

dzxc_wh 发表于 2021-9-14 07:57

一个关键字搞定,idata unsigned char can_tr;
感谢各位回帖的同学
页: [1]
查看完整版本: 求助,有对KEIL工程设置的同学请进