STM32F103RC DMA ADC 温度,电压采样

STM32F103RC DMA ADC 温度,电压采样




#include "stm32f10x.h"
#include	"stm32f10x_adc.h"
#include 	"adc.h"

extern const u16 NTCTab[];

__IO uint16_t ADC_DualConvertedValueTab[10][10];
/**

  */
 void  ADCx_GPIO_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	
	// 打开 ADC IO端口时钟
	ADC_GPIO_APBxClock_FUN ( ADC_GPIO_CLK, ENABLE );
	ADC_GPIO_APBxClock_FUN ( RCC_APB2Periph_GPIOB, ENABLE );
	ADC_GPIO_APBxClock_FUN ( RCC_APB2Periph_GPIOA, ENABLE );
	
	// 配置 ADC IO 引脚模式
	// 必须为模拟输入
	GPIO_InitStructure.GPIO_Pin = ADC_PIN_T1 | ADC_PIN_T2 | ADC_PIN_T3 | ADC_PIN_T4;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
	
	// 初始化 ADC IO
	GPIO_Init(ADC_PORT_T, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin = ADC_PIN_L1 | ADC_PIN_L2 ;
	GPIO_Init(ADC_PORT_L, &GPIO_InitStructure);	
	
	GPIO_InitStructure.GPIO_Pin = ADC_PIN_L3 | ADC_PIN_L4 | ADC_PIN_V1 | ADC_PIN_V2;
	GPIO_Init(ADC_PORT_V, &GPIO_InitStructure);	

	GPIO_InitStructure.GPIO_Pin = TEST_SEL_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_Init(TEST_SEL_PORT, &GPIO_InitStructure);		
}
/**
  * @brief  配置ADC工作模式
  * @param  无
  * @retval 无
  */
static void ADCx_Mode_Config(void)
{
	ADC_InitTypeDef ADC_InitStructure;	
	DMA_InitTypeDef DMA_InitStructure;
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);//使能时钟
  /* DMA1 channel1 configuration ----------------------------------------------*/
  DMA_DeInit(DMA1_Channel1);
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_Address;
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADC_DualConvertedValueTab;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  DMA_InitStructure.DMA_BufferSize = 100;
  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_InitStructure.DMA_M2M = DMA_M2M_Disable;
  DMA_Init(DMA1_Channel1, &DMA_InitStructure);
  /* Enable DMA1 Channel1 */
  DMA_Cmd(DMA1_Channel1, ENABLE);
	
	// 打开ADC时钟
	ADC_APBxClock_FUN ( ADC_CLK, ENABLE );
//    /*IO和ADC使能时钟*/
//    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1|RCC_APB2Periph_GPIOA,ENABLE);
//    RCC_ADCCLKConfig(RCC_PCLK2_Div6);	
	// ADC 模式配置

	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;	// 只使用一个ADC,属于独立模式
	ADC_InitStructure.ADC_ScanConvMode = ENABLE ; 	// 扫描模式,多通道
	ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;	// 连续转换模式
	// 不用外部触发转换,软件开启即可
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;

	// 转换结果右对齐
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
	
	// 转换通道1个
	ADC_InitStructure.ADC_NbrOfChannel = 10;	
		
	// 初始化ADC
	ADC_Init(ADCx, &ADC_InitStructure);
	
	// 配置ADC时钟为PCLK2的8分频,即9MHz
	RCC_ADCCLKConfig(RCC_PCLK2_Div8); 
	
	// 配置 ADC 通道转换顺序和采样时间
	ADC_RegularChannelConfig(ADCx, ADC_CHANNEL_T1, 1,ADC_SampleTime_239Cycles5);
	ADC_RegularChannelConfig(ADCx, ADC_CHANNEL_T2, 2,ADC_SampleTime_239Cycles5);
	ADC_RegularChannelConfig(ADCx, ADC_CHANNEL_T3, 3,ADC_SampleTime_239Cycles5);
	ADC_RegularChannelConfig(ADCx, ADC_CHANNEL_T4, 4,ADC_SampleTime_239Cycles5);
	ADC_RegularChannelConfig(ADCx, ADC_CHANNEL_L1, 5,ADC_SampleTime_239Cycles5);
	ADC_RegularChannelConfig(ADCx, ADC_CHANNEL_L2, 6,ADC_SampleTime_239Cycles5);
	ADC_RegularChannelConfig(ADCx, ADC_CHANNEL_L3, 7,ADC_SampleTime_239Cycles5);
	ADC_RegularChannelConfig(ADCx, ADC_CHANNEL_L4, 8,ADC_SampleTime_239Cycles5);
	ADC_RegularChannelConfig(ADCx, ADC_CHANNEL_V1, 9,ADC_SampleTime_239Cycles5);
	ADC_RegularChannelConfig(ADCx, ADC_CHANNEL_V2, 10,ADC_SampleTime_239Cycles5);
	
	// ADC 转换结束产生中断,在中断服务程序中读取转换值
