Main Menu
Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Messages - Jimmkung

#1
ผมต้องการสร้าง Digital oscilloscope ครับ โดย Display ผ่าน GLCD 128x64 pixel ตอนนี้ผมพยายามจะเขียนในส่วนของ Trigger แต่ติดปัญหาว่าจะออกแบบยังงัยดี รบกวนผู้รู้ช่วยแนะนำหน่อยน่ะครับ
#2
ขอบคุณทุกท่านมากน่ะครับที่ช่วยเหลือผมตลอดมา ตอนนี้ผมแก้ปัญหาได้แล้วครับ
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)
#3
ปัญหาน่าจะมาจากที่ขา Vref+ รึป่าวครับเพราะของผมมัน 3.3v แล้วที่ถูต้องมันควรจะมีค่าประมาณเท่าไรครับเพราะบอร์ดนี้ผมออกแบบเอง ผมใช้  L ที่ 2.2 mH ไม่แน่ใจว่าจะมีผลกระทบรึป่าวครับ
#4
@คุณ deejun ผมลองเอสโค้ตคุณไปลองแล้วมัน error อะครับ ลองเอาไปทกสอบเปนส่วนๆ โดยเอาส่วน set ADC
ๆปลองปรากฎ adc ไม่ทำงานครับ

@คุณ cry wolf ผมเชคที่ขา Vref+ เปน 3.3 v ครับ ขา Vdda ก็ 3.3 v ครับ
ส่วนขา Vref- และขา Vssa ก็เปน 0 v ครับ
#5
#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       
   }
}

อันนี้เป็นโค้ตที่ผมแปลงมาจากของคุณครับ
#6
@ คุณ crywolf ผมลองตามวิธีของคุณแล้วปรากฏว่ามันก็ยังอ่านได้ 2905 เท่าเดิมเลยครับ ผมว่าสงสัย STM32F107VBT6 ของผมจะกลับบ้านเก่าไปแล้วแน่ๆเลยครับ
#7
ตอนนี้ผมกำลังสงสัยอยู่สองกรณีครับคือ
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 ให้ผมโทรไปถามท่านจะขอบคุณมากๆครับ
#8
อันนี้เป็น 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 
     
   }
}