电子大神的日记本,供应链专家的功夫茶盘,在这里记录、分享与共鸣。

登录以开始

PIC24HJ单片机自学笔记-ECAN外设库文件

下面是PIC24H外设库文件的ECAN部分:

  • CANxAbortAll:放弃所有等待传输的内容,设置ABAT 位,操作完成时,ABAT清零
  • CAN1ClearRXFUL1:清空C1RXFUL1中的16位,这个16位对应了RXFUL0~RXFUL15,清空这16个缓冲满的标志位
  • 使能FILTER,比如要使能FILTER8,则在输入参数写入0X08即可。

void CAN1EnableFilter(char filter_no)

{

    if (filter_no <= 15)

       C1FEN1 |= ((unsigned short)1 << filter_no);

   

}

  • CAN1FIFOCon 开辟DMA区域的数量以及FIFO的开始地址,在这里,DMA的数量和FIFO的首地址在寄存器通过如下程序实现

void CAN1FIFOCon(unsigned int fifo_val)

{

   C1FCTRL = fifo_val;

}

在ECAN的头文件中定义了该寄存器定义的两个区,如果要设置开辟BUFFER大小为4,首地址为3,则,

CAN1FIFOCon(CAN_DMA_BUF_SIZE_4& CAN_FIFO_AREA_TRB3)

即可,在编写程序中不要再去找寄存器的位定义。

  • CAN1GetRXErrorCount:获取接收错误的数量,CIEC这个寄存器有两个8位,分别定义接收和发送的错误计数,该寄存器在头文件中定义为两个结构体,而返回的参数就一个8位的返回值,比如i= CAN1GetRXErrorCount();则相当于读取C1EC寄存器的低8位。
  • CAN1GetTXErrorCount:同上。
  • CAN1Initialize:初始化:

void CAN1Initialize(unsigned int config1, unsigned int config2)

{

    C1CFG1 = config1; /* configure SJW and BRP */

    C1CFG2 = config2; /* configure PHSEG2 and PHSEG1 and PROPSEG */

}

第一个参数设置波特率的倍频以及SJW,这个位是用于同步的,比如相位错误和延时,短路造成需要重新同步的情况。

第二个参数,包括了BIT TIMING的三个参数,以及FILTER唤醒和采样次数。

调用时:

CAN1Initialize(CAN_SYNC_JUMP_WIDTH2 &

CAN_BAUD_PRE_SCALE(2),

CAN_WAKEUP_BY_FILTER_DIS &

CAN_PHASE_SEG2_TQ(5) &

CAN_PHASE_SEG1_TQ(4) &

CAN_PROPAGATIONTIME_SEG_TQ(4) &

CAN_SEG2_FREE_PROG &

CAN_SAMPLE1TIME);

  • CAN1IsBusOff:总线关,在正常通信之前当然要保证总线是开的,如果错误导致总线关掉,则返回1,调用如下:

while(CAN1IsBusOff());

  • CAN1IsRXPassive:被动错误,返回总线的状态是不是一个被动错误。同上面的定义,调用时:

rx_bus_status = CAN1IsRXPassive();

  • CAN1IsRXReady:接收缓存是否读完,一共32个RX,定义了两个寄存器,入口参数是寄存器的选择位,返回的是寄存器的值,判断是否为0来决定寄存器是否已经完全读走,准备接收下一个数据。
  • CAN1IsTXPassive:读取判断是否发送是一个被动错误。
  • CAN1IsTXReady:发送已经准备好的状态,和上面的接收类似。
  •  CAN1ReceiveMessage:CAN接收信息,有三个入口参数,包括存放的地址指针,读取的长度,以及从哪个DMA地址中读取,函数的定义如下:

void CAN1ReceiveMessage (unsigned char * data, unsigned char datalen,

                         unsigned char *DMAptr)

{

    unsigned char i;

    for (i = 0; i>18) & 0x7FF) << 2) | (1 << 1) | 1);

 word1 = (unsigned short)((txIdentifier>>6) & 0xFFF);

 word2 = (unsigned short)(((txIdentifier & 0x3F) << 10) | (remoteTransmit << 9) |

                           ( 1 << 8) | (1 << 4) | datalen);

 break;

default:

    // Standard ID

 word0 = (unsigned short)(((txIdentifier & 0x7FF) << 2) | (remoteTransmit << 1));

 word2 = (unsigned short)((remoteTransmit << 9) | (1 << 4) | datalen);

 break;

 }

// Obtain the Address of Transmit Buffer in DMA RAM for a given Transmit Buffer number

 dmaBaseAddress[0] = word0;

 dmaBaseAddress[1] = word1;

 dmaBaseAddress[2] = word2;

   

 ptr=(char *)&dmaBaseAddress[3];

 for(i = 0;i < datalen;i++)

     {

  *ptr++ = data[i];

 

     }

    /* Msg send request */

    switch(MsgFlag)

    {

    case 0:

        C1TR01CONbits.TXREQ0 = 1;

        break;

    case 1:

        C1TR01CONbits.TXREQ1 = 1;

        break;

    case 2:

        C1TR23CONbits.TXREQ2 = 1;

        break;

    case 3:

        C1TR23CONbits.TXREQ3 = 1;

        break;

    case 4:

        C1TR45CONbits.TXREQ4 = 1;

        break;

    case 5:

        C1TR45CONbits.TXREQ5 = 1;

        break;

    case 6:

        C1TR67CONbits.TXREQ6 = 1;

        break;

    case 7:

        C1TR67CONbits.TXREQ7 = 1;

        break;

    default:

        C1TR01CONbits.TXREQ0 = 1;

        break;

    }

}

对照数据帧的格式如下:

此数据帧中,ID和帧类型,以及要发送的数据合成在这个数组中,FILHIT这个5位在寄存器中设置。

  • CAN1SetBUFPNT1~4:每个FILTER的RXbuffer,一共16个BUFFER,在 CxBUFPNT1n寄存器中设置。
  • CAN1SetFilter:设个是设置filter,入口参数有FILTER号,SID和EID,由这三个参数来合成两个寄存器:CiRXFnSID和CiRXFnEID.
  • CAN1SetMask:这个用来设置MASK,入口参数很上面相同。
  • CAN1SetMaskSource:每一个filter3个MASK源。
  • CAN1SetOperationMode:配置操作模式,模式寄存器一共有两个,分别是CiCTRL1&2,具体看寄存器定义。
  • CAN1SetOperationModeNoWait:这个在上面的基础上加入一句:不等了,把要发送的数据丢弃。
  • CAN1SetTXRXMode:发送接收的模式,配置CiTRmnCON寄存器。
  • ConfigIntCAN1:中断配置,包括使能和去使能各种中断的型号,以及中断优先级。

上面是函数的定义,还定义了使能,去使能,和优先级的设置的宏定义。

博主
guitronic@163.com
Guitronic手工坊
生活可以很简单,梦见了,就去做。
点击跳转