这件事情起源于毕业设计,真是坑爹的毕业设计。。。。。。。。
最先的想法是在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啊!!!!!想不通啊!!!
此帖出自
小平头技术问答
一周热门 更多>