Electoday 4.0

ไมโครคอนโทรลเลอร์ => ARM Processors => Topic started by: Jimmkung on March 02, 2013, 02:15:33 am

Title: ADC อ่านค่าไม่ตรงครับ STM32F107 รบกวนผู้รู้ช่วยทีครับ
Post by: Jimmkung on March 02, 2013, 02:15:33 am
ผมอยากทราบอาการที่ทำไม ADC ถึงอ่านค่าเพี้ยนครับ โดยที่ผมจับที่ 0v ก็อ่านได้ 0 และที่ 3.3v ก็อ่านได้ 4095 แต่แทนที่1.5v จะอ่านได้ ประมาณ 2095 แต่กลับอ่านออกมาได้ถึง 3805 ครับ ผมแปลกใจมาก setting ADC ใหม่ก็ไม่หาย ผมใช้ ride7 ครับ
ปล. ผมเอามิเตอร์จับที่ขา adcแล้ว ก็ประมานแค่ 0.2v ผมคิดว่าปัญหาน่าจะอยู่ที่การ init ADC มากกว่าครับ ถ้าผมเข้าใจผิดอย่างไรรบกวนผู้รู้ช่วยแนะนำด้วยน่ะครับ :'(
Title: Re: ADC อ่านค่าไม่ตรงครับ STM32F107 รบกวนผู้รู้ช่วยทีครับ
Post by: tha on March 03, 2013, 09:27:51 am
น่าจะใช่ การ set sampling time ก็อาจจะมีผลด้วยบ้างเป็นบางกรณี สรุปแล้วยังไม่รู้สาเหตที่แน่นอน ข้อมูลน้อยไปหน่อย
Title: Re: ADC อ่านค่าไม่ตรงครับ STM32F107 รบกวนผู้รู้ช่วยทีครับ
Post by: deejun on March 04, 2013, 02:28:48 pm
มีโค๊ดตัวอย่างมั๊ยครับที่เขียน  เผือมีอะไรที่ไม่ถูกต้องได้มีหลายท่านช่วยดู
สิ่งที่สงสัยคือ
1 0V  อ่านค่าได้ถูก  ค่าคือ 0 และ  3.3V อ่านได้ถูก 4095     เคยลองเอามิเตอร์จับดูหรือไม่ว่าโวลต์ได้จริง
2 ที่ประมาณว่า  1.5V  จะต้องได้ค่า    1861 ครับ  และลองวัดโวลต์ว่าได้ 1.5vหรือไม่
3 VR มีแบบค่าเอ็กโปร และแบบลีเนีย  การหมุนรอบองศาเท่ากัน  แต่ค่าไม่เท่ากัน  ยกเว้นช่วงสูงสุด และต่ำสูด เท่ากัน
Title: Re: ADC อ่านค่าไม่ตรงครับ STM32F107 รบกวนผู้รู้ช่วยทีครับ
Post by: activefilter on March 05, 2013, 04:24:55 pm
ค่า 3.3 V ที่ ป้อน ให้มัน น่า จะเลย Full Scale ไปแล้ว ค่า ที่เลย  Full Scale จะอ่าน ได้ 4095 ตลอด

ที่ถูก ต้อง เรา จะต้อง  ค่อยๆปรับ แรงดัน ขึ้น พร้อมแสดงผลขณะปรับ พอได้ค่า 4094 ก็หยุดได้แล้ว ถ้าเพิ่มแรงดัน เราอาจ หมุนเกิน 4095 จะ ทำให้เราคำนวณผิด

แต่กรณีนี้ FULL SCALE น่าจะอยู่ ที่ แค่ 2.0 ไม่ใช่ 3.3 
 
   คำนวณจาก       1.5*(4096/3805)=  1.99

Title: Re: ADC อ่านค่าไม่ตรงครับ STM32F107 รบกวนผู้รู้ช่วยทีครับ
Post by: Jimmkung on March 05, 2013, 05:27:34 pm
อันนี้เป็น code ที่ผมเขียนแล้วแสดงค่าทาง UART ครับ
จนปัญญาแล้ว เสียเวลาเซตมาหลายวันแล้วครับ รบกวนผู้รู้ช่วยแนะนำทีน่ะครับ

#include "stm32f10x_lib.h"

