1 计算机通信技术在仪器中的应用
课程实验报告
指导教师评语:
指导教师:
年
月
日 实验报告内容基本要求及参考格式
一、实验目的 二、实验所用仪器(或实验环境)
三、实验基本原理及步骤(或方案设计及理论计算)
四、实验数据记录(或仿真及软件设计)
五、实验结果分析及回答问题(或测试环境及测试结果)
2
一:研究内容
计算机通信技术在仪器中的应用,在该实验中,我们采用 stm32 单片机,研究多机间利用 232 总线、485 总线和 can 总线进行通信联系。各总线的详细功能和连接方式如下:
(1)232 总线进行双机通信 RS-232 总线是现在主流的串行通信接口之一,是个人计算机上的通讯接口之一,由电子工业协会(Electronic Industries AssociaTIon,EIA)制定的异步串行通讯总线。适合于数据传输速率在 0~20000b/s 范围内的通信。
RS-232 的接口特性 1.1 电气特性
RS-232 标准对逻辑电平的定义。对于数据(信息码):逻辑“1”的电平低于-3V,逻辑“0”的电平高于-3V;对于控制信号:接通状态有效电平高于+3V,断开状态即信号无效的电平低于-3V。所以,在实际中应保证电平在±(3~15)V间。但也因为电压偏高,易损坏接口电路芯片,与 TTL 电平不兼容。
1.2 机械特性
RS-232 标准接口有 25 条线,其中有 9 根常见的应用线,由于其他未定义物理特性,所以,存在 DB-25、DB-15、DB-9 各种类型接口,如下图:
25 针和 9 针接口端 各接口功能如下表:
9 针转接头功能
25 针转接口功能 1 DCD 数据载波检测 8 DCD 数据载波检测
3 2 RXD 接收数据 3 RXD 接收数据 3 TXD 发送数据 2 TXD 发送数据 4 DTR 数据终端准备好 20 DTR 数据终端准备好 5 GND 信号地线 7 GND 信号地线 6 DSR 数据准备好 6 DSR 数据准备好 7 RTS 请求发送 4 RTS 请求发送 8 CTS 清除发送 5 CTS 清除发送 9 DELL 响铃指示 22 DELL 响铃指示
1.3 电缆长度和传输速率
由于 RS-232 为全双工的异步通信端,其发送和接收共用的可编程波特率,最高可达 4.5Mbits/s,可编辑数据字长为 8/9 位。在通信速率低于 20kb/s 时,RS-232 所直接连接的最大物理距离为 15m。
(2)485 总线进行多机通信 RS-485 总线采用半双工工作方式,任何时候只能有一点处于发送状态,因此,发送信号时只能有一方处于发送状态。因此,发送电路须由使能信号加以控制。RS-485 用于多点互连时非常方便,可以省掉许多信号线。应用 RS-485 可以联网构成分布式系统,其允许最多并联 32 台驱动器和 32 台接收器。
RS-485 的接口特性 2.1 电气特性
RS-485 的逻辑电平特性,逻辑“1”以两线间的电压差为+(2~6)V 表示;逻辑“0”以两线间的电压差为-(2~6)V 表示。
2.2 接口物理特性
RS485 接口组成的半双工网络,一半只需要两根连线(AB 线),其接口均采用屏蔽双绞线传输。其接口和内部连接方式如下:
RS-485 以数据最高传输速率为 10Mbps,且其接口的最大传输距离约为 1219m。RS-485 接口再总线上允许连接多达 128 个收发器,即具有多站能力,可利用单一的 RS-485 方便的建起设备网络,进行多机通信。
(3)CAN 总线进行多机通信 CAN 总线是控制器局域网络的简称,是 ISO 国际化标准化的串行通信协议。由于其高性能和可靠性已被认同,广泛的应用于自动化领域,被誉为自动化领域的计算机局域网。
CAN 属于现场总线的范畴,它是一种有效支持分布式控制或实时控制的串行通信网络。较之许多 RS-485 基于 R 线构建的分布式控制系统而言,基于 CAN 总
4 线的分布式控制系统在以许多方面具有明显的优越性。
CAN 总线的控制方式如下图:
其网络各节点之间的数据通信实时性强,网络中的各节点都可根据总线访问优先权(取决于报文标识符)采用无损结构的逐位仲裁的方式竞争向总线发送数据。具有通信速率高、容易实现、且性价比高等诸多特点的一种已形成国际标准的现场总线。并且与一般的通信总线相比,CAN 总线的数据通信具有突出的可靠性、实时性和灵活性。
二:设计思路 2.1 RS-232 进行双机通信 RS-232 采用如下图所示的全双工的工作方式,允许数据在两个方向上同时传输,所以在通信时需要一个发送端和一个接收端。
STM32 开发板集成了 RS232 电平控制芯片 SP3232(原理图如图 4 所示),因此在进行实验时无需搭建外围电路,只需以 USART 协议为基础,对通信代码进行改进,即可完成通信。
5
2.2 RS-485 进行多机通信 RS-485 采用如图所示的半双工的工作方式,允许数据在两个方向上传输。但是,在某一时刻,只允许数据在一个方向上传输,它实际上是一种切换方向的单工通信;它不需要独立的接收端和发送端,两者可以合并一起使用一个端口。
开发板也集成了 RS485 电平控制芯片 SP3485(原理图如图所示),因此在进行RS485 实验时,软件层面采用与 RS232 类似的方案
2.3 CAN 总线进行多机通信 CAN 采用数据块编码的方式,数据块根据帧的类型,能够让挂载在总线上的不同节点接收到相同的数据,再根据每个节点的配置对信息进行选择性处理(处理or 丢弃)。CAN 总线是可同时连接多个单元的总线。可连接的单元总数理论上是没有限制的。但实际上可连接的单元数受总线上的时间延迟及电气负载的限制。降低通信速度,可连接的单元数增加;提高通信速度,则可连接的单元数减少。
CAN 总线的连接网络如下:
6
CAN 总线接口提供了专门的数据链路层协议,故不能再采用 USART 协议,而是利用 STM32 片内 CAN 控制模块结合电平转换芯片 TJA1050 实现数据收发
三:使用的板上资源 3.1 在利用 RS-232 进行双机通信 使用了 STM32 片内的 USART 串口模块,板上的 RS232 电平控制芯片 SP3232 以及标准接口等资源,利用 USART_SR(串口状态寄存器)、USART_DR(串口数据寄存器)USART_CR(串口控制寄存器)寄存器来进行操作。
3.1.1 状态寄存器(USART_SR) 地址偏移:0X00
复位值:0X00C0
该寄存器描述串口寄存器的一些状态,通过读取位值,判断是否收到完整的数据。
3.1.2 数据寄存器(USTAR_DR)
7 地址偏移:0x04
复位值:不确定
只使用了 0-8 位,其他位保留,分为读取该寄存器接收到的数据的读寄存器和向该寄存器写入的发送的数据,并对数据进行发送的写寄存器。
3.1.3 控制寄存器(USART_CR) 地址偏移:0x0C
复位值:0x0000
该寄存器对串口寄存器数据发送和接收进行控制,有发送使能(TE)和接收使能(RE)。
8
USART 的结构框图
3.2 在利用 RS-485 进行多机通信 利用 RS-485 也要利用如上所述的 USART 寄存器。除此之外,还用利用 STM32 上的 RS485 电平控制芯片 SP3485 等资源。
3.3 在利用 CAN 总线进行多机通信
9 使用了 STM32 片内的 CAN 总线模块,以及板上的 CAN 电平控制芯片 TJA1050。
此外我们小组还使用了按键、定时器、LCD 显示器等辅助资源。
四、 软件流程图 4.1RS232
4.2RX485
10
4.3CAN
11
五、 调试过程 经过几周的学习与实践,本小组成员已经基本掌握了本课程要求的三种通信方式的基本原理以及实践方法。调试的过程中使用了 XCOM 串口调试软件,经过测试及调试,安装好驱动后即可通过 usb 转串口进行 pc 与 stm32 之间的数据传输,可以很方便的查看数据修改 bug 以及验证实验的正确性。
12
目前已经实现了 RS232 通信、RS485 通信以及 CAN 通信的基本功能。实验结果如图所示:
RS232:
RS485
13
CAN
六、 源代码 RS232 int main(void) {
u8 txBuffer2[] = {1,2,3,4,5,6,7,8,9,0}; //要发送的数据缓存区 u8 rxBuffer3; //接收数据缓存区
14
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_DMA2D_Init();
MX_LTDC_Init();
MX_FMC_Init();
MX_USART1_UART_Init();
MX_USART2_UART_Init();
MX_USART3_UART_Init(); //重置所有外围设备,初始化闪存接口和 Systick
delay_init(97);
//初始化延时函数
SDRAM_Initialization_Sequence(&hsdram1);//发送 SDRAM 初始化序列
LCD_Init();
//初始化 LCD
POINT_COLOR = RED;
//信息显示红色
HAL_UART_Receive_IT(&huart3, &rxBuffer3, 1); //开启串口 3 接收
//显示提示信息
LCD_ShowString(30, 40, 272, 480, 24, (u8*)"RS232 test");
LCD_ShowString(30, 80, 272, 480, 24, (u8*)"COM2");
LCD_ShowString(30, 100, 272, 480, 24, (u8*)"Send:");
LCD_ShowString(30, 180, 272, 480, 24, (u8*)"COM3");
LCD_ShowString(30, 200, 272, 480, 24, (u8*)"Receice:");
while (1)
{
u8 i;
for(i = 0; i < 10; i++)
{
POINT_COLOR = RED;
HAL_UART_Transmit(&huart2, &txBuffer2[i], 1, 0xFFFF);//串口 2 发送一个数据
LCD_ShowNum(45, 130, txBuffer2[i], 1, 24); //显示发送的数据
delay_ms(500);
}
} } //串口中断回调函数 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
POINT_COLOR = RED;
LCD_ShowNum(30, 400, rxBuffer3, 3, 24);//显示接收到的数据
HAL_UART_Receive_IT(&huart3, &rxBuffer3, 1);//等待下一次接收
}
15 RS485 int main(void) {
u8 key;
u8 i=0,t=0;
u8 cnt=0;
u8 rs485buf[5];
Cache_Enable();
//打开 L1-Cache
HAL_Init();
//初始化 HAL 库
Stm32_Clock_Init(432,25,2,9);
//设置时钟,216Mhz
delay_init(216);
//延时初始化
uart_init(115200);
//串口初始化
usmart_dev.init(108);
//初始化 USMART
LED_Init();
//初始化 LED
KEY_Init();
//初始化按键
SDRAM_Init();
//初始化 SDRAM
LCD_Init();
//LCD 初始化
RS485_Init(9600);
//初始化 RS485
POINT_COLOR=RED;
LCD_ShowString(30,70,200,16,16,"RS485 test");
LCD_ShowString(30,130,200,16,16,"Press KEY0 to send"); //显示提示信息
POINT_COLOR=BLUE;//设置字体为蓝色
LCD_ShowString(30,150,200,16,16,"Count:");
//显示当前计数值
LCD_ShowString(30,170,200,16,16,"Send Data:");
//提示发送的数据
LCD_ShowString(30,210,200,16,16,"Receive Data:"); //提示接收到的数据
while(1)
{
key=KEY_Scan(0);
if(key==KEY0_PRES)//KEY0 按下,发送一次数据
{
for(i=0;i<5;i++)
// 依次发送 5 个数字
{
rs485buf[i]=cnt+i;//填充发送缓冲区
LCD_ShowxNum(30+i*32,190,rs485buf[i],3,16,0X80); //显示数据
}
RS485_Send_Data(rs485buf,5);//发送 5 个字节
}
RS485_Receive_Data(rs485buf,&key);
if(key)//如果接收到有数据
{
if(key>5)key=5;//最大是 5 个数据.
for(i=0;i<key;i++) LCD_ShowxNum(30+i*32,230,rs485buf[i],3,16,0X80); //显示数据
16
}
t++;
delay_ms(10);
if(t==20)
{
LED0_Toggle;//提示系统正在运行
t=0;
cnt++;
POINT_COLOR=BROWN;
LCD_ShowxNum(30+48,150,cnt,3,16,0X80); //显示当前计数值
}
}
}
CAN int main(void) {
u8 key;
u8 i=0,t=0;
u8 cnt=0;
u8 canbuf[8];
u8 res;
u8 mode=1;
Cache_Enable();
//打开 L1-Cache
HAL_Init();
//初始化 HAL 库
Stm32_Clock_Init(432,25,2,9);
//设置时钟,216Mhz
delay_init(216);
//延时初始化
uart_init(115200);
//串口初始化
usmart_dev.init(108);
//初始化 USMART
LED_Init();
//初始化 LED
KEY_Init();
//初始化按键
SDRAM_Init();
//初始化 SDRAM
LCD_Init();
//LCD 初始化
CAN1_Mode_Init(CAN_SJW_1TQ,CAN_BS2_6TQ,CAN_BS1_11TQ,6,CAN_MODE_LOOPBACK);//CAN初始化环回模式,波特率 500Kbps
POINT_COLOR=RED;//设置字体为红色
LCD_ShowString(30,70,200,16,16,"CAN test");
LCD_ShowString(30,130,200,16,16,"LoopBack Mode");
LCD_ShowString(30,150,200,16,16,"KEY0:Send
WK_UP:Mode");//显示提示信息
POINT_COLOR=BLUE;//设置字体为蓝色
17
LCD_ShowString(30,170,200,16,16,"Count:");
//显示当前计数值
LCD_ShowString(30,190,200,16,16,"Send Data:");
//提示发送的数据
LCD_ShowString(30,250,200,16,16,"Receive Data:"); //提示接收到的数据
while(1)
{
key=KEY_Scan(0);
if(key==KEY0_PRES)//KEY0 按下,发送一次数据
{
for(i=0;i<8;i++)
{
canbuf[i]=cnt+i;//填充发送缓冲区
POINT_COLOR=...