精华内容
下载资源
问答
  • 4ADC电压采集与LCD显示 使用ADC1通道和ADC2同时采集 ADC1通道PA0-PA9可在adc.c中先修改引脚, 再修改对应数字通道号adcx=Get_Adc_Average(ADC_Channel_7,20);//获取通道7的转换值,20次取平均 ADC2通道PC0-PC3对应...

    **STM32F407无线遥控4路ADC电压采集与LCD显示

    介绍:使用ADC1通道和ADC2同时采集(正点原子源代码修改)

    ADC1通道PA0-PA9可在adc.c中先修改引脚,
    再修改对应数字通道号adcx=Get_Adc_Average(ADC_Channel_7,20);//获取通道7的转换值,20次取平均
    ADC2通道PC0-PC3对应通道10-13可在adc.c中先修改引脚,
    再修改对应数字通道号adcx=Get_Adc_Average1(ADC_Channel_10,10);//获取通道0的转换值,10次取平均

    遥控:按下KEY_0为接收模式,KEY_1为发射模式,遥控使用PA5,PA7两路电压采集为单遥感可控制小车前进后退左转右转,归位停止
    (未写PWM波控制)
    硬件连接:
    遥感:PA5,PA7
    KEY0按键(连接在PE4)/KEY1按键(连接在PE3)
    NRF24L01模块(SPI1(PB3/PB4/PB5)/IRQ(PG8)/CS(PG7)/CE(PG6)).(原理图下载可看另一篇博客末尾链接)

    电机控制io:PC6 PC7 --PC8 PC9
    (L298N使能端跳线帽不拔,若用PWM波时接IO,电机IO定义位于led.c与led.h)*

    本文源代码链接:
    链接:https://pan.baidu.com/s/1sR2hARq8hdMJc2lxBQjUuQ
    提取码:0eky

    1、adc.c(注释IO有些未改)

    #include "adc.h"
    #include "delay.h"		 
    
    
    //初始化ADC															   
    void  Adc_Init(void)
    {    
      GPIO_InitTypeDef  GPIO_InitStructure;
    	ADC_CommonInitTypeDef ADC_CommonInitStructure;
    	ADC_InitTypeDef       ADC_InitStructure;
    	
      RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA|RCC_AHB1Periph_GPIOC, ENABLE);//使能GPIOA时钟
      RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //使能ADC1时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE); //使能ADC1时钟
      //先初始化ADC1通道5 IO口
      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_7;//PA5 通道5
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;//模拟输入
      GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;//不带上下拉
      GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化  
     
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;//PA5 通道5
    	 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;//模拟输入
      GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;//不带上下拉
      GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化  
    	
    	RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,ENABLE);	  //ADC1复位
    	RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,DISABLE);	//复位结束	 
    	RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC2,ENABLE);	  //ADC1复位
    	RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC2,DISABLE);	//复位结束	 
     
    	
      ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;//独立模式
      ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;//两个采样阶段之间的延迟5个时钟
      ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; //DMA失能
      ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;//预分频4分频。ADCCLK=PCLK2/4=84/4=21Mhz,ADC时钟最好不要超过36Mhz 
      ADC_CommonInit(&ADC_CommonInitStructure);//初始化
    	
      ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;//12位模式
      ADC_InitStructure.ADC_ScanConvMode = DISABLE;//非扫描模式	
      ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//关闭连续转换
      ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;//禁止触发检测,使用软件触发
      ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//右对齐	
      ADC_InitStructure.ADC_NbrOfConversion = 1;//1个转换在规则序列中 也就是只转换规则序列1 
      ADC_Init(ADC1, &ADC_InitStructure);//ADC初始化
    	ADC_Init(ADC2, &ADC_InitStructure);//ADC初始化
    	
     
    	ADC_Cmd(ADC1, ENABLE);//开启AD转换器	
    	ADC_Cmd(ADC2, ENABLE);//开启AD转换器	
    
    }				  
    //获得ADC值
    //ch: @ref ADC_channels 
    //通道值 0~16取值范围为:ADC_Channel_0~ADC_Channel_16
    //返回值:转换结果
    u16 Get_Adc(u8 ch)   
    {
    	  	//设置指定ADC的规则组通道,一个序列,采样时间
    	ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_480Cycles );	//ADC1,ADC通道5,480个周期,提高采样时间可以提高精确度	
    	//ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_480Cycles );	//ADC1,ADC通道7,480个周期,提高采样时间可以提高精确度		
      
    	ADC_SoftwareStartConv(ADC1);		//使能指定的ADC1的软件转换启动功能	
    	 
    	while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束
    
    	return ADC_GetConversionValue(ADC1);	//返回最近一次ADC1规则组的转换结果
    	//ADC_RegularChannelConfig(ADC2, ADC_Channel_10, 1, ADC_SampleTime_480Cycles );	//ADC1,ADC通道5,480个周期,提高采样时间可以提高精确度	
    }
    u16 Get_Adc1(u8 ch)
    	{
    		ADC_RegularChannelConfig(ADC2, ch, 1, ADC_SampleTime_480Cycles );
    	//ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_480Cycles );	//ADC1,ADC通道7,480个周期,提高采样时间可以提高精确度		
      
    	ADC_SoftwareStartConv(ADC2);		//使能指定的ADC1的软件转换启动功能	
    	 
    	while(!ADC_GetFlagStatus(ADC2, ADC_FLAG_EOC ));//等待转换结束
    
    	return ADC_GetConversionValue(ADC2);	//返回最近一次ADC1规则组的转换结果
    	}
    //获取通道ch的转换值,取times次,然后平均 
    //ch:通道编号
    //times:获取次数
    //返回值:通道ch的times次转换结果平均值
    u16 Get_Adc_Average(u8 ch,u8 times)
    {
    	u32 temp_val=0;
    	u8 t;
    	for(t=0;t<times;t++)
    	{
    		temp_val+=Get_Adc(ch);
    		delay_ms(5);
    	}
    	return temp_val/times;
    } 
    
    u16 Get_Adc_Average1(u8 ch,u8 times)
    {
    	u32 temp_val1=0;
    	u8 t;
    	for(t=0;t<times;t++)
    	{
    		temp_val1+=Get_Adc1(ch);
    		delay_ms(5);
    	}
    	return temp_val1/times;
    } 
    

    2、adc.h

    #ifndef __ADC_H
    #define __ADC_H	
    #include "sys.h" 
     							   
    void Adc_Init(void); 				//ADC通道初始化
    u16  Get_Adc(u8 ch); 				//获得某个通道值 
    u16  Get_Adc1(u8 ch); 				//获得某个通道值 
    u16 Get_Adc_Average(u8 ch,u8 times);//得到某个通道给定次数采样的平均值  
    u16 Get_Adc_Average1(u8 ch,u8 times);//得到某个通道给定次数采样的平均值  
    #endif 
    

    3.main.c

    #include "sys.h"
    #include "delay.h"
    #include "usart.h"
    #include "led.h"
    #include "lcd.h"
    #include "spi.h"
    #include "key.h" 
    #include "24l01.h"
    #include "adc.h"
    
    //要写入到W25Q16的字符串数组
    const u8 TEXT_Buffer[]={"Explorer STM32F4 SPI TEST"};
    #define SIZE sizeof(TEXT_Buffer)	 
    	
    int main(void)
    { 
    	u8 key,mode;
    	u16 adcx,adcx1,ADCX2,ADCX3;
    	float temp,temp1,TEMP2,TEMP3;
    	u16 t=0;			 
    	u8 tmp_buf[33];	
    	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
    	delay_init(168);  //初始化延时函数
    	uart_init(115200);	//初始化串口波特率为115200
    	LED_Init();					//初始化LED 
     	LCD_Init();					//LCD初始化  
     	KEY_Init();					//按键初始化
     	NRF24L01_Init();    		//初始化NRF24L01 
      Adc_Init();         //初始化ADC
     	
    	POINT_COLOR=RED;//设置字体为红色      
    	LCD_ShowString(30,50,200,16,16,"ADC1_CH7_VOL:0.000V");	//先在固定位置显示小数点    
    	LCD_ShowString(30,70,200,16,16,"ADC1_CH5_VOL:0.000V");	//先在固定位置显示小数点  
      LCD_ShowString(30,90,200,16,16,"ADC2_CH1_VOL:0.000V");	//先在固定位置显示小数点  
      LCD_ShowString(30,110,200,16,16,"ADC2_CH3_VOL:0.000V");	//先在固定位置显示小数点   	
    	while(NRF24L01_Check())
    	{
    		LCD_ShowString(30,130,200,16,16,"NRF24L01 Error");
    		delay_ms(200);
    		LCD_Fill(30,130,239,130+16,WHITE);
     		delay_ms(200);
    	}
    	LCD_ShowString(30,130,200,16,16,"NRF24L01 OK"); 	 
     	while(1)
    	{	
    		key=KEY_Scan(0);
    		if(key==KEY0_PRES)
    		{
    			mode=0;   
    			break;
    		}else if(key==KEY1_PRES)
    		{
    			mode=1;
    			break;
    		}
    		t++;
    		if(t==100)LCD_ShowString(10,150,230,16,16,"KEY0:RX_Mode  KEY1:TX_Mode"); //闪烁显示提示信息
     		if(t==200)
    		{	
    			LCD_Fill(10,150,230,150+16,WHITE);
    			t=0; 
    		}
    		delay_ms(5);	  
    	}   
     	LCD_Fill(10,150,240,166,WHITE);//清空上面的显示		  
     	POINT_COLOR=BLUE;//设置字体为蓝色	   
    	if(mode==0)//RX模式
    	{
    		LCD_ShowString(30,150,200,16,16,"NRF24L01 RX_Mode");	
    		LCD_ShowString(30,170,200,16,16,"Received DATA:");	
    		NRF24L01_RX_Mode();		  
    		while(1)
    		{	  		    		    				 
    			if(NRF24L01_RxPacket(tmp_buf)==0)//一旦接收到信息,则显示出来.
    			{
    				tmp_buf[32]=0;//加入字符串结束符
    				LCD_ShowString(30,190,lcddev.width-1,32,16,tmp_buf);    
    							switch(tmp_buf[0])
    				{
    					case 'A':
    						//LED0 = 1;                                                                                                         
    						LED1 = 1;
    						IN0=1;IN1=1;
    						IN2=1;IN3=1;
    //						delay_ms(500);
    //						GPIO_ResetBits(GPIOF, GPIO_Pin_2 | GPIO_Pin_3);
    						break;
    					case 'B':
    						//LED0 = 1;
    						LED1 = 0;
    						IN0=0;IN1=1;
    						IN2=0; IN3=1;
    //						delay_ms(100);
    //						GPIO_ResetBits(GPIOF, GPIO_Pin_2 | GPIO_Pin_5);
    						break;
    					case 'C':
    						//LED0 = 0;
    						LED1 = 0;
    						IN0=1;IN1=0;
    					  IN2=1; IN3=0;
    //						delay_ms(500);
    //						GPIO_ResetBits(GPIOF, GPIO_Pin_4 | GPIO_Pin_5);
    						break;
    					case 'D':
    						//LED0 = 0;
    						LED1 = 0;
    						IN0=1;IN1=0;
    					  IN2=0; IN3=1;
    //						delay_ms(100);
    //						GPIO_ResetBits(GPIOF, GPIO_Pin_3 | GPIO_Pin_4);
    						break;
    					case 'E':
    						//LED0 = 0;
    						LED1 = 0;
    						IN0=0;IN1=1;
    					  IN2=1; IN3=0;
    //						delay_ms(100);
    //						GPIO_ResetBits(GPIOF, GPIO_Pin_3 | GPIO_Pin_4);
    						break;
    				}
    				
    			}
    			else 
    				delay_us(100);	   
    			
    		};	
    	}
    				else//TX模式
    	{							    
    		LCD_ShowString(30,150,200,16,16,"NRF24L01 TX_Mode");	
    		NRF24L01_TX_Mode();
    		while(1)
    		{	
    		adcx=Get_Adc_Average(ADC_Channel_7,20);//获取通道7的转换值,20次取平均
    		adcx1=Get_Adc_Average(ADC_Channel_5,10);//获取通道5的转换值,20次取平均
    		ADCX2=Get_Adc_Average1(ADC_Channel_11,10);//获取通道1的转换值,20次取平均
    		ADCX3=Get_Adc_Average1(ADC_Channel_13,10);//获取通道3的转换值,20次取平均
    			
    		temp=(float)adcx*(3.3/4096);          //获取计算后的带小数的实际电压值,比如3.1111
    		temp1=(float)adcx1*(3.3/4096);          //获取计算后的带小数的实际电压值,比如3.1111
    	  TEMP2=(float)ADCX2*(3.3/4096);          //获取计算后的带小数的实际电压值,比如3.1111
    		TEMP3=(float)ADCX3*(3.3/4096);          //获取计算后的带小数的实际电压值,比如3.1111
    			
    		adcx=temp;                            //赋值整数部分给adcx变量,因为adcx为u16整形
    		LCD_ShowxNum(134,50,adcx,1,16,0);    //显示电压值的整数部分,3.1111的话,这里就是显示3
    		temp-=adcx;                           //把已经显示的整数部分去掉,留下小数部分,比如3.1111-3=0.1111
    		temp*=1000;                           //小数部分乘以1000,例如:0.1111就转换为111.1,相当于保留三位小数。
    		
    		adcx1=temp1;                            //赋值整数部分给adcx变量,因为adcx为u16整形
    		LCD_ShowxNum(134,70,adcx1,1,16,0);    //显示电压值的整数部分,3.1111的话,这里就是显示3
    		temp1-=adcx1;                           //把已经显示的整数部分去掉,留下小数部分,比如3.1111-3=0.1111
    		temp1*=1000; 
    		
    		ADCX2=TEMP2;                            //赋值整数部分给adcx变量,因为adcx为u16整形
    		LCD_ShowxNum(134,90,ADCX2,1,16,0);    //显示电压值的整数部分,3.1111的话,这里就是显示3
    		TEMP2-=ADCX2;                           //把已经显示的整数部分去掉,留下小数部分,比如3.1111-3=0.1111
    		TEMP2*=1000; 
    		
    		ADCX3=TEMP3;                            //赋值整数部分给adcx变量,因为adcx为u16整形
    		LCD_ShowxNum(134,110,ADCX3,1,16,0);    //显示电压值的整数部分,3.1111的话,这里就是显示3
    		TEMP3-=ADCX3;                           //把已经显示的整数部分去掉,留下小数部分,比如3.1111-3=0.1111
    		TEMP3*=1000; 
    		
    		LCD_ShowxNum(150,50,temp,3,16,0X80); //显示小数部分(前面转换为了整形显示),这里显示的就是111.
    		LCD_ShowxNum(150,70,temp1,3,16,0X80); //显示小数部分(前面转换为了整形显示),这里显示的就是111.
    		LCD_ShowxNum(150,90,TEMP2,3,16,0X80); //显示小数部分(前面转换为了整形显示),这里显示的就是111.
    		LCD_ShowxNum(150,110,TEMP3,3,16,0X80); //显示小数部分(前面转换为了整形显示),这里显示的就是111.
    
    		if(NRF24L01_TxPacket(tmp_buf)==TX_OK)
    			{
    				LCD_ShowString(30,170,239,32,16,"Sended DATA:");	
    				LCD_ShowString(0,190,lcddev.width-1,32,16,tmp_buf); 	
    	   	if(adcx1>=1&&adcx1<=2&&adcx>=1&&adcx<=2)
    		   {
    					LED0=1;
    					tmp_buf[0]='A';
    				  tmp_buf[31] = 0; 
    				}
    				else if(adcx1==0)
    				{
    						LED0=0;
    					tmp_buf[0]='B';
    				  tmp_buf[31] = 0; 
    				}
    				else if(adcx1>2)
    				{
    						LED0=0;
    					tmp_buf[0]='C';
    				  tmp_buf[31] = 0; 
    				}
    				else if(adcx==0)
    				{
    						LED0=0;
    					tmp_buf[0]='D';
    				  tmp_buf[31] = 0;
    				}
    				else if(adcx>2)
    				{
    					LED0=0;
    					tmp_buf[0]='E';
    				  tmp_buf[31] = 0;
    				}
    				else
    				{
    					LED0=1;
    				}
    			}
    
    //			if(key)
    //			{						   
    //				switch(key)
    //				{				 
    //					case WKUP_PRES:	//?????
    //						mode='A';//??????  
    //						LED0=!LED0;
    //						break;
    //					case KEY0_PRES:	//??LED0??
    //						mode='D';//??????  
    //						LED0=!LED0;
    //						break;
    //					case KEY1_PRES:	//??LED1??
    //						mode='C';//??????  						
    //						LED1=!LED1;
    //						break;
    //					case KEY2_PRES:	//????LED0,LED1??
    //						mode='B';//??????  
    //						LED0=!LED0;
    //						LED1=!LED1;
    //						break;
    //				}
    //			}
    				else
    				{										   	
    					LCD_Fill(0,170,lcddev.width,170+16*3,WHITE);//????			   
    					LCD_ShowString(30,170,lcddev.width-1,32,16,"Send Failed "); 
    				}			
    	}
    	}     
    }
    
    展开全文
  • 数据采集技术是信息科学的重要分支之一,数据采集也是从一个或个信号获取对象信息的过程。数据采集是工业控制等系统中的重要环节,通常采用一些功能相对独立的单片机系统来实现,作为测控系统不可缺少的部分,数据...

    1.引言

    近年来,数据采集及其应用受到了人们越来越广泛的关注,数据采集系统也有了迅速的发展,它可以广泛的应用于各种领域。

    数据采集技术是信息科学的重要分支之一,数据采集也是从一个或多个信号获取对象信息的过程。数据采集是工业控制等系统中的重要环节,通常采用一些功能相对独立的单片机系统来实现,作为测控系统不可缺少的部分,数据采集的性能特点直接影响到整个系统。

    电压的测量最为普遍性,研究设计并提高电压测量精度的方法及仪器具有十分重要的意义。在电压测量设计中,单片机作为控制器,是整个设计的核心。除此之外,设计中还必须有模数转换器(ADC)。ADC用于直接采集模拟电压并将模拟信号转换成数字信号,它直接影响着数据采集的精度和速度。

    2.系统概述

    本设计的微控制器采用STM32单片机。STM32系列单片机是基于ARM公司Cortex-M3内核设计的。它的时钟频率达到72MHz,是同类产品中性能较高的产品,具有高性能、低成本、低功耗的优点,是嵌入式应用设计中良好的选择。设计中的A/D转换器采用STM32内置ADC。STM32的ADC是一种12位逐次逼近型模拟数字转换器。

    它有多达18个通道,可测量16个外部和2个内部信号源。各通道的A/D转换可以单次、连续、扫描或间断模式执行。转换结果可以左对齐或右对齐方式存储在16位数据寄存器中。其输入时钟最大可达到14MHz。

    本设计可测量8通道电压值,测量范围为0-10V的电压,显示误差为±0.001V。LCD实时显示电压值和波形图,MicroSD卡对数据进行同步存储。系统原理框图如图1所示。

    图1 系统原理框图

    3.系统硬件设计

    本设计的硬件主要包括STM32模块,LCD模块,SD卡模块和按键模块。STM32模块不仅作为核心控制器,还包括ADC设备,它主要包括STM32最小系统电路。LCD模块主要包括LCD驱动接口电路。SD卡模块主要是SD卡驱动电路。除此之外,还有用于程序下载调试的J-Link接口电路和电源电路等。

    3.1、STM32最小系统

    本模块主要介绍STM32芯片和设计中用到的外设模块。

    STM32最小系统使用外部高速时钟,外接8M晶振。STM32的两个BOOT引脚都接低电平,以使用户闪存存储器为程序启动区域。芯片采用J-Link下载模式,也可以进行硬件调试。STM32的电源引脚都接了滤波电容以确保单片机电源的稳定。

    STM32F103VET6拥有3个ADC,这些ADC可以独立使用,也可以使用双重模式(提高采样率)。STM32的ADC是12位逐次逼近型的模拟数字转换器。它有18个通道可测量16个外部和2个内部信号源。各通道的A/D转换可以单次、连续、扫描或间断模式执行。在程序正常执行的时候,中断是可以打断程序正常执行的。同这个类似,注入通道的转换可以打断规则通道的转换,在注入通道被转换完成之后,规则通道才得以继续转换。

    本设计中ADC采集的数据使用DMA进行传输,以达到高速实时的目的。

    3.2、ADC控制电路

    STM32的数字/模拟转换模块(DAC)是12位数字输入,电压输出的数字/模拟转换器。本设计中使用DAC来控制ADC匹配电路的增益。在打开DAC模块电源和配置好DAC所需GPIO的基础上,往DAC通道的数据DAC_DHRx寄存器写入数据,如果没有选中硬件触发,存入寄存器DAC_DHRx的数据会在一个APB1时钟周期后自动传至寄存器DAC_DORx。一旦数据从DAC_DHRx寄存器装入DAC_DORx寄存器,在经过一定时间之后,输出即有效,这段时间的长短依电源电压和模拟输出负载的不同会有所变化。

    图2  ADC匹配电路图

    TM32的ADC前加入匹配电路。在ADC控制电路中,输入信号先经过射极电压跟随电路,然后经过分压电路,使输入信号满足AD603的输入要求。然后再经过射极电压跟随电路,输入ADC输入端。AD603的控制输入使用STM32的DAC,可以满足增益的要求。

    匹配电路以AD603为核心.AD603为单通道、低噪声、增益变化范围线性连续可调的可控增益放大器。带宽90MHz时,其增益变化范围为-10dB~+30dB;带宽为9M时范围为10~50dB。

    将VOUT与FDBK短路,即为宽频带模式(90MHz宽频带),AD603的增益设置为-11.07dB~+31.07dB。AD603的5、7脚相连,单片AD603的可调范围为-10dB~30dB。AD603的增益与控制电压成线性关系,其增益控制端输入电压范围为±500mv,增益调节范围为40dB,当步进5dB时,控制端电压需增大:

    ADC匹配电路的电路图如图2所示。

    3.3、LCD控制电路

    本设计所使用的LCD为2.4寸,320&mes;240分辨率。LCD模块使用STM32的FSMC接口控制。FSMC(FlexibleStacMemoryController)即可变静态存储控制器,是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将被看作一个拥有一块地址空间的存储器进行操作。

    3.4、SD卡驱动电路

    本设计中使用的SD卡为MicroSD,也称TF卡。MicroSD卡是一种极细小的快闪存储器卡,主要应用于移动电话,但因它的体积微小和储存容量的不断提升,现在已经使用于GPS设备、便携式音乐播放器、数码相机和一些快闪存储器盘中。MicroSD卡引脚图如图9所示。

    MicroSD卡与SD卡一样,有SPI和SDIO两种操作时总线。SPI总线相对于SDIO总线接口简单,但速度较慢。我们使用SDIO模式。

    展开全文
  • 稍微复杂一点的产品,往往需要多路模拟量采集,今天晓宇姐姐结合实际案例,跟大家一起分享一个我经常用的方案之一,通过定时器自动触发多路ADC进行电压电流的采集,并通过DMA传送数据到内存,在需要的时候,去内..

    在我们的电子设计中,经常需要对外部的模拟量进行采集,如一些传感器的输出量,电位器的旋转量等等,特别是电压电流的采集可以说是家常便饭,这些都离不开MCU最常用的外设,ADC,它可以将模拟量转换为数字量,量化后给MCU进行处理,稍微复杂一点的产品,往往需要多路模拟量采集,今天晓宇姐姐结合实际案例,跟大家一起分享一个我经常用的方案之一,通过定时器自动触发多路ADC进行电压电流的采集,并通过DMA传送数据到内存,在需要的时候,去内存读取数据并进行处理即可,小伙伴们,搞起来吧!

    本次我们采集3路AD信号,一路电压,一路电流,还有一个电位器,方便观察数据。

    硬件电路分析

    图1:AD多路采集

    1、首先来看电压采集跟电位器(模拟传感器信号)的采集,24V的电源电压需要分压,这两个电压都足够高,所以直接送到MCU的AD引脚即可,这里记得要并一个100nF的电容,作用是存储电荷的,ADC在快速充放电的时候,这个电容可以起到补给的作用,另外也有滤波的作用,所以这个一定要加。

    2、电流的采集,这里用了一个经典的差分放大电路,放大原理就不细说了,大概就是经过运放的虚短,虚断等特性,这里方便计算,一般取R4+R5=R8+R9,R6=R10,最终的传递函数位Vout=(CURR_I - GND)* R6/(R4+R5),这里的放大倍数为10倍。

    一般情况下,在将运算放大器的输入端连接到放大器,使用“反相”或“非反相”输入端放大单个输入信号,而另一个输入端接地,也是可以的,只是只能放大一个电平,这里用差分电路展示,上图的反向输入可以接其它电压,有时候我们需要放大的电压两端电势没有一个接地的,比如我们在母线电压输入端串联一个小电阻,分别将电阻两边的电压送到差分放大器,就可以实现母线电流的采集了。

    软件分析

    这里以STM32F051来举例说明,STM32F051包含一个分辨率为12位的ADC模块,所以采样精度能达到Vref/4096,同时具有19个ADC通道,其中16个外部采样通道和3个内部信号源。

    我们一般需要配置引脚,分辨率,数据对齐,触发方式,采样方式,扫描方式等等,这里有一个规则通道跟注入通道之分,注入就是可以插队的意思,有一些时序精度要求很高的场合会用,一般场合用规则通道即可。

    关于通道组,这里有一个点需要注意的是,一个通道组转换完才会进入中断,并不是单个通道,又因为MCU内部只有一个ADC_DR,所以有部分同学在开始配置多通道后发现采集的数据都不对,其实我们这样记就行了,如果是只采样一个通道,分单次转换模式跟连续转换模式(重复启动ADC),如果是规则多通道的采集,我们必须要使用扫描模式,而且,这里一定要开启DMA功能,DMA会在每个通道转换完之后,自动的把结果传到内存中。

    图2:DMA简易示图

    关于DMA,大家应该都有过了解了,DMA控制器依赖于处理器内核,但DMA不影响总线传输,因为DMA控制器总是在系统总线空闲的时候使用总线。该总线实现处理器和DMA控制器之间最优化设计,使两者之间的冲突降到最低,因此传输性能得到提高。如上图所示,我们配置完DMA之后,每次数据采集完毕,DMA会自动的帮MCU把数据运送到我们指定的内存空间,这个搬运不依赖于CPU时钟,所以也算是实现了并行操作,相比在主程序中开启采集,我们的MCU可以有更多的时间去计算运行别的东西。

    关于触发,我们可以选择手动触发一次ADC采集,也可以通过定时器的中断去触发这里强调一点,如果只是利用定时器的更新事件去触发ADC,我们也没必要开启更新中断,定时器会源源不断的产生更新事件。如果选择开启,可以在中断中执行一些操作,例如通过某些参数变化情况去改变AD采集的间隔时间。

    我们采集3个通道的值,分别是通道4(VOL_AD)、通道11(CURR_O)、通道14(POT_AD)

    下面上代码:

    1、ADC IO 配置,配置为模拟输入

    GPIO_InitTypeDef GPIO_InitStructure;
    DMA_InitTypeDef DMA_InitStructure;
    ADC_InitTypeDef ADC_InitStructure; 
    NVIC_InitTypeDef NVIC_InitStructure; 
    ​
    /*-------ADC GPIO配置---------*/
    GPIO_InitStructure.GPIO_Pin  = CURR_O | POT_AD;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; //模拟输入
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOC, &GPIO_InitStructure); 
    GPIO_InitStructure.GPIO_Pin = VOL_AD;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    2、DMA配置,配置3个通道,所以内存中定义一个结构体存储DMA搬运过来的值

    adc_sample_t adc_data;
    ​
    DMA_InitTypeDef DMA_InitStructure;
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);  //DMA时钟开启
    ​
    /*-------DMA配置AD采集---------*/
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;//外设基地,DMA搬运数据的地址 
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&adc_data;//内存基地址,DMA搬运数据放到内存的地址
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;//外设到内存,源是外设
    DMA_InitStructure.DMA_BufferSize = 3;//3个通道
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设地址不变,不自增
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//不同通道的数据,内存要自增
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//外设数据16位
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//内存数据16位
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;//DMA循环模式
    DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;//DMA优先级为中
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;//内存到内存失能   
    DMA_Init(DMA1_Channel1,&DMA_InitStructure);
    ​
    /*--------------DMA中断配置-----------------*/
    NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);   
    DMA_ClearFlag(DMA1_FLAG_TC1);//清除传送完成中断标志
    DMA_ITConfig(DMA1_Channel1,DMA_IT_TC,DISABLE);//中断先不打开
    DMA_Cmd(DMA1_Channel1,ENABLE);

    3、ADC配置,配置各项参数

    /*-------ADC配置,用于采样电流,电压,电位器---------*/
    ADC_JitterCmd(ADC1,ADC_JitterOff_PCLKDiv4,ENABLE);//移除时钟为PCLKDiv4时在触发到启动转换延迟中产生的抖动
    RCC_ADCCLKConfig(RCC_ADCCLK_PCLK_Div4);//ADC时钟为PLCK的4分频。也就是12MHz       
    ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;//ADC的位数。这里选择12位
    ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//连续转换模式禁能
    ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Falling;//触发沿为下降沿触发   
    ADC_InitStructure.ADC_ExternalTrigConv =  ADC_ExternalTrigConv_T1_CC4;//ADC的触发源为定时器1的第四通道
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//数据对齐为右对齐
    ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Upward;//通道的扫描方向,由小到大扫描
    ADC_Init(ADC1, &ADC_InitStructure);
    /*-------ADC通道及采样时间配置---------*/    
    ADC_ChannelConfig(ADC1,Vbus_VOLTAGE_CHANNEL, ADC_SampleTime_7_5Cycles);
    ADC_ChannelConfig(ADC1,Bridge_CURRENT_CHANNEL, ADC_SampleTime_7_5Cycles);
    ADC_ChannelConfig(ADC1,ELE_GUN_CHANNEL, ADC_SampleTime_7_5Cycles); 
    /*-------使用ADC前需要先校准---------*/
    ADC_GetCalibrationFactor(ADC1);
    ADC_Cmd(ADC1, ENABLE);
    /*-------------等待ADC准备好--------------*/
    while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADRDY));
    /*-------------使能ADC的DMA传输功能--------------*/
    ADC_DMACmd(ADC1,ENABLE);
    /*-------------ADC的DMA模式配置--------------*/
    ADC_DMARequestModeConfig(ADC1,ADC_DMAMode_Circular);    
    ADC_StartOfConversion(ADC1);//开始转换

    4、定时器配置,这里只开启通道4的下降沿触发ADC执行一次采集,想要更改采集的时间间隔更改通道4的占空比TIM1->CCR4即可。

    /*------------------结构体变量---------------------*/
    GPIO_InitTypeDef GPIO_InitStructure;
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    TIM_OCInitTypeDef  TIM_OCInitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
    /*------------定时器时钟开启---------------------*/
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);   
    /*-------PWM GPIO配置---------*/
    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_11;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOA, &GPIO_InitStructure); 
    /*---------PWM复用引脚---------*/  
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource11, GPIO_AF_2); 
    /*-------PWM时基配置---------*/
    TIM_TimeBaseStructure.TIM_Prescaler= 0;
    TIM_TimeBaseStructure.TIM_CounterMode= TIM_CounterMode_Up;  
    TIM_TimeBaseStructure.TIM_Period= 3199;//频率为15K,TIM1_Period = (SystemCoreClock / Frequnecy) - 1                       
    TIM_TimeBaseStructure.TIM_ClockDivision= 0;
    TIM_TimeBaseStructure.TIM_RepetitionCounter= 0;
    TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);    
    /*-------PWM配置---------*/
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;//PWM模式一
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//输出使能,可以在通道4引脚看到占空比波形    
    TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;//互补通道输出禁能
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;//有效电平为高      
    TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;//互补通道有效电平为高 
    TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;//空闲时输出高      
    TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Set;//互补通道空闲时输出高
    ​
    /*---------初始化触发AD采样的时间---------*/    
    TIM_OCInitStructure.TIM_Pulse = 100; //占空比
    TIM_OC4Init(TIM1, &TIM_OCInitStructure);
    /*------------通道4触发中断使能---------------*/    
    TIM_ITConfig(TIM1,TIM_IT_CC4,ENABLE);                              
    NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn;          
    NVIC_InitStructure.NVIC_IRQChannelPriority = 2;                
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                  
    NVIC_Init(&NVIC_InitStructure);    
    ​
    /*--------初始化先关闭定时器------------*/    
    TIM_Cmd(TIM1,DISABLE);
    /*--------使能PWM输出------------*/
    TIM_CtrlPWMOutputs(TIM1,ENABLE); 

    5、DMA中断,AD采集完一组数据,进入DMA中断

    void DMA1_Channel1_IRQHandler(void)
    {
        uint32_t adc_value;
        adc_value= adc_data.vol;
        Flag.voltage = adc_value;//电压值
        adc_value= adc_data.curr_o;
        Flag.current = adc_value;//电流值
        adc_value= adc_data.pot;
        Flag.pot = adc_value;//电位器值
        DMA_ClearFlag(DMA1_FLAG_TC1);
    }

    6、定时器中断,可以不加,这里展示一下

    void TIM1_CC_IRQHandler(void)
    {
        if(TIM_GetITStatus(TIM1, TIM_IT_CC4) != RESET)
        {
            TIM_ClearITPendingBit(TIM1, TIM_IT_CC4);
            TIM1->CCR4 = 500; //这里可以更改ADC的采集间隔
        }   
    }

    7、头文件

    #ifndef __ADC_H
    #define  __ADC_H
    ​
    #include "stm32f0xx.h"
    ​
    /*-----------ADC宏定义---------------*/
    #define ADC_POARTC      GPIOC
    #define CURR_O         GPIO_Pin_1      
    #define POT_AD         GPIO_Pin_4      
    ​
    #define ADC_POARTA      GPIOA
    #define VOL_AD          GPIO_Pin_4      
    ​
    #define CURR_O_CHANNEL ADC_Channel_11
    #define POT_CHANNEL    ADC_Channel_14
    #define VOL_CHANNEL    ADC_Channel_4
    ​
    /*---------结构体定义-----------*/
    typedef struct 
    {
        uint16_t vol; 
        uint16_t curr_o;
        uint16_t pot;    
    }adc_sample_t;
    ​
    extern adc_sample_t adc_data;
    void ADC_DMA_Init(void);
    ​
    #endif /* __ADC_H */

    8、主程序中,全部初始化并且开启后,只需要从内存中读取三个值就可以了,想要更改采样的间隔时间就更改定时器1中通道4的占空比值。

    /*
     * main.c
     *
     *      Created on: 20171229  
     *      @Author: 
     *      @version V1.0.0 
     *                        ,%%%%%%%%,
     *                      ,%%/\%%%%/\%%
     *                     ,%%%\c''''J/%%%
     *           %.        %%%%/ o  o \%%%
     *           `%%.      %%%%       |%%%
     *            `%%      `%%%%(__Y__)%%'
     *            //        ;%%%%`\-/%%%'
     *            ((      /   `%%%%%%%'
     *             \\     .'           |
     *              \\   /        \  | |
     *               \\/          ) | |
     *                \          /_ | |__
     *                (____________))))))) ¹¥³Çʨ
     *
     */
     
    float voltage, current;
     
    int main(void)
    {   
        //一系列初始化后
        //..... 
        //DMA中断使能
        DMA_ITConfig(DMA1_Channel1,DMA_IT_TC,ENABLE);   
        //定时器1使能
        TIM_Cmd(TIM1,ENABLE);
        printf("HELLO ADC\r\n");
        while (1)
        {
            voltage = Flag.voltage / 112.84f;  // (Flag.voltage*3.3*51.7)/(4096*4.7)
            current = Flag.current / 4965;  //Flag.motor_current*((3.3/4096)/10)/0.4
            pot = Flag.pot / 1241; //Flag.pot*3.3/4096
            
            //数据处理
            //...
        }
    }

    到这里,我们在配置好之后,基本上就不用管了,需要的时候就读取内存中数据的值就可以了,一切基本都是自动完成的,我们的主程序可以干更重要的事情。关于数据,这里只是展示一下,计算出的都是单次采集一组的值,大家可以根据自己的实际场景进行一些算法处理,如平均值采样法、递推平均值采样法等等,这里由于篇幅问题这里就不一一展开说了,关于ADC其实还有很多学问,下次再跟大家分享!

    关于电子软硬件的学习,希望大家Enjoy!码字不易,喜欢点赞转发,您的支持就是我继续创作的最佳动力!

    芯片之家

    芯片之家提供超过45万个Symbol和封装库免费下载,支持多种EDA格式。网站另有大量参考设计和文档资源下载,电路图和源代码资料齐全,欢迎学习交流!

    展开全文
  • 作者:晓宇,排版:晓宇微信公众号:芯片之家(ID:chiphome-dy)在我们的电子设计中,经常需要对外部的模拟量进行采集,如一些传感器的输出量,电位器的旋转量等等,特别是电压电流的采集...

    e94be9b2c8ae093139be9aa9932c832d.png

    作者:晓宇,排版:晓宇

    微信公众号:芯片之家(ID:chiphome-dy)

    在我们的电子设计中,经常需要对外部的模拟量进行采集,如一些传感器的输出量,电位器的旋转量等等,特别是电压电流的采集可以说是家常便饭,这些都离不开MCU最常用的外设,ADC,它可以将模拟量转换为数字量,量化后给MCU进行处理,稍微复杂一点的产品,往往需要多路模拟量采集,今天晓宇姐姐结合实际案例,跟大家一起分享一个我经常用的方案之一,通过定时器自动触发多路ADC进行电压电流的采集,并通过DMA传送数据到内存,在需要的时候,去内存读取数据并进行处理即可,小伙伴们,搞起来吧!

    328e00461a7d2f99aa98186b8ba8311a.png

    本次我们采集3路AD信号,一路电压,一路电流,还有一个电位器,

    展开全文
  • Arduino ESP32 多路DS18B20温度采样读取 DS18B20温度传感器使用单线协议进行通信,每个传感器都有一个独特的64位串行代码,因此您可以使用单个GPIO从多个传感器读取温度。 实例代码 #include <OneWire.h>...
  • 【实例简介】51单片机驱动ADC0809(8)多路采集电压 【实例截图】 文件:590m.com/f/25127180-494509143-9a31a3(访问密码:551685) 【核心代码】 uchar ADC_GET(uchar temp_channel) { if(temp_channel==0) { ADC...
  • 1.2 ADC的供电及采样电压 二:实验步骤及代码 2.1实验步骤 2.2实验代码 2.2.1 ADC初始化代码 2.2.2 DMA初始化代码 2.2.3 main函数代码 2.2.4 验证步骤 三:一些注意事项(程序运行不成功可以往这找) ADC...
  • 问:ADI公司不给出ADG系列模拟开关和多路转换器的带宽,这是为什么?答:ADG系列模拟开关和多路转换器的输入带宽虽然高达数百兆赫,但是其带宽指标本身不是很有意义的。因为在高频情况下,关断隔离(offisolation)和...
  • EA3059 是四电源管理芯片,应用于直流5V供电或单节锂电池应用。内置四同步电源调整模块,提供轻载高效模式,内置补偿电路,简化客户设计。独立的使能控制设计可以提供灵活的上电时序。EA3059 使用24 脚 QFN 4mm ...
  • 仿真可以实现四个量程的切换(2V、20V、200V、500V),并模拟实现直流电压的测量与显示。
  • 在使用STC8时需要采集多路电压值,使用LCD1602显示。但是STC8单片机内部只有10和12位精度的ADC,采集毫伏级电压就不够精确。这时可采用外挂高精度ADC实现。常见的有ADS1115、ADS1256、MCP3421以及国产的TM7705等。...
  • 多路温度采集及监控系统的设计与实现.pdf多路温度采集及监控系统的设计与实现 一2l一●应用与设计多路温度采集及监控系统的设计与实现郝迎吉,张明,王洪波(西安科技大学机械工程学院,陕西西安7100541摘要:介绍一...
  • 本设计采用AT89C51单片机,ADC0809进行模/数转换,能够测量80~5V的输入电压值,可用四位LED数码管轮流或单路显示测量结果。其最小分辨率约为0.019V,测量误差小于0.02V。一、系统简介本系统分为主控电路、显示...
  • 2总体方案设计 多路巡回数据采集仪设计需要将模拟量转换为数字量,而 A/D是将模拟量转换为数字量的器件,STM32单片机是该系统的基本的微处理系统,它完成数据读取、处理及逻辑控制、数据传输、数据转换等一系列的...
  • 基于单片机的多路数据采集系统设计(包含源程序及原理图)中北大学信息商务学院本科生毕业论文基于单片机的多路数据采集系统设计The Design Of Multi-channel Data Acquisition System Based On SCM摘要本文介绍了基于...
  • 第1章 绪论1.1系统的开发背景在电量的测量中,电压、电流和频率是最基本的三个被测量,其中电压量的测量最为经常。而且随着电子技术的发展,更是经常需要测量高精度的电压,所以数字电压表就成为一种必不可少的测量...
  • 简易数字直流电压表电路及程序设计一个简易数字直流电压表。(量程0V-2V、测量速度为大于等于2次/秒、测量误差在±0.05V以内,有超限报警、数码管显示。)3.5.1模块1:系统设计(1)分析任务要求,写出系统整体设计思路...
  • 模拟多路开关-MOSFET全解1. 漏电流 漏电流:通过断开的模拟开关的电流,用IS表示。 3.3.4 多路开关的电路特性 在n个模拟开关的并联组合中,当一个开关导通时,其它n-1个开关是断开的,未导通开关的漏电流将通过导通...
  • 多路温度采集

    2021-06-23 01:25:57
    根据工业现场的应用需求,多路温度采集主要测量热电偶、热电阻以及温度变送器输出的电压、电流信号,信号经滤波、放大、AD转换后,将采集数据送入单片机进行分析处理,单片机执行相应控制操作,将采集结果存于外...
  • 一种具有分散作用(任务)功能的CPU。与人类相比,大脑就是CPU,PIC 共享的部分相当于人的神经系统。PIC 单片机是一个小的计算机。PIC单片机有计算功能和记忆内存像CPU并由软件控制运行。然而,处理能力—般,存储器...
  • 1.采集电压:0-5V。 2.精度:10mV。 3.LCD1602显示 4.能实时保存要求时间内的数据,并查看。 电路原理图: 完整代码: #include<reg52.h> #define uchar unsigned char #define uint unsigned...
  • 第第 PAGE 1 页 共 NUMPAGES 18 页课 程 设 计设计名称 数字电压表的设计 .全套设计加扣?3012250582学年学期 2014-2015(上)课程名称 单片机课程设计专业年级 电气112班姓 名学 号 1提交日期 2014年6月7日成 绩...
  • 在对实际应用过程中,ADC的采集大多是个通道同时采集的,比如同时采集个传感器的数据,就可能需要我们配置个通道的ADC采集了,而通道的ADC采集大多用到了DMA,笼统的讲通过DMA来传输数据不经过CPU,可以有效...
  • 而 MCU 在 2V 基本就可以工作了,此时的 ADC 的基准电压也在 2V(使用的基准电压芯片只能保证在 2.5V ~ 3.3V 内是准确的),这就造成了 ADC 在这段时间内工作采样数据不准确。问题就是想搞明白此时基准电压低了,...
  • 数字电压表控制C语言程序#include sbit OE=P3^0; //ADC0808的OE端sbit EOC=P3^1; //ADC0808的EOC端sbit CLOCK=P2^6;sbit ST=P3^2; //ADC0808的START和ALE端sbit LED4=P2^3;sbit LED3=P2^2;sbit LED2=P...
  • 课程设计报告(嵌入式接口技术)题 目:基于ARM的多路数据采集系统设计摘 要数据采集系统用于将模拟信号转换为计算机可以识别的数字信号.该系统目的是便于对某些物理量进行监视.数据采集系统的好坏取决于他的精度和...
  • 摘要近些年来,数字电压表逐渐进入人们的视线中,它主要采取数字化测量技术。与传统的指针式仪表相比,它的功能有了进一步的完善,并且精度也有了很大的提高。数字电压表主要采用单片机和模/数转换模块,这样不仅...
  • 针对采集精度低、主控芯片资源占用大,采集速度慢等问题设计了一种多路数据采集系统。系统采用AT89S52单片机为核心,四路24位A/D负责数据采集任务。系统可根据不同的需要对这些数字量进行相应的计算和处理,得到所...
  • verilog练习一:二选一多路
  • 51单片机 多路超声波测距和报警 +Proteus仿真 Proteus仿真 Proteus仿真电路搭建注意事项 蜂鸣器采用的是有源蜂鸣器,选择DC直流驱动的蜂鸣器,供电电压选择5V,默认调用出来的是12V,需要修改。 元器件列表 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 28,714
精华内容 11,485
关键字:

多路电压

友情链接: czmccpuuo.rar