VU16 ADC_ConvertedValue;
char str[14];

//------------------------------ Function RCC Configuration ------------------------------------------//
void RCC_setup()
{
   ErrorStatus HSEStartUpStatus; // Keep error status
   RCC_DeInit();      // RCC system reset(for debug purpose)
   RCC_HSEConfig(RCC_HSE_ON);  // Enable HSE
   HSEStartUpStatus = RCC_WaitForHSEStartUp();   // Wait till HSE is ready
   if(HSEStartUpStatus == SUCCESS)
   {
      RCC_HCLKConfig(RCC_SYSCLK_Div1); // HCLK = SYSCLK
      RCC_PCLK2Config(RCC_HCLK_Div1); // PCLK2 = HCLK
      RCC_PCLK1Config(RCC_HCLK_Div4); // PCLK1 = HCLK/2
      RCC_ADCCLKConfig(RCC_PCLK2_Div4);  // ADCCLK = PCLK2/4
      FLASH_SetLatency(FLASH_Latency_2); // Flash 2 wait state
      FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);  // Enable Prefetch Buffer
      RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9);   // PLLCLK = 8MHz * 9 = 72 MHz
   
      RCC_PLLCmd(ENABLE);  // Enable PLL 
      while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);   // Wait until PLL is ready
     
      RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);  // Select PLL as system clock source
      while(RCC_GetSYSCLKSource() != 0x08); // Wait till PLL is used as system clock source
   }
   
}

//------------------------------ Function GPIO Configuration -----------------------------------------//
void GPIO_setup()
{
   GPIO_InitTypeDef GPIO_InitStructure;
   // Enable GPIOC clock and Enable GPIOA and AFIO clock
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO,ENABLE);
   
   // Configure PC4 as analog input(ADC Channel14)       //ADC_CH1(ADC10)
   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
   GPIO_Init(GPIOC, &GPIO_InitStructure);

   // Configure USART1 Tx (PA9) as alternate function push-pull
   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
   GPIO_Init(GPIOA, &GPIO_InitStructure);
   // Configure USART1 Rx (PA10) as input floating
   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
   GPIO_Init(GPIOA, &GPIO_InitStructure);
}

//------------------------------ Function DMA Configuration ------------------------------------------//
void DMA_setup()
{
   DMA_InitTypeDef DMA_InitStructure;
   // Enable DMA clock
   RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
   // DMA channel1 configuration
   DMA_DeInit(DMA1_Channel1);
   DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&ADC1->DR;
   DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADC_ConvertedValue;
   DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
   DMA_InitStructure.DMA_BufferSize = 1;
   DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
   DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
   DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
   DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
   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);
   DMA_Cmd(DMA1_Channel1, ENABLE);   // Enable DMA channel1
}

//------------------------------ Function ADC Configuration ------------------------------------------//
void ADC_setup()
{
   ADC_InitTypeDef ADC_InitStructure;
   // Enable ADC1 clock
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
   // ADC1 configuration
   ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
   ADC_InitStructure.ADC_ScanConvMode = DISABLE;
   ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
   ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
   ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
   ADC_InitStructure.ADC_NbrOfChannel = 1;
   ADC_Init(ADC1, &ADC_InitStructure);
   // ADC1 regular channel14 configuration 
   ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 1, ADC_SampleTime_13Cycles5);
   ADC_DMACmd(ADC1, ENABLE);  // Enable ADC1 DMA
   ADC_Cmd(ADC1, ENABLE);  // Enable ADC1
 
   ADC_ResetCalibration(ADC1);   // Enable ADC1 reset calibaration register
   while(ADC_GetResetCalibrationStatus(ADC1));
 
   ADC_StartCalibration(ADC1);   // Start ADC1 calibration
   while(ADC_GetCalibrationStatus(ADC1)); // Check the end of ADC1 calibration
   ADC_SoftwareStartConvCmd(ADC1, ENABLE);    // Start ADC1 Software Conversion 
}

