基于dsPIC33FJ128MC506的CAN通信
系统硬件
利用TJA1054作为CAN收发器,dsPIC33FJ128MC506 CAN通讯要注意的是,在处理器和收发器之间要加光耦以隔离两者之间的电源。原理图如图1所示。
?
?
图1 dsPIC33FJ128MC506 CAN通讯原理图
系统初始化
Microchip公司的dspPIC33FJ128MC506芯片中ECAN通信模块的初始化分为五个部分:系统工作时钟设置、ECAN接收和发射缓冲区的设置、ECAN波特率的设置、接收过滤寄存器和屏蔽寄存器的设置以及ECAN收发器TJA1054的启动。
系统工作时钟设置
dsPIC33FJ128MC506可以选择多种外部和内部振荡器作为时钟源,并通过时钟控制寄存器OSCCON进行设置。对时钟的选择要在系统的配置存储区(0x800000-0xFFFFFF)进行,在程序中一般通过几句宏指令语句指定。
以下语句选择时钟并禁能看门狗,其他的功能请参看芯片说明书。
_FOSCSEL(FNOSC_PRIPLL); //选用带PLL的主振荡器
_FOSC(POSCMD_HS); // 主振荡器为HS型晶振
_FWDT(FWDTEN_OFF); // 看门狗禁能
下面的函数对系统时钟进行配置, 外部晶振为8MHz,系统工作时钟为40MHz。
void oscConfig(void)
{
CLKdivbits.PLLPRE = 0; //外设时钟2分频为4M
PLLFBDbits.PLLdiv = 18; //20倍频,为80M
CLKdivbits.PLLPOST = 0; //外设时钟2分频为40M
while(OSCCONbits.LOCK!=1){ }; //等待设置生效
}
ECAN接收和发射缓冲区的设置
DMA(直接存储器访问)方式是外设SFR与RAM间进行数据复制的非常高效的机制,dsPIC33FJ128MC506的ECAN模块支持DMA传输,共有8个DMA通道可供选择。在此我们选用0和2通道分别作为ECAN1的发射和接收。初始化语句如下:
DMA0通道初始化为ECAN1发射:
void dma0init(void)
{
DMACS0=0; //清DMA控制器状态位
DMA0CON=0x2020; //DMA为外设间接寻址模式,支持从DMA读,并写到外设
DMA0PAD=0x0442; //DMA0PAD下载为ECAN1发射寄存器的地址
DMA0CNT=0x0007; //传输计数寄存器为8
DMA0REQ=0x0046; //DMA外设REQ编号选择位
DMA0STA= __builtin_dmaoffset(ecan1msgBuf); //DMA起始地址位
DMA0CONbits.CHEN=1;
}
DMA2通道初始化为ECAN1接收:
void dma2init(void)
{
DMACS0=0; //清DMA控制器状态位
DMA2CON=0x0020; //DM为外设间接寻址模式,支持从DMA写,并读到外设
DMA2PAD=0x0440; //DMA0PAD下载为ECAN1接收寄存器的地址
DMA2CNT=0x0007; //传输计数寄存器为8
DMA2REQ=0x0022; //DMA外设REQ编号选择位
DMA2STA= __builtin_dmaoffset(&ecan1msgBuf[2][0]); //DMA起始地址位
DMA2CONbits.CHEN=1;
}
上面程序中的“DMA0STA= __builtin_dmaoffset(ecan1msgBuf);”和“ DMA2STA= __builtin_dmaoffset(&ecan1msgBuf[2][0]); ”分别指明了DMA的起始地址位为ecan1msgBuf和(&ecan1msgBuf[2][0],ecan1msgBuf是一个两维数组,在相关头文件中定义,其语句为:
ECAN1缓冲器的设置:
#define ECAN1_MSG_BUF_LENGTH 4 //长度为4个字
//缓冲区为二维数据
typedef unsigned int ECAN1MSGBUF [ECAN1_MSG_BUF_LENGTH][8];
//数组位于DMA空间
extern ECAN1MSGBUF ecan1msgBuf __attribute__((space(dma)));
波特率的设置
正确设置通信波特率必须配置以下几个参数:同步跳转宽度、波特率预分频比、相位段1和相位段2的长度、采样次数及传播时间段的长度。设置程序语句如下:
void ecan1ClkInit(void)
{
/*指定 CAN通信时钟利用系统的指令周期,在此为20MHz,即Fcan=20MHz*/
C1CTRL1bits.CANCKS = 1;
/*规定一个CAN位包含16个TQ,分配如下:*/
C1CFG1bits.SJW = 3; //同步段 = 1TQ
C1CFG2bits.SEG1PH=3; //相位传输段1 = 4TQ
C1CFG2bits.SEG2PHTS = 1; //相位传输段2长度可编程设定
C1CFG2bits.SEG2PH = 3; //相位传输段2 = 4TQ
C1CFG2bits.PRSEG = 6; //传播时间段 = 7TQ
C1CFG2bits.SAM = 0; //采样次数为1次
/*根据上面设置,算出波特率的分频比。这里要注意的是,因为C1CFG1bits.BRP只能填入整数,那么在系统时钟、通讯速率和时间份额三者之间要合理选择,否则通信不会成功。例如:如果系统时钟选用其内部FRC,标称值为7.37M,倍频后的系统时钟为36.85M,采用16个TQ为一个CAN位,假设CAN的通信速率为125K的话,那么根据公式BRP=Fcan/(2*16*125K)-1,计算得出的值为3.6,因为不能整除,所以永远不能得到125K的通信速率。 在此我们取40M的时钟,指令周期为20M,一个CAN位为16个TQ,经计算可得BRP的值为4。*/
C1CFG1bits.BRP =4;
}
接收过滤寄存器和屏蔽寄存器的设置
/* 下面的函数用来设置接收过滤器"n" ,各输入参数的意义分别为:
n-> 过滤器号,范围为[0-15]
CAN TJA1054 dsPIC33FJ128MC506 相关文章:
- CAN网络-其特性阻抗及终端阻抗 (04-29)
- 解读CAN总线行车记录仪系统电路(06-04)
- 为什么要使用CAN总线?(05-31)
- 基于CAN总线的智能家居安防系统设计(10-11)
- 如果CAN总线中节点ID相同会怎样?(08-31)
- CAN通信协议在矿井安全生产监控系统中的应用(09-27)