本帖最后由 黑洞不黑 于 2019-7-14 17:32 编辑
//初始化ADC端口
void ADC_IO_init(void)
{
RCC->APB2ENR|=1<<2; //使能PORTA时钟
RCC->APB2ENR|=1<<3; //使能PORTB时钟
RCC->APB2ENR|=1<<4; //使能PORTC时钟
GPIOA->CRL&=0X0000FFFF;//PA4-PA7 模拟输入
GPIOB->CRL&=0XFFFFFF00;//PB0-PB1 模拟输入
GPIOC->CRL&=0XFF000000;//PC0-PC5 模拟输入
}
//初始化ADC
void ADC_init(void)
{
//先初始化IO口
ADC_IO_init();
// //通道13设置
RCC->APB2ENR|=1<<9; //ADC1时钟使能
RCC->APB2RSTR|=1<<9; //ADC1复位
RCC->APB2RSTR&=~(1<<9);//复位结束
// //SYSCLK/DIV2=12M ADC时钟设置为12M(6分频),ADC最大时钟不能超过14M!
// //否则将导致ADC准确度下降!
RCC->CFGR&=~(3<<14); //分频因子清零
RCC->CFGR|=2<<14; //ADC6分频
ADC1->CR1&=0XF0FFFF; //工作模式清零
ADC1->CR1|=0<<16; //独立工作模式
ADC1->CR1&=~(1<<8); //非扫描模式
ADC1->CR2&=~(1<<1); //单次转换模式
ADC1->CR2&=~(7<<17);
ADC1->CR2|=7<<17; //软件控制转换
ADC1->CR2|=1<<20; //使用用外部触发(SWSTART)!!! 必须使用一个事件来触发
ADC1->CR2&=~(1<<11); //右对齐
ADC1->SQR1&=~(0XF<<20);
ADC1->SQR1|=12<<20; //12个转换在规则序列中
//
// //设置通道1的采样时间
ADC1->SMPR2=0x3ffff000; //通道4-9 239.5周期,提高采样时间可以提高精确度
ADC1->SMPR2=0x0003ffff; //通道10-15 239.5周期,提高采样时间可以提高精确度
ADC1->CR2|=1<<0; //打开AD转换器
ADC1->CR2|=1<<3; //使能复位校准
while(ADC1->CR2&1<<3); //等待校准结束
// //该位由软件设置并由硬件清除。在校准寄存器被初始化后该位将被清除。
ADC1->CR2|=1<<2; //开启AD校准
while(ADC1->CR2&1<<2); //等待校准结束
MY_NVIC_Init(1,0,ADC1_2_IRQn,1);//抢占优先级0,子优先级0,组0
ADC1->CR1|=1<<5; //打开规则转换中断
// ADC1->SQR3=0xffffffe0; //选择规则序列1
ADC1->SQR3|=ADC_ch;
ADC1->CR2|=1<<22; //启动规则转换通道
}
这是ADC相关的初始化程序,用的中断读取ADC数值,第一版的时候没发现问题,后面就有问题了,而且是有时候不行有时候正常 |