//------------------------------ Function USART1 Configuration -----------------------------------------//
void USART1_setup()
{
   USART_InitTypeDef USART_InitStructure;
   // Enable USART1 clock
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
   // USART1 configured
   USART_InitStructure.USART_BaudRate = 115200;
   USART_InitStructure.USART_WordLength = USART_WordLength_8b;
   USART_InitStructure.USART_StopBits = USART_StopBits_1;
   USART_InitStructure.USART_Parity = USART_Parity_No;
   USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
   USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
   
   USART_Init(USART1, &USART_InitStructure); // Configure the USART1
   USART_Cmd(USART1, ENABLE);  // Enable USART1
   
}

//------------------------------ Function USART1 send 1 character ------------------------------------//
void usart1_putc(unsigned char c)
{
   while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);   // Wait until transmition ready
   USART_SendData(USART1,(int)c);   // Send character
}

//------------------------------ Function USART1 send string -----------------------------------------//
void usart1_puts(unsigned char *s)
{
   while(*s)   // Check end of string
   {
      usart1_putc(*s++);   // Send charracter 1 time
   }
}

//------------------------------ Function USART1 wait character --------------------------------------//
int usart1_getc()
{
   while(USART_GetFlagStatus(USART1,USART_FLAG_RXNE)==RESET);   // Wait until receive data
   return(USART_ReceiveData(USART1));  // Return  character
}

//---------------------------------------- Main Program ----------------------------------------------//
int main()
{   
   unsigned long percentage;
   
   RCC_setup();       // RCC Configuration   
   GPIO_setup();      // GPIO Configuration
   DMA_setup();       // DMA Configuration
   ADC_setup();       // ADC Configuration
 
   USART1_setup();    // USART1 Configuration
   
  while(1)       
   { 
         
      percentage = ADC_ConvertedValue;     
      sprintf(str,"%d%%   ",percentage);  // Convert percentage value to string
      usart1_puts(str);       // Send character from buffer
      usart1_puts("\r\n");    // New line
      delay_ms(100);     // Delay a few time 
     
   }
}
Title: Re: ADC อ่านค่าไม่ตรงครับ STM32F107 รบกวนผู้รู้ช่วยทีครับ
Post by: Jimmkung on March 05, 2013, 05:50:39 pm
ตอนนี้ผมกำลังสงสัยอยู่สองกรณีครับคือ
1. ผม set ADC config ผิด
2. STM32F107VBT6 ของผมมีปัญหา

เพราะผมลองเอาโค้ดตัวอย่างแบบที่ไม่ได้ใช้ DMA มาลองมันก็ยังอ่านไม่ตรงครับ ลองตามหนังสือเค้าทุกอย่าง เปลี่ยนไปใช้ ADC ช่องเดียวกับเค้าด้วยก็ไม่หาย

Case ADC ของผมในตอนนี้น่ะครับ
1. ที่ 0 V ADC อ่านได้ 0 จริง ลองเอามิเตอร์มาจับก็ 0 โวลต์จริงครับ
2. ที่ 3.3 V ADC อ่านได้ 4095 จริง ลองเอามิเตอร์มาจับก็ 3.3V จริงครับ
3. VR แบบที่ผมเลือกใช้เป็นแบบ Linear ครับ เอามิเตอร์วัดตลอดช่วงครับ
4. ผมลองเอา R 2 ตัวมาต่อแบบ Voltage Divider โดยใช้ R 2 ตัว ค่าเท่ากัน จ่ายไฟเลี้ยง ที่ 3.3V ดังนั้นเมื่อผ่านวงจร Voltage Divider จะเหลือ 1.65 ลองเอามิเตอร์มาวัด
ก็ได้ค่าตามที่คำนวณจริงครับ
5. ผมเอาสัญญาณที่ผ่านวงจร Voltage divider แล้ว เข้า ADC1 channel 14 ซึ่งก็น่าจะอ่านได้ 2048 แต่ปรากฏว่า ณ ปัจจุบันตามโค้ตที่ผมโพสไว้ ผมอ่าน ADC ได้ 2904
ซึ่งแตกต่างจากค่าความเป็นจริงอยู่ถึงประมาณ 900

Case Setting ADC ที่ผมเคยลองน่ะครับ
1.ผมลองเปลี่ยน sampling time จาก 13.5 เป็น 7.5, 5.5 , 28.5 ก็ไม่มีความแตกต่างจากเดิมครับ
2.ผมลองเปลี่ยน ADC_InitStructure.ADC_Mode จาก Independent เป็น ADC_Mode_FastInterl, ADC_Mode_RegSimlt ก็ไม่มีความแตกต่างเช่นกันครับ

