0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

STM32F103雙重ADC同步規(guī)則模式采集實驗

王琪 ? 來源:pgph ? 作者:pgph ? 2022-02-24 10:47 ? 次閱讀

雙重 ADC 同步規(guī)則模式采集實驗與多路LCD 波形示波器制作顯示,本文展示了STM32 AD 雙重 ADC 同步規(guī)則模式采集實驗。

內(nèi)容涉及 :

STM32 AD 雙重 ADC 同步規(guī)則

AD多通道DMA采集與存儲調(diào)用

AD采樣點的構(gòu)造體封裝

AD 的處理以及 LCD波形輸出 模仿示波器的原理

LCD觸摸畫板的控制

SRAM 內(nèi)存擴(kuò)展管理

FatFs 文件系統(tǒng)移植

SPI函數(shù)移植過程

SPI字節(jié)數(shù)據(jù)模擬輸出獨(dú)寫 緩存讀寫

USART串口的識別

IO口輸入輸出

按鍵的外部中斷處理

32位數(shù)據(jù)通訊,字符串通訊,單字符通訊

一:編程要點

初始 ADC 用到的 GPIO;

初始化 ADC GPIO;

初始化 DMA 配置;

初始化 ADC 參數(shù);

讀取 ADC 采集的數(shù)據(jù),并打印出來校正;

設(shè)置 ADC 的工作參數(shù)并初始化;

設(shè)置 ADC 工作時鐘;

設(shè)置 ADC 轉(zhuǎn)換通道順序及采樣時間;

配置 DMA 工作參數(shù);;

使能 ADC 7) 讀取 ADC 采集的數(shù)據(jù)。

同步規(guī)則模式是 ADC1 和 ADC2 同時轉(zhuǎn)換一個規(guī)則通道組,ADC1 是主,ADC2 是從。

ADC1 轉(zhuǎn)換的結(jié)果放在 ADC1_DR 的低 16位,ADC2 轉(zhuǎn)換的結(jié)果放在 ADC1_DR 的高十六位。

并且必須開啟 DMA 功能。外部觸發(fā)來自 ADC1 的規(guī)則組多路開關(guān)(由 ADC1_CR2 寄存器的 EXTSEL[2:0]選擇)。

它同時給 ADC2 提供同步觸發(fā)。為了簡單起見,ADC1 我們選擇軟件觸發(fā),ADC2 必須選擇外部觸發(fā)。

這個外部觸發(fā)來自于 ADC1 的規(guī)則組多路開關(guān)。

二:ADC 的工作具體如下

AD轉(zhuǎn)換包括采樣階段和轉(zhuǎn)換階段,在采樣階段才對通道數(shù)據(jù)進(jìn)行采集;

而在轉(zhuǎn)換階段只是將采集到的數(shù)據(jù)進(jìn)行轉(zhuǎn)換為數(shù)字量輸出,此刻通道數(shù)據(jù)變化不會改變轉(zhuǎn)換結(jié)果。

獨(dú)立模式的 ADC 采集需要在一個通道采集并且轉(zhuǎn)換完成后才會進(jìn)行下一個通道的采集。

而雙重 ADC 的機(jī)制就是使用兩個 ADC 同時采樣一個或者多個通道。

雙重 ADC 模式較獨(dú)立模式一個最大的優(yōu)勢就是提高了采樣率,彌補(bǔ)了單個 ADC 采樣不夠快的缺點。

啟用雙 ADC模式的時候,通過配置 ADC_CR1寄存器的 DUALMOD[3:0]位,可以有幾種不同的模式,具體見表格 31-1

模式 簡要說明
同步注入模式 ADC1和ADC2同時轉(zhuǎn)換一個注入通道組,其中ADC1為主,ADC2為從。轉(zhuǎn)換的數(shù)據(jù)存儲在每個 ADC 接口的 ADC_JDRx 寄存器中。
同步規(guī)則模式 ADC1 和 ADC2 同時轉(zhuǎn)換一個規(guī)則通道組,其中 ADC1 為主,ADC2 為從。
ADC1 轉(zhuǎn)換的結(jié)果放在 ADC1_DR 的低 16 位,ADC2 轉(zhuǎn)換的結(jié)果放在 ADC1_DR 的高十六位。
快速交叉模式 ADC1 和 ADC2 交替采集一個規(guī)則通道組(通常為一個通道)。當(dāng)ADC2 觸發(fā)之后,ADC1 需要等待 7 個 ADCCLK 之后才能觸發(fā)。
慢速交叉模式 ADC1 和 ADC2 交替采集一個規(guī)則通道組(只能為一個通道)。當(dāng)ADC2 觸發(fā)之后,ADC1 需要等待 14 個 ADCCLK 之后才能觸發(fā)。

三:代碼分析

1:ADC_book.h

#ifndef      __ADC_BOOK_H
#define	     __ADC_BOOK_H
#include "stm32f10x.h"

// ADC GPIO宏定義
// 注意:用作ADC采集的IO必須沒有復(fù)用,否則采集電壓會有影響// ADC 編號選擇
// 可以是 ADC1/2,如果使用ADC3,中斷相關(guān)的要改成ADC3的
#define    ADC_GPIO_APBxClock_FUN        RCC_APB2PeriphClockCmd
#define    ADC_GPIO_CLK                  RCC_APB2Periph_GPIOC  
#define    ADC_PORT                      GPIOC

// ADC 編號選擇
// 可以是 ADC1/2,如果使用ADC3,中斷相關(guān)的要改成ADC3的
#define   ADC_APBxClock_FUN             RCC_APB2PeriphClockCmd
#define   ADC_X                         ADC1 //ADC2
#define   ADC_Y                         ADC2 //ADC2
#define   ADC_CLKX                      RCC_APB2Periph_ADC1
#define   ADC_CLKY                      RCC_APB2Periph_ADC2