//	ADC_ITConfig(ADCx, ADC_IT_EOC, ENABLE);
	
	// 开启ADC ,并开始转换
	ADC_DMACmd(ADC1, ENABLE);//开启ADC的DMA支持
	ADC_Cmd(ADCx, ENABLE);
	
	// 初始化ADC 校准寄存器  
	ADC_ResetCalibration(ADCx);
	// 等待校准寄存器初始化完成
	while(ADC_GetResetCalibrationStatus(ADCx));
	
	// ADC开始校准
	ADC_StartCalibration(ADCx);
	// 等待校准完成
	while(ADC_GetCalibrationStatus(ADCx))
	{
	}
	
	// 由于没有采用外部触发,所以使用软件触发ADC转换 
		ADC_SoftwareStartConvCmd(ADC1, ENABLE);  //开始转换

}
/**********************************************************************
//
******************************************
static void ADC_NVIC_Config(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;
	// 优先级分组
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

  // 配置中断优先级
  NVIC_InitStructure.NVIC_IRQChannel = ADC_IRQ;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}
*/

/**
  * @brief  ADC初始化
  * @param  无
  * @retval 无
  */
void ADCx_Init(void)
{
	ADCx_GPIO_Config();
	ADCx_Mode_Config();
//	ADC_NVIC_Config();
}
/******************************************************
计算平均数
******************************************************/
u16  adc_result(u8	ch)
{
	u8 i;
	u16  Value;
	u32	sum;
	sum = 0;
	for(i=0;i<10;i++)
		sum += ADC_DualConvertedValueTab[i][ch];
	Value	= sum / 10;
	return Value;
}
/******************************************************
查表函数
******************************************************/
u16 look_up_table(const u16 *a,u16 ArrayLong,u16 data)
{    
    u16 begin,end,middle ;  
    u16 i ;  
    begin = 0 ;  
    end = ArrayLong-1 ;  
    i = 0  ;  
    if(data >= a[begin])
      {
      
			return begin ;  
      }
    else if(data <= a[end])
				return end ;  
    while(begin < end)  
    {  
		middle = (begin+end)/2 ;  
		if(data == a[middle] )
				break ;  
		if(data < a[middle] && data > a[middle+1])
				break ;   
		if(data > a[middle])
			end = middle ;                      
		else 
			begin = middle ;      
		if(i++ > ArrayLong)
			break ;  
    }  
    if(begin > end )
			return 0 ;   
    return middle ;  
}