ปล.รบกวนผู้รู้ทุกท่านที่เมตตา ที่ให้คำปรึกษาได้ฝากเบอร์โทรไว้ใน Terawat.k@gmail.com ให้ผมโทรไปถามท่านจะขอบคุณมากๆครับ
Title: Re: ADC อ่านค่าไม่ตรงครับ STM32F107 รบกวนผู้รู้ช่วยทีครับ
Post by: crywolf on March 05, 2013, 06:00:28 pm
ลองดู Code ของผมนะครับ http://www.electoday.com/index.php?topic=447.msg1388#msg1388
ผม Test บน STM32-Discovery แสดงผลได้ถูต้อง ลอง Print มาโชว์ดูครับ ADC_RAW_Value นะครับ
Title: Re: ADC อ่านค่าไม่ตรงครับ STM32F107 รบกวนผู้รู้ช่วยทีครับ
Post by: Jimmkung on March 05, 2013, 06:21:35 pm
@ คุณ crywolf ผมลองตามวิธีของคุณแล้วปรากฏว่ามันก็ยังอ่านได้ 2905 เท่าเดิมเลยครับ ผมว่าสงสัย STM32F107VBT6 ของผมจะกลับบ้านเก่าไปแล้วแน่ๆเลยครับ
Title: Re: ADC อ่านค่าไม่ตรงครับ STM32F107 รบกวนผู้รู้ช่วยทีครับ
Post by: crywolf on March 05, 2013, 06:57:58 pm
ขอดู Code ทั้งหมดได้มั้ยครับ ส่งมาเป็นไฟล์เลยครับ
Title: Re: ADC อ่านค่าไม่ตรงครับ STM32F107 รบกวนผู้รู้ช่วยทีครับ
Post by: Jimmkung on March 05, 2013, 07:08:09 pm
#include "stm32f10x_lib.h"

unsigned short ADC_ConvertedValue;
char str[14];

//------------------------------ Function RCC Configuration ------------------------------------------//
void RCC_setup()
{
   ErrorStatus HSEStartUpStatus; // Keep error status
   RCC_DeInit();      // RCC system reset(for debug purpose)
   RCC_HSEConfig(RCC_HSE_ON);  // Enable HSE
   HSEStartUpStatus = RCC_WaitForHSEStartUp();   // Wait till HSE is ready
   if(HSEStartUpStatus == SUCCESS)
   {
      RCC_HCLKConfig(RCC_SYSCLK_Div1); // HCLK = SYSCLK
      RCC_PCLK2Config(RCC_HCLK_Div1); // PCLK2 = HCLK
      RCC_PCLK1Config(RCC_HCLK_Div4); // PCLK1 = HCLK/2
      //RCC_ADCCLKConfig(RCC_PCLK2_Div4);  // ADCCLK = PCLK2/4
      RCC_ADCCLKConfig(RCC_PCLK2_Div6);   
      FLASH_SetLatency(FLASH_Latency_2); // Flash 2 wait state
      FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);  // Enable Prefetch Buffer
      RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9);   // PLLCLK = 8MHz * 9 = 72 MHz
   
      RCC_PLLCmd(ENABLE);  // Enable PLL 
      while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);   // Wait until PLL is ready
     
      RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);  // Select PLL as system clock source
      while(RCC_GetSYSCLKSource() != 0x08); // Wait till PLL is used as system clock source
   }
   
}

//------------------------------ Function GPIO Configuration -----------------------------------------//
void GPIO_setup()
{
   GPIO_InitTypeDef GPIO_InitStructure;
   // Enable GPIOC clock and Enable GPIOA and AFIO clock
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO,ENABLE);
   
   // Configure PC0 as analog input(ADC Channel10)       //ADC_CH1(ADC10)
   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
   GPIO_Init(GPIOC, &GPIO_InitStructure);

   // Configure USART1 Tx (PA9) as alternate function push-pull
   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
   GPIO_Init(GPIOA, &GPIO_InitStructure);
   // Configure USART1 Rx (PA10) as input floating
   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
   GPIO_Init(GPIOA, &GPIO_InitStructure);
}