//-------------------------------- ADC DMA 配置 ------------------------
         
 // ADC1 對應(yīng) DMA1 通道 1,ADC3 對應(yīng) DMA2 通道 5,ADC2 沒有 DMA 功能
#define 	ADC_DMA_CLK  									  RCC_AHBPeriph_DMA1
#define 	ADC_DMA_CHANEL 									DMA1_Channel1
#endif    

//ADC   中斷相關(guān)宏定義
#define    ADC_IRQ                       ADC1_2_IRQn
#define    ADC_IRQHandler                ADC1_2_IRQHandler

//-------------------------------- ADC配置 ------------------------------
 
// 雙通道ADC同步設(shè)計
#define  	 __ADC_RegSimult_Mode__ 						//使能標(biāo)志位
#ifdef    __ADC_RegSimult_Mode__ 
#define    NOFCHANEL										 2  //轉(zhuǎn)換通道的個數(shù)
#define    _DMA_BufferSize               1
 
  	#define    ADC_PIN1                      GPIO_Pin_1
	#define    ADC_CHANNEL1                  ADC_Channel_11
	#define    ADC_PIN4                      GPIO_Pin_4
	#define    ADC_CHANNEL4                  ADC_Channel_14

#endif 

 
typedef union {
  struct{
    unsigned char BIT0:1;unsigned char BIT1:1;unsigned char BIT2:1;unsigned char BIT3:1;
    unsigned char BIT4:1;unsigned char BIT5:1;unsigned char BIT6:1;unsigned char BIT7:1;
    //unsigned char BIT8:1;unsigned char BIT9:1;unsigned char BIT10:1;unsigned char BIT11:1;
    //unsigned char BIT12:1;unsigned char BIT13:1;unsigned char BIT14:1;unsigned char BIT15:1;
  }DATA_BIT;
  uint8_t DATA_BYTE;
}Per_adc_type;

extern volatile  Per_adc_type  adc_flag;
  #define badc_10ms         adc_flag.DATA_BIT.BIT0
 
extern volatile  uint32_t   Count_Adc_flag;


//----------- 雙通道ADC同步設(shè)計-------	
#ifdef  	 __ADC_RegSimult_Mode__
	extern volatile  uint32_t   ADC_RegSimult_ConvertedValue[NOFCHANEL];
	extern volatile  float 			ADC_RegSimult_ConvertedValueLocal[NOFCHANEL];
#endif

void ADCx_Init(void);
void ADC_get_value(void);

#endif 

2:ADC_book.c

使用到 GPIO 時候都必須開啟對應(yīng)的 GPIO 時鐘,GPIO 用于 AD 轉(zhuǎn)換功能必須配置為模擬輸入模式。

ADCx_Mode_Config()與獨(dú)立模式多通道配置基本一樣,只是有幾點需要注意:
ADC 工作模式要設(shè)置為同步規(guī)則模式;兩個 ADC 的通道的采樣時間需要一致;
ADC1設(shè)置為軟件觸發(fā);ADC2 設(shè)置為外部觸發(fā)。其他的基本一樣,看代碼注釋理解即可。

#include "ADC_book.h"
#include "XPT2046_LCD_GridDiagram_book.h"

volatile  Per_adc_type  adc_flag;		  
volatile  uint32_t 			Count_Adc_flag;

#ifdef  	 __ADC_RegSimult_Mode__ 
__IO 		uint32_t 		ADC_RegSimult_ConvertedValue[NOFCHANEL]={0,0};
__IO 		uint32_t 		ADC_RegSimult_ConvertedValue_Show[NOFCHANEL]={0,0};
__IO 		float 		  ADC_RegSimult_ConvertedValueLocal[NOFCHANEL];
#endif


/**
  * @brief  ADC GPIO 初始化函數(shù)
  * @param  無
  * @retval 無
  */
static void ADCx_GPIO_Config(void){
	GPIO_InitTypeDef GPIO_InitStructure;
	// 打開ADC IO 端口時鐘
	ADC_GPIO_APBxClock_FUN (ADC_GPIO_CLK , ENABLE); 
	//配置 ADC IO 端口的模式   
	//-----------雙通道ADC同步設(shè)計-------------
	#ifdef  	 __ADC_RegSimult_Mode__
	GPIO_InitStructure.GPIO_Pin = ADC_PIN1|
	ADC_PIN4; 
	#endif 
 
	// 必須為模擬輸入
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; 
	//初始化 ADDC_IO
	GPIO_Init(ADC_PORT , &GPIO_InitStructure );
	
}
	
/**
  * @brief  配置ADC DMA 工作模式
  * @param  
  * @retval 
  */
