历史上的今天
返回首页

历史上的今天

今天是:2024年09月09日(星期一)

正在发生

2018年09月09日 | 基于C8051F040单片机的CAN总线通信

2018-09-09 来源:eefocus

硬件部分

  硬件部分电路结构如下: 
这里写图片描述
  CAN收发模块原本采用的是ATA6660高速CAN收发芯片,电路连接如下: 
  ATA6660收发器电路图
  设计电路为:当单片机发送数据时,D18闪烁,并将数据传送给ATA6660芯片;当ATA6660芯片接受到总线上的数据时,D17闪烁,并将数据传送给单片机。 
  实际调试时,发现C8051F040单片机既没办法发送数据到总线上,也没办法从总线上接收到数据。 
  用示波器对电路检测发现,当单片机需要发送数据时,ATA6660芯片的TXD引脚上能检测到数据,且D18闪烁。示波器检测总线上的电压,没有变化。PC端显示总线上的数据为FE。当PC端给总线发送数据时,总线上能检测到电压的变化,而ATA6660芯片的RXD引脚电压为0。故怀疑为CAN收发部分硬件存在问题。 
  因此,将CAN收发模块换为直接购买的TJA1050CAN收发模块,电路如下图所示。通过测试,CAN模块工作正常。而单片机能够成功发送数据,接收数据失败。 
TJA1050收发器电路图
  对比前后两个电路可以发现,区别在于CAN收发芯片的RS引脚。ATA6660芯片的RS引脚悬空,而TJA1050芯片的RS引脚接地。 
  查阅ATA6660芯片数据手册,发现RS引脚的功能为Switch Standby Mode/Normal Mode。而Standy Mode的解释为: 
  这里写图片描述
  故使用ATA6660模块时无法正常收发数据。而正确的电路应为: 
这里写图片描述

软件部分

  程序参考自童长飞编著的《C8051F系列单片机开发与C语言编程》例程12-1。

1.基本设置

    int n;            

    //看门狗禁止

    WDTCN = 0x07;

    WDTCN = 0xDE;   

    WDTCN = 0xAD;

    SFRPAGE = 0x0F;

    //交叉开关使能,但没有进行外围设备配置

    XBR0 = 0x00;    

    XBR1 = 0x00;    

    XBR2 = 0x40;

    XBR3 = 0x00;   

    //管脚输出配置,P0口为开漏输出,其中P0.6接上拉电阻,P0为数字输入口

    SFRPAGE = 0x0F;

    P0MDOUT = 0x00; 

    P1MDIN = 0xFF;  

    //晶振配置

    OSCXCN  = 0x77;//选择外部晶振22.1MHz。

                //系统时钟为外部时钟二分频:22.1 MHz / 2 = 11.05 MHz

    for (n = 0; n < 255; n++);

    while ((OSCXCN & 0x80) == 0);

    CLKSEL |= 0x01;


2.CAN消息对象清零


void clear_msg_objects (void) //将所有消息清零

{   

    uchar i;

    SFRPAGE = CAN0_PAGE;

    CAN0ADR = IF1CMDMSK;       

    CAN0DATL = 0xFF;            

    for (i=1;i<33;i++)

    {

        CAN0ADR = IF1CMDRQST;     

        CAN0DATL = i;

    }   

}


3.CAN发送初始化


void init_msg_object_TX (char MsgNum,uint id) 

{

    uint temp;

    SFRPAGE = CAN0_PAGE;

    CAN0ADR = IF1CMDMSK; //指向IF1 Command Mask Registers

    CAN0DAT = 0x00b3; 

    /*   IF1 Command Mask Registers  =0x00b3 

    WR/RD=1,Mask=0,Arb=1,Control=1,ClrIntPnd=0,TxRqst=0,DataA=1,DataB=1,一次发送8字节数据*/

    CAN0ADR = IF1ARB1;            

    CAN0DAT = 0x0000;  

    /*IF1 Arbitration Registers1 =0x0000,即ID15-0=0*/

    temp=id<<2;//标准id为ID28-ID18,所以要左移2位

    temp&=0x1fff;

    temp|=0xa000;

    CAN0DAT = temp; //地址自增,指向IF1 Arbitration Registers2

    /*IF1 Arbitration Registers2=101(id)00b

    MsgVal=1,Xtd=0,为标准模式,扩展ID无效,Dir=1,为发送*/

    CAN0DAT = 0x0088;

    /*IF1 Message Control Registers=0x0088

    NewDat=0,MsgLst=0,IntPnd=0,UMask=0,TxIE=0,RxIE=0,RmtEn=0,TxRqst=0

    EoB=1,DLC3-0=1000,即数据长度为8*/

    CAN0ADR = IF1CMDRQST;         

    CAN0DAT = MsgNum;   

    /*IF1 Command Request Registers=MsgNum,将以上配置写入MsgNum号消息*/

}


