ผมอยากทราบอาการที่ทำไม ADC ถึงอ่านค่าเพี้ยนครับ โดยที่ผมจับที่ 0v ก็อ่านได้ 0 และที่ 3.3v ก็อ่านได้ 4095 แต่แทนที่1.5v จะอ่านได้ ประมาณ 2095 แต่กลับอ่านออกมาได้ถึง 3805 ครับ ผมแปลกใจมาก setting ADC ใหม่ก็ไม่หาย ผมใช้ ride7 ครับ
ปล. ผมเอามิเตอร์จับที่ขา adcแล้ว ก็ประมานแค่ 0.2v ผมคิดว่าปัญหาน่าจะอยู่ที่การ init ADC มากกว่าครับ ถ้าผมเข้าใจผิดอย่างไรรบกวนผู้รู้ช่วยแนะนำด้วยน่ะครับ :'(
น่าจะใช่ การ set sampling time ก็อาจจะมีผลด้วยบ้างเป็นบางกรณี สรุปแล้วยังไม่รู้สาเหตที่แน่นอน ข้อมูลน้อยไปหน่อย
มีโค๊ดตัวอย่างมั๊ยครับที่เขียน เผือมีอะไรที่ไม่ถูกต้องได้มีหลายท่านช่วยดู
สิ่งที่สงสัยคือ
1 0V อ่านค่าได้ถูก ค่าคือ 0 และ 3.3V อ่านได้ถูก 4095 เคยลองเอามิเตอร์จับดูหรือไม่ว่าโวลต์ได้จริง
2 ที่ประมาณว่า 1.5V จะต้องได้ค่า 1861 ครับ และลองวัดโวลต์ว่าได้ 1.5vหรือไม่
3 VR มีแบบค่าเอ็กโปร และแบบลีเนีย การหมุนรอบองศาเท่ากัน แต่ค่าไม่เท่ากัน ยกเว้นช่วงสูงสุด และต่ำสูด เท่ากัน
ค่า 3.3 V ที่ ป้อน ให้มัน น่า จะเลย Full Scale ไปแล้ว ค่า ที่เลย Full Scale จะอ่าน ได้ 4095 ตลอด
ที่ถูก ต้อง เรา จะต้อง ค่อยๆปรับ แรงดัน ขึ้น พร้อมแสดงผลขณะปรับ พอได้ค่า 4094 ก็หยุดได้แล้ว ถ้าเพิ่มแรงดัน เราอาจ หมุนเกิน 4095 จะ ทำให้เราคำนวณผิด
แต่กรณีนี้ FULL SCALE น่าจะอยู่ ที่ แค่ 2.0 ไม่ใช่ 3.3
คำนวณจาก 1.5*(4096/3805)= 1.99
อันนี้เป็น 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
}
}
ตอนนี้ผมกำลังสงสัยอยู่สองกรณีครับคือ
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 ให้ผมโทรไปถามท่านจะขอบคุณมากๆครับ
ลองดู Code ของผมนะครับ http://www.electoday.com/index.php?topic=447.msg1388#msg1388
ผม Test บน STM32-Discovery แสดงผลได้ถูต้อง ลอง Print มาโชว์ดูครับ ADC_RAW_Value นะครับ
@ คุณ crywolf ผมลองตามวิธีของคุณแล้วปรากฏว่ามันก็ยังอ่านได้ 2905 เท่าเดิมเลยครับ ผมว่าสงสัย STM32F107VBT6 ของผมจะกลับบ้านเก่าไปแล้วแน่ๆเลยครับ
ขอดู Code ทั้งหมดได้มั้ยครับ ส่งมาเป็นไฟล์เลยครับ
#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
}
}
อันนี้เป็นโค้ตที่ผมแปลงมาจากของคุณครับ
ผมไม่ถนัดใช้ 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);
}
}
ลองวัด +VREF ดูครับ อาจจะไม่ไช่ 3.3V
@คุณ deejun ผมลองเอสโค้ตคุณไปลองแล้วมัน error อะครับ ลองเอาไปทกสอบเปนส่วนๆ โดยเอาส่วน set ADC
ๆปลองปรากฎ adc ไม่ทำงานครับ
@คุณ cry wolf ผมเชคที่ขา Vref+ เปน 3.3 v ครับ ขา Vdda ก็ 3.3 v ครับ
ส่วนขา Vref- และขา Vssa ก็เปน 0 v ครับ
ปัญหาน่าจะมาจากที่ขา Vref+ รึป่าวครับเพราะของผมมัน 3.3v แล้วที่ถูต้องมันควรจะมีค่าประมาณเท่าไรครับเพราะบอร์ดนี้ผมออกแบบเอง ผมใช้ L ที่ 2.2 mH ไม่แน่ใจว่าจะมีผลกระทบรึป่าวครับ
Quote from: Jimmkung on March 06, 2013, 03:03:37 PM
ปัญหาน่าจะมาจากที่ขา Vref+ รึป่าวครับเพราะของผมมัน 3.3v แล้วที่ถูต้องมันควรจะมีค่าประมาณเท่าไรครับเพราะบอร์ดนี้ผมออกแบบเอง ผมใช้ L ที่ 2.2 mH ไม่แน่ใจว่าจะมีผลกระทบรึป่าวครับ
เอาแต่ส่วน ADC ฟังก์ชันไปอย่างลืมเปิดคล๊อกให้ ADCด้วยน่ะครับ
RCC_APB2ENR_ADC1EN;
..................................................
ถ้าจะรันทั้งหมดโค๊ด มันหา .h ไม่เจอแน่เลย
ตอนคอมไฟ เซ็คสถานที่จัดเก็บใน INC ของ STM32
ให้มันรู้จัดว่าจะไปดึงที่ไหน ก็จะผ่านแล้ว อย่างลืมแอด startup.s และ system_stm32f10x.c เข้ามาเก็บในโฟรดเดอร์ที่สร้างด้วยเพื่อความสะดวก เท่านี้ก็ไม่น่าจะผิดพลาดครับ
ขอบคุณทุกท่านมากน่ะครับที่ช่วยเหลือผมตลอดมา ตอนนี้ผมแก้ปัญหาได้แล้วครับ
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)