static void ADCx_DMA_Config(void){
  DMA_InitTypeDef  DMA_InitStructure; 
  //打開DMA時鐘
	RCC_AHBPeriphClockCmd(ADC_DMA_CLK , ENABLE);
	//復(fù)位DMA 控制器
  DMA_DeInit(ADC_DMA_CHANEL);
	//配置DMA初始化結(jié)構(gòu)體
  // 外設(shè)基址為:ADC 數(shù)據(jù)寄存器地址
	DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&(ADC_X->DR));
	
  // 存儲器地址,實際上就是一個內(nèi)部SRAM的變量
	#ifdef  	 __ADC_RegSimult_Mode__
	//----------- 雙通道ADC同步設(shè)計-------	
	DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADC_RegSimult_ConvertedValue;
	#endif 
  // 數(shù)據(jù)源來自外設(shè)
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
	// 緩沖區(qū)大小為1,緩沖區(qū)的大小應(yīng)該等于存儲器的大小 
  DMA_InitStructure.DMA_BufferSize = _DMA_BufferSize ;
	// 外設(shè)寄存器只有一個,地址不用遞增
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

  
	#ifdef  	 __ADC_RegSimult_Mode__
	// 外設(shè)數(shù)據(jù)大小為半字,即兩個字節(jié)
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
	// 存儲器數(shù)據(jù)大小也為半字,跟外設(shè)數(shù)據(jù)大小相同
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;																							 
	#else
	// 外設(shè)數(shù)據(jù)大小為半字,即兩個字節(jié)
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
	// 存儲器數(shù)據(jù)大小也為半字,跟外設(shè)數(shù)據(jù)大小相同
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
	#endif

	// 循環(huán)傳輸模式
	DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
	// DMA 傳輸通道優(yōu)先級為高,當(dāng)使用一個DMA通道時,優(yōu)先級設(shè)置不影響
	DMA_InitStructure.DMA_Priority = DMA_Priority_High;
	// 禁止存儲器到存儲器模式,因為是從外設(shè)到存儲器
	DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
	// 初始化DMA
	DMA_Init(ADC_DMA_CHANEL,&DMA_InitStructure);
	// 使能 DMA 通道
	DMA_Cmd(ADC_DMA_CHANEL , ENABLE);
}
	
/**
  * @brief  配置ADC 工作模式
  * @param  
  * @retval 
  */
static void ADCx_Mode_Config(void){
	ADC_InitTypeDef ADC_InitStructure;
  //----------- 雙通道ADC同步設(shè)計-------	
  #ifdef  	 __ADC_RegSimult_Mode__
	//打開ADC時鐘 
	ADC_APBxClock_FUN (ADC_CLKX , ENABLE);
	ADC_APBxClock_FUN (ADC_CLKY , ENABLE);
	#else
	ADC_APBxClock_FUN (ADC_CLKX , ENABLE);
  #endif 
  
	//--------ADC 模式配置  -----
	//----------- 雙通道ADC同步設(shè)計-------	
  #ifdef  	 __ADC_RegSimult_Mode__
  // 雙 ADC 的規(guī)則同步
  ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult;
  // 掃描模式
	ADC_InitStructure.ADC_ScanConvMode = ENABLE; 
  #endif
    
	//連續(xù)轉(zhuǎn)換模式
	ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
	// 不用外部觸發(fā)轉(zhuǎn)換 ,軟件開啟即可 
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
	//轉(zhuǎn)換結(jié)果右側(cè)對齊 
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;

  //----------- 雙通道ADC同步設(shè)計-------	
  #ifdef  	 __ADC_RegSimult_Mode__
	ADC_InitStructure.ADC_NbrOfChannel = NOFCHANEL/2; 
  //初始化ADC 
	ADC_Init(ADC_X , &ADC_InitStructure);
  ADC_Init(ADC_Y , &ADC_InitStructure);
	#endif
  
	//配置ADC時鐘為PCLCK2的8分頻 為9HZ
	RCC_ADCCLKConfig(RCC_PCLK2_Div8);
	//配置ADC轉(zhuǎn)換通道轉(zhuǎn)換順序和采樣時間
	
 
  //----------- 雙通道ADC同步設(shè)計-------	
  #ifdef  	 __ADC_RegSimult_Mode__
	ADC_RegularChannelConfig(ADC_X , ADC_CHANNEL1 , 1 , ADC_SampleTime_239Cycles5);
	ADC_RegularChannelConfig(ADC_Y , ADC_CHANNEL4 , 1 , ADC_SampleTime_239Cycles5);
	#endif
	//-----------AD通道采集------- 
  //-----------DMA模式----------
	#ifdef 	__ADC_DMA_Mode__   
		#ifdef  	 __ADC_RegSimult_Mode__
		// 只需要使能ADC1 DMA 請求
    //ADC1 我們選擇軟件觸發(fā),ADC2 必須選
		//擇外部觸發(fā),這個外部觸發(fā)來自于 ADC1 的規(guī)則組多路開關(guān)。
		ADC_DMACmd(ADC_X, ENABLE);
     /* 使能 ADCx_2 的外部觸發(fā)轉(zhuǎn)換 */
    ADC_ExternalTrigConvCmd(ADC_Y, ENABLE);
		#else
		// 使能ADC DMA 請求
		ADC_DMACmd(ADC_X, ENABLE);
		#endif 
	#else
	//ADC 轉(zhuǎn)換結(jié)束產(chǎn)生中斷,在中斷服務(wù)程序中讀取轉(zhuǎn)換值
	ADC_ITConfig(ADC_X , ADC_IT_EOC , ENABLE);
	// 使能ADC DMA 請求
	ADC_DMACmd(ADC_X, ENABLE);
	#endif 
	//-----------DMA模式----------
  
	/* ----------------ADC 校準(zhǔn)--------------------- */
  //----------- 雙通道ADC同步設(shè)計-------	
  #ifdef  	 __ADC_RegSimult_Mode__
	//開啟ADC 并開始轉(zhuǎn)換
	ADC_Cmd(ADC_X , ENABLE);
	// 初始化ADC 校準(zhǔn)寄存器 
	ADC_ResetCalibration(ADC_X);
	// 等待校準(zhǔn)寄存器初始化完成
	while(ADC_GetResetCalibrationStatus(ADC_X));
	//ADC_采集校準(zhǔn) 
	ADC_StartCalibration(ADC_X);
	//等待校準(zhǔn)完成
	while(ADC_GetCalibrationStatus(ADC_X));
  

   //開啟ADC 并開始轉(zhuǎn)換
	ADC_Cmd(ADC_Y , ENABLE);
	// 初始化ADC 校準(zhǔn)寄存器 
	ADC_ResetCalibration(ADC_Y);
	// 等待校準(zhǔn)寄存器初始化完成
	while(ADC_GetResetCalibrationStatus(ADC_Y));
	//ADC_采集校準(zhǔn) 
	ADC_StartCalibration(ADC_Y);
	//等待校準(zhǔn)完成
	while(ADC_GetCalibrationStatus(ADC_Y));
   
	//由于沒有采用外部觸發(fā) ,所以使用軟件ADC轉(zhuǎn)換
    //ADC 工作模式要設(shè)置為同步規(guī)則模式;兩個 ADC 的通道的采樣時間需要一致;
    //ADC1設(shè)置為軟件觸發(fā);ADC2 設(shè)置為外部觸發(fā) 
	ADC_SoftwareStartConvCmd(ADC_X , ENABLE);
  
	
}
 

