CAN是控制器局域网络(Controller Area Network, CAN)的简称,是国际上应用最广泛的现场总线之一。 在北美和西欧,CAN总线协议已经成为汽车计算机控制系统和嵌入式工业控制局域网的标准总线,并且拥有以CAN为底层协议专为大型货车和重工机械车辆设计的J1939协议。
本例通过用MC9S12XS128MAA来实现CAN标准帧的接收。
以下为本例所用到的寄存器介绍(CAN初始化部分用到的寄存器此篇不再赘述,见“利用CAN进行简单的数据发送”)
CANRFLG寄存器
WUPIF (唤醒中断标志)= 1 时,MSCAN在CAN总线上检测到活动并请求唤醒
= 0 时,睡眠模式下未观察到唤醒活动
CSCIF(CAN状态改变中断标志) = 1 时, MSCAN更改了当前CAN总线状态
= 0 时,CAN总线状态未发生变化
RSTAT[1:0] (接收状态位)= 00 时,RxOK :0 ≤ 接收错误计数器 ≤ 96
= 01 时,RxWRN :96 < 接收错误计数器 ≤ 127
= 10 时,RxERR :127 < 接收错误计数器 ≤ 255
= 11 时,Bus-off : 传输错误计数器 > 255
TSTAT[1:0] (发送状态位) = 00 时,TxOK :0 ≤ 发送错误计数器 ≤ 96
= 01 时,TxWRN :96 < 发送错误计数器 ≤ 127
= 10 时,RxERR :127 < 发送错误计数器 ≤ 255
= 11 时,Bus-off : 传输错误计数器 > 255
OVRIF(溢出中断标志) = 1 时,数据溢出
= 0 时,没有溢出
RXF(接收缓冲区满标志) = 1 时,RxFG中有一条新消息
= 0 时,RxFG无可用新消息
CANRXIDR:用来存放CAN报文的ID、远程帧或数据帧状态、标准帧或扩展帧
CANRXDSR:用来存放数据长度用来存放数据(最多8个字节)
CAN0RXDLR:用来存放数据长度
以下为完整的CAN接收报文程序
#include #include "derivative.h" #define LED PORTB_PB0 //定义连接发光二级管的PORTB_PB0口数据寄存 //器为LED,写'0'亮,写'1' 灭 #define LED_dir DDRB_DDRB0 //定义连接发光二级管的PORTB_PB0口方向寄存器 //为LED_dir,写'0'做输入口,写'1'做输出口 struct can_msg //定义接收报文的结构体 { unsigned int id; //报文的ID号 Bool RTR; unsigned char data[8]; //报文的数据 unsigned char len; //数据长度 }; struct can_msg msg_get; //定义结构体变量 void INIT_PLL(void) //初始化锁相环 { CLKSEL_PLLSEL=0; //内部总线时钟来源于晶振 PLLCTL_PLLON=0; //关闭PLL SYNR=0x40 | 0x03; REFDV=0x80 | 0x01; POSTDIV=0x00; //PLL为64MHz PLLCTL_PLLON=1; //打开PLL _asm(nop); _asm(nop); //等待两个机器周期 while(CRGFLG_LOCK==0); //根据CRGFLG寄存器的LOCK位,确定PLL是否稳定 LOCK==1 稳定,==0 不稳定 CLKSEL_PLLSEL =1; //选择PLL作为时钟源 } void INIT_CAN0(void) //初始化CAN0 { if(CAN0CTL0_INITRQ==0) // 查询是否进入初始化状态 CAN0CTL0_INITRQ =1; // 进入初始化状态 while (CAN0CTL1_INITAK==0); //初始化握手标志 CAN0BTR0_SJW = 0; //设置同步 CAN0BTR0_BRP = 7; //设置波特率 CAN0BTR1 = 0x1c; //设置时段1和时段2的Tq个数 ,总线频率为250kb/s /* Bit Time = [(Prescaler value)*(1+TimeSegment1+TimeSegment2)]/fCANCLK f = 1 / Bit Time Prescaler value = 8 TimeSegment1 = 13 TimeSegment2 = 2 fcanclk = 32MHz f = 250kb/s */ CAN0IDMR0 = 0xFF; CAN0IDMR1 = 0xFF; CAN0IDMR2 = 0xFF; CAN0IDMR3 = 0xFF; CAN0IDMR4 = 0xFF; CAN0IDMR5 = 0xFF; CAN0IDMR6 = 0xFF; CAN0IDMR7 = 0xFF; // 关闭滤波器 CAN0CTL1 = 0xC0; //使能MSCAN模块,设置为一般运行模式、使用总线时钟源 CAN0CTL0 = 0x00; //返回一般模式运行 while(CAN0CTL1_INITAK); //等待回到一般运行模式 while(CAN0CTL0_SYNCH==0); //等待总线时钟同步 CAN0RIER_RXFIE = 1; //打开接收中断 } Bool MSCAN0GetMsg(struct can_msg *msg) //CAN0接收函数 { unsigned char sp2; if(!(CAN0RFLG_RXF)) // 检测接收标志 0没有新消息,1有新消息 return(FALSE); if(CAN0RXIDR1_IDE) // 检测 CAN协议报文模式 (标准帧/扩展帧) 0标准帧 1扩展帧 return(FALSE); msg->id = (unsigned int)(CAN0RXIDR0<<3) | (unsigned char)(CAN0RXIDR1>>5); //将ID通过移位放入相应的寄存器位置 if(CAN0RXIDR1&0x10) msg->RTR = TRUE; else msg->RTR = FALSE; // 读标识符 RTR0数据帧 1远程帧 msg->len = CAN0RXDLR; // 读取数据长度 for(sp2 = 0; sp2 < msg->len; sp2++) msg->data[sp2] = *((&CAN0RXDSR0)+sp2); // 读取数据 CAN0RFLG = 0x01; // 清 RXF 标志位 (缓冲器准备接收) return(TRUE); } #pragma CODE_SEG __NEAR_SEG NON_BANKED //中断接收函数 void interrupt VectorNumber_Vcan0rx CAN_receive(void) //通过中断向量VectorNumber_Vcan0rx来定义中断接收函数 { if(MSCAN0GetMsg(&msg_get)) //判断是否有合法的标准帧收到 { LED = ~LED; //接收到合法标准帧LED反相 } else //错误进入死循环 { for(;;); } } void main(void) { DisableInterrupts; //禁止打开所有中断 INIT_PLL(); //初始化PLL模块,设置busclock=32Mhz INIT_CAN0(); //初始化can0模块 LED_dir=1; //LED接口PB0设置为输出口 LED=0; //初始化LED初始状态为亮 EnableInterrupts; //允许打开所有中断 for(;;) { } } 注意:1.本例CAN初始化中 CAN0RIER_RXFIE 一定要赋值为1,打开接收中断,否则将无法接收到数据 2.中断向量可以通过查看Project -> Includes -> MC9S12XS128.h文件寻找 3.由于本单片机只有一路CAN,所以无法实现自发自收,因而选择通过CANTest进行发送,通过指示灯闪烁来判断是否收到数据 接线实物图见下方: 通过CANTest发送数据,数据内容可以通过下图粉色椭圆框起来的部分填写,点击发送就可以将所填写的信息发送出来了,此时开发板的指示灯将会由亮变暗或者由暗变亮
上一篇:stm32f103 学习笔记 —— 07 CAN通讯协议
下一篇:STM32F4 CAN2配置
推荐阅读
史海拾趣
Akustica 公司是一家微机电系统(MEMS)技术公司,于2001年成立于美国匹兹堡,后来成为博世集团(Bosch)的子公司。以下是关于 Akustica 公司发展的五个相关故事:
公司成立和早期发展: Akustica 公司成立于2001年,由匹兹堡卡内基梅隆大学的研究团队创建。该公司专注于 MEMS 技术的研发和创新,致力于开发高性能的声学传感器和系统解决方案。在成立初期,Akustica 聚焦于市场需求日益增长的消费电子和汽车应用领域,并不断推出创新产品,赢得了市场认可。
博世收购: 随着市场竞争的加剧和技术进步的不断推动,Akustica 公司于2009年被博世集团收购。作为全球领先的技术和服务供应商,博世集团的收购加速了 Akustica 的发展步伐,并为其提供了更广阔的市场和资源,以加速产品创新和业务扩展。
技术创新和产品发展: 在博世集团的支持下,Akustica 公司不断进行技术创新和产品开发,推出了一系列声学传感器产品,包括麦克风、扬声器和超声波传感器等。这些产品在消费电子、汽车、工业和医疗等领域得到了广泛应用,为用户提供了更优质的声音和声学体验。
市场拓展和全球业务: 随着技术和产品的不断进步,Akustica 公司逐渐拓展了全球业务,并与各行各业的客户建立了合作关系。公司在美国、欧洲和亚洲等地建立了销售和服务网络,以更好地满足客户的需求,并开拓新的市场机会。
持续发展和未来展望: Akustica 公司作为博世集团的一部分,继续致力于声学传感器技术和产品的创新,不断提升产品性能和功能,以满足不断变化的市场需求。未来,公司将继续加强在智能手机、智能家居、车载系统、工业自动化和医疗设备等领域的业务拓展,助力客户实现更加智能、便捷和安全的生活和工作环境。
随着技术的不断进步和市场需求的日益多样化,CSR plc意识到单一的业务领域已无法满足公司的长远发展。于是,公司开始寻求多元化的发展道路。2007年,CSR plc成功收购了Nordnav Technologies和Cambridge Positioning Systems,开始进军GPS市场。这一战略转型不仅让公司的业务范围得到了极大的拓展,也使其在GPS领域取得了显著的成就。
Able Systems公司成立于1982年,初创时期面临着资金短缺、市场竞争激烈等诸多挑战。然而,公司凭借对微型打印机技术的深刻理解和独特见解,成功开发出了具有竞争力的产品。通过不懈的努力和持续的技术创新,Able Systems逐渐在市场中站稳了脚跟,并赢得了客户的信任。
Blue Giga的创立可以追溯到芬兰埃斯波的一个科技孵化器。创始人看到了物联网和短距离无线连接技术的巨大潜力,决定成立一家公司专注于这一领域。初期,Blue Giga面临着资金紧张、市场认知度低等诸多挑战,但凭借其卓越的技术和不懈的努力,逐渐在行业中崭露头角。
在产品质量和技术水平得到认可后,ETAL开始积极拓展市场。公司制定了详细的市场营销策略,通过参加国际电子展会、与知名企业合作等方式提高品牌知名度。同时,ETAL还注重客户服务,建立了完善的售后服务体系,确保客户在使用产品过程中得到及时、专业的支持。这些举措使得ETAL的市场份额不断扩大,品牌影响力逐渐增强。
EVC---关于ShellExecuteEx调用可执行文件的问题 在EVC下调用一个可执行文件A用 ShellExecuteEx(&A); 但是如果该文件A正在执行,如何切换至可执行A,而不让他再次执行一次。 如何实现?高手指教!!… 查看全部问答∨ |
ST7FILT15BF采用内部复位电路可靠吗?怎样实现不用外部复位电路,实现ST7FILT15BF单片机复位?需要设置什么?需要进行特殊功能寄存器设置或其它吗?复位脚如何处理?… 查看全部问答∨ |
现象:使用stm32的SPI2读写铁电FM25L512,软件IAR 5.4,仿真器JTAGE。 接上仿真器,使用硬件SPI2读写正常;把仿真器去掉开机,硬件SPI2读写错误,其它程序正常。 该用软件SPI2读写,带上仿真器正常,不带仿真器也正常。 附硬件SPI2初始化 ...… 查看全部问答∨ |
有一个比较大的程序,里面有显示屏和其他功能,现在需要将原来的串口程序改掉,在单步调试的过程中,一旦程序到了传输字节的程序部分,单片机就会自动往电脑里发数据,一次2024个0x00字节,在其它板子上感觉,到了单步运行的过程中,单片机不应该这 ...… 查看全部问答∨ |
求救啊,怎么用51的32个IO口直接驱动32x16的点阵屏(不许用其他的类似锁存的芯片)! 最近想做个点阵屏,网上游荡,无意中发现一个叫“杜洋工作室”的地方,杜老师的做的mini3216点阵时钟竟然不用串锁存或者行锁存芯片,直接用stc12c5as60的32个IO口控制32x16的点阵屏,而且还有多余的引脚接时钟温度等等IC,我百思不得其解,查阅了许 ...… 查看全部问答∨ |
在前不久我发了《LCD单层菜单翻滚的实现》https://bbs.eeworld.com.cn/thread-314573-1-1.html,在此帖中实现了单层菜单的上下翻滚。此贴中实现的算法不能不说非常经典,而且此方法在我的一个手持机项目中也得 ...… 查看全部问答∨ |