/******************************************************
温度查表转换计算(33K+100K)3路
******************************************************/
int temp_LookUp(uchar a)
{
	uint i;
	uint dy1=0,xsd;
	int	tt;
	dy1 = adc_result(a);
	i = look_up_table(NTCTab,260,dy1);

	tt = NTCTab[i] - NTCTab[i+1];
	xsd = 10-((dy1 % tt)*10/tt);   //计算小数点后的数值
	if(i>40)
		{
		tt = i - 40;
		tt = tt * 10;
		tt = tt + xsd;
		}
	else if(i > 0)
	{
		tt =  -40 + (int)i;
		tt = tt * 10;
		tt = tt + xsd;		

	}
	else
		tt = -400;
	
	return(tt);
}
/*************************************
检查漏电互感器
*************************************/
void CheckLeak(u16	*lc,u16 *ca,u16 *cb,u16 *cc)
{
	u32 	sum;
	u16  i;
	
  SET_TEST_SEL;      //模拟开关常开NO -> ON 常闭打开NC -> OFF
  DelayMsKey(500);
	sum = 0;
	for(i=0;i<10;i++)
		sum += 0xfff-ADC_DualConvertedValueTab[i][ADC_LC1];
	*lc = sum;	
//	*lc = adc_result(ADC_LC1);	
	sum = 0;
	for(i=0;i<10;i++)
		sum += 0xfff-ADC_DualConvertedValueTab[i][ADC_CA];
	*ca = sum;	
	sum = 0;
	for(i=0;i<10;i++)
		sum += 0xfff-ADC_DualConvertedValueTab[i][ADC_CB];
	*cb = sum;
	sum = 0;
	for(i=0;i<10;i++)
		sum += 0xfff-ADC_DualConvertedValueTab[i][ADC_CC];
	*cc = sum;
//	*ca = adc_result(ADC_CA);
//	*cb = adc_result(ADC_CB);
//	*cc = adc_result(ADC_CC);
  CLR_TEST_SEL;      //模拟开关常开NO -> OFF   常闭打开NC -> ON
  DelayMsKey(1500);

}
/**********************
电源模块输出电压
**********************/
u16		GetSysVoltage(void)
{
	float  temp;
	temp = (float)adc_result(ADC_SV);
	temp = (temp/4096)*3.3*2;
	temp *= 10;
	return((u16)temp);
}