static void ADC_NVIC_Config(void){
	NVIC_InitTypeDef  NVIC_InitStructure;
	//優(yōu)先級分組
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
	//配置中斷優(yōu)先級
	NVIC_InitStructure.NVIC_IRQChannel = ADC_IRQ;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
}


void ADC_IRQHandler(void){
	if( ADC_GetITStatus(ADC_X  , ADC_IT_EOC )==SET ){
		//讀取ADC的轉(zhuǎn)換值
		 //--------DMA模式-----
		#ifdef 	__ADC_DMA_Mode__ 
		#else
		ADC_ConvertedValue = ADC_GetConversionValue(ADC_X);		
		#endif 
	//--------DMA模式-----
		ADC_ClearITPendingBit(ADC_X , ADC_IT_EOC);
	}
  if( ADC_GetITStatus(ADC_Y  , ADC_IT_EOC )==SET ){
		//讀取ADC的轉(zhuǎn)換值
		 //--------DMA模式-----
		#ifdef 	__ADC_DMA_Mode__ 
		#else
		ADC_ConvertedValue = ADC_GetConversionValue(ADC_Y);		
		#endif 
	//--------DMA模式-----
	  ADC_ClearITPendingBit(ADC_Y , ADC_IT_EOC);	
	} 
  
}
 
/**********************END OF FILE**********************/

/**
  * @brief  ADC初始化
  * @param  無
  * @retval 無
  */
 void ADCx_Init(void){
	 //--------DMA模式-----
	#ifdef 	__ADC_DMA_Mode__ 
	ADCx_GPIO_Config();
  ADCx_DMA_Config();
	ADCx_Mode_Config();
	#else
	ADCx_GPIO_Config();
	ADCx_Mode_Config();
	ADC_NVIC_Config();  // DMA 模式不需要對中斷進(jìn)行處理	
	#endif 
	//--------DMA模式-----
	 
}


void ADC_get_value(void){
  uint16_t temp0=0 ,temp1=0;
  if(badc_10ms==0){return;}
  badc_10ms = 0;

  //-----------AD通道采集-------	
  #ifdef 		 __ADC_RegSimult_Mode__ 
	// 取出 ADC1 數(shù)據(jù)寄存器的高 16 位,這個是 ADC2 的轉(zhuǎn)換數(shù)據(jù)
	temp0 = (ADC_RegSimult_ConvertedValue[0]&0XFFFF0000) >> 16;
	// 取出 ADC1 數(shù)據(jù)寄存器的低 16 位,這個是 ADC1 的轉(zhuǎn)換數(shù)據(jù)
	temp1 = (ADC_RegSimult_ConvertedValue[0]&0XFFFF);
	printf("The current AD value %d = 0x%08X   \r\n",0,ADC_RegSimult_ConvertedValue[0]); 
  ADC_RegSimult_ConvertedValue_Show[0] = temp0 ;
  ADC_RegSimult_ConvertedValue_Show[1] = temp1  ;

	ADC_RegSimult_ConvertedValueLocal[0] = (float)temp0 /4096*3.3; 
	ADC_RegSimult_ConvertedValueLocal[1] = (float)temp1 /4096*3.3;
 		 
	printf("The current AD value %d = 0x%04X   %f V\r\n",0,ADC_RegSimult_ConvertedValue_Show[0],ADC_RegSimult_ConvertedValueLocal[0]); 
  printf("The current AD value %d = 0x%04X   %f V\r\n",1,ADC_RegSimult_ConvertedValue_Show[1],ADC_RegSimult_ConvertedValueLocal[1]); 
	printf("\r\n\r\n");
  GDScream_Data_show( ADC_RegSimult_ConvertedValue_Show,NOFCHANEL);
	#endif 
     
}

  

3:main.c

/*******************************************************************************
* @file    GPIO/JTAG_Remap/main.c 
* @author  MCD Application Team
* @version V3.5.0
* @date    08-April-2011
* @brief   Main program body
******************************************************************************
* @attention
*    
*    
******************************************************************************
*/ 

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include "PROJ_book.h" 

 

/**
  * @brief  Main program.
  * @param  None
  * @retval None
  */
void delay(int x);
void fn_LED_Flash_Init(void);
void fn_usart_show_Init(void);
void fn_DMA_show_Init(void);
void fn_I2C_EE_Init(void);
void fn_I2C_EE_Soft_Init(void);
void fn_SPI_FLASH_Soft_Init(void);
void fn_FatFs_Document_Init(void);
void fn_SRAM_Init(void);
void fn_LCD_Init(void);
void fn_XPT2046_Init(void);
void fn_Adc_Init(void);

