心情绿茶 发表于 2012-4-17 15:53:10

opencore下载的CAN IP的寄存器读写问题

这件事情起源于毕业设计,真是坑爹的毕业设计。。。。。。。。



最先的想法是在FPGA内集成一个CAN控制器,然后通过读写它来对外部的传感器数据进行采集。。。。。



第一步:新建Quartus II工程,如图所示:



在SOPC利用PIO内核直接对CAN控制器进行数据的读取,想法挺简单,实施却难啊。。。。



第二步:在IDE环境中编程,在IDE中编程相关的CAN控制器的读写代码,问题来了



首先是CAN控制器的初始化:

void CAN_IO_init()
{
    ALE_CLR;
    WR_SET;
    RD_SET;
    CS_SET;
    AD_OUT;//首先确定PIO_AD口是数据输出口
}



然后是两个最为关键的寄存器读写子函数,也就是这两个子函数,让我头疼了两个星期,先来看读子函数,在看子函数之前,先来看相关的宏定义:



#define   ALE_SET   IOWR_ALTERA_AVALON_PIO_DATA(PIO_ALE_BASE, 1)   //ALE
#define   ALE_CLR   IOWR_ALTERA_AVALON_PIO_DATA(PIO_ALE_BASE, 0)



#define   WR_SET    IOWR_ALTERA_AVALON_PIO_DATA(PIO_WR_BASE, 1)    //WR
#define   WR_CLR    IOWR_ALTERA_AVALON_PIO_DATA(PIO_WR_BASE, 0)



#define   RD_SET    IOWR_ALTERA_AVALON_PIO_DATA(PIO_RD_BASE, 1)    //RD
#define   RD_CLR    IOWR_ALTERA_AVALON_PIO_DATA(PIO_RD_BASE, 0)



#define   CS_SET    IOWR_ALTERA_AVALON_PIO_DATA(PIO_CS_BASE, 1)    //CS
#define   CS_CLR    IOWR_ALTERA_AVALON_PIO_DATA(PIO_CS_BASE, 0)



#define   AD_WR(data)   IOWR_ALTERA_AVALON_PIO_DATA(PIO_AD_BASE, data)   //AD
#define   AD_RD         IORD_ALTERA_AVALON_PIO_DATA(PIO_AD_BASE)



#define   AD_IN   IOWR_ALTERA_AVALON_PIO_DIRECTION(PIO_AD_BASE, 0)   //AD_DIR
#define   AD_OUT    IOWR_ALTERA_AVALON_PIO_DIRECTION(PIO_AD_BASE, 0xFF)   



以上这些都是直接对IO口进行操作,进行简单的置位与复位



//------------------------------------------------------------------------------------------------------
// 函数类别 SJA1000基本操作
// 函数名称 CANREG_read
// 入口函数 addr
// 出口函数 data
// 函数功能 读SJA1000的寄存器
//------------------------------------------------------------------------------------------------------
alt_u8 CANREG_read(alt_u8 addr)
{
    alt_u8 data;
    ALE_CLR;
    WR_SET;
    RD_SET;
    CS_SET;
    AD_OUT;    //再次初始化
    ALE_SET;
    delay(1);
    AD_WR(addr);
    delay(1);
    ALE_CLR;
    delay(1);   //先送地址
    AD_IN;    //改变AD_PIO的方向,变为读取口
    delay(1);
    CS_CLR;
    RD_CLR;
    delay(2);
    data=AD_RD;    //读取数据
    RD_SET;
    CS_SET;
    AD_OUT;
    return(data);
}



接下来是写寄存器子函数:



//------------------------------------------------------------------------------------------------------
// 函数类别 SJA1000基本操作
// 函数名称 CANREG_write
// 入口函数 addr,data
// 出口函数 无
// 函数功能 写SJA1000的寄存器
//------------------------------------------------------------------------------------------------------
void CANREG_write(alt_u8 addr, alt_u8 data)
{
    ALE_CLR;
    WR_SET;
    RD_SET;
    CS_SET;
    AD_OUT; //确保AD为数据输出模式
    ALE_SET;
    delay(1);
    AD_WR(addr);
    delay(1);
    ALE_CLR;   //先送地址
    delay(1);
    CS_CLR;
    WR_CLR;
    delay(1);
    AD_WR(data);//再写数据
    WR_SET;
    delay(1);
    CS_SET;
    delay(1);
    ALE_SET;
}





可是当我往测试寄存器进行读写测试的时候,无论写进去的数据是什么,读出来的永远都是0xff,下面是测试寄存器的读写函数:



//------------------------------------------------------------------------------------------------------
// 函数类别   SJA1000基本操作
// 函数名称   SJAconnect_judge
// 入口函数   无
// 出口函数   无
// 全局变量   connect_OK
// 操作寄存器 测试寄存器(地址09)
// 函数功能   判断SJA1000与控制器连接是否正常
//------------------------------------------------------------------------------------------------------
void SJAconnect_judge(void)
{
    CANREG_write(0x09,0x55);                //写AA到测试寄存器(地址09)
    if(CANREG_read(0x09)==0x55)
    {
      connect_OK=1;                         //连接正常
    }
    else
    {
      connect_OK=0;                         //连接故障
    }
}



哎,我实在是没有办法了,请各位大侠给我看看,到底问题出在何方,小弟感激不尽!!!!!!为什么读出来的数据永远都是0xff啊!!!!!想不通啊!!!

心情绿茶 发表于 2012-4-19 09:28:29

自己顶了,免得沉了

pocker5200 发表于 2012-4-19 09:29:05

上个RTL图呢,再看看CAN控制器的操作时序……
页: [1]
查看完整版本: opencore下载的CAN IP的寄存器读写问题