4.CAN接收初始化


void init_msg_object_RX (char MsgNum,uchar id) 

{

    uint temp;

    SFRPAGE = CAN0_PAGE;

    CAN0ADR = IF2CMDMSK; 

    CAN0DAT = 0x00fb;             

    /*   IF2 Command Mask Registers  =0x00fb 

    WR/RD=1,Mask=1,Arb=1,Control=1,ClrIntPnd=1,TxRqst=0,DataA=1,DataB=1,一次接收8字节数据*/

    CAN0ADR = IF2MSK1;

    CAN0DAT = 0x0000;

    CAN0DAT = 0x0000;

    CAN0ADR = IF2ARB1;           

    CAN0DAT = 0x0000; 

    /*IF2 Arbitration Registers1 =0x0000,即ID15-0=0*/            

    temp=id<<2;//标准id为ID28-ID18,所以要左移2位

    temp&=0x1fff;

    temp|=0x8000;

    CAN0DAT = temp; 

    /*IF2 Arbitration Registers2=100(id)00b

    MsgVal=1,Xtd=0,为标准模式,扩展ID无效,Dir=0,为接收*/

    CAN0DAT = 0x0488;

    /*IF2 Message Control Registers=0x0488

    NewDat=0,MsgLst=0,IntPnd=0,UMask=0,TxIE=0,RxIE=1,接收中断使能;RmtEn=0,TxRqst=0

    EoB=1,DLC3-0=1000,即数据长度为8*/

    CAN0ADR = IF2CMDRQST;        

    CAN0DATL = MsgNum;           

    /*IF2 Command Request Registers=MsgNum,将以上配置写入MsgNum号消息*/

}


5.CAN波特率设置 

Calculation of the CAN bit timing :


System clock f_sys = 22.1184 MHz/2 = 11.0592 MHz. 

System clock period t_sys = 1/f_sys = 90.422454 ns. 

CAN time quantum tq = t_sys (at BRP = 0)


Desired bit rate is 1 MBit/s, desired bit time is 1000 ns. 

Actual bit time = 11 tq = 996.65ns ~ 1000 ns 

Actual bit rate is 1.005381818 MBit/s = Desired bit rate+0.5381%


CAN bus length = 10 m, with 5 ns/m signal delay time. 

Propagation delay time : 2*(transceiver loop delay + bus line delay) = 400 ns 

(maximum loop delay between CAN nodes)


Prop_Seg = 5 tq = 452 ns ( >= 400 ns). 

Sync_Seg = 1 tq


Phase_seg1 + Phase_Seg2 = (11-6) tq = 5 tq 

Phase_seg1 <= Phase_Seg2, => Phase_seg1 = 2 tq and Phase_Seg2 = 3 tq 

