#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时钟
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显示电压值主循环
//------------------------------------------------------------------------------
static void ADCValueDisplay_MainLoop(void)
{
uint32_t uwVoltage =0,uwMVoltage=0;
uint8_t aTextBuffer[50];
//把ADC采样值转换成电压值
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);
}
//------------------------------------------------------------------------------
//电压波形显示主循环
//------------------------------------------------------------------------------
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); //设置为背景层
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设置为前景显示层
LCD_SetTransparency(120); //前景层透明度
LCD_Clear( LCD_COLOR_BLACK );
}
//------------------------------------------------------------------------------
//主函数
//------------------------------------------------------------------------------
int main(void)
{
LCD_Init(); //LCD初始化
LCD_LayerInit(); //LCD层次显示初始化
LTDC_Cmd(ENABLE); //打开LTDC
LCD_GUIDisplay();
ADC3_CH13_DMA_Config(); //配置ADC3
ADC_SoftwareStartConv(ADC3); //开始ADC转换
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}}; //结构体数组
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; //计算坐标增量
delta_y=y2-y1;
uRow=x1;
uCol=y1;
if(delta_x>0)incx=1; //设置单步方向
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; //选取基本增量坐标轴
else distance=delta_y;
for(t=0;t<=distance+1;t++ )//画线输出
{
lcd_point(uRow,uCol,color);//画点
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;//定义外部高速晶体启动状态枚举变量
RCC_DeInit();//复位RCC外部设备寄存器到默认值
RCC_HSEConfig(RCC_HSE_ON);//打开外部高速晶振
HSEStartUpStatus=RCC_WaitForHSEStartUp();//等待外部高速时钟准备好
if(HSEStartUpStatus==SUCCESS)//外部高速时钟已经准备好
{
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
FLASH_SetLatency(FLASH_Latency_2);
RCC_HCLKConfig(RCC_SYSCLK_Div1);//配置AHB(HCLK)时钟=SYSCLK
RCC_PCLK2Config(RCC_HCLK_Div1);//配置APB2(PCLK2)时钟=AHB时钟
RCC_PCLK1Config(RCC_HCLK_Div2);//配置APB1(PCLK1)时钟=AHB 1/2时钟
RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9);//配置PLL时钟=外部高速晶体时钟*9
RCC_PLLCmd(ENABLE);//使能PLL时钟
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET)//等待PLL时钟就绪
{}
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);//配置系统时钟=PLL时钟
while(RCC_GetSYSCLKSource()!=0x08)//检查PLL时钟是否作为系统时钟
{}
}
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); //将外设 ADC1 的全部寄存器重设为缺省值
/* ADC1 configuration------------------------------------------------------*/
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //ADC工作模式:ADC1和ADC2工作在独立模式
ADC_InitStructure.ADC_ScanConvMode =ENABLE; //模数转换工作在扫描模式
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //模数转换工作在连续转换模式
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //外部触发转换关闭
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //ADC数据右对齐
ADC_InitStructure.ADC_NbrOfChannel = 1; //顺序进行规则转换的ADC通道的数目
ADC_Init(ADC1, &ADC_InitStructure); //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器
RCC_ADCCLKConfig(RCC_PCLK2_Div8);
/* ADC1 regular channel11 configuration */
//设置指定ADC的规则组通道,设置它们的转化顺序和采样时间
//ADC1,ADC通道x,规则采样顺序值为y,采样时间为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支持(要实现DMA功能,还需独立配置DMA通道等参数)
ADC_DMACmd(ADC1, ENABLE);
/*Enable ADC1 */
ADC_Cmd(ADC1, ENABLE); //使能指定的ADC1
/* Enable ADC1 reset calibaration register */
ADC_ResetCalibration(ADC1); //复位指定的ADC1的校准寄存器
/* Check the end of ADC1 reset calibration register */
while(ADC_GetResetCalibrationStatus(ADC1)); //获取ADC1复位校准寄存器的状态,设置状态则等待
/* Start ADC1 calibaration */
ADC_StartCalibration(ADC1);
//开始指定ADC1的校准状态
/* Check the end of ADC1 calibration */
while(ADC_GetCalibrationStatus(ADC1));
//获取指定ADC1的校准程序,设置状态则等待
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}
voidDMA_Configuration(void)
{
/* ADC1 DMA1 Channel Config */
DMA_InitTypeDef DMA_InitStructure;
DMA_DeInit(DMA1_Channel1); //将DMA的通道1寄存器重设为缺省值
DMA_InitStructure.DMA_PeripheralBaseAddr= (u32)&ADC1->DR;
//DMA外设ADC基地址
DMA_InitStructure.DMA_MemoryBaseAddr= (u32)&ADC_GetConversionValue;
//DMA内存基地址
DMA_InitStructure.DMA_DIR= DMA_DIR_PeripheralSRC;
//内存作为数据传输的目的地
DMA_InitStructure.DMA_BufferSize= 1;
//DMA通道的DMA缓存的大小
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_InitStructure.DMA_Priority= DMA_Priority_High;
//DMA通道 x拥有高优先级
DMA_InitStructure.DMA_M2M= DMA_M2M_Disable;
//DMA通道x没有设置为内存到内存传输
DMA_Init(DMA1_Channel1,&DMA_InitStructure);
//根据DMA_InitStruct中指定的参数初始化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); //获得新数据 并放大10倍
j++; //记录采样个数
if( ( j >= 2 ) && ( j <= 400) ) //2个到400个点之间只画 j 个点
{
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个点每次都要画400个点
{
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 // 第一个点
{
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); //求的结果扩大了10倍,方便下面求出小数
//可以用来显示频率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;
}
}
//
// }
|