这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 综合技术 » 基础知识 » 2119 请教深思,2119滤波问题!

共2条 1/1 1 跳转至

2119 请教深思,2119滤波问题!

院士
2006-09-17 18:14:16     打赏
2119 请教深思,2119滤波问题!



关键词: 请教     深思     滤波     问题    

院士
2006-12-22 22:43:00     打赏
2楼
问 在用2119CAN滤波器的时候,用深思提供的滤波程序(CAN_InitSA())运行到“*p++ = SFF_sa[i];”时候出现取数据中断什么的,程序走不下去了,不知道什么原因?

另:我做最简单的独立标准滤波,大概4个ID吧,各位大侠是否可给一个最简单的好用的滤波程序,谢谢!
相关代码如下:第一个是深思在论坛上给的,被我了简化一下,第二个是按照easyARM2100开发板配的书上写的(不滤波好用)。

static const INT32U SFF_sa[] = {
    ((CAN1+1)<<29 | 0<<28 | 0x000<<320)  |  ((CAN1+1)<<13 | 0<<12 | 0x420<<0),
};

#define CANAFRAM   0xE0038000                        /* AF RAM 首地址 */
static void CAN_InitSA(void)
{
    int i;
    INT32U *p = (INT32U *)CANAFRAM;

    CANSFF_sa = (INT32U)p & 0x7fc;                    /* 独立标准帧起始地址 */
    for (i=0; i<(sizeof(SFF_sa)/sizeof(SFF_sa[0])); i++) {
        *p++ = SFF_sa[i];
    }


    CANENDofTable = (INT32U)p & 0x0ffc;                /* AF 表格终止地址 */
}

void InitCAN(uint8 CANNum)
{
  
  PinSet(CANNum);
  switch(CANNum)
  {
case  CAN1:
  CAN1MOD=CAN1MOD|0x01;
  SetWARMVal(CAN1);
  SetBaud(CAN1);
  SetInterrupt(CAN1);
  CANAFMR=0x03;
  CAN_InitSA();
  CANAFMR=0x00;
  CAN1MOD=CAN1MOD&0xFE;
  break;
case  CAN2:
  CAN2MOD=CAN2MOD|0x01;
  SetWARMVal(CAN2);
  SetBaud(CAN2);
  SetInterrupt(CAN2);
  CANAFMR=0x03;
  CAN_InitSA();
  CANAFMR=0x00;
  CAN2MOD=CAN2MOD&0xFE;
  break;
default:
  break;
  }

}

1: re我调用你的这个 CAN_InitSA 函数不会异常,你检查一下寄存器定义头文件,周立功公司提供的有几个写错了的。

