⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 can.txt

📁 can总线接收和发送的c语言程序,是简单的can通讯程序
💻 TXT
字号:
一,引言 
CAN具有十分优越的特点,使人们乐于选择,这些特性包括: 
低成本,极高的总线利用率,很远的数据传输距离(10Km),高速的数据传输效率
(1Mbit/s),可根据报文的ID决定接收或屏蔽该报文,可靠的错误处理和检错机制,发送的
信息遭到破坏以后,可自动重发,节点在错误严重的情况下具有自动退出总线的功能,报文
不含源地址和目标地址,仅用标识符来指示功能信息和优先级信息. 
单片机与CAN总线连接的传统方式是将CPU与CAN总线控制器和总线收发器相连后再接
入总线网络,这样使CPU外围电路复杂化,整个系统受外部影响较大.为了解决这一问题,
很多单片机厂商纷纷将CAN控制器集成在单片机芯片上.目前,单片机内部集成的CAN控制
器有Motorola公司的MC68HC912DG128A,Philips公司的P87C591,Atmel公司的AT89C51CC01
和AT89C51CC02,Intel公司的TN87C196CA和TN87C196CB以及Silicon Laboratories公司
的C8051F040等.这里以C8051F040为例详细介绍其内部CAN控制器的使用方法及其在分布
式电源系统中的应用. 
二,C8051F040 CAN控制器构成 
C8051F040内部集成的CAN控制器是Bosch全功能 CAN模块的完全实现,完全符合CAN
规范2.0B.此CAN控制器由以下几部分构成:CAN内核,报文RAM(与C8051 RAM相互独立),
报文处理状态机制和CAN控制寄存器.其原理框图如图1所示. 