#define countof(a)      (sizeof(a) / sizeof(*(a)))
  
#define  _I2C_BufferSize (countof(writeData)-1)
static uint8_t writeData[_I2C_PageSize]={4,5,6,7,8,9,10,11};
static uint8_t writeData2[_I2C_PageSize]={24,25,26,27,28,29,30,31};
static uint8_t ReadData[_I2C_BufferSize]={0};

#define  _SPI_BufferSize  SPI_PAGE_SIZE   //(countof(write_SPI_Data)-1)
static uint8_t write_SPI_Data[_SPI_BufferSize]={0};
static uint8_t Read_SPI_Data[_SPI_BufferSize]={0};

int main(void)
{  
      int16_t sAD_X, sAD_Y ;
      fn_Adc_Init(); 							//ADC 采集
      //*************LCD系統(tǒng)初始化**************  
      fn_XPT2046_Init(); 
      fn_Lcd_Page_Init();  
      fn_Lcd_Page4();
      while(1){     				 
	    ADC_get_value(); 	 
      }
}

 
//======================================================================
//======================================================================

void fn_LCD_Init(void){             //LCD運(yùn)行測試
    __IO int16_t int_check;
    fn_Systick_Delay(500,_Systick_ms);
    int_check = (__IO int16_t)ILI9341_Init();
    Display_LCD_clear();
      switch(int_check){
        case 0x05:
            printf("\n-->LCD 運(yùn)行正常\r\n");
            Lcd_display_String("  LCD 運(yùn)行正常\r\n");     
            break;
        default:
            printf("\n-->LCD 運(yùn)行異常\r\n");
            Lcd_display_String("   LCD 運(yùn)行異常\r\n\r\n");
            
      }       
}

//======================================================================
//======================================================================

void fn_XPT2046_Init(void){             //XPT2046運(yùn)行測試
   printf("\n-->LCD 觸摸初始化\r\n");
   Lcd_display_String("  LCD 觸摸初始化\r\n");   
   XPT2046_GPIO_Init();  
//   while(XPT2046_Touch_Calibrate_Page() == 0){;}
   Lcd_display_String("  LCD 觸摸初始化ok\r\n");
}
//======================================================================
//======================================================================


void fn_Adc_Init(void){ 
		ADCx_Init();
}
 
/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/


顯示屏:

4: XPT2046_LCD_GridDiagram_book.h

#ifndef      __XPT2046_LCD_GRIDDIAGRAM_BOOK__
#define	     __XPT2046_LCD_GRIDDIAGRAM_BOOK__

#include "stm32f10x.h"
															 
#include "XPT2046_LCD_Function_book.h"
#include "XPT2046_LCD_book.h"
#include "LCD_book.h"
#include "LCD_Draw_book.h" 
#include "XPT2046_LCD_Device_book.h"
#include "ADC_book.h"
#include "USART_book.h"

 
//======================================================形式是默認(rèn)還是定制化=====================================================
/**

模式0:				.		模式1:		.	模式2:			.	模式3:					
					A		.					A		.		A					.		A									
					|		.					|		.		|					.		|							
					Y		.					X		.		Y					.		X					
					0		.					1		.		2					.		3					
	<--- X0 o		.	<----Y1	o		.		o 2X--->  .		o 3Y--->	
------------------------------------------------------------	
模式4:				.	模式5:			.	模式6:			.	模式7:					
	<--- X4 o		.	<--- Y5 o		.		o 6X--->  .		o 7Y--->	
					4		.					5		.		6					.		7	
					Y		.					X		.		Y					.		X						
					|		.					|		.		|					.		|							
					V		.					V		.		V					.		V		
---------------------------------------------------------				
											 LCD屏示例
								|---------|-----------------------------|
								|	AD測試	| 													  |
								|					|													    |
								|					|													    |
								|					|													    |
								|					|													    |
								|					|													    |
								|					|													    |
								|					|										    			|
								|					|										    			|
								|---------|-----------------------------|
								屏幕正面(寬240,高320)270 50 -2
**/
 
///******************************* XPT2046 觸摸屏參數(shù)定義 ***************************/
 
 
#define	 XPT2046_GDCHANNEL_X 	       ILI9341_MORE_PIXEL 	          //通道Y+的選擇控制字	
#define	 XPT2046_GDCHANNEL_Y 	       ILI9341_LESS_PIXEL	            //通道X+的選擇控制字

#define  LCD_GDWork_X_LENGTH         270
#define  LCD_GDNwork_Y_LENGTH        238

#define  LCD_GDControl_X_Start       0
#define  LCD_GDControl_Y_Start       0
#define  LCD_GDControl_X_LENGTH      (XPT2046_GDCHANNEL_X - LCD_GDWork_X_LENGTH - 2)
#define  LCD_GDControl_Y_LENGTH      XPT2046_GDCHANNEL_Y

#define  LCD_GDSCAN_X_Start          (LCD_GDControl_X_LENGTH+1)
#define  LCD_GDSCAN_Y_Start          1
#define  LCD_GDSCAN_X_LENGTH         LCD_GDWork_X_LENGTH
#define  LCD_GDSCAN_Y_LENGTH         LCD_GDNwork_Y_LENGTH
#define  LCD_GDSCAN_X_End          	 (XPT2046_GDCHANNEL_X-1)
#define  LCD_GDSCAN_Y_End          	 (XPT2046_GDCHANNEL_Y-1)
#define  Center_lineNum 						 6

#define GDBUTTON_NUM     3


typedef struct{
	int16_t value_x_before ; 
	int16_t value_x_now ;
	int16_t value_y_before ; 
	int16_t value_y_now ;
	uint32_t para_color;	
	uint16_t data_value; 
  void (*draw_point)(void *draw_pot);     //按鍵描繪函數(shù)
   
}AD_Point;

void GDScream_Data_show(int32_t *data_value , uint16_t data_num);

 

#endif




5: XPT2046_LCD_GridDiagram_book.c

/**
  ******************************************************************************
  * @file    palette.c
  * @author  fire
  * @version V1.0
  * @date     
  * @brief   觸摸畫板應(yīng)用函數(shù)
  ******************************************************************************
  * @attention
  *
  ******************************************************************************
  */

#include "XPT2046_LCD_GridDiagram_book.h"
#include  
#include 

Touch_Button GDbutton[GDBUTTON_NUM];

static void GDTouch_Button_Init(void);
static void Draw_btn_GDcontrol_Button(void *btn); 
static void Btn_command_GDcontrol_Button(void);
static void GDControl_Text_Init(void);
static void GDScream_show_Init(void);
static void GDScream_Line_Init(void);
static void GDScream_Data_show_init(void);
static void Draw_point(void * draw_pot);
 /**
* @brief  Palette_Init 畫板初始化
* @param  無
* @retval 無
*/
#define _LCD_GDSCAN_MODE   LCD_SCAN_MODE_3
void GridDiagram_Init(void){
	uint16_t datax , datay;
  ILI9341_GramScan(_LCD_GDSCAN_MODE);
  
  //初始化畫板顏色
  LCD_SetBackColor(CL_GREY2);
  ILI9341_Clear(0,0,XPT2046_GDCHANNEL_X+1,XPT2046_GDCHANNEL_Y+1);
  
  
  LCD_SetColors(CL_YELLOW , CL_WHITE);

 
  ILI9341_DrawRectangle(1,1,LCD_GDControl_X_LENGTH-1,LCD_GDControl_Y_LENGTH-1,0,1);
	LCD_SetColors(CL_WHITE , CL_WHITE);	
					 
  ILI9341_DrawRectangle(LCD_GDControl_X_Start ,
                        LCD_GDControl_Y_Start ,                    
                        LCD_GDControl_X_LENGTH, 
                        LCD_GDControl_Y_LENGTH,0,1);
   
  LCD_SetColors(CL_BLACK , CL_WHITE);						 
  ILI9341_DrawRectangle(LCD_GDSCAN_X_Start,
                        LCD_GDSCAN_Y_Start,                    
                        LCD_GDSCAN_X_LENGTH, 
                        LCD_GDSCAN_Y_LENGTH,1,1);
  GDScream_Line_Init();
  GDScream_Data_show_init();
  //初始化按鈕
  GDTouch_Button_Init();
  GDControl_Text_Init();
  //對屬性物件進(jìn)行刷新
  GDScream_show_Init();
  
}


/**
* @brief  GDTouch_Button_Init 畫板初始化
* @param  無
* @retval 無
*/
static void GDTouch_Button_Init(void){
	uint8_t i ;
	for(i = 0 ;i<=GDBUTTON_NUM ;i++ ){
    GDbutton[i].start_x = BUTTON_START_X+3; 
    GDbutton[i].end_x = GDbutton[i].start_x+COLOR_BLOCK_WIDTH ;
    GDbutton[i].start_y = (COLOR_BLOCK_HEIGHT + 20)*(i+1);
    GDbutton[i].end_y = GDbutton[i].start_y + COLOR_BLOCK_HEIGHT ;    
    GDbutton[i].touch_flag = 0;  
    GDbutton[i].draw_btn = Draw_btn_GDcontrol_Button ;
    GDbutton[i].btn_command = Btn_command_GDcontrol_Button ;
  }
  GDbutton[0].para = CL_GREY; //構(gòu)建按鈕的屬性
	GDbutton[1].para = CL_GREY; //構(gòu)建按鈕的屬性
	GDbutton[2].para = CL_GREY; //構(gòu)建按鈕的屬性
	//描繪按鈕
  for(i=0 ;itouch_flag == 0){
    //背景為功能鍵的顏色
    LCD_SetColors(ptr->para , CL_WHITE);
    ILI9341_DrawRectangle(ptr->start_x , ptr->start_y,\
                          ptr->end_x - ptr->start_x,\
												  ptr->end_y - ptr->start_y,1,1);
     
    //白色背景邊框
    LCD_SetColors(CL_BOX_BORDER1 , CL_WHITE);
    ILI9341_DrawRectangle(ptr->start_x , ptr->start_y,\
                          ptr->end_x - ptr->start_x,\
												  ptr->end_y - ptr->start_y,0,2);
  }else{//按鍵按下
    //白色背景
    LCD_SetColors(CL_WHITE , CL_WHITE);
    ILI9341_DrawRectangle(ptr->start_x , ptr->start_y,\
                          ptr->end_x - ptr->start_x,\
												  ptr->end_y - ptr->start_y,1,1);
     //白色背景邊框
    LCD_SetColors(CL_BOX_BORDER2 , CL_WHITE);
    ILI9341_DrawRectangle(ptr->start_x , ptr->start_y,\
                          ptr->end_x - ptr->start_x,\
												  ptr->end_y - ptr->start_y,0,2);
  }
}


/**
* @brief  Btn_command_GDcontrol_Button 畫板初始化
* @param  無
* @retval 無
*/
static void Btn_command_GDcontrol_Button(void){
				 ;
}