/**********************
电池电压
**********************/
u16		GetBatVoltage(void)
{
	float  temp;
	temp = (float)adc_result(ADC_BatVol);
	temp = (temp/4096)*3.3*2;
	temp *= 10;
	return((u16)temp);
}
/*******************************************
ADC 温度转换
********************************************/
const u16 NTCTab[]=
{
0xfff,//0
0xFF3,//-40℃
0xFF2,//-39℃
0xFF1,//-38℃
0xFF0,//-37℃
0xFEF,//-36℃
0xFED,//-35℃
0xFED,//-34℃
0xFEC,//-33℃
0xFEA,//-32℃
0xFE9,//-31℃
0xFE8,//-30℃
0xFE6,//-29℃
0xFE4,//-28℃
0xFE3,//-27℃
0xFE1,//-26℃
0xFDF,//-25℃
0xFDD,//-24℃
0xFDB,//-23℃
0xFD9,//-22℃
0xFD7,//-21℃
0xFD6,//-20℃
0xFD3,//-19℃
0xFD1,//-18℃
0xFCE,//-17℃
0xFCB,//-16℃
0xFC8,//-15℃
0xFC5,//-14℃
0xFC2,//-13℃
0xFBF,//-12℃
0xFBB,//-11℃
0xFB7,//-10℃
0xFB3,//-9℃
0xFAF,//-8℃
0xFAB,//-7℃
0xFA6,//-6℃
0xFA2,//-5℃
0xF9D,//-4℃
0xF98,//-3℃
0xF92,//-2℃
0xF8D,//-1℃
0xF87,//0℃
0xF81,//1℃
0xF7B,//2℃
0xF74,//3℃
0xF6D,//4℃
0xF66,//5℃
0xF5E,//6℃
0xF57,//7℃
0xF4F,//8℃
0xF46,//9℃
0xF3E,//10℃
0xF35,//11℃
0xF2B,//12℃
0xF21,//13℃
0xF17,//14℃
0xF0C,//15℃
0xF01,//16℃
0xEF5,//17℃
0xEEA,//18℃
0xEDE,//19℃
0xED1,//20℃
0xEC4,//21℃
0xEB7,//22℃
0xEA9,//23℃
0xE9A,//24℃
0xE8C,//25℃
0xE7C,//26℃
0xE6D,//27℃
0xE5D,//28℃
0xE4C,//29℃
0xE3B,//30℃
0xE2A,//31℃
0xE18,//32℃
0xE05,//33℃
0xDF2,//34℃
0xDDF,//35℃
0xDCB,//36℃
0xDB6,//37℃
0xDA1,//38℃
0xD8C,//39℃
0xD78,//40℃
0xD61,//41℃
0xD4B,//42℃
0xD33,//43℃
0xD1C,//44℃
0xD03,//45℃
0xCEB,//46℃
0xCD1,//47℃
0xCB8,//48℃
0xC9E,//49℃
0xC83,//50℃
0xC68,//51℃
0xC4D,//52℃
0xC31,//53℃
0xC15,//54℃
0xBF8,//55℃
0xBDB,//56℃
0xBBD,//57℃
0xBA0,//58℃
0xB81,//59℃
0xB63,//60℃
0xB44,//61℃
0xB25,//62℃
0xB06,//63℃
0xAE6,//64℃
0xAC6,//65℃
0xAA6,//66℃
0xA85,//67℃
0xA64,//68℃
0xA44,//69℃
0xA23,//70℃
0xA02,//71℃
0x9E0,//72℃
0x9BF,//73℃
0x99D,//74℃
0x979,//75℃
0x957,//76℃
0x935,//77℃
0x914,//78℃
0x8F2,//79℃
0x8D1,//80℃
0x8AF,//81℃
0x88E,//82℃
0x86D,//83℃
0x84C,//84℃
0x82B,//85℃
0x80A,//86℃
0x7E9,//87℃
0x7C8,//88℃
0x7A8,//89℃
0x789,//90℃
0x769,//91℃
0x74A,//92℃
0x72B,//93℃
0x70C,//94℃
0x6ED,//95℃
0x6CF,//96℃
0x6B0,//97℃
0x692,//98℃
0x675,//99℃
0x657,//100℃
0x63A,//101℃
0x61D,//102℃
0x601,//103℃
0x5E4,//104℃
0x5C8,//105℃
0x5AD,//106℃
0x592,//107℃
0x577,//108℃
0x55C,//109℃
0x542,//110℃
0x528,//111℃
0x50F,//112℃
0x4F6,//113℃
0x4DD,//114℃
0x4C3,//115℃
0x4AB,//116℃
0x493,//117℃
0x47C,//118℃
0x463,//119℃
0x44F,//120℃
0x439,//121℃
0x424,//122℃
0x40E,//123℃
0x3FA,//124℃
0x3E5,//125℃
0x3D1,//126℃
0x3BE,//127℃
0x3AA,//128℃
0x397,//129℃
0x385,//130℃
0x373,//131℃
0x361,//132℃
0x34F,//133℃
0x33E,//134℃
0x32E,//135℃
0x31D,//136℃
0x30D,//137℃
0x2FD,//138℃
0x2EE,//139℃
0x2E0,//140℃
0x2D1,//141℃
0x2C2,//142℃
0x2B4,//143℃
0x2A6,//144℃
0x298,//145℃
0x28B,//146℃
0x27E,//147℃
0x271,//148℃
0x264,//149℃
0x258,//150℃
0x24B,//151℃
0x240,//152℃
0x234,//153℃
0x229,//154℃
0x21D,//155℃
0x212,//156℃
0x208,//157℃
0x1FD,//158℃
0x1F3,//159℃
0x1E9,//160℃
0x254,//161℃
0x24C,//162℃
0x243,//163℃
0x23B,//164℃
0x232,//165℃
0x22A,//166℃
0x222,//167℃
0x21A,//168℃
0x212,//169℃
0x20A,//170℃
0x203,//171℃
0x1FB,//172℃
0x1F4,//173℃
0x1ED,//174℃
0x1E6,//175℃
0x1DE,//176℃
0x1D7,//177℃
0x1D1,//178℃
0x1CA,//179℃
0x1C3,//180℃
0x1BD,//181℃
0x1B6,//182℃
0x1B0,//183℃
0x1AA,//184℃
0x1A4,//185℃
0x19E,//186℃
0x198,//187℃
0x192,//188℃
0x18C,//189℃
0x186,//190℃
0x181,//191℃
0x17B,//192℃
0x176,//193℃
0x170,//194℃
0x16B,//195℃
0x166,//196℃
0x161,//197℃
0x15C,//198℃
0x157,//199℃
0x152,//200℃
0x14D,//201℃
0x148,//202℃
0x144,//203℃
0x13F,//204℃
0x13B,//205℃
0x136,//206℃
0x132,//207℃
0x12D,//208℃
0x129,//209℃
0x125,//210℃
0x121,//211℃
0x11D,//212℃
0x119,//213℃
0x115,//214℃
0x111,//215℃
0x10D,//216℃
0x10A,//217℃
0x106,//218℃
0x102,//219℃
0x0FF,//220℃

0x000 //短路



};



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


