void ADC_3_task((void *p_agr) //3ADC,3路通道任务,转换速度每通道都为1M
{
OS_ERR err;
u16 adcx[3];
u32 AD1[3];
u32 AD[3];
u16 ADV1[3];
u16 ADV2[3];
Adc_3_Init(); //3ADC初始化
MYDMA_Config(DMA1_Channel1,(u32)&ADC1->DR,(u32)&AD1,3,32);//DMA1通道1,外设为ADC1,存储器为adcx,长度8,32位数据宽度
MYDMA_Config(DMA2_Channel5,(u32)&ADC3->DR,(u32)&adcx,3,16);//DMA1通道1,外设为ADC1,存储器为adcx,长度8.16位数据宽度
ADC1->CR2|=1<<22; //开始规则转换
ADC3->CR2|=1<<22; //开始规则转换
while(1)
{
AD[0]=AD1[0];
AD[1]=AD1[1];
AD[2]=AD1[2];
ADV1[0]=AD[0]; //提取低半字
ADV2[0]=AD[0]>>16;
ADV1[1]=AD[1]; //提取低半字
ADV2[1]=AD[1]>>16;
ADV1[2]=AD[2]; //提取低半字
ADV2[2]=AD[2]>>16;
OLED_ShowNum(16,16,ADV1[0],4,16);//显示ADC的值
OLED_ShowNum(56,16,ADV2[0],4,16);//显示ADC的值
OLED_ShowNum(96,16,adcx[0],4,16);//显示ADC的值
OLED_ShowNum(16,32,(u16)((float)ADV1[0]*(3300.0/4096)),4,16);//显示ADC的值
OLED_ShowNum(56,32,(u16)((float)ADV2[0]*(3300.0/4096)),4,16);//显示ADC的值
OLED_ShowNum(96,32,(u16)((float)adcx[0]*(3300.0/4096)),4,16);//显示ADC的值
OLED_Refresh_Gram();
OSTimeDlyHMSM(0,0,0,500,OS_OPT_TIME_PERIODIC,&err);//延时5ms
}
}
void Adc_3_Init(void)
{
RCC->APB2ENR|=1<<4; //全能PORTC口时钟
GPIOC->CRL&=0XFFFFF000; //PC0、PC1、PC2模拟输入
RCC->APB2ENR|=1<<9; //ADC1时钟使能
RCC->APB2ENR|=1<<10; //ADC2时钟使能
RCC->APB2ENR|=1<<15; //ADC3时钟使能 ADC3数据由DMA2 通道5控制
RCC->APB2RSTR|=1<<9; //ADC1复位
RCC->APB2RSTR|=1<<10; //ADC2复位
RCC->APB2RSTR|=1<<15; //ADC3复位
RCC->APB2RSTR&=~(1<<9|1<<10|1<<15);//复位结束
RCC->CFGR&=~(3<<14); //分频因子清零
RCC->CFGR|=1<<15;//设置为4分频给ADC转换时钟
//SYSCLK/DIV2=12M ADC时钟设置为12M,ADC最大时钟不能超过14M!
//否则将导致ADC准确度下降!
ADC1->CR1&=0XF0FFFF; //工作模式清零
ADC1->CR1|=6<<16; //同步规则模式 此寄存器只有ADC1有,ADC2 3此位为保留位
ADC1->CR1|=1<<8; //扫描模式
ADC2->CR1|=1<<8; //扫描模式
ADC3->CR1|=1<<8;
ADC1->CR2|=1<<1; //连续转换模式
ADC2->CR2|=1<<1;
ADC3->CR2|=1<<1;
ADC1->CR2&=~(7<<17); //清除外部事件
ADC2->CR2&=~(7<<17);
ADC3->CR2&=~(7<<17);
ADC1->CR2|=7<<17; //软件控制转换
ADC1->CR2|=1<<20; //使用外部触发(SWSTART)!!! 必须使用一个事件来触发
ADC2->CR2|=7<<17; //软件控制转换
ADC2->CR2|=1<<20; //使用外部触发(SWSTART)!!! 必须使用一个事件来触发
ADC3->CR2|=7<<17; //软件控制转换
ADC3->CR2|=1<<20; //使用外部触发(SWSTART)!!! 必须使用一个事件来触发
ADC1->CR2&=~(1<<11); //右对齐
ADC2->CR2&=~(1<<11);
ADC3->CR2&=~(1<<11);
ADC1->CR2|=1<<0; //开启AD转换器
ADC2->CR2|=1<<0;
ADC3->CR2|=1<<0;
ADC1->CR1|=1<<23; //在规格通道上开启模拟看门狗(监测所有规则通道)
ADC2->CR1|=1<<23;
ADC3->CR1|=1<<23;
ADC1->CR1|=1<<6; //允许产生模拟看门狗中断
ADC2->CR1|=1<<6;
ADC3->CR1|=1<<6;
//ADC1->CR1|=* //模拟看门狗通道选择位 4:0,
ADC1->HTR=3000; //ADC看门狗高阀值寄存器
ADC2->HTR=4000;
ADC3->HTR=3000;
ADC1->LTR=1000; //ADC看门狗低阀值寄存器
ADC2->LTR=100;
ADC3->LTR=300;
NVIC->ISER[0]=1<<18; //ADC1 2中断向量
NVIC->ISER[1]=1<<15; //ADC3 中断向量
ADC1->SQR1&=~(0XF<<20);
ADC1->SQR1|=0<<20; //1个转换在规则序列中
ADC2->SQR1&=~(0XF<<20);
ADC2->SQR1|=0<<20; //1个转换在规则序列中
ADC3->SQR1&=~(0XF<<20);
ADC3->SQR1|=0<<20;
// ADC1->SMPR1&=~(7<<0); //清除通道10原来的设置
// ADC1->SMPR1|=7<<0; //通道10 239.5周期,提高采样时间可以提高精确度
//
// ADC2->SMPR1&=~(7<<3); //清除通道11原来的设置
// ADC2->SMPR1|=7<<3; //通道11 239.5周期,提高采样时间可以提高精确度
//
// ADC3->SMPR1&=~(7<<6); //清除通道12原来的设置
// ADC3->SMPR1|=7<<6; //通道12 239.5周期,提高采样时间可以提高精确度
ADC1->CR2|=1<<8; //允许DMA访问 只有ADC1 和ADC3能使用DMA
ADC3->CR2|=1<<8;
ADC1->CR2|=1<<3; //使能复位校准
while(ADC1->CR2&1<<3); //等待校准结束 //该位由软件设置并由硬件清除。在校准寄存器被初始化后该位将被清除。
ADC2->CR2|=1<<3; //使能复位校准
while(ADC2->CR2&1<<3); //等待校准结束 //该位由软件设置并由硬件清除。在校准寄存器被初始化后该位将被清除。
ADC3->CR2|=1<<3; //使能复位校准
while(ADC3->CR2&1<<3); //等待校准结束 //该位由软件设置并由硬件清除。在校准寄存器被初始化后该位将被清除。
ADC1->CR2|=1<<2; //开启AD校准 开启ADC校准之前ADC必须处于断电状态2个ADC时钟周期
while(ADC1->CR2&1<<2); //等待校准结束 //该位由软件设置以开始校准,并在校准结束时由硬件清除
ADC2->CR2|=1<<2; //开启AD校准
while(ADC2->CR2&1<<2); //等待校准结束 //该位由软件设置以开始校准,并在校准结束时由硬件清除
ADC3->CR2|=1<<2; //开启AD校准
while(ADC3->CR2&1<<2); //等待校准结束 //该位由软件设置以开始校准,并在校准结束时由硬件清除
// ADC1->CR2|=1<<22; //开始规则转换
// ADC2->CR2|=1<<22;
// ADC3->CR2|=1<<22;
ADC1->SQR3=10;
ADC2->SQR3=11;
ADC3->SQR3=12;
}