银杏科技有限公司旗下技术文档发布平台 |
技术支持电话 | 0379-69926675-801 |
技术支持邮件 | Gingko@vip.163.com |
版本 | 日期 | 作者 | 修改内容 |
V1.0 | 2020-04-01 | gingko | 初次建立 |
STM32CubeMX教程五十四——RS_485通信实验
1.在主界面选择File–>New Project 或者直接点击ACCEE TO MCU SELECTOR
2.出现芯片型号选择,搜索自己芯片的型号,双击型号,或者点击Start Project进入配置
在搜索栏的下面,提供的各 种查找方式,可以选择芯片内核,型号,等等,可以帮助你查找芯片。本实验选取的芯片型号为:STM32H750IBKx。
3.配置RCC,使用外部时钟源
4.时基源选择SysTick
5.将PA10,PB7,PB8设置为GPIO_Output
6.引脚模式配置
7.配置串口
在NVIC Settings一栏使能接收中断
引脚配置
8.时钟源设置,选择外部高速时钟源,配置为最大主频
9.工程文件的设置, 这里就是工程的各种配置 我们只用到有限几个,其他的默认即可 IDE我们使用的是 MDK V5.27
10.点击Code Generator,进行进一步配置
Copy all used libraries into the project folder
将HAL库的所有.C和.H都复制到所建工程中
Copy only the necessary library files
只复制所需要的.C和.H(推荐)
Add necessary library files as reference in the toolchain project configuration file
不复制文件,直接从软件包存放位置导入.C和.H
自行选择方式即可
Generate peripheral initialization as a pair of ‘.c/.h’ files per peripheral
每个外设生成单独的.c和.h文件
Backup previously genareated files when re-generating
重新生成时备份以前产生的文件
Keep User Code when re-generating
重新生成时保留用户代码
Delete previously generated files when not re-generated
重新生成时删除以前生成的文件
Set all free pins as analog (to optimize the power consumption)
没用到的引脚设置为模拟状态
11.然后点击GENERATE CODE 创建工程
创建成功,打开工程。
实验五十四:RS_485通信实验——收发测试
一、 实验目的与意义
了解STM32的UART结构。
了解STM32的UART特征。
掌握STM32的UART的使用方法。
掌握RS-485的使用方法。
掌握KEIL MDK 集成开发环境使用方法。
二、 实验设备及平台
-
iCore4T 扩展底板。
-
Micro USB线缆。
Keil MDK 开发平台。
STM32CubeMX开发平台。
装有WIN XP(及更高版本)系统的计算机。
三、 实验原理
1.串口通讯协议简介
串口通讯(Serial Communication)是一种设备间非常常用的串行通讯方式,因为它简单便捷,大部分电子设备都支持该通讯方式,电子工程师在调试设备时也经常使用该通讯方式输出调试信息。
在计算机科学里,大部分复杂的问题都可以通过分层来简化。如芯片被分为内核层和片上外设;对于通讯协议,我们也以分层的方式来理解,最基本的是把它分为物理层和协议层。物理层规定通讯系统中具有机械、电子功能部分的特性,确保原始数据在物理媒体的传输。协议层主要规定通讯逻辑,统一收发双方的数据打包、解包标准。简单来说物理层规定我们用嘴巴还是用肢体来交流,协议层则规定我们用中文还是英文来交流。
RS-485 是一种工业控制环境中常用的通讯协议,隶属于 OSI 模型物理层的电气特性规定为 2 线,半双工,多点通信的标准。它具有抗干扰能力强、传输距离远的特点。 RS-485 通讯协议由 RS-232 协议改进而来,协议层不变,只是改进了物理层,用缆线两端的电压差值来表示传递信号。RS485 仅仅规定了接受端和发送端的电气特性,它没有规定或推荐任何数据协议,因而保留了串口通讯协议应用简单的特点。
RS485 的特点:
① 接口电平低,不易损坏芯片。 RS485 的电气特性:逻辑“ 1”以两线间的电压差为+(2~6)V表示;逻辑“ 0”以两线间的电压差为-(2~6)V 表示。接口信号电平比 RS232 降低了,不易损坏接口电路的芯片,且该电平与 TTL 电平兼容,可方便与 TTL 电路连接。
② 传输速率高。 10 米时, RS485 的数据最高传输速率可达 35Mbps,在 1200m 时,传输速度可达 100Kbps。
③ 抗干扰能力强。 RS485 接口是采用平衡驱动器和差分接收器的组合,抗共模干扰能力增强,即抗噪声干扰性好。 传输距离远,支持节点多。 RS485 总线最长可以传输 1200m以上(速率≤100Kbps)
④ 一般最大支持 32 个节点,如果使用特制的 485 芯片,可以达到 128 个或者 256 个节点,最大的可以支持到 400 个节点。RS485 推荐使用在点对点网络中,线型,总线型,不能是星型,环型网络。理想情况下 RS485需要 2 个终端匹配电阻,其阻值要求等于传输电缆的特性阻抗(一般为 120Ω)。没有特性阻抗的话,当所有的设备都静止或者没有能量的时候就会产生噪声,而且线移需要双端的电压差。没有终接电阻的话,会使得较快速的发送端产生多个数据信号的边缘,导致数据传输出错。
物理层:
我们知道差分信号线具有很强的干扰能力,特别适合应用于电磁环境复杂的工业控制环境中, RS-485 协议主要是把 RS-232 的信号改进成差分信号,从而大大提高了抗干扰特性,它的通讯网络示意图见下图。
在 RS-485 通讯网络中,每个节点都是由一个通讯控制器和一个收发器组成,节点中的串口控制器使用 RX 与 TX信号线连接到收发器上,而收发器通过差分线连接到网络总线,串口控制器与收发器之间一般使用 TTL 信号传输,收发器与总线则使用差分信号来传输。发送数据时,串口控制器的 TX 信号经过收发器转换成差分信号传输到总线上,而接收数据时,收发器把总线上的差分信号转化成 TTL 信号通过 RX 引脚传输到串口控制器中,这里我们使用了SP3485芯片进行转换。
RS-485 通讯网络的最大传输距离可达 1200 米,总线上可挂载 128 个通讯节点,而由于 RS-485 网络只有一对差分信号线,它使用差分信号来表达逻辑,当 AB 两线间的电压差为-6V~-2V 时表示逻辑 1,当电压差为+2V~+6V 表示逻辑 0,在同一时刻只能表达一个信号,所以它的通讯是半双工形式的,它与 RS-232 通讯协议的特性对比见下图。
RS-485 与 RS-232 的差异只体现在物理层上,它们的协议层是相同的,也是使用串口数据包的形式传输数据。而由于 RS-485 具有强大的组网功能,人们在基础协议之上还制定了 MODBUS 协议,被广泛应用在工业控制网络中。
由于 RS-485 与 RS-232 的协议层没有区别,进行通讯时,我们同样是使用 STM32 的USART 外设作为通讯节点中的串口控制器,再外接一个 RS-485 收发器芯片把 USART 外设的 TTL 电平信号转化成 RS-485 的差分信号即可。
协议层:
串口通讯的数据包由发送设备通过自身的 TXD 接口传输到接收设备的 RXD 接口。在串口通讯的协议层中,规定了数据包的内容,它由启始位、主体数据、校验位以及停止位组成,通讯双方的数据包格式要约定一致才能正常收发数据。串口数据包的基本组成如下图:
1. 波特率
2. 通讯的起始和停止信号
3. 有效数据
4. 数据校验
奇校验要求有效数据和校验位中“1”的个数为奇数,比如一个 8 位长的有效数据为: 01101001,此时总共有 4 个“1”,为达到奇校验效果,校验位为“1”,最后传输的数据将是 8 位的有效数据加上 1 位的校验位总共 9 位。
偶校验与奇校验要求刚好相反,要求帧数据和校验位中“1”的个数为偶数,比如数据帧: 11001010,此时数据帧“1”的个数为 4 个,所以偶校验位为“0”。
0 校验是不管有效数据中的内容是什么,校验位总为“0”, 1 校验是校验位总为“1”。
在无校验的情况下,数据包中不包含校验位。
在本实验中,我们的计算机通过转接模块连接iCore4T的RS-485,通过串口工具向RS-485发送数据并接收RS-485发来的数据。
原理图:
四、 实验程序
1.主函数
int main(void)
{
char buffer[UART_BUFFER_SIZE];
HAL_Init();
SystemClock_Config();
i2c.initialize();
axp152.initialize();
axp152.set_dcdc1(3500);//[ARM & FPGA BK1/2/6 &OTHER]
axp152.set_dcdc2(1200);//[FPGA INT & PLL D]
axp152.set_aldo1(2500);//[FPGA PLL A]
axp152.set_dcdc4(3300);//[POWER_OUTPUT]
axp152.set_dcdc3(3300);//[FPGA BK4][Adjustable]
axp152.set_aldo2(3300);//[FPGA BK3][Adjustable]
axp152.set_dldo1(3300);//[FPGA BK7][Adjustable]
axp152.set_dldo2(3300);//[FPGA BK5][Adjustable]
HAL_Delay(100);
MX_GPIO_Init();
MX_USART1_UART_Init();
usart1.initialize(115200);
usart1.printf("Hello, I am iCore4T\r\n");
while (1)
{
if(usart1.receive_ok_flag){ //接收完成
usart1.receive_ok_flag = 0;
memcpy(buffer,usart1.receive_buffer,UART_BUFFER_SIZE);
memset(usart1.receive_buffer,0,UART_BUFFER_SIZE);
usart1.printf(buffer);//将接收数据发送出去
}
}
}
2.UART结构体定义
UART_HandleTypeDef huart1;
typedef struct __UART_HandleTypeDef
{
USART_TypeDef *Instance;
//UART寄存器基地址
UART_InitTypeDef Init;
//UART通信参数
uint8_t * pTxBuffPtr;
//指向UART Tx传输缓冲区的指针
uint16_t TxXferSize;
//UART Tx传输大小
__IO uint16_t TxXferCount;
//UART Tx传输计数器
uint8_t * pRxBuffPtr;
//指向UART Rx传输缓冲区的指针
uint16_t RxXferSize;
//UART Rx传输大小
__IO uint16_t RxXferCount;
//UART Rx传输计数器
DMA_HandleTypeDef * hdmatx;
//UART Tx DMA句柄参数
DMA_HandleTypeDef * hdmarx;
//UART Rx DMA句柄参数
HAL_LockTypeDef Lock;
//锁定对象
__IO HAL_UART_StateTypeDef gState;
//与全局句柄管理有关的UART状态信息并且与Tx操作有关。
__IO HAL_UART_StateTypeDef RxState;
//与Rx操作有关的UART状态信息
__IO uint32_t ErrorCode;
//UART错误代码
} UART_HandleTypeDef;
3.串口发送/接收函数
HAL_UART_Transmit();串口发送数据,使用超时管理机制
HAL_UART_Receive();串口接收数据,使用超时管理机制
HAL_UART_Transmit_IT();串口中断模式发送
HAL_UART_Receive_IT();串口中断模式接收
HAL_UART_Transmit_DMA();串口DMA模式发送
HAL_UART_Transmit_DMA();串口DMA模式接收
串口发送数据
HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
4.串口中断函数
HAL_UART_IRQHandler(UART_HandleTypeDef *huart);
//串口中断处理函数
HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart);
//串口发送中断回调函数
HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart); //串口发送一半中断回调函数(用的较少)
HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);
//串口接收中断回调函数
HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart);
//串口接收一半回调函数(用的较少)
HAL_UART_ErrorCallback();
//串口接收错误函数
HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);
HAL_UART_IRQHandler(UART_HandleTypeDef *huart);
HAL_UART_GetState();
//判断UART的接收是否结束,或者发送数据是否忙碌
五、 实验步骤
把仿真器与iCore4T的SWD调试口相连(直接相连或者通过转接器相连);
把iCore4T通过Micro USB线与计算机相连,为iCore4T供电;
打开 Keil MDK 开发环境,并打开本实验工程;
烧写程序到 iCore4T 上;
也可以进入Debug 模式,单步运行或设置断点验证程序逻辑。
六、 实验现象