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

2019-04-02 14:31

因题目要求测量为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


基于STM32的CAN总线的数据采集卡设计(4).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:全国中小学生学籍信息管理系统问题学籍处理方法

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: