当前位置:首页 > 单片机 > 单片机
[导读]一、背景:使用LPC1769来做CAN的收发,在此对使用LPC1769的CAN控制器进行收发做个总结和记录,以备下次开发快速上手使用。附:LPC1768/1769除了支持最高频率不同以外,其它基本上一致。二、正文:先贴一张LPC1769CAN

一、背景:使用LPC1769来做CAN的收发,在此对使用LPC1769的CAN控制器进行收发做个总结和记录,以备下次开发快速上手使用。附:LPC1768/1769除了支持最高频率不同以外,其它基本上一致。二、正文:先贴一张LPC1769CAN控制器的方框图:


  .


由上图可见,整个CAN控制器一头是CPU,另一头是CAN收发器:    CAN收发器负责CAN数据与CAN网络的通信。CAN内核模块解析和封装要发送到CAN收发器以及从CAN  收发器发过来的数据,此处CAN内核工作由硬件自行完成。    CPU通过APB总线即可设置CAN控制器状态,以及读取中断信息和中断状态。    一共有3个发送缓冲器(邮箱),这样就可以保证,最少可以发送3组并发的CAN数据;2个接收缓冲  器(邮箱),这样就可以在CPU处理1个邮箱的接收数据的同时,还能用另一个邮箱接收网络上的数据。    LPC1769CAN的验收滤波器比较特殊,它是一个独立于CAN控制器的器件,也属于一种外设,不过  比较特殊的是,它是服务于CAN控制器的外设,这么做的意义就在于,验收滤波这方面,不再需要软件来  来做任何事情,直接由硬件来实现查表算法,节省宝贵的CPU资源,由于它也算是一个独立的外设,运用  起来也比较复杂,而本篇篇幅有限,暂不详述,下次再另开篇博客来说。    至此,LPC1769CAN的结构就介绍完毕,接下说明,做哪些事情可让其开始正确收发CAN数据。
CAN1/2使用以下寄存器进行设置:a)电源使能:在PCONP寄存器中,设置PCAN1/2。注:复位时,CAN1/2会被使能(PCAN1/2=0)。b)时钟使能:在PCLK_SEL0寄存器中选择PCLK_CAN1/2和验收滤波器的PCLK_ACF。注:如果所需使用的CAN波特率必须高于100kbit/s(参见表16.12),那么就不能选择IRC    作为时钟源。c)唤醒:CAN控制器能够将微控制器从掉电模式唤醒。d)引脚:通过PINSEL寄存器选择CAN1/2引脚,并通过PINMODE寄存器选择引脚模式。e)中断:CAN中断是通过CAN1/2IER寄存器来使能的。中断的使能是通过在NIVC中使用相应的中断设置使能寄存器(InterruptSetEnableregister)来实现的。f)CAN控制器初始化:在CANNOD寄存器中设置。以上为数据手册介绍的CAN控制器初始化过程,白话点说:"a)"CAN是LPC1769的外设器件,要让其工作,首先要设置PCONP,该寄存器的各个位来决定外设的时钟是否打开或关闭,若某个外设不被使用,则关闭它,以达到节省功耗的目的;此处要需       要使用CAN,所以先打开CAN的外设时钟。"b)"其次,外设若要正常工作,则均需要一个合适的时钟频率,通PCLK_SEL0l来决定CAN的外设时钟来源,以及大小。"c)"为了进一步减少MCU的功耗,当CAN网络上没有数据传输时,也没有CAN中断在处理,并且对应       的睡眠位被置“1”,CAN外设会进入睡眠状态,若CAN总线上出现了显性位,则CAN外设从睡眠       状态被唤醒。同时,若已配置了相关位,且此时整个MCU都进入掉电或者深度睡眠模式,则CAN       也可将MCU唤醒"d)"配置CAN的收发引脚,无需多言,告诉CAN控制器,从哪个引脚收发CAN数据。"e)"配置CAN的各种中断使能条件,此处使能了发送/接收中断,错误中断;以及配置NVIC内CAN外设中断。"f)"配置CAN相关的参数,譬如波特率等等。至此,CAN控制器初始化部分完成,还需要做接收和发送函数,以及中断函数,来实现CAN的收发,和错误管理。当然,在CAN控制器初始化部分,波特率的参数设置还有许多要说,本篇篇幅有限,暂不详述,下次再开篇博客进行介绍。CAN中断函数:/*-----------------INTERRUPTSERVICEROUTINES--------------------------*//*********************************************************************//***@briefCAN_IRQHandler,controlreceivemessageoperation*param[in]none*@returnnone**********************************************************************/voidCAN_IRQHandler(){uint8_tIntStatus;uint32_tdata1;/*getinterruptstatus*Notethat:InterruptregisterCANICRwillberesetafterread.*Sofunction"CAN_IntGetStatus"shouldbecallonlyonetime*///以下函数获取的是CAN1ICR/CAN2ICR的寄存器数据,该寄存器指明了中断来源IntStatus=CAN_IntGetStatus(LPC_CAN1);if((IntStatus>>0)&0x01){//接收中断}...//省略的内容为,根据寄存器的各位的中断来源数据来解析中断信息。       //IntStatus=CAN_IntGetStatus(LPC_CAN2);      //if(...)...}CAN接收函数:此函数为NXP提供的库函数,库函数下载链接在本文第三部分,该函数做的内容无非就是,在中断内,检查两个接收邮箱内是否有信息,若有,则将信息提取。/********************************************************************//***@briefReceivemessagedata*@param[in]CANxpointertoLPC_CAN_TypeDef,shouldbe:*-LPC_CAN1:CAN1peripheral*-LPC_CAN2:CAN2peripheral*@param[in]CAN_MsgpointtotheCAN_MSG_TypeStruct,itwillcontainreceived*messageinformationsuchas:ID,DLC,RTR,IDFormat*@returnStatus:*-SUCCESS:receivemessagesuccessfully*-ERROR:receivemessageunsuccessfully*********************************************************************/StatusCAN_ReceiveMsg(LPC_CAN_TypeDef*CANx,CAN_MSG_Type*CAN_Msg){uint32_tdata;CHECK_PARAM(PARAM_CANx(CANx));//checkstatusofReceiveBufferif((CANx->SR&0x00000001)){/*Receivemessageisavailable*//*Readframeinformations*/CAN_Msg->format=(uint8_t)(((CANx->RFS)&0x80000000)>>31);CAN_Msg->type=(uint8_t)(((CANx->RFS)&0x40000000)>>30);CAN_Msg->len=(uint8_t)(((CANx->RFS)&0x000F0000)>>16);/*ReadCANmessageidentifier*/CAN_Msg->id=CANx->RID;/*ReadthedataifreceivedmessagewasDATAFRAME*/if(CAN_Msg->type==DATA_FRAME){/*Readfirst4databytes*/data=CANx->RDA;*((uint8_t*)&CAN_Msg->dataA[0])=data&0x000000FF;*((uint8_t*)&CAN_Msg->dataA[1])=(data&0x0000FF00)>>8;;*((uint8_t*)&CAN_Msg->dataA[2])=(data&0x00FF0000)>>16;*((uint8_t*)&CAN_Msg->dataA[3])=(data&0xFF000000)>>24;/*Readsecond4databytes*/data=CANx->RDB;*((uint8_t*)&CAN_Msg->dataB[0])=data&0x000000FF;*((uint8_t*)&CAN_Msg->dataB[1])=(data&0x0000FF00)>>8;*((uint8_t*)&CAN_Msg->dataB[2])=(data&0x00FF0000)>>16;*((uint8_t*)&CAN_Msg->dataB[3])=(data&0xFF000000)>>24;/*releasereceivebuffer*/CANx->CMR=0x04;}else{/*ReceivedFrameisaRemoteFrame,nothavedata,wejustreceive*messageinformationonly*/CANx->CMR=0x04;/*releasereceivebuffer*/returnSUCCESS;}}else{//noreceivemessageavailablereturnERROR;}returnSUCCESS;}CAN发送函数:该函数还是库函数,即依次查询3个发送邮箱的状态,若邮箱状态为空,则将数据填充到该邮箱并置位发送标志,然后由CAN内核模块硬件自动发送。发送的优先级在寄存器内均可配置,不详述。篇幅不想过长,因此查询邮箱2/3代码部分省略。/********************************************************************//***@briefSendmessagedata*@param[in]CANxpointertoLPC_CAN_TypeDef,shouldbe:*-LPC_CAN1:CAN1peripheral*-LPC_CAN2:CAN2peripheral*@param[in]CAN_MsgpointtotheCAN_MSG_TypeStructure,itcontainsmessage*informationsuchas:ID,DLC,RTR,IDFormat*@returnStatus:*-SUCCESS:sendmessagesuccessfully*-ERROR:sendmessageunsuccessfully*********************************************************************/StatusCAN_SendMsg(LPC_CAN_TypeDef*CANx,CAN_MSG_Type*CAN_Msg){uint32_tdata;CHECK_PARAM(PARAM_CANx(CANx));CHECK_PARAM(PARAM_ID_FORMAT(CAN_Msg->format));if(CAN_Msg->format==STD_ID_FORMAT){CHECK_PARAM(PARAM_ID_11(CAN_Msg->id));}else{CHECK_PARAM(PARAM_ID_29(CAN_Msg->id));}CHECK_PARAM(PARAM_DLC(CAN_Msg->len));CHECK_PARAM(PARAM_FRAME_TYPE(CAN_Msg->type));//CheckstatusofTransmitBuffer1if(CANx->SR&(1<<2)){/*TransmitChannel1isavailable*//*WriteframeinformationsandframedataintoitsCANxTFI1,*CANxTID1,CANxTDA1,CANxTDB1register*/CANx->TFI1&=~0x000F0000;CANx->TFI1|=(CAN_Msg->len)<<16;if(CAN_Msg->type==REMOTE_FRAME){CANx->TFI1|=(1<<30);//setbitRTR}else{CANx->TFI1&=~(1<<30);}if(CAN_Msg->format==EXT_ID_FORMAT){CANx->TFI1|=(0x80000000);//setbitFF}else{CANx->TFI1&=~(0x80000000);}/*WriteCANID*/CANx->TID1=CAN_Msg->id;/*Writefirst4databytes*/data=(CAN_Msg->dataA[0])|(((CAN_Msg->dataA[1]))<<8)|          ((CAN_Msg->dataA[2])<<16)|((CAN_Msg->dataA[3])<<24);CANx->TDA1=data;/*Writesecond4databytes*/data=(CAN_Msg->dataB[0])|(((CAN_Msg->dataB[1]))<<8)|          ((CAN_Msg->dataB[2])<<16)|((CAN_Msg->dataB[3])<<24);CANx->TDB1=data;/*Writetransmissionrequest*///注意该值,置位发送邮箱1,告知硬件,邮箱1的信息已经填充完毕可发送。CANx->CMR=0x21;returnSUCCESS;}//checkstatusofTransmitBuffer2elseif(CANx->SR&(1<<10)){/*TransmitChannel2isavailable*//*WriteframeinformationsandframedataintoitsCANxTFI2,*CANxTID2,CANxTDA2,CANxTDB2register*/.../*Writetransmissionrequest*///注意该值,置位发送邮箱2,告知硬件,邮箱2的信息已经填充完毕可发送。CANx->CMR=0x41;returnSUCCESS;}//checkstatusofTransmitBuffer3elseif(CANx->SR&(1<<18)){/*TransmitChannel3isavailable*//*WriteframeinformationsandframedataintoitsCANxTFI3,*CANxTID3,CANxTDA3,CANxTDB3register*/.../*Writetransmissionrequest*///注意该值,置位发送邮箱3,告知硬件,邮箱3的信息已经填充完毕可发送。CANx->CMR=0x81;returnSUCCESS;}else{//所有邮箱都处于非空闲状态,无法发送returnERROR;}}至此,有了初始化部分,CAN中断函数,CAN发送、接收函数,也就实现了CAN数据的收发。滤波以波特率以及CAN总线错误处理,下次再开博客详述。三、参考文档LPC175x_6xCMSIS-CompliantStandardPeripheralFirmwareDriverLibrary(Keil,IAR,GNU)  https://www.lpcware.com/content/nxpfile/lpc175x6x-cmsis-compliant-standard-peripheral-firmware-driver-library-keil-iar-gnu至此,记录完毕。

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

9月2日消息,不造车的华为或将催生出更大的独角兽公司,随着阿维塔和赛力斯的入局,华为引望愈发显得引人瞩目。

关键字: 阿维塔 塞力斯 华为

加利福尼亚州圣克拉拉县2024年8月30日 /美通社/ -- 数字化转型技术解决方案公司Trianz今天宣布,该公司与Amazon Web Services (AWS)签订了...

关键字: AWS AN BSP 数字化

伦敦2024年8月29日 /美通社/ -- 英国汽车技术公司SODA.Auto推出其旗舰产品SODA V,这是全球首款涵盖汽车工程师从创意到认证的所有需求的工具,可用于创建软件定义汽车。 SODA V工具的开发耗时1.5...

关键字: 汽车 人工智能 智能驱动 BSP

北京2024年8月28日 /美通社/ -- 越来越多用户希望企业业务能7×24不间断运行,同时企业却面临越来越多业务中断的风险,如企业系统复杂性的增加,频繁的功能更新和发布等。如何确保业务连续性,提升韧性,成...

关键字: 亚马逊 解密 控制平面 BSP

8月30日消息,据媒体报道,腾讯和网易近期正在缩减他们对日本游戏市场的投资。

关键字: 腾讯 编码器 CPU

8月28日消息,今天上午,2024中国国际大数据产业博览会开幕式在贵阳举行,华为董事、质量流程IT总裁陶景文发表了演讲。

关键字: 华为 12nm EDA 半导体

8月28日消息,在2024中国国际大数据产业博览会上,华为常务董事、华为云CEO张平安发表演讲称,数字世界的话语权最终是由生态的繁荣决定的。

关键字: 华为 12nm 手机 卫星通信

要点: 有效应对环境变化,经营业绩稳中有升 落实提质增效举措,毛利润率延续升势 战略布局成效显著,战新业务引领增长 以科技创新为引领,提升企业核心竞争力 坚持高质量发展策略,塑强核心竞争优势...

关键字: 通信 BSP 电信运营商 数字经济

北京2024年8月27日 /美通社/ -- 8月21日,由中央广播电视总台与中国电影电视技术学会联合牵头组建的NVI技术创新联盟在BIRTV2024超高清全产业链发展研讨会上宣布正式成立。 活动现场 NVI技术创新联...

关键字: VI 传输协议 音频 BSP

北京2024年8月27日 /美通社/ -- 在8月23日举办的2024年长三角生态绿色一体化发展示范区联合招商会上,软通动力信息技术(集团)股份有限公司(以下简称"软通动力")与长三角投资(上海)有限...

关键字: BSP 信息技术
关闭
关闭