//------------------------------ Function ADC Configuration ------------------------------------------//
void ADC_setup()
{
   ADC_InitTypeDef ADC_InitStructure;
   // Enable ADC1 clock
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
   // ADC1 configuration
   ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
   ADC_InitStructure.ADC_ScanConvMode = DISABLE;
   ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
   ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
   ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
   ADC_InitStructure.ADC_NbrOfChannel = 1;
   ADC_Init(ADC1, &ADC_InitStructure);

   ADC_Cmd(ADC1, ENABLE);  // Enable ADC1
 
   ADC_ResetCalibration(ADC1);   // Enable ADC1 reset calibaration register
   while(ADC_GetResetCalibrationStatus(ADC1));
 
   ADC_StartCalibration(ADC1);   // Start ADC1 calibration
   while(ADC_GetCalibrationStatus(ADC1)); // Check the end of ADC1 calibration
   ADC_SoftwareStartConvCmd(ADC1, ENABLE);    // Start ADC1 Software Conversion 
}

//------------------------------ Function USART1 Configuration -----------------------------------------//
void USART1_setup()
{
   USART_InitTypeDef USART_InitStructure;
   // Enable USART1 clock
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
   // USART1 configured
   USART_InitStructure.USART_BaudRate = 115200;
   USART_InitStructure.USART_WordLength = USART_WordLength_8b;
   USART_InitStructure.USART_StopBits = USART_StopBits_1;
   USART_InitStructure.USART_Parity = USART_Parity_No;
   USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
   USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
   
   USART_Init(USART1, &USART_InitStructure); // Configure the USART1
   USART_Cmd(USART1, ENABLE);  // Enable USART1
   
}


//------------------------------ Function USART1 send 1 character ------------------------------------//
void usart1_putc(unsigned char c)
{
   while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);   // Wait until transmition ready
   USART_SendData(USART1,(int)c);   // Send character
}

//------------------------------ Function USART1 send string -----------------------------------------//
void usart1_puts(unsigned char *s)
{
   while(*s)   // Check end of string
   {
      usart1_putc(*s++);   // Send charracter 1 time
   }
}

//------------------------------ Function USART1 wait character --------------------------------------//
int usart1_getc()
{
   while(USART_GetFlagStatus(USART1,USART_FLAG_RXNE)==RESET);   // Wait until receive data
   return(USART_ReceiveData(USART1));  // Return  character
}

//---------------------------------------- Main Program ----------------------------------------------//
int main()
{   
   unsigned int percentage;
   
   RCC_setup();       // RCC Configuration   
   GPIO_setup();      // GPIO Configuration
   ADC_setup();       // ADC Configuration

   USART1_setup();    // USART1 Configuration

   usart1_puts("TEST\r\n");
   usart1_puts("ADC\r\n");
 
     
  while(1)       
   { 
      ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_239Cycles5);
      ADC_SoftwareStartConvCmd(ADC1, ENABLE);
      while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);
      percentage = ADC_GetConversionValue(ADC1); // Convert analog to percentage(0-100% reference from 0-4095)     
      sprintf(str,"%d   ",percentage);  // Convert percentage value to string
      usart1_puts(str);       // Send character from buffer
      usart1_puts("\r\n");    // New line
      delay_ms(100);     // Delay a few time       
   }
}

อันนี้เป็นโค้ตที่ผมแปลงมาจากของคุณครับ
Title: Re: ADC อ่านค่าไม่ตรงครับ STM32F107 รบกวนผู้รู้ช่วยทีครับ
Post by: deejun on March 05, 2013, 10:49:23 pm
ผมไม่ถนัดใช้ LIB ครับ ผมชอบยิงตรง register เลย ครับ ผมว่ามันเป็นไรที่ตอบได้ดี
อาจจะเหนื่อยในการศึกษาและไม่เหมือนใครที่ใช้กันกับ LIB แต่ผมว่ามันทีเดียวจบ
ความเห็นส่วนตัวน่ะครับ
โค๊ดตัวอย่างที่เทสครับ


#include"stm32f10x.h"

unsigned int bn;
void delay_ms(unsigned int in)
                             {
                                             unsigned int jn,kn;
                                             for(jn=0;jn<in;jn++)
                                             for(kn=0;kn<6000;kn++);                                                                                                                 
                             }
