#include "Com.h"
#define MESSAGE1 " ECG Waveform "
#define MESSAGE1_1 " Display "
#define MESSAGE2 "ADCValue:"
#define MESSAGE5 " ADC3=%d.%1d V "
#define LINENUM 0x15
#define ADC3_DR_ADDRESS ((uint32_t)0x4001224C)
__IO uint16_t uhADC3ConvertedValue = 0;
__IO uint32_t uwADC3ConvertedVoltage = 0;
static uint16_t Xpos=6,Ypos1=249,Ypos2=249,Xpos1=6,Xpos2=6;
static uint16_t DrawData;
static uint16_t Counter=0;
//------------------------------------------------------------------------------
//ADC3通道13 DMA配置
//------------------------------------------------------------------------------
static void ADC3_CH13_DMA_Config(void)
{
ADC_InitTypeDef ADC_InitStructure;
ADC_CommonInitTypeDefADC_CommonInitStructure;
DMA_InitTypeDef DMA_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
//打開ADC3,DMA2,GPIO時(shí)鐘
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2| RCC_AHB1Periph_GPIOC, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3,ENABLE);
DMA_InitStructure.DMA_Channel =DMA_Channel_2;
DMA_InitStructure.DMA_PeripheralBaseAddr= (uint32_t)ADC3_DR_ADDRESS;
DMA_InitStructure.DMA_Memory0BaseAddr= (uint32_t)&uhADC3ConvertedValue;
DMA_InitStructure.DMA_DIR =DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize= 1;
DMA_InitStructure.DMA_PeripheralInc= DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc= DMA_MemoryInc_Disable;
DMA_InitStructure.DMA_PeripheralDataSize= DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize= DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode =DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority= DMA_Priority_High;
DMA_InitStructure.DMA_FIFOMode= DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold= DMA_FIFOThreshold_HalfFull;
DMA_InitStructure.DMA_MemoryBurst= DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst= DMA_PeripheralBurst_Single;
DMA_Init(DMA2_Stream0,&DMA_InitStructure);
DMA_Cmd(DMA2_Stream0, ENABLE);
GPIO_InitStructure.GPIO_Pin =GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode =GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd =GPIO_PuPd_NOPULL ;
GPIO_Init(GPIOC,&GPIO_InitStructure);
ADC_CommonInitStructure.ADC_Mode= ADC_Mode_Independent;
ADC_CommonInitStructure.ADC_Prescaler= ADC_Prescaler_Div2;
ADC_CommonInitStructure.ADC_DMAAccessMode= ADC_DMAAccessMode_Disabled;
ADC_CommonInitStructure.ADC_TwoSamplingDelay= ADC_TwoSamplingDelay_5Cycles;
ADC_CommonInit(&ADC_CommonInitStructure);
ADC_InitStructure.ADC_Resolution= ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode= DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode= ENABLE;
ADC_InitStructure.ADC_ExternalTrigConvEdge= ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_ExternalTrigConv= ADC_ExternalTrigConv_T1_CC1;
ADC_InitStructure.ADC_DataAlign= ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion= 1;
ADC_Init(ADC3,&ADC_InitStructure);
ADC_RegularChannelConfig(ADC3,ADC_Channel_13, 1, ADC_SampleTime_3Cycles);
ADC_DMARequestAfterLastTransferCmd(ADC3,ENABLE);
ADC_DMACmd(ADC3, ENABLE);
ADC_Cmd(ADC3, ENABLE);
}
//------------------------------------------------------------------------------
//LCD顯示電壓值主循環(huán)
//------------------------------------------------------------------------------
static void ADCValueDisplay_MainLoop(void)
{
uint32_t uwVoltage =0,uwMVoltage=0;
uint8_t aTextBuffer[50];
//把ADC采樣值轉(zhuǎn)換成電壓值
uwADC3ConvertedVoltage =uhADC3ConvertedValue *3000/0xFFF;
LCD_SetLayer(LCD_BACKGROUND_LAYER);
LCD_SetBackColor(((220>>3)<<11)|((220>>2)<<5)|(220>>3));
LCD_SetTextColor(LCD_COLOR_BLUE );
uwVoltage =(uwADC3ConvertedVoltage)/1000;
uwMVoltage =(uwADC3ConvertedVoltage%1000)/100;
sprintf((char*)aTextBuffer,MESSAGE5, uwVoltage, uwMVoltage);
LCD_DisplayStringLine(LCD_LINE_12,(uint8_t*)aTextBuffer);
LCD_SetLayer(LCD_FOREGROUND_LAYER);
}
//------------------------------------------------------------------------------
//電壓波形顯示主循環(huán)
//------------------------------------------------------------------------------
static void ADCWaveformDisp_MainLoop(void)
{
DrawData = uhADC3ConvertedValue*(178.0/0xFFF);
if(++Counter == 4 )
{
Counter = 0;
LCD_SetTextColor( LCD_COLOR_BLACK );
LCD_DrawFullRect( Xpos+1, 50, 2, 218);
LCD_SetTextColor( LCD_COLOR_GREEN );
Xpos=Xpos+1;
if(Xpos>232)
{
Xpos=6;
LCD_SetTextColor( LCD_COLOR_BLACK );
LCD_DrawLine( Xpos, 50, 218, LCD_DIR_VERTICAL);
LCD_SetTextColor( LCD_COLOR_GREEN );
}
Xpos2=Xpos2+1;
Ypos2=249-DrawData;
if(Xpos2>232)
{
Xpos2=6;Xpos1=6;
}
LCD_DrawUniLine( Xpos1, Ypos1,Xpos2, Ypos2);
Xpos1=Xpos2;
Ypos1=Ypos2;
}
}
//------------------------------------------------------------------------------
//界面初始化顯示
//------------------------------------------------------------------------------
static void LCD_GUIDisplay(void)
{
uint16_t i;
LCD_SetLayer(LCD_BACKGROUND_LAYER); //設(shè)置為背景層
LCD_SetTransparency(255); //背景層透明度
LCD_Clear(((220>>3)<<11)|((220>>2)<<5)|(220>>3) ); //把LCD清除為指定顏色
LCD_SetBackColor(LCD_COLOR_BLUE);
LCD_SetTextColor(LCD_COLOR_BLACK);
LCD_DrawFullRect(5, 49, 229, 219);
LCD_SetTextColor(((180>>3)<<11)|((180>>2)<<5)|(180>>3) );
LCD_DrawRect( 5, 49, 219, 229);
LCD_SetTextColor(((180>>3)<<11)|((180>>2)<<5)|(180>>3) );
LCD_DrawUniLine( 4, 48, 234, 48);
LCD_DrawUniLine( 4, 48, 4, 268);
LCD_SetTextColor(((128>>3)<<11)|((128>>2)<<5)|(128>>3) );
LCD_DrawUniLine( 5, 49, 233, 49);
LCD_DrawUniLine( 5, 49, 5, 267);
LCD_SetTextColor( 0XFFFF );
LCD_DrawUniLine( 235, 49, 235, 269);
LCD_DrawUniLine( 5, 269, 235, 269);
LCD_SetTextColor(((30>>3)<<11)|((30>>2)<<5)|(30>>3) );
for(i=69; i<269; i+=20 )
LCD_DrawUniLine( 6, i, 233, i);
for(i=44; i<233; i+=38 )
LCD_DrawUniLine( i, 50, i, 267);
LCD_SetBackColor(((220>>3)<<11)|((220>>2)<<5)|(220>>3));
LCD_SetTextColor(LCD_COLOR_BLUE);
LCD_SetFont(&Font16x24);
LCD_DisplayStringLine(LCD_LINE_0, (uint8_t*)MESSAGE1);
LCD_DisplayStringLine(LCD_LINE_1, (uint8_t*)MESSAGE1_1);
LCD_SetLayer(LCD_FOREGROUND_LAYER); //把LCD設(shè)置為前景顯示層
LCD_SetTransparency(120); //前景層透明度
LCD_Clear( LCD_COLOR_BLACK );
}
//------------------------------------------------------------------------------
//主函數(shù)
//------------------------------------------------------------------------------
int main(void)
{
LCD_Init(); //LCD初始化
LCD_LayerInit(); //LCD層次顯示初始化
LTDC_Cmd(ENABLE); //打開LTDC
LCD_GUIDisplay();
ADC3_CH13_DMA_Config(); //配置ADC3
ADC_SoftwareStartConv(ADC3); //開始ADC轉(zhuǎn)換
while(1)
{
ADCValueDisplay_MainLoop(); //顯示電壓值
ADCWaveformDisp_MainLoop(); //波形顯示
}
}
#include <stm32f10x_lib.h>
#include "lcd.h"
// ×××××××××××畫線×××××××××××××××voidLCD_DrawPoint(u8 x,u8 y,u16 color)
struct IO_port{ GPIO_TypeDef *GPIO_X; u16 GPIO_Pin;};
static struct IO_port Key_output[]={{GPIOA,GPIO_Pin_0},{GPIOA,GPIO_Pin_1},{GPIOA,GPIO_Pin_2},{GPIOA,GPIO_Pin_3}}; //結(jié)構(gòu)體數(shù)組
static struct IO_port Key_input[]={{GPIOC,GPIO_Pin_4},{GPIOC,GPIO_Pin_5},{GPIOC,GPIO_Pin_6},{GPIOC,GPIO_Pin_7}};
u8 key[4][4] ={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
void LCD_DrawLine(u16 x1, u16 y1, u16 x2,u16 y2,u16 color)
{
u16 t;
int xerr=0,yerr=0,delta_x,delta_y,distance;
int incx,incy,uRow,uCol;
delta_x=x2-x1; //計(jì)算坐標(biāo)增量
delta_y=y2-y1;
uRow=x1;
uCol=y1;
if(delta_x>0)incx=1; //設(shè)置單步方向
else if(delta_x==0)incx=0;//垂直線
else {incx=-1;delta_x=-delta_x;}
if(delta_y>0)incy=1;
else if(delta_y==0)incy=0;//水平線
else{incy=-1;delta_y=-delta_y;}
if( delta_x>delta_y)distance=delta_x; //選取基本增量坐標(biāo)軸
else distance=delta_y;
for(t=0;t<=distance+1;t++ )//畫線輸出
{
lcd_point(uRow,uCol,color);//畫點(diǎn)
xerr+=delta_x ;
yerr+=delta_y ;
if(xerr>distance)
{
xerr-=distance;
uRow+=incx;
}
if(yerr>distance)
{
yerr-=distance;
uCol+=incy;
}
}
}
//*********************RCC_Configuration**************************************
void RCC_Configuration()
{
ErrorStatus HSEStartUpStatus;//定義外部高速晶體啟動(dòng)狀態(tài)枚舉變量
RCC_DeInit();//復(fù)位RCC外部設(shè)備寄存器到默認(rèn)值
RCC_HSEConfig(RCC_HSE_ON);//打開外部高速晶振
HSEStartUpStatus=RCC_WaitForHSEStartUp();//等待外部高速時(shí)鐘準(zhǔn)備好
if(HSEStartUpStatus==SUCCESS)//外部高速時(shí)鐘已經(jīng)準(zhǔn)備好
{
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
FLASH_SetLatency(FLASH_Latency_2);
RCC_HCLKConfig(RCC_SYSCLK_Div1);//配置AHB(HCLK)時(shí)鐘=SYSCLK
RCC_PCLK2Config(RCC_HCLK_Div1);//配置APB2(PCLK2)時(shí)鐘=AHB時(shí)鐘
RCC_PCLK1Config(RCC_HCLK_Div2);//配置APB1(PCLK1)時(shí)鐘=AHB 1/2時(shí)鐘
RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9);//配置PLL時(shí)鐘=外部高速晶體時(shí)鐘*9
RCC_PLLCmd(ENABLE);//使能PLL時(shí)鐘
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET)//等待PLL時(shí)鐘就緒
{}
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);//配置系統(tǒng)時(shí)鐘=PLL時(shí)鐘
while(RCC_GetSYSCLKSource()!=0x08)//檢查PLL時(shí)鐘是否作為系統(tǒng)時(shí)鐘
{}
}
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOG |RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | RCC_APB2Periph_GPIOC |RCC_APB2Periph_GPIOF | RCC_APB2Periph_ADC1,ENABLE);
}
/*配置DMA*/
void ADC1_Configuration(void)
{
ADC_InitTypeDef ADC_InitStructure;
ADC_DeInit(ADC1); //將外設(shè) ADC1 的全部寄存器重設(shè)為缺省值
/* ADC1 configuration------------------------------------------------------*/
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //ADC工作模式:ADC1和ADC2工作在獨(dú)立模式
ADC_InitStructure.ADC_ScanConvMode =ENABLE; //模數(shù)轉(zhuǎn)換工作在掃描模式
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //模數(shù)轉(zhuǎn)換工作在連續(xù)轉(zhuǎn)換模式
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //外部觸發(fā)轉(zhuǎn)換關(guān)閉
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //ADC數(shù)據(jù)右對(duì)齊
ADC_InitStructure.ADC_NbrOfChannel = 1; //順序進(jìn)行規(guī)則轉(zhuǎn)換的ADC通道的數(shù)目
ADC_Init(ADC1, &ADC_InitStructure); //根據(jù)ADC_InitStruct中指定的參數(shù)初始化外設(shè)ADCx的寄存器
RCC_ADCCLKConfig(RCC_PCLK2_Div8);
/* ADC1 regular channel11 configuration */
//設(shè)置指定ADC的規(guī)則組通道,設(shè)置它們的轉(zhuǎn)化順序和采樣時(shí)間
//ADC1,ADC通道x,規(guī)則采樣順序值為y,采樣時(shí)間為239.5周期
ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_1,2, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_2,3, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_3,4, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_10,1,ADC_SampleTime_55Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_9,6, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_10,7,ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_11,8, ADC_SampleTime_55Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_12,9,ADC_SampleTime_239Cycles5); ADC_RegularChannelConfig(ADC1,ADC_Channel_13,10,ADC_SampleTime_239Cycles5); ADC_RegularChannelConfig(ADC1,ADC_Channel_14,11,ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_15,12,ADC_SampleTime_239Cycles5);
// 開啟ADC的DMA支持(要實(shí)現(xiàn)DMA功能,還需獨(dú)立配置DMA通道等參數(shù))
ADC_DMACmd(ADC1, ENABLE);
/*Enable ADC1 */
ADC_Cmd(ADC1, ENABLE); //使能指定的ADC1
/* Enable ADC1 reset calibaration register */
ADC_ResetCalibration(ADC1); //復(fù)位指定的ADC1的校準(zhǔn)寄存器
/* Check the end of ADC1 reset calibration register */
while(ADC_GetResetCalibrationStatus(ADC1)); //獲取ADC1復(fù)位校準(zhǔn)寄存器的狀態(tài),設(shè)置狀態(tài)則等待
/* Start ADC1 calibaration */
ADC_StartCalibration(ADC1);
//開始指定ADC1的校準(zhǔn)狀態(tài)
/* Check the end of ADC1 calibration */
while(ADC_GetCalibrationStatus(ADC1));
//獲取指定ADC1的校準(zhǔn)程序,設(shè)置狀態(tài)則等待
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}
voidDMA_Configuration(void)
{
/* ADC1 DMA1 Channel Config */
DMA_InitTypeDef DMA_InitStructure;
DMA_DeInit(DMA1_Channel1); //將DMA的通道1寄存器重設(shè)為缺省值
DMA_InitStructure.DMA_PeripheralBaseAddr= (u32)&ADC1->DR;
//DMA外設(shè)ADC基地址
DMA_InitStructure.DMA_MemoryBaseAddr= (u32)&ADC_GetConversionValue;
//DMA內(nèi)存基地址
DMA_InitStructure.DMA_DIR= DMA_DIR_PeripheralSRC;
//內(nèi)存作為數(shù)據(jù)傳輸?shù)哪康牡?/font>
DMA_InitStructure.DMA_BufferSize= 1;
//DMA通道的DMA緩存的大小
DMA_InitStructure.DMA_PeripheralInc= DMA_PeripheralInc_Disable;
//外設(shè)地址寄存器不變
DMA_InitStructure.DMA_MemoryInc= DMA_MemoryInc_Enable;
//內(nèi)存地址寄存器遞增
DMA_InitStructure.DMA_PeripheralDataSize= DMA_PeripheralDataSize_HalfWord;
//數(shù)據(jù)寬度為16位
DMA_InitStructure.DMA_MemoryDataSize= DMA_MemoryDataSize_HalfWord;
//數(shù)據(jù)寬度為16位
DMA_InitStructure.DMA_Mode= DMA_Mode_Circular;
//工作在循環(huán)緩存模式
DMA_InitStructure.DMA_Priority= DMA_Priority_High;
//DMA通道 x擁有高優(yōu)先級(jí)
DMA_InitStructure.DMA_M2M= DMA_M2M_Disable;
//DMA通道x沒有設(shè)置為內(nèi)存到內(nèi)存?zhèn)鬏?/font>
DMA_Init(DMA1_Channel1,&DMA_InitStructure);
//根據(jù)DMA_InitStruct中指定的參數(shù)初始化DMA的通道
DMA_Cmd(DMA1_Channel1, ENABLE);
}
void TIME_Configuration(viod)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
TIM_DeInit(TIM2);
TIM_TimeBaseInitStruct.TIM_Prescaler = 19;
TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInitStruct.TIM_Period = 399;
TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStruct.TIM_RepetitionCounter = ;
TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStruct);
TIM_ClearFlag(TIM2, TIM_FLAG_Update);
TIM_ITConfig(TIM2,TIM_FLAG_Update,ENABLE);
TIM_Cmd(TIM2,ENABLE);
}
void delay_us(u16 t)
{
u16 i,j;
for(i=0;i<t;i++)
for(j=0;j<5;j++);
}
void delay_ms(u16 T)
{
u16 i,j;
for(i=0;i<T;i++)
for(j=0;j<6000;j++);
}
int main()
{
u16Voltage[400];
u16i=0,ADCVal=0;
u16 New = 0 ;
u16 *ADC_Val = &New , j , k , Tem = 0,stop_y ;
j=0;
RCC_Configuration();
TIME_Configuration();
GPIO_Configuration();
DMA_Configuration();
ADC1_Configuration();
lcd_init();
color_test();
LCD_DrawLine(120,0,120,399,Black);
LCD_DrawLine(0,200,239,200,Black);
while(1)
{
delay_ms(20);
Tem= ADC_GetConversionValue(ADC1);
New= (u16)( Tem* 33 / 4096); //獲得新數(shù)據(jù) 并放大10倍
j++; //記錄采樣個(gè)數(shù)
if( ( j >= 2 ) && ( j <= 400) ) //2個(gè)到400個(gè)點(diǎn)之間只畫 j 個(gè)點(diǎn)
{
k=j;
ADC_Val = Change( New );
LCD_DrawLine( *(ADC_Val+k-1)+100 , k-1 , *(ADC_Val+k)+100 , k , Red );
}
else if( j > 400 ) //超過400個(gè)點(diǎn)每次都要畫400個(gè)點(diǎn)
{
for( k=1 ; k<400 ; k++ )
{
ADC_Val = Change( New );
LCD_DrawLine( *(ADC_Val+k-1)+100 , k-1 , *(ADC_Val+k)+100 , k , Red );
}
delay_ms(300);
lcd_clear(White);
}
else // 第一個(gè)點(diǎn)
{
ADC_Val = Change( New );
lcd_point( *ADC_Val+100,0 , Red);
}
}
}
while(1)
{
delay_ms(10);
ADCVal = ADC_GetConversionValue(ADC1);
Voltage = (u16)(ADCVal* 33*5/ 4096); //求的結(jié)果擴(kuò)大了10倍,方便下面求出小數(shù)
//可以用來顯示頻率lcdshow_number(100,200,Voltage,Blue,Red);
lcd_point(ADCVal , 0 , Black );
if(i>0)
{
LCD_DrawLine(Voltage[i-1]+ 80, i-1 ,Voltage+80 , i , Red);
}
i++;
if(i==399)
{
lcd_clear(White);
i=0;
}
}
//
// }
|