基于STM32的CAN总线的数据采集卡设计.docx
- 文档编号:5834482
- 上传时间:2023-01-01
- 格式:DOCX
- 页数:43
- 大小:246.13KB
基于STM32的CAN总线的数据采集卡设计.docx
《基于STM32的CAN总线的数据采集卡设计.docx》由会员分享,可在线阅读,更多相关《基于STM32的CAN总线的数据采集卡设计.docx(43页珍藏版)》请在冰豆网上搜索。
基于STM32的CAN总线的数据采集卡设计
学号:
0121311371307
能力拓展训练
题目
基于STM32的CAN总线数据采集卡设计
学院
自动化学院
专业
自动化专业
班级
自动化1305班
姓名
司文雷
指导教师
罗璠
2016
年
8
月
27
日
任务书
1、要求设计如下功能的数据采集卡:
(1)采用STM32对8路0~5V模拟信号进行采集,采样频率为100Hz。
(2)采集的数据要求通过CAN总线发送出去。
(3)数据采集卡的CAN总线标识符可用拨码开关指定。
2、要求选择合适的STM32微控制器,具备对CAN总线的支持,并选择合适的CAN接口电路芯片;
3、要求完成采集卡的硬件电路设计,包括原理图设计、PCB布线设计;
4、要求完成STM32程序设计,并进行仿真;
5、提交设计报告。
摘要
摘要:
CAN(ControllerAreaNetwork,控制器局域网)是一种有效支持实时控制的串行数据通信网络。
自上世纪80年代诞生以来,CAN总线以其可靠性好、实时性高及组网简便灵活等优势而受到人们的青睐,并在众多行业领域内得到了广泛的应用。
随着工业技术的不断进步,控制过程的自动化与网络化是必然的发展趋势,同时数据的传输量越来越大,对数据传输的实时性要求也更加苛刻。
笔者采用内置CAN控制器的高性能微处理器STM32F105vct6作为节点的微处理器,使用带隔离的高速集成CTM1050T作为CAN收发器,数据输入输出通道采用光电耦合器进行隔离,设计了CAN总线系统的数据采集节点。
本设计节点具有体积小、功耗低、抗干扰能力强、实时性高及数据处理能力强等优势。
实现,它主要实现现场节点的监控及数据的显示、分析和存储。
数据转换器采用RS-232转CAN,它主要实现串口协议与CAN协议之间的桥接,并将接收的数据进行转发。
各节点与工业现场的仪器仪表相连接,不分主次地挂接在CAN总线上,它主要实现数据的采集与处理,并接收来自CAN总线上的数据或将数据发送到CAN总线上。
关键词:
STM32;CAN总线;数据采集
1STM32简介
STM32F105xx增强型系列使用高性能的ARM/Cortex-M3/32位的RISC内核,工作频率为72MHz,内置高速存储器(高达128K字节的闪存和20K字节的SRAM),丰富的增强I/O端口和联接到两条APB总线的外设。
所有型号的器件都包含2个12位的ADC、3个通用16位定时器和一个PWM定时器,还包含标准和先进的通信接口:
多达2个I2C和SPI、3个USART、一个USB和一个CAN。
STM32F105xx增强型系列工作于-40℃至+105℃的温度范围,供电电压2.0V至3.6V,一系列的省电模式保证低功耗应用的要求。
这些丰富的外设配置,使得STM32F105xx增强型微控制器适合于多种应用场合:
电机驱动和应用控制;
·医疗和手持设备;
·PC外设和GPS平台;
·工业应用:
可编程控制器、变频器、打印机和扫描仪;STM32开发板核心芯片的参数如表1-1
表1-1器件功能和配置(STM32F105xx增强型)
芯片引脚图如图1-2:
图1-2STM32F105xx增强型LQPFP48管脚图
1.2内部资源
STM32有丰富的内部资源,如下所示:
·RealViewMDK(MiertocontrollerDevelopmentKit)基于ARM微控制器的专业嵌入式开发工具;
·内置闪存存储器;
·内置SRAM;
·嵌套的向量式中断控制器(NVIC);
·外部中断/事件控制器(EXTI);
·时钟和启动;
·自举模式;
·DMA;
·RTC(实时时钟)和后备寄存器;
·窗口看门狗;
·I2C总线;
·通用同步/异步接受发送器(USART);
·串行外设接口(SPI);
·控制器区域网络(CAN);
·通用串行总线(USB);
·通用输入输出接口(GPIO);
·ADC(模拟/数字转换器);
·温度传感器;
·串行线JTAG调试口(SWJ-DP)。
1.3Cortex-M3内核简介
Cortex-M3内核包含一个适用于传统Thumb和新型Thumb-2指令的译码器、一个支持硬件乘法和硬件除法的先进ALU、控制逻辑和用于连接处理器其他部件的接口。
Cortex-M3处理器是首款基于ARMv7-M架构的ARM处理器。
中央Cortex-M3内核使用3级流水线哈佛架构,运用分支预测、单周期乘法和硬件除法功能实现了出色的效率(1.25DMIPS/MHz)。
Cortex-M3处理器是一个32位处理器,带有32位宽的数据路径、寄存器库和基于传统ARM7处理器的系统只支持访问对齐的数据,沿着对齐的字边界即可对数据进行访问和存储。
Cortex-M3处理器采用非对齐数据访问方式,使非对齐数据可以在单核访问中进行传输。
Cortex-M3处理器是专为那些对成本和功耗非常敏感但同时对性能要求又相当高的应用而设计的。
凭借缩小的内核尺寸和出色的中断延迟性能、集成的系统部件、灵活的配置、简单的高级编程和强大的软件系统,Cortex-M3处理器将成为从复杂的芯片系统到低端微控制器等各种系统的理想解决方案。
表2-3为Cortex-M3处理器与ARM7作比较。
表2-3Cortex-M3与ARM7相比较
2CAN概述
2.1CAN简介
CAN,全称为“ControllerAreaNetwork”,即控制器局域网,是国际上应用最广泛的现场总线之一。
最初,CAN被设计作为汽车环境中的微控制器通讯,在车载各电子控制装置ECU之间交换信息,形成汽车电子控制网络。
比如:
发动机管理系统、变速箱控制器、仪表装备、电子主干系统中,均嵌入CAN控制装置。
一个由CAN总线构成的单一网络中,理论上可以挂接无数个节点。
实际应用中,节点数目受网络硬件的电气特性所限制。
例如,当使用PhilipsP82C250作为CAN收发器时,同一网络中允许挂接110个节点。
CAN可提供高达1Mbit/s的数据传输速率,这使实时控制变得非常容易。
另外,硬件的错误检定特性也增强了CAN的抗电磁干扰能力。
2.2工作原理
当CAN总线上的一个节点(站)发送数据时,它以报文形式广播给网络中所有节点。
对每个节点来说,无论数据是否是发给自己的,都对其进行接收。
每组报文开头的11位字符为标识符,定义了报文的优先级,这种报文格式称为面向内容的编址方案。
在同一系统中标识符是唯一的,不可能有两个站发送具有相同标识符的报文。
当几个站同时竞争总线读取时,这种配置十分重要。
当一个站要向其它站发送数据时,该站的CPU将要发送的数据和自己的标识符传送给本站的CAN芯片,并处于准备状态;当它收到总线分配时,转为发送报文状态。
CAN芯片将数据根据协议组织成一定的报文格式发出,这时网上的其它站处于接收状态。
每个处于接收状态的站对接收到的报文进行检测,判断这些报文是否是发给自己的,以确定是否接收它。
由于CAN总线是一种面向内容的编址方案,因此很容易建立高水准的控制系统并灵活地进行配置。
我们可以很容易地在CAN总线中加进一些新站而无需在硬件或软件上进行修改。
当所提供的新站是纯数据接收设备时,数据传输协议不要求独立的部分有物理目的地址。
它允许分布过程同步化,即总线上控制器需要测量数据时,可由网上获得,而无须每个控制器都有自己独立的传感器。
2.3CAN的高层协议
CAN的高层协议(也可理解为应用层协议)是一种在现有的底层协议(物理层和数据链路层)之上实现的协议。
高层协议是在CAN规范的基础上发展起来的应用层。
许多系统(像汽车工业)中,可以特别制定一个合适的应用层,但对于许多的行业来说,这种方法是不经济的。
一些组织已经研究并开放了应用层标准,以使系统的综合应用变得十分容易。
一些可使用的CAN高层协议有:
制定组织主要高层协议
CiACAL协议
CiACANOpen协议
ODVADeviceNet协议
HoneywellSDS协议
KvaserCANKingdom协议
2.4CAN波特率计算
2.4.1波特率
波特率(Baudrate)即调制速率,指的是信号被调制以后在单位时间内的变化,即单位时间内载波参数变化的次数。
它是对符号传输速率的一种度量,1波特即指每秒传输1个符号。
单位“波特”本身就已经是代表每秒的调制数。
2.4.2CAN波特率的计算
CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;
CAN_InitStructure.CAN_BS1=CAN_BS1_3tq;
注意//#defineCAN_BS1_3tq((uint8_t)0x02)/*!
<3timequantum*/
CAN_InitStructure.CAN_BS2=CAN_BS2_5tq;
CAN_InitStructure.CAN_Prescaler=4;//2
nominalbittime(3+5+1)tq=9tq
关于分频系数查看system_stm32f10x.c下面的
staticvoidSetSysClockTo72(void)函数
/*HCLK=SYSCLK*/
/*PCLK2=HCLK*/
/*PCLK1=HCLK/2*/
所以can时钟72MHZ/2/4=9Mhz
tq=1/36Mhz
波特率为1/nominalbittime=9/9=1MHZ
voidCAN_Configuration(void)
{
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
/*CANregisterinit*/
CAN_DeInit();
CAN_StructInit(&CAN_InitStructure);
/*CANcellinit*/
CAN_InitStructure.CAN_TTCM=DISABLE;
CAN_InitStructure.CAN_ABOM=DISABLE;
CAN_InitStructure.CAN_AWUM=DISABLE;
CAN_InitStructure.CAN_NART=DISABLE;
CAN_InitStructure.CAN_RFLM=DISABLE;
CAN_InitStructure.CAN_TXFP=DISABLE;
CAN_InitStructure.CAN_Mode=CAN_Mode_Normal;
CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;
CAN_InitStructure.CAN_BS1=CAN_BS1_9tq;
CAN_InitStructure.CAN_BS2=CAN_BS2_8tq;
CAN_InitStructure.CAN_Prescaler=200;
CAN_Init(&CAN_InitStructure);
/*CANfilterinit*/
CAN_FilterInitStructure.CAN_FilterNumber=0;
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_16bit;
CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;
CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment=0;
CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;
CAN_FilterInit(&CAN_FilterInitStructure);
}
注意//#defineCAN_BS1_3tq((uint8_t)0x02)/*!
<3timequantum*/
拨特率10K,公式:
72MHZ/2/200/(1+9+8)=0.01,即10K,和SJA1000测试通过 ,要加上 120欧姆电阻。
CAN->BTR=(u32)((u32)CAN_InitStruct->CAN_Mode<<30)|((u32)CAN_InitStruct->CAN_SJW<<24)|
((u32)CAN_InitStruct->CAN_BS1<<16)|((u32)CAN_InitStruct->CAN_BS2<<20)|
((u32)CAN_InitStruct->CAN_Prescaler-1);
Fpclk=36M时can波特率250k的配置为
/*CANcellinit*/
CAN_InitStructure.CAN_TTCM=DISABLE;
CAN_InitStructure.CAN_ABOM=DISABLE;
CAN_InitStructure.CAN_AWUM=DISABLE;
CAN_InitStructure.CAN_NART=DISABLE;
CAN_InitStructure.CAN_RFLM=DISABLE;
CAN_InitStructure.CAN_TXFP=DISABLE;
CAN_InitStructure.CAN_Mode=CAN_Mode_LoopBack;
CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;
CAN_InitStructure.CAN_BS1=CAN_BS1_8tq;
CAN_InitStructure.CAN_BS2=CAN_BS2_7tq;
CAN_InitStructure.CAN_Prescaler=9;
CAN_Init(&CAN_InitStructure);
100k查询和500k中断方式的例子分别设置如下:
CAN_Polling:
/*CANcellinit*/
CAN_InitStructure.CAN_TTCM=DISABLE;
CAN_InitStructure.CAN_ABOM=DISABLE;
CAN_InitStructure.CAN_AWUM=DISABLE;
CAN_InitStructure.CAN_NART=DISABLE;
CAN_InitStructure.CAN_RFLM=DISABLE;
CAN_InitStructure.CAN_TXFP=DISABLE;
CAN_InitStructure.CAN_Mode=CAN_Mode_LoopBack;
CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;
CAN_InitStructure.CAN_BS1=CAN_BS1_8tq;
CAN_InitStructure.CAN_BS2=CAN_BS2_7tq;
CAN_InitStructure.CAN_Prescaler=5;
CAN_Init(&CAN_InitStructure);100k
/*CANcellinit*/ CAN_Interrupt
CAN_InitStructure.CAN_TTCM=DISABLE;
CAN_InitStructure.CAN_ABOM=DISABLE;
CAN_InitStructure.CAN_AWUM=DISABLE;
CAN_InitStructure.CAN_NART=DISABLE;
CAN_InitStructure.CAN_RFLM=DISABLE;
CAN_InitStructure.CAN_TXFP=DISABLE;
CAN_InitStructure.CAN_Mode=CAN_Mode_LoopBack;
CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;
CAN_InitStructure.CAN_BS1=CAN_BS1_8tq;
CAN_InitStructure.CAN_BS2=CAN_BS2_7tq;
CAN_InitStructure.CAN_Prescaler=1;
CAN_Init(&CAN_InitStructure);//500k
can时钟是RCC_APB1PeriphClock,需注意CAN时钟频率
CAN波特率=RCC_APB1PeriphClock/CAN_SJW+CAN_BS1+CAN_BS2/CAN_Prescaler;
如果CAN时钟为8M,CAN_SJW=1,CAN_BS1=8,CAN_BS2=7,CAN_Prescaler=2那么波特率就是=8M/(1+8+7)/2=250K
得到500Kb/s的波特率
CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;
CAN_InitStructure.CAN_BS1=CAN_BS1_8tq;
CAN_InitStructure.CAN_BS2=CAN_BS2_7tq;
CAN_InitStructure.CAN_Prescaler=1;
每一位的Tq数目=1(固定SYNC_SEG)+ 8(BS1)+7(BS2)=16
如果CAN时钟是8MHz:
(8M/1)/16=500K
其中:
1为分频系数
16为每一位的Tq数目
为了设置为100K,把分频系数改为5即可,BS1BS2不变
每一位的Tq数目=1(固定)+8(BS1)+7(BS2)=16
如果CAN时钟是8MHz:
(8M/5)/16=100K
如果想得到1M的波特率,CAN时钟仍然是8MHz的情况下,分频系数不变
应该改变BS1BS2
CAN_InitStructure.CAN_BS1=CAN_BS1_5tq;
CAN_InitStructure.CAN_BS2=CAN_BS2_2tq;
每一位的Tq数目=1(固定)+5(BS1)+2(BS2)=8
如果CAN时钟是8MHz:
(8M/1)/8=1000K
另外尽可能的把采样点设置为CiA推荐的值:
75% when波特率>800K
80% when波特率>500K
87.5% when波特率<=500K
所以对于100K的波特率(假定使用8MHz时钟)
可以修改该BS1BS2为:
CAN_InitStructure.CAN_Prescaler=5;
CAN_InitStructure.CAN_BS1=CAN_BS1_13tq;
CAN_InitStructure.CAN_BS2=CAN_BS2_2tq;
(1+13)/(1+13+2)=87.5%
所以对于500K的波特率(假定使用8MHz时钟)
可以修改该BS1BS2为:
CAN_InitStructure.CAN_Prescaler=1;
CAN_InitStructure.CAN_BS1=CAN_BS1_13tq;
CAN_InitStructure.CAN_BS2=CAN_BS2_2tq;
(1+13)/(1+13+2)=87.5%
所以对于1000K的波特率(假定使用8MHz时钟)
可以修改该BS1BS2为:
CAN_InitStructure.CAN_Prescaler=1;
CAN_InitStructure.CAN_BS1=CAN_BS1_5tq;
CAN_InitStructure.CAN_BS2=CAN_BS2_2tq;
(1+5)/(1+5+2)=75%
上边这个公式算出来的就是CAN的速率了
3硬件电路设计
数据采集卡整体硬件程序框图如图3.1所示,由信息调理电路,STM32芯片(内含CAN总线控制器),CAN总线收发单元组成
图3.1
因题目要求测量为0~5v电压,而STM32参考电压为3.3v,所以应采用放大器将5v转化为3.3v,正相放大器放大倍数均大于一,反相放大器放大后结果为负,因此采用两个反向放大器来实现。
放大电路如图3.2
图3.2将采集信号放大为参考电压电路
其中Rf1/R1=3.3/5,Rf2=R1’
则,输入电压为5v是,Vo为3.3v,为参考电压。
整体硬件原理图见附录1
4软件实现
软件实现主要分为STM32的电压数据采集实现和CAN总线CAN总线节点的软件设计。
4.1STM32电压数据采集的软件实现
4.1.1AD-DA模块的编写
STM32F105最少有2个AD模数转换器,每个ADC都有18个通道,可以测量16个外部和2个内部模拟量。
最大转换频率为1Mhz,也就是转换时间为1us(在ADCCLK=14Mhz,采样周期为1.5个时钟周期时)。
最大时钟超过14Mhz,将导致ADC转换准确度降低。
stm32的ADC是12位精度的。
stm32的ADC转换有两种通道,规则通道和注入通道,注入通道可以抢占式地打断规则通道的采样,执行注入通道采样后,再执行之前的规则通道采样,和中断类似。
此处只使用规则通道实现独立模式的中断采样。
stm32的ADC可以由外部事件触发(例如定时器捕获,EXTI线)和软件触发(即在配置相关寄存器时,直接开启采样)。
ADC采样得到的只是一个相对值,将转换值/4096*参考电压即可得到采样电压这里的4096是因为stm32的adc为12位精度,表示参考电压时即为2^12=4096
AD转换程序代码如下:
#include
#include"system.h"
#include"usart.h"
#include"adc.h"
#include"stdio.h"
#defineLED
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于 STM32 CAN 总线 数据 采集 设计