最强干货!CAN总线看不懂是不可能的!
扫描二维码
随时随地手机看文章
CAN总线标准
物理层
数据链路层
帧起始
仲裁段
控制段
数据段
CRC段
ACK段
远程帧
过载帧
帧间隔
构建CAN节点
CAN协议应用层概述
CAN收发器
CAN控制器与MCU的连接方式
#define REG_BASE_ADDR 0xA000 // 寄存器基址unsigned char *SJA_CS_Point = (unsigned char *) REG_BASE_ADDR ;// 写SJA1000寄存器void WriteSJAReg(unsigned char RegAddr, unsigned char Value) {*(SJA_CS_Point + RegAddr) = Value;return;}// 读SJA1000寄存器unsigned char ReadSJAReg(unsigned char RegAddr) {return (*(SJA_CS_Point + RegAddr));}
将缓存区的数据连续写入寄存器
……for (i=0;i<len;i++){WriteSJAReg(RegAdr+i,ValueBuf[i]);}……
将连续多个寄存器连续读入缓存区
……for (i=0;i<len;i++) {ReadSJAReg(RegAdr+i,ValueBuf[i]);}……
头文件包含方案:
每个程序包含用到的头文件
每个程序包含一个公用头文件,公用头文件包含所有其他头文件
# __CONFIG_H__ // 防止头文件被重复包含# __CONFIG_H__## // 包含SJA1000寄存器定义头文件// 定义取字节运算# LOW_BYTE(x) (unsigned char)(x)# HIGH_BYTE(x) (unsigned char)((unsigned int)(x) >> 8)// 定义振荡器时钟和处理器时钟频率(用户可以根据实际情况作出调整)# OSCCLK 11059200UL// 宏定义MCU的时钟频率# CPUCLK (OSCCLK / 12)# // __CONFIG_H__
SJA1000上电后处于复位状态,必须初始化后才能工作。
(1)置位模式寄存器Bit0位进入复位模式;
(2)设置时钟分频寄存器选择时钟频率、CAN模式;
(3)设置验收滤波,设定验证码和屏蔽码;
(4)设置总线定时器寄存器0、1设定CAN波特率;
(5)设置输出模式;
(6)清零模式寄存器Bit0位退出复位模式;
模式寄存器
只检测模式:SJA1000发送CAN帧时不检查应答位;
只听模式:此模式下SJA1000不会发送错误帧,用于自动检测波特率;SJA1000以不同的波特率接收CAN帧,当收到CAN帧时,表明当前波特率与总线波特率相同。
波特率设置
CAN总线无时钟,使用异步串行传输;波特率是1秒发送的数据位;
CAN帧发送:
发送CAN帧的步骤:1.检测状态寄存器,等待发送缓冲区可用;
2.填充报文到发送缓冲区;
3.启动发送。
SJA1000具有一个12字节的缓冲区,要发送的报文可以通过寄存器16-28写入,也可通过寄存器96-108写入或读出
设置发送模式
char SetSJASendCmd(unsigned char cmd) {unsigned char ret;switch (cmd) {default:case 0:ret = SetBitMask(REG_CAN_CMR, TR_BIT); //正常发送break;case 1:ret = SetBitMask(REG_CAN_CMR, TR_BIT|AT_BIT); //单次发送break;case 2:ret = SetBitMask(REG_CAN_CMR, TR_BIT|SRR_BIT);//自收自发break;case 0xff:ret = SetBitMask(REG_CAN_CMR, AT_BIT);//终止发送break;}return ret;}
发送函数
unsigned char SJA_CAN_Filter[8] = { // 定义验收滤波器的参数,接收所有帧0x00, 0x00, 0x00, 0x00,// ACR0~ACR30xff, 0xff, 0xff, 0xff// AMR0~AMR3};unsigned char STD_SEND_BUFFER[11] = { // CAN 发送报文缓冲区0x08, // 帧信息,标准数据帧,数据长度 = 80xEA, 0x60, // 帧ID = 0x7530x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa // 帧数据};void main(void) // 主函数,程序入口{timerInit();// 初始化D1 = 0;SJA1000_RST = 1; // 硬件复位SJA1000timerDelay(50); // 延时500msSJA1000_RST = 0;SJA1000_Init(0x00, 0x14, SJA_CAN_Filter); // 初始化SJA1000,设置波特率为1Mbps// 无限循环,main()函数不允许返回for(;;) {SJASendData(STD_SEND_BUFFER, 0x0);timerDelay(100); // 延时1000ms}}
为什么帧ID是0x753,这与CAN帧在缓冲区的存储格式有关。
终端电阻非常重要,当波特率较高而且没加终端电阻时,信号过冲非常严重。
SJA1000有64个字节的接收缓冲区(FIFO),这可以降低对MCU的要求。MCU可以通过查询或中断的方式确定SJA1000接收到报文后读取报文。
-END-
| 整理文章为传播相关技术,版权归原作者所有 |
| 如有侵权,请联系删除 |
【1】看了这20种运放典型电路,你还敢说你用不到吗?
【2】直观的让人发毛!巧识滤波、稳压、比较、运放电路
【3】干货!运放的电压追随电路分析
【4】怎样理解运放的轨至轨特性?这篇文章给你打开大门!
【5】运放的电压追随电路
免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!






