基于STM32的数字电压表的设计.docx

上传人:b****1 文档编号:1170861 上传时间:2023-04-30 格式:DOCX 页数:22 大小:1.32MB
下载 相关 举报
基于STM32的数字电压表的设计.docx_第1页
第1页 / 共22页
基于STM32的数字电压表的设计.docx_第2页
第2页 / 共22页
基于STM32的数字电压表的设计.docx_第3页
第3页 / 共22页
基于STM32的数字电压表的设计.docx_第4页
第4页 / 共22页
基于STM32的数字电压表的设计.docx_第5页
第5页 / 共22页
基于STM32的数字电压表的设计.docx_第6页
第6页 / 共22页
基于STM32的数字电压表的设计.docx_第7页
第7页 / 共22页
基于STM32的数字电压表的设计.docx_第8页
第8页 / 共22页
基于STM32的数字电压表的设计.docx_第9页
第9页 / 共22页
基于STM32的数字电压表的设计.docx_第10页
第10页 / 共22页
基于STM32的数字电压表的设计.docx_第11页
第11页 / 共22页
基于STM32的数字电压表的设计.docx_第12页
第12页 / 共22页
基于STM32的数字电压表的设计.docx_第13页
第13页 / 共22页
基于STM32的数字电压表的设计.docx_第14页
第14页 / 共22页
基于STM32的数字电压表的设计.docx_第15页
第15页 / 共22页
基于STM32的数字电压表的设计.docx_第16页
第16页 / 共22页
基于STM32的数字电压表的设计.docx_第17页
第17页 / 共22页
基于STM32的数字电压表的设计.docx_第18页
第18页 / 共22页
基于STM32的数字电压表的设计.docx_第19页
第19页 / 共22页
基于STM32的数字电压表的设计.docx_第20页
第20页 / 共22页
亲,该文档总共22页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

基于STM32的数字电压表的设计.docx

《基于STM32的数字电压表的设计.docx》由会员分享,可在线阅读,更多相关《基于STM32的数字电压表的设计.docx(22页珍藏版)》请在冰点文库上搜索。

基于STM32的数字电压表的设计.docx

基于STM32的数字电压表的设计

华南理工大学广州学院

 

题目:

基于STM32的数字电压表的设计

姓名:

学号:

系别:

班级:

指导老师:

完成时间:

 

1、设计目的

1.培养综合运用所学知识、独立分析和解决实际问题的能力,培养创新意识和创新能力,并获得科学研究的基础训练。

2.掌握AD转换的基础知识,学习基于DMA专递方式的ADC采集软件的编制及控制流程。

3.通过软硬件设计实现数字电压表的功能。

2、设计内容

1、将一模拟电压信号输入到A/D转换器的任一通道。

     

2、A/D转换器将输入的模拟电压值转换成数字量。

 

3、根据学习开发板所用A/D转换器的类型,将转换成的数字量通过一定的算法转换成相应的电压值。

 

 4、将转换成电压值通过学习开发板上的LCD显示屏进行显示,要求显示一位小数。

3、设计原理

1、A/D变换原理

◆采样:

间隔一定时间对信号进行采样,用信号序列来代替原来时间上连续的信号。

均匀采样:

可完整地恢复原始信号,其中,T为采样时间间隔,fs表示采样频率,fm表示原始信号最大频率。

◆量化:

把采集到的数值送到量化器编码成数字形式,每个样值代表一次采样所获得的信号的瞬时幅度。

A/D转换器一般为标量均匀量化。

(量化还可分为:

标量量化、矢量量化)

量化误差(与舍入方式相关):

1LSB或1/2LSB

◆编码:

A/D模拟/数字转换器一般采用二进制编码,A/D变换后的结果到此可以表示为一个以0、1二进制形式表示的比特流,单位时间内可以传输的二进制比特速率就是A/D之后的码速率,数值上等于采样频率与量化比特数值之乘积。

二进制编码:

量化与字长的关系。

3、ADC的A/D转换方式

 

在查询方式下,软件可通过读取ADC模块转换完毕引脚EOC的状态或状态寄存器中的转换完成标志位判断本次A/D是否结束;

若结束则从数据总线或数据寄存器中读取A/D结果数据。

2、ADC模拟/数字转换器:

STM32的ADC是12位逐次逼近型的模拟数字转换器。

它有18个通道可测量16个外部和2个内部信号源。

各通道的A/D转换可以单次、连续、扫描或间断模式执行。

ADC的结果可以左对齐或右对齐方式存储在16位数据寄存器中。

3、转换特点:

STM32的ADC最大的转换速率为1Mhz,也就是转换时间为1us(ADCCLK=14M,采样周期为1.5个ADC时钟下得到),不能让ADC的时钟超过14M,否则将导致结果准确度下降。