/**
* @brief  Draw_btn_GDcontrol_Button 畫板初始化
* @param  無
* @retval 無
*/
static void GDControl_Text_Init(void){
		LCD_SetColors(CL_RED,CL_WHITE);
	/*選擇字體,使用中英文顯示時,盡量把英文選擇成8*16的字體,
	*中文字體大小是16*16的,需要其它字體請自行制作字模*/
	/*這個函數(shù)只對英文字體起作用*/
	LCD_SetFont(&Font8x16);
	ILI9341_DispString_EN_CH( LCD_GDControl_X_Start +2, LCD_GDControl_Y_Start + 5, "AD檢查");

  	LCD_SetColors(CL_BLACK,CL_WHITE);
	/*選擇字體,使用中英文顯示時,盡量把英文選擇成8*16的字體,
	*中文字體大小是16*16的,需要其它字體請自行制作字模*/
	/*這個函數(shù)只對英文字體起作用*/
	LCD_SetFont(&Font8x16);
	ILI9341_DispString_EN_CH( LCD_GDControl_X_Start +2, LCD_GDControl_Y_Start + 25, " 王琪");
}


/**
* @brief  Draw_btn_GDcontrol_Button 畫板初始化
* @param  無
* @retval 無
*/


static void GDScream_Line_Init(void){
	uint8_t i ;	
	uint16_t center_linexstart , center_lineystart ,center_linexend , center_lineyend;
  uint16_t center_linespace  ;
	center_linexstart = LCD_GDSCAN_X_Start ;
	center_lineystart = XPT2046_GDCHANNEL_Y / 2;
	center_linexend   = LCD_GDSCAN_X_End;
	center_lineyend	= center_lineystart ;
  
  center_linespace = (XPT2046_GDCHANNEL_Y - 2 )/Center_lineNum ;
													 

  LCD_SetColors(CL_RED , CL_WHITE); 
  
  ILI9341_DrawLine( center_linexstart ,center_lineystart ,center_linexend ,center_lineyend,1 );
	LCD_SetColors(CL_YELLOW , CL_WHITE); 
	ILI9341_DrawLine( center_linexstart ,center_lineystart + center_linespace ,center_linexend ,center_lineyend + center_linespace,1 );
	ILI9341_DrawLine( center_linexstart ,center_lineystart - center_linespace ,center_linexend ,center_lineyend - center_linespace,1 );
	LCD_SetColors(CL_BLUE , CL_WHITE);
  ILI9341_DrawLine( center_linexstart ,center_lineystart + (center_linespace*2) ,center_linexend ,center_lineystart + (center_linespace*2),1 );
	ILI9341_DrawLine( center_linexstart ,center_lineystart - (center_linespace*2) ,center_linexend ,center_lineystart - (center_linespace*2),1 );
}

/**
* @brief  Draw_btn_GDcontrol_Button 畫板初始化
* @param  無
* @retval 無
*/
static void GDScream_show_Init(void){
	uint8_t i ;	 
  for( i=0 ; i< (GDBUTTON_NUM); i++ ) {
		GDbutton[i].draw_btn(&GDbutton[i]);
	}
}

//===============================================關(guān)于屏幕畫點的程序函數(shù)============================================== 

// 屏幕正面(寬320,高240) 

//   270 個像素
//   238 / 6  38   
//   500MS  一個數(shù)字  
//   像素間隔 Dx = 2 = 135 個數(shù)字
//   可以測試85S 的數(shù)據(jù)
//   4096 12 AD   每個像素高度為 20 *38 = 760  大約 0.6V  精度為0.02V   
//   設(shè)定變量 :uint16 data_value /  DX = 2  DY =  1 HX= 1 HY = 20 , uint16 data_value_before   data_value_now  ,    
	
#define   DX   1 
#define   DY   1 
#define   HX   1 
#define   HY   20
  
__IO int16_t data_value_x_before = -1;    //之前的狀態(tài)點
__IO int16_t data_value_x_now = -1;       // 現(xiàn)在的狀態(tài)點
__IO int16_t data_value_y_before = -1; 
__IO int16_t data_value_y_now = -1;

AD_Point  ad_point[NOFCHANEL];      //采樣數(shù)據(jù)模塊

static void GDScream_Data_show_init(void){       //顯示數(shù)據(jù)AD的樣式初始化
  uint8_t i=0 ;
	data_value_x_before = -1 ;
	data_value_x_now = -1;
	data_value_y_before = -1 ;
	data_value_y_now = -1;
	for( i=0;ivalue_x_before) == -1){
			ILI9341_SetPointPixel(ptr_point->value_x_now,ptr_point->value_y_now,1);
	}else{
		  ILI9341_DrawLine(ptr_point->value_x_before,ptr_point->value_y_before,ptr_point->value_x_now,ptr_point->value_y_now,1);
	}
}