// ADC 编号选择
// 可以是 ADC1/2,如果使用ADC3,中断相关的要改成ADC3的
#define    ADC_APBxClock_FUN             RCC_APB2PeriphClockCmd
#define    ADCx                          ADC1
#define    ADC_CLK                       RCC_APB2Periph_ADC1

// ADC GPIO宏定义
#define  TEST_SEL_PORT		GPIOC
#define  TEST_SEL_PIN 		(1<<9)	 //PC9 模块开关选择
#define  CLR_TEST_SEL 		TEST_SEL_PORT->ODR &= ~TEST_SEL_PIN 
#define	 SET_TEST_SEL 		TEST_SEL_PORT->ODR |= TEST_SEL_PIN	


// 注意:用作ADC采集的IO必须没有复用,否则采集电压会有影响
#define    ADC_GPIO_APBxClock_FUN        RCC_APB2PeriphClockCmd
#define    ADC_GPIO_CLK                  RCC_APB2Periph_GPIOC  
#define    ADC_PORT_T                    GPIOA
#define    ADC_PIN_T1                    GPIO_Pin_7
#define    ADC_PIN_T2                    GPIO_Pin_6
#define    ADC_PIN_T3                    GPIO_Pin_5
#define    ADC_PIN_T4                    GPIO_Pin_4
#define    ADC_PORT_L                    GPIOB
#define    ADC_PIN_L1                    GPIO_Pin_0
#define    ADC_PIN_L2                    GPIO_Pin_1

#define    ADC_PORT_V                    GPIOC
#define    ADC_PIN_L3                    GPIO_Pin_0
#define    ADC_PIN_L4                    GPIO_Pin_1

#define    ADC_PIN_V1                    GPIO_Pin_2 //开关电源
#define    ADC_PIN_V2                    GPIO_Pin_3 //电池
// ADC 通道宏定义
#define    ADC_CHANNEL_T1                ADC_Channel_7
#define    ADC_CHANNEL_T2                ADC_Channel_6
#define    ADC_CHANNEL_T3                ADC_Channel_5
#define    ADC_CHANNEL_T4                ADC_Channel_4

#define    ADC_CHANNEL_L1   ADC_Channel_8 //漏电
#define    ADC_CHANNEL_L2   ADC_Channel_9 //A相
#define    ADC_CHANNEL_L3   ADC_Channel_10
#define    ADC_CHANNEL_L4   ADC_Channel_11
#define    ADC_CHANNEL_V1   ADC_Channel_12  //开关电源
#define    ADC_CHANNEL_V2   ADC_Channel_13 //电池

#define    ADC_LC1  4
#define    ADC_CA  5
#define    ADC_CB  6
#define    ADC_CC  7
#define    ADC_SV  8
#define    ADC_BatVol  9

// ADC 中断相关宏定义
#define    ADC_IRQ                       ADC1_2_IRQn
#define    ADC_IRQHandler                ADC1_2_IRQHandler

//#define    ADC_IRQ                       ADC3_IRQn
//#define    ADC_IRQHandler                ADC3_IRQHandler
#define ADC1_DR_Address    ((uint32_t)0x4001244C)

void ADCx_Init(void);

int temp_LookUp(uchar a);
void CheckLeak(u16	*lc,u16 *ca,u16 *cb,u16 *cc);
u16		GetSysVoltage(void);
u16		GetBatVoltage(void);

#endif


  • 2
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

fpd_led

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值