void sys_clock()
                {
                 RCC->CFGR   =  0;
                 RCC->CR     =  RCC_CR_HSION;
                 while((RCC->CR & RCC_CR_HSIRDY)==0);       
                 RCC->CR     |= RCC_CR_HSEON;
                         while((RCC->CR & RCC_CR_HSERDY)==0);
                         RCC->CFGR   =  RCC_CFGR_SW_PLL|RCC_CFGR_PPRE1_DIV2|RCC_CFGR_ADCPRE_DIV6|
                                                RCC_CFGR_PLLSRC|RCC_CFGR_PLLMULL9;
                         RCC->CR     |= RCC_CR_PLLON;
                         while((RCC->CR & RCC_CR_PLLRDY)==0);       
                                   
                        }
                       
void ADC()
           {
            ADC1->CR1      =    ADC_CR1_SCAN;
            ADC1->SMPR1    =    0;        // 1.5 cycles conversion time
             ADC1->SQR3     =    14;     //channel number 14 PC4 first conversion
           
            ADC1->CR2      =    ADC_CR2_ADON;
             ADC1->CR2      |=   ADC_CR2_EXTSEL|ADC_CR2_SWSTART|ADC_CR2_EXTTRIG;//
           
            ADC1->CR2 |=ADC_CR2_RSTCAL ;    //reset calibration
            while ((ADC1->CR2 & ADC_CR2_RSTCAL) != 0x00);
           
            ADC1->CR2      |=   ADC_CR2_CAL;
            while((ADC1->CR2 & ADC_CR2_CAL) != 0x00);/* Check the end of ADC1 calibration */
       

           
            }     
               

void usartSetup (void)
                             {
                                 RCC->APB2ENR   =   0;
                                 RCC->APB2ENR   |=  RCC_APB2ENR_USART1EN | RCC_APB2ENR_IOPAEN | RCC_APB2ENR_ADC1EN;
                                 
                                 // Put PA9  (TX) to alternate function output push-pull at 50 MHz
                      // Put PA10 (RX) to floating input
                      GPIOA->CRL       =  0;
                                 GPIOA->CRH       =  0x000004B0;                                 
                                 USART1->BRR      =  72000000/57600;
                      USART1->CR1 = USART_CR1_UE | USART_CR1_TE | USART_CR1_RE;
                         
                               }


