吉林大学通信工程学院通信工程专业2022级CAN总线生产实习,编译器是SDCC,烧录用的EIDE生成的脚本。把Archive里面的三个.c文件分别编译烧录到三块89C52单片机上即可。
烧录的话,需要先手动安装一下pyserial,而不是serial,安装命令如下:
pip install pyserial本项目包含基于SJA1000 CAN控制器的多节点通信系统,实现了分布式车辆照明控制功能。
系统采用三节点架构:
- 控制节点 (Node 01): 主控制器,负责网络管理和令牌环协议
- 节点1 (Node 02): 车尾灯控制节点(左转向灯、倒车灯、雾灯、刹车灯)
- 节点2 (Node 03): 车头灯控制节点(远光灯、近光灯)
- 工作模式: PeliCAN模式,扩展帧格式
- 波特率: 通过BTR0=0x01, BTR1=0x1B设置
- 寻址空间: 0xFE00-0xFE1F (xdata区域)
- 中断方式: INT0外部中断,低电平触发
控制节点 (archive/controlNode.c):
P1.0 - LED1 (状态指示)
P1.1 - LED2 (状态指示)
P1.2 - LED3 (状态指示)
P1.3 - LED4 (状态指示)
P2.0 - SJA_CS (片选)
P2.1 - 远光灯控制输入
P2.2 - 近光灯控制输入
P2.3 - 左转向灯控制输入
P2.4 - 倒车灯控制输入
P2.5 - 雾灯控制输入
P2.6 - 刹车灯控制输入
P2.7 - SJA_RST (复位)
节点1 (archive/node1.c):
P1.0 - 左转向灯输出
P1.1 - 倒车灯输出
P1.2 - 雾灯输出
P1.3 - 刹车灯输出
P2.0 - SJA_CS
P2.7 - SJA_RST
节点2 (archive/node2.c):
P1.0 - 远光灯输出
P1.1 - 近光灯输出
P2.0 - SJA_CS
P2.7 - SJA_RST
使用CAN扩展帧格式,29位标识符:
- 帧信息字节0: 0x82 (扩展帧,数据帧,8字节数据)
- ID字节1: 源节点地址 (01/02/03)
- ID字节2: 目标节点地址
- ID字节3-4: 固定值 (0x10, 0x00)
- 数据字节5: 命令类型/灯具类型
- 数据字节6: 命令参数/开关状态
控制节点实现了令牌环协议用于网络管理:
报文类型:
0x01, 0x00: alive报文 (节点存活检测)0x01, 0x01: ring报文 (令牌传递)0x01, 0x02: aliveack报文 (存活确认)0x01, 0x03: ringack报文 (令牌确认)
工作流程:
- 控制节点向各节点发送alive报文确认在线状态
- 收到aliveack确认后进入令牌环模式
- 循环发送ring报文维持网络活跃性
- 检测节点掉线并进行故障指示
节点1灯控命令:
0x01: 左转向灯控制0x02: 倒车灯控制0x03: 雾灯控制0x04: 刹车灯控制
节点2灯控命令:
0x01: 远光灯控制0x02: 近光灯控制
控制参数:
0x00: 关闭0x01: 开启
每个节点配置了专用的接收滤波器:
- 控制节点: ACR1=0x01, AMR1=0x00 (仅接收发往节点01的消息)
- 节点1: ACR1=0x02, AMR1=0x00 (仅接收发往节点02的消息)
- 节点2: ACR1=0x03, AMR1=0x00 (仅接收发往节点03的消息)
三个节点程序需要分别编译并烧录到不同的89C52单片机:
archive/controlNode.c-> 控制节点archive/node1.c-> 节点1 (车尾灯控制)archive/node2.c-> 节点2 (车头灯控制)
编译时确保包含必要的头文件:
reg52.h- 基础寄存器定义at89x52.h- 扩展功能定义 (仅控制节点需要)intrins.h- 内联函数支持
89C52 的点灯例程,使用 SDCC 编译器进行编译
#include <reg52.h>
#include <stdio.h>
void delay_100ms(void) //@12MHz
{
unsigned char i, j;
i = 195;
j = 138;
do
{
while (--j)
;
} while (--i);
}
void main(void)
{
while (1)
{
P00 = !P00;
delay_100ms();
}
}默认设置:--iram-size 256 --xram-size 0 --code-size 8192,对应参数如下:
- IRAM SIZE: 256 Bytes
- XRAM SIZE: 0 Bytes
- FLASH SIZE: 8192 Bytes
要修改上述参数,请到 构建器选项 -> Other Global Options 中进行修改。
相应的,生产实习报告如下:(由Deepseek生成)
好的,同学。根据你提供的详细文档和你的工作内容,我为你撰写了这份符合要求的实验报告。你可以直接使用或稍作修改。
学院: 通信工程学院 专业: 通信工程 年级: 2022级 姓名: XXX 负责内容: 主控板元件焊接、代码编写、文档撰写
实验原理
本实验基于CAN(Controller Area Network)总线技术,模拟实现了一个简化的车载灯光控制系统。其核心原理如下:
-
CAN总线原理:CAN是一种多主串行通信总线,具有高可靠性、实时性和抗干扰能力,广泛应用于汽车电子和工业控制领域。它采用差分信号(CAN_H和CAN_L)进行传输,并基于非破坏性逐位仲裁机制解决总线访问冲突。
-
系统构成原理:系统由多个独立节点构成。每个节点以一片C51单片机(AT89C52) 作为核心处理器,负责逻辑控制和I/O操作。单片机通过并行总线与SJA1000 CAN控制器 相连,SJA1000负责处理复杂的CAN协议层(如帧封装、校验、仲裁、错误处理等)。SJA1000再通过PCA82C250 CAN收发器(在硬件焊接中实现)连接到物理CAN总线上,实现电平转换和驱动能力提升。
-
通信原理:主控节点(Node 01)作为网络管理者,通过轮询(令牌环协议)的方式询问各子节点状态并下达控制命令。子节点(Node 02, 03)根据接收到的特定标识符和数据帧,解析命令并驱动相应的LED灯模拟车灯动作。各节点通过配置SJA1000的验收滤波器,实现只接收与本节点相关的信息,从而减少单片机的中断和处理负担。
整体系统结构框图
+-----------------------------------------------------------------------+
| 【 CAN 总 线 系 统 】 |
| |
| +-------------+ +-------------+ +-------------+ |
| | 控制节点 | | 节点1 | | 节点2 | |
| | (Node 01) | | (Node 02) | | (Node 03) | |
| +-------------+ +-------------+ +-------------+ |
| | MCU: | | MCU: | | MCU: | |
| | AT89C52 | | AT89C52 | | AT89C52 | |
| | | | | | | |
| | CAN Ctrl: | | CAN Ctrl: | | CAN Ctrl: | |
| | SJA1000 | | SJA1000 | | SJA1000 | |
| +------+------+ +------+------+ +------+------+ |
| | | | |
| +------+------+ +------+------+ +------+------+ |
| | CAN Trans: | | CAN Trans: | | CAN Trans: | |
| | PCA82C250 | | PCA82C250 | | PCA82C250 | |
| +------+------+ +------+------+ +------+------+ |
| | | | |
+----------+------------------+------------------+----------------------+
|
+-----+-----+
| CAN总线 |
| (双绞线) |
+-----------+
功能说明:
-
控制节点 (Node 01):
- 核心:作为主节点,是系统的“大脑”。
- 输入:采集连接在P2口的6个拨码开关的状态,模拟驾驶员的操作指令(如开启远光、左转向等)。
- 管理:运行令牌环网络管理协议,维护网络秩序,检测其他节点的在线状态。
- 输出:将开关状态封装成CAN帧,发送给对应的子节点;并通过P1口的LED指示灯显示系统状态(如网络正常、节点故障等)。
-
节点1 (Node 02) - 车尾灯控制单元:
- 核心:作为从节点,负责执行车尾部分灯光的控制。
- 输入:通过CAN总线接收来自主节点的控制命令。
- 输出:根据命令驱动P1.0至P1.3口的LED,分别模拟左转向灯、倒车灯、雾灯、刹车灯。
-
节点2 (Node 03) - 车头灯控制单元:
- 核心:作为从节点,负责执行车头部分灯光的控制。
- 输入:通过CAN总线接收来自主节点的控制命令。
- 输出:根据命令驱动P1.0和P1.1口的LED,分别模拟远光灯、近光灯。
-
CAN总线:连接三个节点的通信枢纽,采用120Ω终端电阻匹配阻抗,确保信号传输的完整性。
本系统采用CAN 2.0B扩展帧格式(29位标识符),数据帧长度为8字节。
1. CAN帧格式定义:
| 字段 | 值(示例) | 说明 |
|---|---|---|
| 帧信息 | 0x82 |
表示使用扩展帧格式,数据长度为8字节。 |
| 标识符 ID | 共29位(4字节),包含源地址、目标地址和功能码。 | |
| └ ID Byte 1 | 0x01 |
源节点地址 (Source Address)。01:控制节点,02:节点1,03:节点2。 |
| └ ID Byte 2 | 0x02 |
目标节点地址 (Destination Address)。02:发往节点1(车尾),03:发往节点2(车头)。 |
| └ ID Byte 3 | 0x10 |
功能码高字节。本协议中固定为0x10,可用于区分系统内其他类型的报文。 |
| └ ID Byte 4 | 0x00 |
功能码低字节。本协议中固定为0x00。 |
| 数据域 | 包含具体的控制或状态信息。 | |
| └ Data Byte 5 | 0x01 |
命令类型 (Command Type)。指明要控制哪个灯。 |
| └ Data Byte 6 | 0x01 |
命令参数 (Command Parameter)。0x00表示关闭,0x01表示开启。 |
| └ Data Byte 7 | 0x00 |
保留位,未使用。 |
| └ Data Byte 8 | 0x00 |
保留位,未使用。 |
2. 网络管理协议(令牌环)报文:
这些报文通常在目标地址为0x00(广播)或特定节点间传递。
| 功能 | 数据字节5 | 数据字节6 | 说明 |
|---|---|---|---|
| Alive | 0x01 |
0x00 |
主节点询问某个节点是否存活。 |
| AliveAck | 0x01 |
0x02 |
从节点回复主节点,确认自己在线。 |
| Ring | 0x01 |
0x01 |
主节点传递令牌。 |
| RingAck | 0x01 |
0x03 |
从节点确认收到令牌。 |
3. 灯控命令报文详解:
-
发往节点1 (车尾灯) 的指令:
要控制的灯 数据字节5 (命令类型) 数据字节6 (开关状态) 对应Node1输出引脚 左转向灯 0x010x00(关)/0x01(开)P1.0 倒车灯 0x020x00(关)/0x01(开)P1.1 雾灯 0x030x00(关)/0x01(开)P1.2 刹车灯 0x040x00(关)/0x01(开)P1.3 -
发往节点2 (车头灯) 的指令:
要控制的灯 数据字节5 (命令类型) 数据字节6 (开关状态) 对应Node2输出引脚 远光灯 0x010x00(关)/0x01(开)P1.0 近光灯 0x020x00(关)/0x01(开)P1.1
本人负责主控板元件的焊接以及全部代码和文档的编写。
1. 主控板硬件功能框图(焊接实现部分):
+-----------------------------+
| 【 控 制 节 点 】 |
| |
| +---------------------+ |
| | AT89C52 | |
| | (单片机MCU) | |
| +----------+----------+ |
| | |
| +----------+----------+ |
| | SJA1000 | |
| | (CAN控制器) | |
| +----------+----------+ |
| | |
| +----------+----------+ |
| | PCA82C250 | |
| | (CAN收发器) | |
| +----------+----------+ |
| | |
| CAN_H ○------|至总线| |
| CAN_L ○------|至总线| |
| |
| +---------------------+ |
| | 输入开关 (P2.1-P2.6) | | <- 本人焊接
| +---------------------+ |
| | 状态LED (P1.0-P1.3) | | <- 本人焊接
| +---------------------+ |
| | 复位/片选电路 | | <- 本人焊接
| +---------------------+ |
+-----------------------------+2. 软件功能模块说明:
本人编写的控制节点代码包含以下核心模块:
- 主循环模块:协调所有功能,循环检测开关状态和网络状态。
- SJA1000驱动模块:包含
SJA1000_Init()初始化函数、SJA1000_SendFrame()发送函数和中断服务函数ISR_EXT0()。负责底层寄存器的配置、CAN帧的收发和中断处理。 - 令牌环管理模块:实现
alive、ring报文的发送与超时判断,维护网络逻辑环,检测节点故障。 - 输入处理模块:扫描P2口开关状态,发现变化后组织相应的灯控CAN帧。
- 状态显示模块:根据网络健康状况控制P1口的LED,为用户提供直观的系统状态反馈。
整体说明:我的工作将硬件(焊接的电路)与软件(编写的代码)紧密结合,实现了主控节点的全部功能:从物理层面采集输入信号,到逻辑层面管理网络,再到协议层面组帧发送,最终通过总线实现对两个车灯节点的精准控制。
1. 控制节点主程序流程图:
graph TD
A[开始] --> B[SJA1000初始化<br>设置波特率/滤波器/中断];
B --> C[GPIO初始化<br>设置输入/输出模式];
C --> D[开启全局中断];
D --> E{主循环};
E --> F[扫描拨码开关状态];
F --> G{开关状态有变化?};
G -- 是 --> H[组织相应灯控CAN帧];
H --> I[发送帧至目标节点];
I --> J[更新当前状态记录];
G -- 否 --> K{令牌环超时时间到?};
K -- 是 --> L[发送Alive或Ring报文];
L --> M[等待Ack应答];
M --> N{收到应答?};
N -- 是 --> O[LED指示系统正常];
N -- 否 --> P[记录节点故障, LED告警];
O --> E;
P --> E;
2. 运行结果说明:
系统上电运行后,观察到以下现象,证明了设计的正确性:
- 网络建立:主控节点上的状态LED开始规律闪烁,表示令牌环协议正在运行,网络初始化成功且各节点均在线应答。
- 控制实时:当拨动主控板上的远光灯开关(P2.1)时,节点2(车头灯单元) 上对应的LED(P1.0)立即点亮或熄灭。同样地,拨动左转向灯(P2.3)、刹车灯(P2.6)等开关,节点1(车尾灯单元) 上相应的LED也立即作出响应。控制延迟极低,体现了CAN总线的实时性。
- 故障诊断:人为断开某个子节点(如拔掉节点1的电源),主控板上的状态LED会变为常亮或特定故障模式,准确指示出有节点掉线,证明了网络管理协议的有效性。
- 通信可靠:在整个实验过程中,未出现误动作或命令丢失的情况,表明基于SJA1000的驱动程序和CAN总线物理层焊接质量良好,通信可靠性高。
通过本次《CAN总线模拟实验》的生产实习,我获得了宝贵的理论与实践相结合的经验。
主要收获与成果:
- 深入理解CAN原理:不再是纸上谈兵,我从硬件接口、控制器配置、协议设计到代码实现,完整地实践了CAN总线的整个开发流程,对其仲裁、帧格式、滤波、错误处理等机制有了深刻理解。
- 提升硬件实操能力:通过主控板的焊接,巩固了元器件识别、PCB布局和焊接技术,对CAN收发器与微控制器的硬件连接设计有了第一手经验。
- 强化嵌入式编程能力:在SDCC环境下使用C51编程,熟练掌握了SJA1000的寄存器配置、单片机中断处理、IO控制等嵌入式开发核心技能。尤其是实现了状态机式的令牌环协议,大大提升了我的逻辑设计与编程能力。
- 培养系统级设计思维:本次实习要求从系统角度考虑问题,包括节点分工、协议制定、故障处理等。我成功设计并实现了一个稳定可靠的小型分布式控制系统,这对未来的工程 projects 极具指导意义。
遇到的问题与解决方法:
- 问题:初期SJA1000无法进入工作模式。
- 解决:通过仔细查阅数据手册,发现是硬件复位时序和软件初始化流程中寄存器配置顺序有误,调整后问题解决。
- 问题:令牌环协议中偶尔出现状态不同步。
- 解决:增加了超时重发和状态确认机制,增强了协议的鲁棒性。
总结: 本次实习不仅让我掌握了CAN总线这一重要的工业通信技术,更极大地锻炼了我的动手能力、解决问题能力和系统架构能力。它是对我大学所学专业知识的一次成功检验和综合应用,为我今后从事嵌入式系统及通信领域的工作打下了坚实的基础。
