雙重 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++){>
審核編輯:湯梓紅
-
示波器
+關(guān)注
關(guān)注
113文章
6173瀏覽量
184357 -
adc
+關(guān)注
關(guān)注
98文章
6406瀏覽量
543853 -
內(nèi)存
+關(guān)注
關(guān)注
8文章
2981瀏覽量
73825
發(fā)布評論請先 登錄
相關(guān)推薦
評論