main()
      {
         int i,m,n,o,p;   
          sys_clock();
       usartSetup();
         ADC();   
          for(;
             {
                      ADC1->CR2 |= ADC_CR2_SWSTART|ADC_CR2_ADON;/* Start ADC1 Software Conversion */   
                while((ADC1->SR & ADC_SR_EOC )==0)
                ADC1->SR = 0;
                     
                     i = ADC1->DR; // keep data
                     m = i/1000;
                     n = i%1000/100;
                     o = i%100/10;
                     p = i%10;
                     
                   USART1->DR = 48+m;
                     while ((USART1->SR & USART_SR_TXE) == 0);
                     
                     USART1->DR = 48+n;
                     while ((USART1->SR & USART_SR_TXE) == 0);
                     
                     USART1->DR = 48+o;
                     while ((USART1->SR & USART_SR_TXE) == 0);
                     
                     USART1->DR = 48+p;
                     while ((USART1->SR & USART_SR_TXE) == 0);
                     
                     
                     USART1->DR = 0x0D;   // new line
                     while ((USART1->SR & USART_SR_TXE) == 0);   
                     USART1->DR = 0x0A;   // goto left
                     while ((USART1->SR & USART_SR_TXE) == 0);     
                     delay_ms(500);
                                                                           
                                 
             }
}
Title: Re: ADC อ่านค่าไม่ตรงครับ STM32F107 รบกวนผู้รู้ช่วยทีครับ
Post by: crywolf on March 06, 2013, 06:54:25 am
ลองวัด +VREF ดูครับ อาจจะไม่ไช่ 3.3V
Title: Re: ADC อ่านค่าไม่ตรงครับ STM32F107 รบกวนผู้รู้ช่วยทีครับ
Post by: Jimmkung on March 06, 2013, 02:58:40 pm
@คุณ deejun ผมลองเอสโค้ตคุณไปลองแล้วมัน error อะครับ ลองเอาไปทกสอบเปนส่วนๆ โดยเอาส่วน set ADC
ๆปลองปรากฎ adc ไม่ทำงานครับ

@คุณ cry wolf ผมเชคที่ขา Vref+ เปน 3.3 v ครับ ขา Vdda ก็ 3.3 v ครับ
ส่วนขา Vref- และขา Vssa ก็เปน 0 v ครับ
Title: Re: ADC อ่านค่าไม่ตรงครับ STM32F107 รบกวนผู้รู้ช่วยทีครับ
Post by: Jimmkung on March 06, 2013, 03:03:37 pm
ปัญหาน่าจะมาจากที่ขา Vref+ รึป่าวครับเพราะของผมมัน 3.3v แล้วที่ถูต้องมันควรจะมีค่าประมาณเท่าไรครับเพราะบอร์ดนี้ผมออกแบบเอง ผมใช้  L ที่ 2.2 mH ไม่แน่ใจว่าจะมีผลกระทบรึป่าวครับ
Title: Re: ADC อ่านค่าไม่ตรงครับ STM32F107 รบกวนผู้รู้ช่วยทีครับ
Post by: deejun on March 06, 2013, 04:07:23 pm
ปัญหาน่าจะมาจากที่ขา Vref+ รึป่าวครับเพราะของผมมัน 3.3v แล้วที่ถูต้องมันควรจะมีค่าประมาณเท่าไรครับเพราะบอร์ดนี้ผมออกแบบเอง ผมใช้  L ที่ 2.2 mH ไม่แน่ใจว่าจะมีผลกระทบรึป่าวครับ

เอาแต่ส่วน ADC ฟังก์ชันไปอย่างลืมเปิดคล๊อกให้ ADCด้วยน่ะครับ
RCC_APB2ENR_ADC1EN;
..................................................
ถ้าจะรันทั้งหมดโค๊ด มันหา .h ไม่เจอแน่เลย
ตอนคอมไฟ เซ็คสถานที่จัดเก็บใน INC ของ STM32
ให้มันรู้จัดว่าจะไปดึงที่ไหน ก็จะผ่านแล้ว อย่างลืมแอด startup.s และ system_stm32f10x.c เข้ามาเก็บในโฟรดเดอร์ที่สร้างด้วยเพื่อความสะดวก เท่านี้ก็ไม่น่าจะผิดพลาดครับ
Title: Re: ADC อ่านค่าไม่ตรงครับ STM32F107 รบกวนผู้รู้ช่วยทีครับ
Post by: Jimmkung on March 06, 2013, 05:42:23 pm
ขอบคุณทุกท่านมากน่ะครับที่ช่วยเหลือผมตลอดมา ตอนนี้ผมแก้ปัญหาได้แล้วครับ
software ไม่ได้มีปัญหาครับ ของที่ทุกท่านให้ผมและของที่ผมใช้ตอนแรก ใช้ได้ดีทุกๆโค้ดครับ ผมมาลองดูที่ขา Vref+ ของผม
ปรากฎว่ามัน drop ไปอยู่ที่ 2.3 V ดังนั้น ที่ 2905 จะได้เท่ากับ
 
                                                       X Volt = (2905*2.3)/4095

ซึ่งได้เท่ากับ 1.64 V ครับ ดังนั้น จริงๆแล้วโปรแกรมมันไม่ได้อ่านผิดครับ แต่ Vref+ มันไม่ถึง 3.3 V ครับ เลยทำให้ทุกท่านต้องเดือดร้อนไปด้วย

ปล. ถึงคุณ crywolf ตอนที่คุณลองให้ผมวัดที่ขา Vref+ แล้วที่ผมตอบกลับไปว่ามัน 3.3 v ผมลืมดูว่าผมเข้าโหมด Program อยู่ครับ Vref+ เลยกลายเป็น 3.3V ทำให้ผมเข้าใจผิด
ต้องขอบคุณ คุณ crywolf และคุณ deejun มากๆด้วยครับ

สำหรับคนที่ต้องการเปิดใช้ ADC ผมแนะนำ code ในหน้านี้ครับ เป็นแนวทางที่ดีที่ทุกท่านได้แนะนำไว้ครับ(ใช้ได้ทุก code ครับ conform)