4、STM32将ADC的转换分为2个通道组:

规则通道组和注入通道组。

规则通道相当于运行的程序,而注入通道就相当于中断。

在程序正常执行的时候,中断是可以打断程序正常执行的。

同这个类似,注入通道的转换可以打断规则通道的转换,在注入通道被转换完成之后,规则通道才得以继续转换。

规则组设置后,可以按照设置的通道顺序对各通道进行依次采集。

方便于对多路ADC通道的自动采集。

注入组最多设置4个通道,简单来讲就是需要触发才能采集设置的通道ADC值。

本设计选择了采用规则组,设置了一个通道进行自动采集。

5、此设计显示电压的特点:

本设计测量电压值范围为0-3.3V的电压,显示误差为±0.001V。

LCD实时显示电压值,MicroSD卡对数据进行同步存储。

系统原理框图如图1所示。

6、DMA请求:

在这次设计中用到了ADC转换结果采用DMA传递方式。

直接存储器存取用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。

无须CPU任何干预,通过DMA数据可以快速地移动。

这就节省了CPU的资源来做其他操作。

7、LCD控制电路

(1)本设计所使用的LCD为3寸,400X240分辨率。

LCD模块使用STM32的FSMC接口控制。

3TFT显示屏焊接在奋斗显示转接板上,在屏上贴有触摸屏,通过40芯的接口与V3或者MINI连接。

40芯接口定义如下:

对要显示在LCD上的数据进行写入寄存器,其时序图如下:

图(a)写入寄存器时序图

 

对要显示在LCD上的数据进行读取,其时序图如下:

图(a)读出寄存器时序图

(2)FSMC(FlexibleStaticMemoryController)即可变静态存储控制器,是STM32系列中内部集成256KB以上Flash,后缀为xC、xD和xE的高存储密度微控制器特有的存储控制机制。

通过对特殊功能寄存器的设置,FSMC能够根据不同的外部存储器类型,发出相应的数据/地址/控制信号类型以匹配信号的速度,从而使得STM32系列微控制器不仅能够应用各种不同类型、不同速度的外部静态存储器,在STM32内部,FSMC的一端通过内部高速总线AHB连接到内核Cortex-M3,另一端则是面向扩展存储器的外部总线。

内核对外部存储器的访问信号发送到AHB总线后,经过FSMC转换为符合外部存储器通信规约的信号,送到外部存储器的相应引脚,实现内核与外部存储器之间的数据交互。

FSMC起到桥梁作用,既能够进行信号类型的转换,又能够进行信号宽度和时序的调整,屏蔽掉不同存储类型的差异,使之对内核而言没有区别。

FSMC可以连接NOR/PSRAM/NAND/PC卡等设备,并且拥有FSMC_A[25:

0]共26条地址总线,FSMC[15:

0]共16条数据总线。

另外,FSMC扩展的存储空间被分成8个块。

通过地址线选择操作的块。

这样,LCD将被看作一个拥有一块地址空间的存储器进行操作。

从FSMC的角度看,可以把外部存储器划分为固定大小为256M字节的四个存储块。

●存储块1用于访问最多4个NOR闪存或PSRAM存储设备。

这个存储区被划分为4个NOR/PSRAM区并有4个专用

的片选。

●存储块2和3用于访问NAND闪存设备,每个存储块连接一个NAND闪存。

●存储块4用于访问PC卡设备,每一个存储块上的存储器类型是由用户在配置寄存器中定义的。

4、设计程序(命令)清单以及程序流程图

1、主程序:

intmain(void)