SJW = (min(Phase_Seg1, 4) tq = 2 tq


TSEG1 = (Prop_Seg + Phase_Seg1 - 1) = 6 

TSEG2 = (Phase_Seg2 - 1) = 2 

SJW_p = (SJW - 1) = 1


Bit Timing Register = BRP + SJW_p*0x0040 = TSEG1*0x0100 + TSEG2*0x1000 = 2640


Clock tolerance df :


A: df < min(Phase_Seg1, Phase_Seg2) / (2 * (13*bit_time - Phase_Seg2)) 

B: df < SJW / (20 * bit_time)


A: df < 2/(2*(13*11-3)) = 1/(141-3) = 1/138 = 0.7246% 

B: df < 2/(20*11) = 1/110 = 0.9091%


Actual clock tolerance is 0.7246% - 0.5381% = 0.1865% (no problem for quartz)


    SFRPAGE = CAN0_PAGE;

    CAN0CN=0X41;

    CAN0ADR=BITREG;

    CAN0DAT=0x2640;//调波特率


6.发送函数


void transmit (char MsgNum) 

{   uchar num;

    SFRPAGE = CAN0_PAGE;

    CAN0ADR = IF1CMDMSK;          

    CAN0DAT = 0x0087;             

    /*   IF1 Command Mask Registers  =0x0087

    WR/RD=1,Mask=0,Arb=0,Control=0,ClrIntPnd=0,TxRqst=1,DataA=1,DataB=1,一次发送8字节数据*/

    CAN0ADR = IF1DATA1;           

    /*将8字节数据写入IF1*/

    for(num=0;num<4;num++)

    {

        CAN0DATH=sdata[2*num+1];

        CAN0DATL=sdata[2*num];

    }

    CAN0ADR = IF1CMDRQST;         

    CAN0DATL = MsgNum; //将以上配置写入MsgNum号CAN消息

}


7.接收函数


void receive_data (uchar MsgNum)

{

    uchar i;

    SFRPAGE = CAN0_PAGE;

    CAN0ADR = IF2CMDMSK;        

    CAN0DATL = 0x0f;          

    /*   IF1 Command Mask Registers  =0xxx0f

    WR/RD=0,Mask=0,Arb=0,Control=0,ClrIntPnd=1,NewDat=1,DataA=1,DataB=1,一次发送8字节数据*/

    CAN0ADR = IF2CMDRQST;       

    CAN0DATL = MsgNum; //指向MsgNum号消息           

    CAN0ADR = IF2DATA1;          

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

        rdata[i].tempval=CAN0DAT;//接收数据

    isnewdata=1;

 }

  最后现象:单片机发送成功,PC端能成功接收发送的数据。而单片机接收CAN总线数据时异常。TJA1050芯片的RXD引脚能检测到电压变化,而单片机Status Register寄存器中RxOk位为‘1’,但没有产生接收中断,接收消息对象中的数据也未改变。 
这里写图片描述 
  其中0x02为发送消息对象,0x04为接收消息对象。 
这里写图片描述 
  CAN0STA为Status Register寄存器中低8位。RxOk为‘1’。 
  将单片机设置为测试模式,CAN Control Register寄存器中Test位置1。使用回路静音模式时,将CAN Test Register寄存器LBack和Silent同时置1,使TX与RX自身形成回路,单片机自发自收。结果为单片机接收不到自己发送的数据。 

这里写图片描述 


  使用测试模式中的基本模式时,将CAN Test Register寄存器Basic位置1。此模式下,控制器不使用消息内存,即控制器不使用32个消息对象,而是将IF1寄存器作为发送缓存区,将IF2寄存器作为接收缓存区。此模式下,单片机发送数据正常,接收数据时,IF2寄存器缓存区接收到的数据不正确。 


推荐阅读

史海拾趣

ACT [Advanced Crystal Technology]公司的发展小趣事

ACT(Advanced Crystal Technology)公司是一家专注于晶体技术的企业。以下是该公司发展的五个相关故事:

  1. 公司成立与起步阶段: ACT公司成立于1984年,总部位于美国加利福尼亚州。创始人致力于研究和开发高性能的晶体材料和晶振产品。公司最初是一家小型的研究型企业,致力于满足军事和航空航天领域对高精度晶振的需求。

  2. 技术创新和产品拓展: 随着市场需求的增长和技术进步,ACT公司不断进行技术创新,并扩展了产品线。公司推出了一系列高精度、高稳定性的晶振产品,覆盖了频率范围广泛的应用,包括通信、医疗、工业控制等领域。

  3. 市场拓展和国际化发展: ACT公司积极开拓国内外市场,并与全球各地的客户建立了合作关系。公司的产品不仅畅销于美国本土市场,还远销至欧洲、亚洲等国家和地区。通过与国际合作伙伴的合作,ACT逐步实现了国际化发展战略。

  4. 质量控制和技术支持: ACT公司注重产品质量和技术支持,建立了严格的质量控制体系和售后服务体系。公司拥有一支专业的研发团队和技术支持团队,为客户提供定制化的解决方案和技术支持,确保产品的稳定性和可靠性。

  5. 未来发展展望: ACT公司将继续致力于晶体技术领域的研发和生产,不断推出更先进、更高性能的晶振产品,以满足客户在不断变化的市场需求。公司将加强与客户的合作,深化技术创新,提升产品品质和服务水平,努力成为行业内的领先企业。

Chengdu Sino Microelectronics Technology Co Ltd公司的发展小趣事

随着国内市场的逐渐饱和,成都华微科技开始将目光投向国际市场。公司凭借过硬的产品质量和完善的服务体系,逐渐在国际市场上崭露头角。通过与国外客户的深入合作,华微科技不仅提升了自身的国际影响力,也为中国集成电路设计行业在国际市场上赢得了更多的话语权。

振华(CEC)公司的发展小趣事

随着企业规模的不断扩大和市场竞争的加剧,振华意识到单纯的自我发展已经难以满足企业的长远发展需求。因此,公司开始积极探索并购与资源整合的道路。通过并购具有技术优势和市场潜力的企业,振华不仅获得了更多的技术资源和市场份额,还实现了产业链的延伸和拓展。同时,公司还注重内部资源的整合和优化,提高资源的利用效率和管理水平。

Highland Electronics Co Ltd公司的发展小趣事

High Tech Chips Inc深知人才是企业发展的核心竞争力。因此,公司一直将人才战略放在企业发展的重要位置。公司不仅吸引了大量来自国内外顶尖高校的优秀人才加盟,还建立了完善的人才培养体系和激励机制。通过举办技术交流会、设立创新基金等方式激发员工的创新潜能和工作热情。这些举措为公司的发展奠定了坚实的人才基础和技术储备。

Allied Controls Incorporated公司的发展小趣事

High Tech Chips Inc成立之初,便专注于研发高性能的AI芯片。在公司创始人李博士的带领下,团队突破了传统芯片设计的瓶颈,开发出了一款具有超低功耗和高效能比的AI加速器芯片。这款芯片迅速获得了市场的认可,被广泛应用于智能手机、智能家居和自动驾驶等领域。随着技术的不断迭代和产品的持续优化,High Tech Chips Inc逐渐在AI芯片市场占据了一席之地,并成为了行业内的技术领先者。

Big-Sun Electronics Co Ltd公司的发展小趣事

随着国内市场的逐步饱和,Big-Sun Electronics Co Ltd公司开始将目光投向国际市场。公司积极参与国际电子展会,与海外客户建立起了良好的合作关系。同时,Big-Sun还与国际知名电子企业开展技术合作,共同研发新产品,进一步提升了公司的国际竞争力。

问答坊 | AI 解惑

求高手帮我分析一下这个电路

请教一下这个电路的U4A是什么类型的电路呢,怎么分析它呢,VSR/VAR是用电阻分压得到的一个稳定电压,在这起什么作用呢,还有他的输出为什么要接一个R24与C3的RC滤波呢,再接到比较器呢? 还有就是U4C是由单片机控制的上半周锯齿波发生器,这个我明 ...…

查看全部问答>

单片机外围器件

本帖最后由 paulhyde 于 2014-9-15 09:36 编辑 单片机外围器件  …

查看全部问答>

我最近想实现s3c2440的USB device,哪位高手有经验,帮帮忙!

我最近想实现s3c2440的USB device,不知道有没有高手实现过,给点帮助,谢谢了,不是在Linux下,不带操作系统的。…

查看全部问答>

汽车电子硬件

学硬件从事汽车电子方面的工作如何,各位给点意见?…

查看全部问答>

我的笔记本Bios密码忘了,哪位大侠帮帮忙??

Bios密码跟登陆密码不是一个,也就是说现在还是能正常使用。但还是挺闹心的,大家帮帮忙想想办法啊! 拿到厂里去的方法就不要说了,这个我也知道,我希望是一个我自己能解决的办法!先谢谢大家了! 我是新手,分不多,大家体谅啊!!…

查看全部问答>

关于NLED Driver

在ce6.0 nleddrvr.dll是如何生成的呢?在$CEROOT\\PUBLIC\\COMMON\\OAK\\DRIVERS\\NLEDDRVR目录生成的是nleddrvr_lib.lib。 SYSGEN_NLED = 1,SOURCE文件中 WINCETARGETFILES=dummy 就生成了?过程是怎样的呢?…

查看全部问答>

如何高效运用嵌入式ARM程序开发?

在多媒体、通信等计算复杂度高的应用中,为了满足制造费用、功耗、性能以及实时性等诸多**条件的要求,嵌入式系统程序往往需要特殊设计。这使得设计师在设计面向特定应用的嵌入式软件时,需要有一套切实可行的编程准则。而在实际程序设计中,工程师 ...…

查看全部问答>

本版主最近请到一位高人,在ST10方面有很深造诣,在此帮助

请各路英雄留下你们的问题,高人会经常过来巡视并解答问题。特此公告,敬请互相转告。谢谢!…

查看全部问答>

DMA用于通信,如何判断前次操作完成

我想用DAM做USRAT1 发送,在发送下一个数据包之前,首先应该判断上一个数据包是否发送完毕。或者一个DMA通道分时复用IIC和USART通信,需要对上次的传输是否完成进行判断。使用了下面的判断语句:while (DMA_GetFlagStatus(DMA1_FLAG ...…

查看全部问答>

quartus 11.0版本的sdram地址宽度

地址宽度21位,是20-0?显示是21-0这个地方有没有问题,以前版本是地址宽度22,才是21~0。 [ 本帖最后由 tianma123 于 2012-4-27 11:20 编辑 ]…

查看全部问答>