华南理工大学广州学院题目:基于STM32的数字电压表的设计姓名:学号:系别:班级:指导老师:完成时间:一、设计目的1.培养综合运用所学知识、独立分析和解决实际问题的能力,培养创新意识和创新能力,并获得科学研究的基础训练。2.掌握AD转换的基础知识,学习基于DMA专递方式的ADC采集软件的编制及控制流程。3.通过软硬件设计实现数字电压表的功能。二、设计内容1、将一模拟电压信号输入到A/D转换器的任一通道。2、A/D转换器将输入的模拟电压值转换成数字量。3、根据学习开发板所用A/D转换器的类型,将转换成的数字量通过一定的算法转换成相应的电压值。4、将转换成电压值通过学习开发板上的LCD显示屏进行显示,要求显示一位小数。三、设计原理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值。本设计选择了采用规则组,设置了一个通道进行自动采集。D0D1D2D3D4D5D6D7数据输出开始转换SOC结束转换EOC输出使能模拟信号A/D转换器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卡设备,每一个存储块上的存储器类型是由用户在配置寄存器中定义的。四、设计程序(命令)清单以及程序流程图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();//系统时钟配置为72MHzUsart1_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次幂为0xfffVoltage=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----------------------------------------------*///使能DMADMA_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.DM