在ad实验时,AD在100mv内与万用表差距不大,当到600mv时,比万用表显示值大50mv左右。
ADC->CCR|=ADC_CCR_ADCPRE_1;//这里配置ADC的HSI分频,通过swd调试看,内部并没有写成功?
void ADC_Init (void) {
RCC->AHBENR |= ( 1UL << 1); /* Enable GPIOB clock */
GPIOB->MODER |= ( 3UL << 2*13); /* PB.12 is Analog mode */
#ifndef __ADC_IRQ
/* DMA1 Channel1 configuration ---------------------------------------------*/
RCC->AHBENR |= (1UL << 24); /* enable DMA1 clock */
DMA1_Channel1->CMAR = (uint32_t)&AD_last; /* Set memory address */
DMA1_Channel1->CPAR = (uint32_t)&(ADC1->DR); /* Set peripheral address */
DMA1_Channel1->CNDTR = 1; /* Transmit 1 data item */
DMA1_Channel1->CCR = 0x00002522; /* configure DMA channel */
NVIC_EnableIRQ(DMA1_Channel1_IRQn); /* enable DMA1 Channel Interrupt */
DMA1_Channel1->CCR |= (1UL << 0); /* enable DMA channel 1 */
#endif
/* Setup and initialize ADC converter */
RCC->CR |= ( 1UL << 0); /* Enable Internal high-speed clock */
RCC->APB2ENR |= ( 1UL << 9); /* enable periperal clock for ADC1 */
ADC->CCR|=ADC_CCR_ADCPRE_1;//这里配置ADC的HSI分频,通过swd调试看,内部并没有写成功?
ADC1->CR1 = ( 1UL << 8); /* Scan mode on, 12 Bit */
ADC1->CR2 = 0;
ADC1->SQR1 = 0; /* Regular chn. Sequence length = 1 */
ADC1->SQR2 = 0; /* Clear register */
ADC1->SQR3 = 0; /* Clear register */
ADC1->SQR4 = 0; /* Clear register */
ADC1->SQR5 = (19UL << 0); /* 1. conversion = channel 18 */
ADC1->SMPR1 = 0 ; /* Clear register */
ADC1->SMPR2 =(7UL << 27); /* Chn 18 sample time is 48 cyc */
#ifndef __ADC_IRQ
ADC1->CR2 |= ( 3UL << 8); /* DMA mode enable, cont. DMA req. */
#else
ADC1->CR1 |= ( 1UL << 5); /* enable for EOC Interrupt */
NVIC_EnableIRQ(ADC1_IRQn); /* enable ADC Interrupt */
#endif
ADC1->CR2 |= ( 1UL << 0); /* ADC enable */
}
/*----------------------------------------------------------------------------
start AD Conversion
*----------------------------------------------------------------------------*/
void ADC_StartCnv (void) {
if ((ADC1->SR & ((1 << 6) | (1 << 8))) == (1 << 6)) {
ADC1->CR2|= (1UL << 30); /* Start A/D conversion */
}
}
/*----------------------------------------------------------------------------
get converted AD value
*----------------------------------------------------------------------------*/
uint16_t ADC_GetCnv (void) {
while (!(AD_done)); /* Wait for Conversion end */
AD_done = 0;
return(AD_last);
}
/*----------------------------------------------------------------------------
A/D IRQ: Executed when A/D Conversion is done
*----------------------------------------------------------------------------*/
void ADC1_IRQHandler(void) {
if (ADC1->SR & (1 << 1)) { /* ADC1 EOC interrupt? */
AD_last = ADC1->DR;
AD_done = 1;
ADC1->SR &= ~(1 << 1); /* clear EOC interrupt */
}
}
int main(void)
{
u8 t;
u16 ad_val,ad_val_;
u16 ad_avg;
delay_init(24);
delay_s(5);
uart_init(24,9600);
ADC_Init();
LED_Init();
while(1)
{
delay_ms(1000);
PAout(1)=~(PAout(1));
for(t=0;t<16;t++)
{
ADC_StartCnv();
ad_val=ADC_GetCnv();
ADC_StartCnv();
ad_val_=ADC_GetCnv();
if(ad_val>>8==ad_val_>>8)
ad_avg+=ad_val;
else t--;
delay_ms(1);
}
ad_avg/=16;
printf("ADC = %04X Volt = %d mv\r\n", ad_avg, ad_avg*2948/4096);
}
}
file:///D:\My Documents\Tencent Files\18930478\Image\MT}()VLZHIOCJR7YK2_N}WQ.jpg
大虾给看看呗。呵呵
|