#define CANSFF_sa       (*((volatile unsigned long *) 0xE003C004))    /* 标准帧单个起始地址寄存器 */ 2: 继续请教深思多谢深思!!!
程序现在能走过去了,但是不能过滤,好像。
我有4个id(0x00,0x023,0x320,0x420),表格
const uint32    SFF_sa[] ={((CAN1+1)<<29 | 0<<28 | 0x00<<16)|((CAN1+1)<<13 | 0<<12 |0x023<<0),
((CAN1+1)<<29 | 0<<28 | 0x320<<16)|((CAN1+1)<<13 | 0<<12 |0x420<<0)};
单步执行的时候也看到0xE0038000和0xE0038004里面写上了0x20002023和0x23202420,用的还是上面的初始化程序。我用pc卡发什么id的信息,我都能从接收寄存器里面读到。更奇怪的事是,CAN1GSR(0xE0044008)的RBS位(接收完成)不置位,但是DOS位(接收溢出)确会置位。在发现溢出和读取数据后我都执行了释放接收缓冲区命令
CAN1CMR=CAN1CMR|0x04;          //释放接收缓冲区
但是如果我不进行过滤设置,即
//  CAN_InitSA();
//  CANAFMR=0x00;
则可以看到CAN1GSR(0xE0044008)的RBS位(接收完成)置位。
下面是我自己编的一个接收程序。
void CAN1GetMSG(MSG_BUF *msg)
{ uint32 dataA,dataB,dataID;
  uint8 i,BUF[11];
  uint8 *p;
  if (CAN1GSR&0x02!=0)  
  {
     CAN1CMR=CAN1CMR|0x04;          //释放接收缓冲区
  }
  else
  {
   dataID=CAN1RID;
   dataA=CAN1RDA;
   dataB=CAN1RDB;
   BUF[0]=(uint8)dataA;
   BUF[1]=(uint8)(dataA>>8);
   BUF[2]=(uint8)(dataA>>16);
   BUF[3]=(uint8)(dataA>>24);
   BUF[4]=(uint8)dataB;
   BUF[5]=(uint8)(dataB>>8);
   BUF[6]=(uint8)(dataB>>16);
   BUF[7]=(uint8)(dataB>>24);
   BUF[8]=(uint8)(dataID&0x0F);//SRC
   BUF[9]=(uint8)((dataID>>4)&0x0F);//DEST
   BUF[10]=(uint8)((dataID>>8)&0x07);//INDEX
   p=BUF;
   for (i=0;i<8;i++)
      {
       *(uint8 *)(msg->BUF+i)=*(p+i);
      
      }

   msg->SRC=*(p+8);
   msg->DEST=*(p+9);
   msg->INDEX=*(p+10);
   CAN1CMR=CAN1CMR|0x04;          //释放接收缓冲区

  }


}
在主程序里面用下面的语句等待接收完成
while (0==(CAN1GSR&0x01));  // 等待接收完成置位
CAN1GetMSG(&s1);
.......
能否帮我分析一下。(即现在不用滤波可用,还是滤波出问题) 3: 检查检查参数设置及设置步骤/****************************************************************************
* 功能:初始化 CAN1
****************************************************************************/
static void CAN1Init()
{
    PCONP  |= 1<<13;                                /* CAN1 控制器使能 */
    PINSEL1 = (PINSEL1 & ~(3<<18)) | (1<<18);        /* 设置CAN1引脚 */

    CANResetMode(CAN1);
    CAN1MOD = 0<<7 | 0<<5 | 0<<4 | 0<<3 | 0<<2 | 0<<1 | 1<<0;
/*
7 TM    0:正常工作模式。1:测试模式。Rx 脚的状态被记录到Tx 脚上。
5 RPM 0:如果传输的是显性位,Rx 和Tx 脚为低电平。
4 SM  0:正常工作模式。1:睡眠模式.
3 TPM 0:3 个发送缓冲区的优先级由各自的 CAN ID 决定。1:3 个发送缓冲区的优先级由各自的Tx 优先级域决定
2 STM 0:发送的信息必须被应答才被认可。
1 LOM 0:当 CAN 总线成功接收到信息时,CAN 控制器产生应答。
0 RM  0:CAN 控制器正常工作,某些寄存器不能写入。 1:复位模式(禁止CAN),可写寄存器可以写入数据。
*/
    CAN1CMR = 0<<7 | 0<<6 | 0<<5 | 0<<4 | 1<<3 | 1<<2 | 0<<1 | 0<<0;
/*
7 STB3 1:选择发送Tx 缓冲区3 的内容。
6 STB2 1:选择发送Tx 缓冲区2 的内容。
5 STB1 1:选择发送Tx 缓冲区1 的内容。
4 SRR  1:自接收请求,先前写入CANTFS 和CANTID 的内容以及CANTDA 和CANTDB 寄存器的内容等待发送。
        该位与TR 位的不同在于:发送过程中接收器并未禁能,接收器仍能够接收符合验收过滤器识别标识的信息。
3 CDO  1:清除数据溢出——清除CANSR 的数据溢出位。
2 RRB  1:释放接收缓冲区
1 AT   1:中止发送——所有等待发送请求取消,正在处理的发送请求除外。如果该位和TR 在同一次写操作中置
        位,尝试执行一次单帧发送,如果既未建立错误标志仲裁也未丢失,则不再执行帧发送。
0 TR   1:发送请求——先前写入CANTFI 和CANTID 的内容以及CANTDA 和CANTDB 寄存器的内容等待发送。
*/
    CAN1GSR = 0x0000000c;                            /* CAN1 全局状态寄存器 */
/*
23:16 RXERR Rx 错误计数器的当前值。
31:24 TXERR Tx 错误计数器的当前值。
*/
    CAN1ICR = 0x00000000;                            /* CAN1 中断和捕获寄存器 */
    CAN1IER = 0<<8 | 0<<7 | 0<<6 | 0<<5 | 0<<4 | 0<<3 | 1<<2 | 0<<1 | 1;
/*
0  RIE  1: 接收器中断使能
1  TIE1 1: 发送中断使能(1)
2  EIE  1: 出错警告中断使能
3  DOIE 1: 数据溢出中断使能
4  WUIE 1: 唤醒中断使能
5  EPIE 1: 错误认可中断使能
6  ALIE 1: 仲裁丢失中断使能
7  BEIE 1: 总线错误中断使能
8  IDIE 1: ID 准备就绪中断使能
9  TIE2 1: 发送中断使能(2)
10 TIE3 1: 发送中断使能(3)
*/
    CAN1BTR = BPS_50K;                                /* 总线时序 */

    CAN1EWL = 0x7f;                                    /* 出错警告界限 */

    SetCAN1TxVIC;
    SetCAN1RxVIC;
    VICIntEnable  = 1<<20 | 1<<26;                    /* CAN1 Tx Rx 中断允许 */

    EnCANTIE(CAN1, Port1);
}


         CAN1Init();

    SetCANErrVIC;
    VICIntEnable = 1<<19;                        /* CAN 错误中断允许 */

    CANAFMR = 0<<2 | 1<<1 | 1<<0;
