新手上路
- 积分
- 29
- 金钱
- 29
- 注册时间
- 2017-9-9
- 在线时间
- 4 小时
|
5金钱
以下是代码:
void adc2_init(void)
{
//使能PB0 配置为模拟输入功能
RCC->APB2ENR |= 0x01<<3;
GPIOB->CRL &= ~(0xf<<0);
//使能ADC2
RCC->APB2ENR |= 0x01 <<10;
// //复位ADC2
// RCC->APB2RSTR|=1<<10;
// RCC->APB2RSTR&=~(1<<10);//复位结束
RCC->CFGR&=~(3<<14); //分频因子清零
//SYSCLK/DIV2=12M ADC时钟设置为12M,ADC最大时钟不能超过14M!
//否则将导致ADC准确度下降!
RCC->CFGR|=2<<14; // PCLK2 6分频作为ADC时钟
//模块初始化
ADC2->CR1&=0XF0FFFF; //工作模式清零
ADC2->CR1|=0<<16; //独立工作模式
ADC2->CR1&=~(1<<8); //非扫描模式
ADC2->CR2&=~(1<<1); //单次转换模式
ADC2->CR2&=~(7<<17); //外部事件清零
ADC2->CR2|=7<<17; //软件控制转换
ADC2->CR2|=1<<20; //使用用外部触发(SWSTART) 必须使用一个事件来触发
ADC2->CR2&=~(1<<11); //右对齐
ADC2->SQR1&=~(0XF<<20); //规则通道一个转换
ADC2->SQR1|=0<<20; //1个转换在规则序列中 也就是只转换规则序列1
//设置通道8的采样时间
ADC2->SMPR2 &= ~(7<<24);//通道0,1,2,3采样时间清空
ADC2->SMPR2 |= 7<<24; //通道8 239.5周期,提高采样时间可以提高精确度
ADC2->CR2|=1<<0; //开启AD转换器
ADC2->CR2|=1<<3; //使能复位校准
while(ADC1->CR2&1<<3); //等待校准结束
//该位由软件设置并由硬件清除。在校准寄存器被初始化后该位将被清除。
ADC2->CR2|=1<<2; //开启AD校准
while(ADC2->CR2&1<<2); //等待校准结束
//该位由软件设置以开始校准,并在校准结束时由硬件清除
}
//获得ADC值
//通道值 8
u16 Get_Adc(void)
{
u16 DATE;
//设置转换序列
ADC2->SQR3&=0XFFFFFFE0;//规则序列1 通道8
ADC2->SQR3|=8<<0;
ADC2->CR2|=1<<22; //启动规则转换通道
DATE= ADC2->DR;
while(!(ADC2->SR&1<<1));
// while((ADC2->SR &(0X01<<1))==0);//等待转换结束
return DATE; //返回adc值
}
#define N 7
//连续采样N个数据,去掉一个最大值和一个最小值
//然后计算N-2个数据的算术平均值
u16 gets_adc2_ch8(void)
{
char temp=0;
char count,i,j;
int value_buf[N];
int sum=0;
for (count=0;count<N;count++)
{
value_buf[count] = Get_Adc();
delay_us(2000);
}
for (j=0;j<N-1;j++)
{
for (i=0;i<N-j;i++)
{
if ( value_buf>value_buf[i+1] )
{
temp = value_buf;
value_buf = value_buf[i+1];
value_buf[i+1] = temp;
}
}
}
for(count=1;count<N-1;count++)
sum += value_buf[count];
return (char)(sum/(N-2));
}
int main()
{
u32 adc=0;
u32 adc_num=0;
float temp;
float count=0;
adc2_init();
while(1)
{
adc=gets_adc2_ch8();
delay_ms(500);
temp=(float)adc*5000/4096;
adc_num = (temp *100/5);
delay_ms(500);
}
}
|
|