{u16len,c2len,c3len,c4len;

u8c[]="Voltage";

u8c2[]="";

u8c3[]="";

u8c4[]=".V";

u16bkColor;

len=sizeof(c)-1;//计算字节数长度sizeof()

c2len=sizeof(c2)-1;

c3len=sizeof(c3)-1;

c4len=sizeof(c2)-1;

bkColor=White;

RCC_Configuration();//系统时钟配置为72MHz

Usart1_Init();//串口1初始化

ADC_Configuration();//ADC初始化

FSMC_LCD_Init();//FSMC总线配置

lcd_Init();//液晶初始化

//lcd_PutChar(10,10,'g',0x0000,0xffff);

//LCD_test();

USART_OUT(USART1,"\r\nUSART1printAD_value--------------------------\r\n");

while

(1)

{

if(ticks++>=900000){//间隔时间显示转换结果

ticks=0;

Clock1s=1;

}

if(Clock1s){

Clock1s=0;

USART_OUT(USART1,"ThecurrentADvalue=%d\r\n",ADC_ConvertedValue);//串口显示字符段

//Delay(0xAFFFFf);

Precent=(ADC_ConvertedValue*100/4096);//算出百分比,2的12次幂为0xfff

Voltage=Precent*33;//Voltage为实际电压值的1000倍.

c4[3]=(Voltage/1000+'0');//取千位数的整数部分

c4[5]=((Voltage%1000)/100+'0');//对千位数取余数后再取其百位的整数部分

c4[6]=(((Voltage%100)/10)+'0');//对百位数取余数后再取其十位的整数部分

c4[7]=((Voltage%10)+'0');//对百位数取余数后再取其个位的整数部分

lcd_PutStr_16x24_Center(0,c3,c4len,Black,bkColor);

lcd_PutStr_16x24_Center(Line1,c,len,Black,bkColor);

lcd_PutStr_16x24_Center(Line2,c3,c3len,Black,bkColor);

lcd_PutStr_16x24_Center(Line3,c4,c4len,Black,bkColor);

lcd_PutStr_16x24_Center(Line4,c2,c2len,Black,bkColor);

USART_OUT(USART1,"Thevvalue=%d.%d%d%dV\r\n",c4[3]=(Voltage/1000),c4[5]=((Voltage%1000)/100),c4[6]=(Voltage%100)/10,c4[7]=(Voltage%10));//显示实际电压值

LCD_test();

}

}

}

2、ADC配置:

ADC_Configuration函数用于配置ADC1的通道11,因为只用了ADC1所以采用了ADC独立模式,设置通道11进入规则组,规则组里的通道只有1个,就是通道1,转换用了扫描方式,软件触发,转换结果采用DMA方式传递到2字节长度的缓存区里(ADC_ConvertedValue),默认的ADCCLK为36MHz,采样周期是55.5+12.5时钟周期,相当于采样时间是间隔(68/36)us。

voidADC_Configuration(void)

{

ADC_InitTypeDefADC_InitStructure;

GPIO_InitTypeDefGPIO_InitStructure;

DMA_InitTypeDefDMA_InitStructure;

//设置AD模拟输入端口为输入1路AD规则通道

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1;

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;

GPIO_Init(GPIOC,&GPIO_InitStructure);

/*EnableDMAclock*/

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);

/*EnableADC1andGPIOCclock*/

RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);

/*DMAchannel1configuration----------------------------------------------*/

//使能DMA

DMA_DeInit(DMA1_Channel1);

DMA_InitStructure.DMA_PeripheralBaseAddr=ADC1_DR_Address;//DMA通道1的地址

DMA_InitStructure.DMA_MemoryBaseAddr=(u32)&ADC_ConvertedValue;//DMA传送地址

DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralSRC;//传送方向

DMA_InitStructure.DMA_BufferSize=1;//传送内存大小,100个16位

DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Disable;

DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Enable;//传送内存地址递增

DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_HalfWord;//ADC1转换的数据是16位

DMA_InitStructure.DMA_MemoryDataSize=DMA_MemoryDataSize_HalfWord;//传送的目的地址是16位宽度

DMA_InitStructure.DMA_Mode=DMA_Mode_Circular;//循环

DMA_InitStructure.DMA_Priority=DMA_Priority_High;

DMA_InitStructure.DMA_M2M=DMA_M2M_Disable;

DMA_Init(DMA1_Channel1,&DMA_InitStructure);

/*允许DMA1通道1传输结束中断*/

//DMA_ITConfig(DMA1_Channel1,DMA_IT_TC,ENABLE);

//使能DMA通道1

DMA_Cmd(DMA1_Channel1,ENABLE);

//ADC配置

ADC_InitStructure.ADC_Mode=ADC_Mode_Independent;//ADC1工作在独立模式

ADC_InitStructure.ADC_ScanConvMode=ENABLE;//模数转换工作在扫描模式(多通道)还是单次(单通道)模式

ADC_InitStructure.ADC_ContinuousConvMode=ENABLE;//模数转换工作在扫描模式(多通道)还是单次(单通道)模式

ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;//转换由软件而不是外部触发启动

ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;//ADC数据右对齐

ADC_InitStructure.ADC_NbrOfChannel=1;//规定了顺序进行规则转换的ADC通道的数目。

这个数目的取值范围是1到16

ADC_Init(ADC1,&ADC_InitStructure);

/*ADC1regularchannelsconfiguration[规则模式通道配置]*/

//ADC1规则通道配置

ADC_RegularChannelConfig(ADC1,ADC_Channel_11,1,ADC_SampleTime_55Cycles5);//通道11采样时间55.5周期

//使能ADC1DMA

ADC_DMACmd(ADC1,ENABLE);

//使能ADC1