消息处理器
控制器核
TX
CANTX
C8051F040
MCU
CIP-51
SYSCLK
中断
CAN控制器
消息RAM
CAN
CANRX
RX
(fsys)
BRP预分频器
R
F
S
CAN_CLK
图1:CAN控制器原理框图 
CIP-51可以通过特殊功能寄存器直接或间接访问CAN控制器中的CAN控制寄存器
(CAN0CN),CAN测试寄存器(CAN0TST)和CAN状态寄存器(CAN0STA),所有其它的寄存
器只能通过CAN0ADR,CAN0DATH和CAN0DATL寄存器以地址索引的方式间接访问. 
三,CAN控制器应用时寄存器配置 
(一),报文对象初始化处理 
在控制器复位后,CPU对Init清0以前,需要将各个不使用的消息对象MsgVal清0,再
对程序中使用的消息对象初始化.这些操作均在Init清0以前完成. 
报文对象的配置是通过相应的接口寄存器来设置其屏蔽码,仲裁场,控制场和数据场值,
而这一设置过程由相应的IFX命令请求寄存器来完成. 
当CAN控制寄存器中的Init位清零,CAN内核中的CAN协议控制器状态机制和报文处理
状态机制将控制C_CAN的内部数据流.接收到的报文通过接收滤波后都存放在报文RAM中. 
(二),发送对象的配置 
当报文对象作为发送对象时,仲裁寄存器(ID28-0和Xtd位)将被应用,它们定义了即
将发送的报文识别符和类型,如果使用11位识别符(标准帧),那么使用的是ID28~ID18,
而ID17~ID0将被忽视.如果TxIE位被置位,则IntPnd位在此报文对象被成功发送后被置
位;如果RmtEn位被置位,在接收到匹配的远程帧将引起TxRqst位被置位,也就是说该消息
对象能够响应其它节点的远程桢请求. 
四,CAN控制器的应用 
CAN总线一般用在工业检测和控制现场,它将各功能模块连接在一起组成一个现场级通
信网络.在本应用中,CAN总线完成双机热备的通讯控制器和下位各个电源模块之间的通讯.
上位机和下位机均以C8051F040为核心. 
(一),CAN控制器外围硬件电路实现 
由于Silicon Laboratories内部的CAN控制器只是个协议控制器,不能提供物理层驱动,
所以在使用时还需外加CAN总线收发器,本应用中使用的是TJA1050.TJA1050有两种工作模
式:高速模式和静音模式.TJA1050是PCA82C250的后续产品.TJA1050在以下方面做了重要
改进: 
CANH和CANL理想配合,使电磁辐射减到最低,在有不上电节点时,性能有所改进. 
为了进一步提高系统的抗干扰能力,在CAN控制器引脚CANTX,CANRX和收发器TJA1050
之间并不是直接相连,而是通过由高速光耦6N137构成的隔离电路后再与TJA1050相连,这
样就可以很好的实现总线上各节点的电气隔离.这部分增加了节点的复杂性,但它却提高了
节点的稳定性和安全性.此通信物理层电路图如图2所示. 
图2:CAN收发器部分原理图 
(二),CAN通信的软件实现 
本系统要实现的主要任务是:双机热备的通讯控制器将采集到的给定信号(电压信号)
进行A/D转换以后,判断有几个电源模块在正常工作,然后通过CAN总线,发送到各个电源
模块,同时接收各个电源模块的系统状态以及实际输出电流大小. 
由上可知,CAN通信主要包括系统初始化程序,发送程序,接收程序等.在本例中,系
统软件采用结构化程序设计方案,使其具有较好的模块化和可移植性,对于不同的系统功能
或不同的应用环境,可以方便地进行编程重组. 
1.系统初始化 
初始化程序主要完成对所有的报文对象初始化(一般将所有值清零),对CAN控制寄存
器(CAN0CN),位定时寄存器(BITREG)进行设置,还要对发送报文对象和接收报文对象分
别初始化.本系统中,使用的晶振频率为16M,位定时器的设置为500Kbps. 
下面为CAN初始化程序: 
void can_ini(void) 
{ 
EA=0; 
clear_msg_objects(); 
EIE2 |= 0x20; 
SFRPAGE = CAN0_PAGE; //指向CAN0页面 
CAN0CN=0X41; //将CCE和Init置"1"开始初始化 
CAN0ADR=BITREG; 
CAN0DAT= Can0_BITREG_Rate_500k; //调波特率500K 
CAN0CN|=0x0a; 
CAN0CN &=~0x41; //清除CCE和INIT位,启动CAN状态机制 
EA = 1; 
} 
2.发送程序 
CAN报文发送是由CAN控制器自动完成的,不需要用户软件干预,这样就极大的减少了
软件开销.用户只需根据接收到的远程帧的识别符,将对应的数据转移到发送缓冲寄存器,
然后将此报文对象的编码写入命令请求寄存器启动发送即可,而发送由硬件来完成.其发送
程序结构如下: 
void transmit (char MsgNum,char *p) 
{ 
SFRPAGE = CAN0_PAGE; 
CAN0ADR = IF1CMDMSK; 
CAN0DAT = 0x0087; 
CAN0ADR=IF1DATA1; 
CAN0DATL=*(p++); 
CAN0ADR=IF1DATA1; 
CAN0DATH=*(p++); 
CAN0ADR=IF1DATA2; 
CAN0DATL=*(p++); 
CAN0ADR=IF1DATA2; 
CAN0DATH=*(p++); 
CAN0ADR=IF1DATB1; 
CAN0DATL=*(p++); 
CAN0ADR=IF1DATB1; 
CAN0DATH=*(p++); 
CAN0ADR=IF1DATB2; 
CAN0DATL=*(p++); 
CAN0ADR=IF1DATB2; 
CAN0DATH=*(p++); 
CAN0ADR = IF1CMDRQST; 
CAN0DATL = MsgNum; 
} 
3.接收程序 
CAN报文的接收与发送一样,是由CAN控制器自动完成的,接收程序只需从接收缓存器
中读取接收的数据.为增强系统的实时性,接收程序采用中断方式.接收程序结构如下: 
void receive_data (unsigned char MsgNum,char *p) 
{ 
SFRPAGE = CAN0_PAGE; 
CAN0ADR = IF2CMDMSK; 
CAN0DATL = 0x0f; 
CAN0ADR = IF2CMDRQST; 
CAN0DATL = MsgNum; 
CAN0ADR=IF2DATA1; 
*(p++)=CAN0DATL; 
CAN0ADR=IF2DATA1; 
*(p++)=CAN0DATH; 
CAN0ADR=IF2DATA2; 
*(p++)=CAN0DATL; 
CAN0ADR=IF2DATA2; 
*(p++)=CAN0DATH; 
CAN0ADR=IF2DATB1; 
*(p++)=CAN0DATL; 
CAN0ADR=IF2DATB1; 
*(p++)=CAN0DATH; 
CAN0ADR=IF2DATB2; 
*(p++)=CAN0DATL; 
CAN0ADR=IF2DATB2; 
*(p++)=CAN0DATH; 
} 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -