基于STM32的CAN总线的数据采集卡设计

更新时间:2024-06-14 08:12:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

学 号: 0121311371307

能力拓展训练

题 目 学 院 专 业 班 级 姓 名 指导教师

2016 年 8 月 27 日

基于STM32的CAN总线数据采集卡设计

自动化学院 自动化专业 自动化1305班

司文雷 罗璠

任务书

1、要求设计如下功能的数据采集卡:

(1)采用STM32对8路0~5V模拟信号进行采集,采样频率为100Hz。 (2)采集的数据要求通过CAN总线发送出去。 (3)数据采集卡的CAN总线标识符可用拨码开关指定。

2、要求选择合适的STM32微控制器,具备对CAN总线的支持,并选择合适的CAN接口电路芯片;

3、要求完成采集卡的硬件电路设计,包括原理图设计、PCB布线设计; 4、要求完成STM32程序设计,并进行仿真; 5、提交设计报告。

1 STM32简介 .................................................................................................................................... 3 1.1 STM32F105VCT6的参数 .................................................................. 错误!未定义书签。 1.2 内部资源 .................................................................................................................................. 4 1.3 Cortex-M3内核简介 ............................................................................................................... 5 2 CAN概述........................................................................................................................................ 6 2.1CAN简介 ...................................................................................................................................... 6 2.2工作原理 .................................................................................................................................... 7 2.3CAN的高层协议 .......................................................................................................................... 7 2.4 CAN波特率计算 ........................................................................................................................ 8 2.4.1 波特率 ..................................................................................................................................... 8 2.4.2CAN波特率的计算 ................................................................................................................. 8 3硬件电路设计 .............................................................................................................................. 13 4软件实现...................................................................................................................................... 14 4.1STM32电压数据采集的软件实现 ........................................................................................... 14

4.1.1AD-DA模块的编写 ..................................................................................................... 14 4.2CAN 总线节点的软件设计 ..................................................................................................... 24 结论 ................................................................................................................................................ 32 参考文献......................................................................................................................................... 33 附录1 ............................................................................................................................................. 35 附录2 ............................................................................................................................................. 36

1

摘要

摘要:CAN(Controller Area Network,控制器局域网)是一种有效支持实时控制的串行数据通信网络。自上世纪80年代诞生以来,CAN总线以其可靠性好、实时性高及组网简便灵活等优势而受到人们的青睐,并在众多行业领域内得到了广泛的应用。随着工业技术的不断进步,控制过程的自动化与网络化是必然的发展趋势,同时数据的传输量越来越大,对数据传输的实时性要求也更加苛刻。笔者采用内置 CAN 控制器的高性能微处理器STM32F105vct6 作为节点的微处理器,使用带隔离的高速集成 CTM1050T 作为 CAN 收发器,数据输入输出通道采用光电耦合器进行隔离,设计了 CAN 总线系统的数据采集节点。本设计节点具有体积小、功耗低、抗干扰能力强、实时性高及数据处理能力强等优势。实现,它主要实现现场节点的监控及数据的显示、分析和存储。数据转换器采用 RS-232 转 CAN,它主要实现串口协议与 CAN 协议之间的桥接,并将接收的数据进行转发。各节点与工业现场的仪器仪表相连接,不分主次地挂接在 CAN 总线上,它主要实现数据的采集与处理,并接收来自 CAN 总线上的数据或将数据发送到 CAN 总线上。

关键词:STM32;CAN总线;数据采集

2

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 增强型)

3

CAN_DeInit();

CAN_StructInit(&CAN_InitStructure);

/* CAN cell init */

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);

/* CAN filter init */

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); }

注意//#define CAN_BS1_3tq((uint8_t)0x02) /*!< 3 time quantum */ 拨特率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) |

9

((u32)CAN_InitStruct->CAN_BS1 << 16) | ((u32)CAN_InitStruct->CAN_BS2 << 20) |

((u32)CAN_InitStruct->CAN_Prescaler - 1);

Fpclk=36M 时can波特率250k的配置为

/* CAN cell init */

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: /* CAN cell init */

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

10

/* CAN cell init */ 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时钟是 8 MHz : (8M / 1 ) / 16 = 500K 其中: 1 为分频系数

16 为每一位的Tq数目

11

为了设置为100K,把分频系数改为5即可,BS1 BS2不变

每一位的Tq数目 = 1(固定)+8 (BS1)+7 (BS2) = 16 如果CAN时钟是8MHz : (8M/5)/16 = 100K

如果想得到1M 的波特率,CAN时钟仍然是 8MHz的情况下,分频系数不变

应该改变 BS1 BS2

CAN_InitStructure.CAN_BS1=CAN_BS1_5tq; CAN_InitStructure.CAN_BS2=CAN_BS2_2tq;

每一位的Tq数目 = 1(固定)+5 (BS1) + 2 (BS2) = 8 如果CAN时钟是 8 MHz : (8M / 1 ) / 8 = 1000K

另外尽可能的把采样点设置为 CiA 推荐的值:

75% when 波特率> 800K 80% when 波特率> 500K 87.5% when 波特率<= 500K

所以对于 100K 的波特率(假定使用 8MHz 时钟) 可以修改该BS1 BS2 为:

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 时钟) 可以修改该BS1 BS2 为:

CAN_InitStructure.CAN_Prescaler=1; CAN_InitStructure.CAN_BS1=CAN_BS1_13tq;

12

CAN_InitStructure.CAN_BS2=CAN_BS2_2tq;

(1+13) / (1+13+2) = 87.5%

所以对于 1000K 的波特率(假定使用 8MHz 时钟) 可以修改该BS1 BS2 为:

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

13

因题目要求测量为0~5v电压,而STM32参考电压为3.3v,所以应采用放大器将5v转化为3.3v,正相放大器放大倍数均大于一,反相放大器放大后结果为负,因此采用两个反向放大器来实现。放大电路如图3.2

图3.2 将采集信号放大为参考电压电路

其中Rf1/R1=3.3/5,Rf2=R1’

Vo?Vi(-Rf/R1)*(?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线)和软件触发(即在配置相关寄存器时,直接开启采样)。

14

ADC采样得到的只是一个相对值,将 转换值/4096*参考电压 即可得到采样电压 这里的4096是因为stm32的adc为12位精度,表示参考电压时即为 2^12=4096

AD转换程序代码如下: #include #include \#include \#include \#include \

#define LED1 PAout(4) #define LED2 PAout(5)

#define VREF 3.3

int main(void) {

while(1){

ADValue = Get_Adc(ADC_1,8);

temp = (float)VREF*(ADValue/4096); //ADC精度为12位精Adc1_Init(8,7); //使用8通道采样,采样时间系数为7(111),Gpio_Init();

据手册可得采样时间为 (239.5+12.5)/12= 21 (us)

Rcc_Init(9);

//系统时钟设置

//设置串口时钟和波特率

Usart1_Init(72,9600);

u16 ADValue; float temp;

//参考电压

void Gpio_Init(void);

度,即达到 VREF电压时为 2^12 = 4096

15

}

printf(\LED2 = !LED2;

delay(100000); //延时100ms

}

void Gpio_Init(void) { }

Library/src/adc.c

#include #include \

//ADC1采样初始化

GPIOA -> CRH&=0xFFFFF00F; //设置USART1 的Tx(PA.9)为第二功能GPIOA -> CRH|=0x000008B0;

推挽,50MHz;Rx(PA.10)为浮空输入

//USART1 串口I/O设置 GPIOB->CRL&=0xFFFFFFF0;

GPIOB->CRL|=0xFFFFFFF0; // PB0设置为模拟输入 GPIOA->CRL&=0xFF0FFFF0;

GPIOA->CRL|=0xFF3FFFF0; // PA0设置为模拟输入,PA4推挽输出 RCC->APB2ENR|=1<<2; //使能PORTA时钟 RCC->APB2ENR|=1<<3; //使能PORTB时钟

16

//独立工作模式 //参数说明: // //

void Adc1_Init(u8 ADC_CH_x,u8 ADC_CH_SMP) {

if(ADC_CH_x <= 9 ){

ADC1 -> SMPR2 &= 0x00000000; ADC1 -> SMPR1 &= 0xFF000000;

//清零通道采样时间

ADC1 -> SQR1 &= ~(0xF<<20); ADC1 -> SQR1 |= 15<<20;

//清零规则序列的数量 //设置规则序列的数量为16

ADC1 -> CR2 |= 1<<20;

//使用外部事件触发 SWSTART

ADC1 -> CR2 &= ~(1<<11);

//设置对齐模式为右对齐

ADC1 -> CR2 &= ~(7<<17); ADC1 -> CR2 |= 7<<17;

//清除规则通道启动事件

//设定规则通道启动事件为软件启

ADC1 -> CR1 &= 0xF0FFFF; ADC1 ->

CR1 |= 0<<16;

ADC1 -> CR1 &= ~(1<<8); ADC1 -> CR2 &= ~(1<<1);

//工作模式清零

//设定为独立模式 //非扫描工作模式 //关闭连续转换

RCC -> CFGR &= ~(3<<14); RCC -> CFGR |= 2<<14;

//分频因子清零

//设定分频因数为2,PCLK2 6分频

RCC -> APB2ENR |= 1<<9; RCC -> APB2RSTR |= 1<<9;

//开启ADC1时钟 //复位ADC1

ADC_CH_x 选择使用通道(0~17),目前暂支持0~15通道 ADC_CH_SMP

设定采样周期(0~7)

//采样周期算法:

RCC -> APB2RSTR &= ~(1<<9); //ADC1复位结束

后作为ADC时钟

动(SWSTART)

17

}

}

ADC1 -> SMPR2 |= 7<<(ADC_CH_x*3); //设置通道x采样

时间,提高采样时间可以提高采样精度

if(ADC_CH_x > 9 ){ }

ADC1 -> CR2 |= 1<<0; ADC1 -> CR2 |= 1<<3; ADC1 -> CR2 |= 1<<2;

//开启AD转换

//使能复位校准,由硬件清零 //开启AD校准,由硬件清零

ADC1 -> SMPR1 |= 7<<((ADC_CH_x-10)*3);

while((ADC1 -> CR2)& (1<<3)); //等待校准结束 while((ADC1 -> CR2)& (1<<2)); //等待校准结束

//取得数模转换的值

//参数说明:(参数定义于adc.h) // // {

data = ADC1->DR;

ADC1 -> SQR3 &= 0xFFFFFFE0; ADC1 -> SQR3 |= ADC_CH_x; ADC1 -> CR2 |= 1<<22;

//清除通道选择

//选择通道 //等待转换结束 //开启AD转换

switch(ADC_x) {

case 1 : { u16 data = 0;

ADC_x (0~3),选择数模转换器 ADC_CH_x (0~15),选择通道

u16 Get_Adc(u8 ADC_x,u8 ADC_CH_x)

while(!(ADC1 -> SR & 1<<1));

18

本文来源:https://www.bwwdw.com/article/j1u6.html

Top