ADC_Cmd(ADC1,ENABLE);

//初始化ADC1校准寄存器

ADC_ResetCalibration(ADC1);

//检测ADC1校准寄存器初始化是否完成

while(ADC_GetResetCalibrationStatus(ADC1));

//开始校准ADC1

ADC_StartCalibration(ADC1);

//检测是否完成校准

while(ADC_GetCalibrationStatus(ADC1));

//ADC1转换启动

ADC_SoftwareStartConvCmd(ADC1,ENABLE);

}

3、程序流程图:

 

 

5、运行步骤、结果,保存截屏,实物图

1、运行步骤、结果:

步骤:

(1)对程序编译并且下载到STM32开发板;

(2)按下复位键,记录所测到的内部电压值U内部;

(3)用跳线把外部20个GPIO电压源端口分别接入到CANERA的14口,从而测量外部电压U外部GPIO1—U外部GPIO20

(4)在每次接入一个外部GPIO电压源时,都复位一次并且记录所测到电压值U外部GPIO1—U外部GPIO20。

结果:

(1)内部电压值:

U内部=1.683V

(2)外部端口电压值:

外部端口

U外部GPIO1

U外部GPIO2

U外部GPIO3

U外部GPIO4

U外部GPIO5

电压值

3.267V

0.000V

3.267V

3.267V

3.267V

外部端口

U外部GPIO6

U外部GPIO7

U外部GPIO8

U外部GPIO9

U外部GPIO10

电压值

3.267V

3.267V

1.617V

1.650V

0.429V

外部端口

U外部GPIO11

U外部GPIO12

U外部GPIO13

U外部GPIO14

U外部GPIO15

电压值

1.650V

1.650V

2.409V

3.267V

0.000V

外部端口

U外部GPIO16

U外部GPIO17

U外部GPIO18

U外部GPIO19

U外部GPIO20

电压值

1.617V

1.617V

1.617V

3.267V

0.000V

2、保存截屏:

测试到的个别电压值在串行助手显示结果如下:

(1)内部电压值:

(2)外部端口1电压值:

(3)外部端口8电压值:

(4)外部端口10电压值:

(5)外部端口13电压值:

3、实物图:

 

上图显示结果如下图:

 

六、设计的收获与体会

今个学期刚刚接触到STM32,经过黄金杨老师的介绍,我真正的体会到了STM32的强大之处,STM32采用Contex-M3内核,是32位的,比起8位的51单片机好多了,并且其处理数据速度非常快,flash,ram也是很大的,还有16位的FSMC总线等等的强项,这是51单片机望而不及的。

老师刚刚定好课程设计的题目的时候,正好黄老师在跟我们讲解STM32的AD模数转换,这里的STM32F103X是一个12位的逐次逼近型的ADC模块,所以说它的采样精度是很高的,同时自己以前还没有做过有关于AD的模块,所以我决定亲自尝试做一个简单的STM32数字电压表。

首先自己根据上一次做过的ADC实验拿出来慢慢的看main.c的ADC、DMA、GPIO、RCC、USART配置对照着库函数理解,其实这些配置基本上都是固定的,只不过根据自己的需要或者硬件的不同而配置不同而已。

利用库函数可以减少了编程的复杂性,更有利于开发更多的产品,相对于采用寄存器来编程好多了,所以说利用固件库来写程序是很重要的。

在我刚开始编程的时候,我首先先在以前那个ADC实验,把采样到的电压值准确的在串口线上显示出来,显示出采样到的电压值,其实就是要将采样值经过转化后(采样值最高为4096,采样最高电压都为3.3V)利用相应的比例算出测量的电压值,所以利用以前C语言学到的知识,先求出千位、然后再求百位、十位、个位(采样的精度为0.001),我认为这是关键性的一步,然后在LCD上显示就容易些了。

搞定了在串口上的显示电压后,紧接着就是让电压值在LCD上显示了,在这里,LCD的配置,函数,我觉得是很难理解的,故根据以往的经验,要先看看使用的LCD的文档,读懂时序图,理解LCD的命令表,这是深入了解LCD的关键,另外LCD的初始化可以在库函数里面找到。

功夫不负有心人,我足足花了一个星期,终于把程序编好了,在期间,自己不懂的东西,就问同学或者网上学习,说真的,在课程设计期间自己学到的东西是最多的。

这个课程设计可能就是大学四年最后一个课程设计了,所以我每次做课程设计的时候,我都会格外的用心,或许这是出于自己的兴趣爱好吧。

故在以后的路,我会继续保持着这种好习惯。

 

课程设计评语

优秀

良好

中等

及格

不及格

出勤

方案设计

安装调试

答辩

报告

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 人文社科 > 法律资料

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2