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

2014-1-16 06:07 1799 14 14 分类: MCU/ 嵌入式 文集: PIC24HJ单片机自学笔记

下面是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<datalen; i++)
    {
        data = *(DMAptr + i);
    }
}
调用的时候:

unsigned char *rx_data;

CAN1ReceiveMessage (rx_data, 3, 0x4030);

  • 消息发送:这里有7个参数,包括*data,用来保存要发送出去的数据存放的地址,DATALEN,为发送的数据字节长度, txIdentifier为发送的数据的ID号,IDE是用来表示标准帧还是扩展帧, remoteTransmit用来表示是否是一个远程帧, dmaBaseAddress为要发送的DMA的基址,MsgFlag为发送请求号。

void CAN1SendMessage (unsigned char *data,

   unsigned char datalen,

   unsigned long txIdentifier,   

   unsigned char ide,

   unsigned char remoteTransmit,       

   unsigned int *dmaBaseAddress, char MsgFlag);

函数的定义如下:

void CAN1SendMessage(unsigned char *data, unsigned char datalen, unsigned long txIdentifier,\

unsigned char ide, unsigned char remoteTransmit, unsigned int *dmaBaseAddress, unsigned char MsgFlag){

   

unsigned char i; //给for循环用,用来循环合成要发送的数据帧。

unsigned int word1;

unsigned int word2, word0; //这三个字用来存放数据帧的头三个字

char *ptr; //用来合成一个帧,作为指针指向*data区间

switch(ide)

 {

case 0:

    // Standard ID

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

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

 break;

case 1:

 //Extended ID

 word0 = (unsigned short)((((txIdentifier>>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;

 

     }

    /* 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:中断配置,包括使能和去使能各种中断的型号,以及中断优先级。
上面是函数的定义,还定义了使能,去使能,和优先级的设置的宏定义。























PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
14
关闭 站长推荐上一条 /3 下一条