void  GDScream_Data_show(int32_t *data_value , uint16_t data_num){  //GD顯示 
  
  uint8_t i=0 , j=0 ;
  char cStr [ 100 ];	
	char * pStr = 0;
   float ADC_ValueLocal;
 
    int16_t data_value_x , data_value_y ;


	for(i=0 ; i LCD_GDSCAN_X_End-2)){   // 如果是第一次進(jìn)入最左端存儲點就刷新程序
		LCD_SetColors(CL_BLACK , CL_WHITE);						 
		ILI9341_DrawRectangle(LCD_GDSCAN_X_Start,
                        LCD_GDSCAN_Y_Start,                    
                        LCD_GDSCAN_X_LENGTH, 
                        LCD_GDSCAN_Y_LENGTH,1,1);
		GDScream_Line_Init();

    GDScream_Data_show_init();
 
	} 
  if(data_value_x_before == -1){  //說明是第一次     如果是初始化第一次需要在最左端繪制描繪點
		 for(i=0 ;i;i++){>

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 示波器
    +關(guān)注

    關(guān)注

    113

    文章

    6173

    瀏覽量

    184357
  • adc
    adc
    +關(guān)注

    關(guān)注

    98

    文章

    6406

    瀏覽量

    543853
  • 內(nèi)存
    +關(guān)注

    關(guān)注

    8

    文章

    2981

    瀏覽量

    73825
收藏 人收藏

    評論

    相關(guān)推薦

    CKS32F107xx系列MCU的雙重ADC模式

    獨(dú)立模式ADC采集需要在一個通道采集并且轉(zhuǎn)換完成后才會進(jìn)行下一個通道的采集。而雙重
    的頭像 發(fā)表于 07-22 09:19 ?388次閱讀
    CKS32<b class='flag-5'>F</b>107xx系列MCU的<b class='flag-5'>雙重</b><b class='flag-5'>ADC</b><b class='flag-5'>模式</b>

    STM32F103xC,STM32F103xD,STM32F103xE中文資料

    電子發(fā)燒友網(wǎng)站提供《STM32F103xC,STM32F103xD,STM32F103xE中文資料.pdf》資料免費(fèi)下載
    發(fā)表于 06-17 14:12 ?1次下載

    STM32F103進(jìn)入睡眠模式或者待機(jī)模式或者停機(jī)模式,IO腳原先設(shè)置的電平值是否會改變?

    STM32F103進(jìn)入睡眠模式或者待機(jī)模式或者停機(jī)模式,IO腳原先設(shè)置的電平值是否會改變? 鎖定STM32F103的IO腳,那么當(dāng)
    發(fā)表于 05-17 09:22

    stm32f302和stm32f103ADC區(qū)別是什么?

    請問stm32f302和stm32f103ADC除了stm32f103有2個ADCADC1和
    發(fā)表于 05-15 08:03

    關(guān)于STM32F103使用FSMC同步模式問題求解

    大家好,我現(xiàn)在正在使用STM32F103的FSMC同步模式。 需要讀取高速ADC數(shù)據(jù),ADC是8位并口,但需要一個時鐘去觸發(fā)轉(zhuǎn)換,在時鐘上升
    發(fā)表于 04-17 08:13

    如何減少STM32F103 ADC采集時間?

    環(huán)境: STM32CubeMX 5.6.1(庫為:STM32F11.8.0) IAR for ARM 8.40.2 STM32F103C8T6 BluePill 問題: 使用PA1~PA4進(jìn)行4
    發(fā)表于 04-10 08:20

    stm32f103ADC同步規(guī)則模式兩個ADC轉(zhuǎn)換的通道數(shù)量能不一樣嗎?

    stm32f103rct6,配置成雙ADC同步規(guī)則模式時,主ADC1、從
    發(fā)表于 04-10 06:21

    STM32F103采集模擬量只要低于3.3V,采集的值就是0怎么解決?

    利用STM32F103 ADC直接采集模擬量,現(xiàn)場返修板出現(xiàn)的問題。 采集電壓引腳不論是多少,只要低于3.3V,通過keil仿真直接觀察ADC
    發(fā)表于 04-08 07:24

    想用STM32F373的三個SDADC同步采集電壓信號,DMA是工作在什么模式?怎么配置?

    我想用STM32F373的三個SDADC同步采集電壓信號,請問如果要搭配DMA工作,DMA是工作在什么模式?怎么配置?(沒有看到像F4系列的
    發(fā)表于 03-28 06:49

    STM32F407的規(guī)則同步ADC采集如何實現(xiàn)256k采樣+轉(zhuǎn)換速度?

    F407的規(guī)則同步ADC采集如何 實現(xiàn)256k采樣+轉(zhuǎn)換速度?
    發(fā)表于 03-07 07:51

    ARM系列STM32F103芯片的解密方法

    本文介紹ARM系列STM32F103芯片的解密方法,其內(nèi)核是Cortex-M3,內(nèi)存從16K-512K都有。
    發(fā)表于 02-28 11:20 ?1518次閱讀

    stm32f103 flash模擬eeprom

    STM32F103是意法半導(dǎo)體(STMicroelectronics)推出的一款32位單片機(jī)系列,該系列芯片具有高性能和豐富的外設(shè)接口,廣泛應(yīng)用于工業(yè)控制、消費(fèi)電子、汽車電子等領(lǐng)域。其中
    的頭像 發(fā)表于 01-09 11:21 ?1863次閱讀

    請問adxrs620輸出范圍怎么調(diào)理到適合stm32f103adc量程?

    adxrs620輸出范圍怎么調(diào)理到適合stm32f103adc量程了?stm32f103是3.3v供電的。620輸出我想加一級rc的濾波帶寬控制在300hz內(nèi)即可。
    發(fā)表于 01-02 07:23

    gd32f103可以完全替代stm32f103

    GD32F103是中國廠商GigaDevice推出的一款低成本、高性能的微控制器產(chǎn)品線。STM32F103是意法半導(dǎo)體(STMicroelectronics)的旗艦產(chǎn)品之一,享有良好的聲譽(yù)和廣泛
    的頭像 發(fā)表于 12-07 11:26 ?4877次閱讀

    基于STM32F103的直流電機(jī)pid調(diào)節(jié)閉環(huán)控制

    基于STM32F103的直流電機(jī)pid調(diào)節(jié)的閉環(huán)控制,主要模塊:NOKIA5110顯示屏紅外測速模塊
    發(fā)表于 11-27 16:50 ?8次下載