/*
0 AccOff 1:关闭接收过滤器。若AccBP为0,则接收器忽略总线上所出现的数据。
1 AccBP  1:允许所有接收通过(ByPass),这时接收过滤器作用被旁路。如果该位和AccOff都为0,接收到的CAN标识符将通
          过接收过滤器进行筛选。注意在修改其他与CAN接收过滤相关的寄存器和LUT内容时,必须先置位AccBP(置位或
          清零标识符行的禁能位除外)。
2 eFCAN  1:由接收过滤器自身来处理所选CAN总线上FullCAN指定标准ID值的信息的接收和保存;当FullCAN标准帧ID表格
          没有匹配的ID时,进入常规接收过滤匹配检查。0:软件必须从所有使能的CAN总线上读取允许通过的标示符的
          报文。
*/

    CANInitSA();
    CANAFMR = 0<<2 | 0<<1 | 0<<0;

    CANNormalMode(CAN1);                            /* 正常工作模式 */

4: 还是不行按照你提供的程序,注销掉向量中断的设置,查询状态寄存器,还是不好用。
————————————————————————————————

/****************************************************************************
* 功能:初始化 CAN1
****************************************************************************/
void CAN1Init()
{
    PCONP  |= 1<<13;                                /* CAN1 控制器使能 */
    PINSEL1 = (PINSEL1 & ~(3<<18)) | (1<<18);        /* 设置CAN1引脚 */

//   CANResetMode(CAN1);
    CAN1MOD = 0<<7 | 0<<5 | 0<<4 | 0<<3 | 0<<2 | 0<<1 | 1<<0;

    CAN1CMR = 0<<7 | 0<<6 | 0<<5 | 0<<4 | 1<<3 | 1<<2 | 0<<1 | 0<<0;

    CAN1ICR = 0x00000000;                            /* CAN1 中断和捕获寄存器 */
    CAN1IER = 0<<8 | 0<<7 | 0<<6 | 0<<5 | 0<<4 | 0<<3 | 1<<2 | 0<<1 | 1;

    CAN1BTR = BPS_500K;                                /* 总线时序 */

    CAN1EWL = 0x7f;                                    /* 出错警告界限 */

//    SetCAN1TxVIC;
//    SetCAN1RxVIC;
    VICIntEnable  = 1<<20 | 1<<26;                    /* CAN1 Tx Rx 中断允许 */

//    EnCANTIE(CAN1, Port1);
}
/****************************************************************************
* 功能:初始化 CAN
****************************************************************************/
void CANInit(void)
{
         CAN1Init();

//    SetCANErrVIC;
    VICIntEnable = 1<<19;                        /* CAN 错误中断允许 */

    CANAFMR = 0<<2 | 1<<1 | 1<<0;


    CAN_InitSA();
    CANAFMR = 0<<2 | 0<<1 | 0<<0;

  CAN1MOD=CAN1MOD&0xFE;
  }
int main (void)
{
   uint32 aaa,bbb,ccc,ddd;
   MSG_BUF s1;
   TargetInit();                       // 初始化系统时钟
//  InitCAN(CAN1);                           // 初始化CAN1口
   CANInit();
while(1)
{
// while (0==(CAN1ICR&0x01));  // 等待接收中断置位
   while (0==(CAN1GSR&0x01));  // 等待接收完成置位
   CAN1GetMSG(&s1);
×s1.INDEX=3;             //断点设置在这儿,走不过来
   CAN1SendMSG(&s1);  
}

}

如果注销掉void CANInit(void)中的滤波功能,则可走到断点,并可完成收发功能
//  CAN_InitSA();
  //  CANAFMR = 0<<2 | 0<<1 | 0<<0;

你是否可以给我发一个好用的滤波程序,我自己再仔细看看,谢谢了!

gaopu1089163.com 或者  gaopu1089@hit.edu.cn

共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]