Question
Stm32f103 adc stable conversion
I am making a ntc thermometer with stm32f103c8 (by writing over registers without using state library). The code works as it is,I did the adc conversion in 7.5 cycles. I used the calibration register and ran the adc in continuous conversion mode. but it is not fully stable, the value in the last step is constantly changing. How can I make adc more stable?.I want the adc value to stay as constant as possible (I used a 10k ntc between 3.3v and a2 pin. I connected a 10k resistor between gnd and a2 pin ).
#include "stm32f10x.h" // Device header
#include "math.h"
float heat = 0;
char analog[10];
char analog2[10];
int temp;
int a;
void int2char(int num, char str[])
{
char lstr[30];
int cnt = 0;
int div = 10;
int j = 0;
while( num >= div)
{
lstr[cnt] = num % div + 0x30;
num /= 10;
cnt++;
}
lstr[cnt] = num + 0x30;
for(j= cnt ; j >=0;j--)
{
str[cnt-j] = lstr[j];
}
}
void DelayUs(unsigned long t)
{
for(;t>0;t--)
{
SysTick->LOAD = 72;
SysTick->VAL = 0;
while((SysTick->CTRL & 0x00010000) == 0);
}
}
void lcd_cmd(unsigned char data)
{
//pin_output(0,11);
GPIOA->ODR &=~0x100;//lcd_rs(LOW);
GPIOA->ODR &=~0x200;//lcd_rw(LOW);
DelayUs(10);
GPIOA->ODR |=0x400;//lcd_e(HIGH);
DelayUs(5);
GPIOA->ODR &= 0xff0f;
GPIOA->ODR |= (data & 0x00f0);
DelayUs(10);
GPIOA->ODR &=~0x400;//lcd_e(LOW);
DelayUs(20);
GPIOA->ODR |=0x400;//lcd_e(HIGH);
DelayUs(5);
GPIOA->ODR &= 0xff0f;
GPIOA->ODR |= ((data << 4) & 0x00f0);
DelayUs(10);
GPIOA->ODR &=~0x400;//lcd_e(LOW);
}
void lcd_data(unsigned char data)
{
//pin_output(4,7);
GPIOA->ODR |=0x100;//lcd_rs(HIGH);
GPIOA->ODR &=~0x200;//lcd_rw(LOW);
DelayUs(10);
GPIOA->ODR |=0x400;//lcd_e(HIGH);
DelayUs(5);
GPIOA->ODR &= 0xff0f;
GPIOA->ODR |= (data & 0x00f0);
DelayUs(10);
GPIOA->ODR &=~0x400;//lcd_e(LOW);
DelayUs(20);
GPIOA->ODR |=0x400;//lcd_e(HIGH)
DelayUs(5);
GPIOA->ODR &= 0xff0f;
GPIOA->ODR |= ((data << 4) & 0x00f0);
DelayUs(10);
GPIOA->ODR &=~0x400;//lcd_e(LOW)
}
void lcd_send( char str[])
{
int i = 0;
while(str[i])
{
lcd_data(str[i]);
i++;
DelayUs(100);
}
}
void lcd_msg(unsigned char line_1_2, unsigned char pos_0_16, char msg[])
{
short pos = 0;
if(line_1_2==1)
{
pos = 0;
}
else if(line_1_2==2)
{
pos = 0x40;
}
lcd_cmd(0x80 +pos + pos_0_16);
DelayUs(100);
lcd_send(msg);
}
int main(void)
{
// initialize the delay function (Must initialize)
SysTick->CTRL = 0;
SysTick->LOAD = 0x00FFFFFF;
SysTick->VAL = 0;
SysTick->CTRL = 5;
//pin_output(4,11);
RCC->APB2ENR = 0x04; /// port a active
GPIOA->CRL = 0x33330000; /// pin a4-a7
GPIOA->CRH = 0x00003333; /// pin a8-a11
DelayUs(20000);
GPIOA->ODR |=0x100;//lcd_rs(LOW);
GPIOA->ODR |=0x200;//lcd_rw(LOW);
DelayUs(10);
GPIOA->ODR |=0x400;//lcd_e(HIGH);
DelayUs(5);
GPIOA->ODR &= 0xff0f;
GPIOA->ODR |= 0x30; // 8 bit communication mode
DelayUs(10);
GPIOA->ODR &=~0x400;//lcd_e(LOW);
DelayUs(20000);
GPIOA->ODR &=~0x100;//lcd_rs(LOW);
GPIOA->ODR &=~0x200;//lcd_rw(LOW);
DelayUs(10);
GPIOA->ODR |=0x400;//lcd_e(HIGH);
DelayUs(5);
GPIOA->ODR &= 0xff0f;
GPIOA->ODR |= 0x20; // 4 bit communication mode
DelayUs(10);
GPIOA->ODR &=~0x400;//lcd_e(LOW);
lcd_cmd(0x2C); // 4 bit communication mode / 2 lines
DelayUs(5000);
lcd_cmd(0x0C); // Display ON
DelayUs(5000);
lcd_cmd(0x01); // Clear Display
DelayUs(5000);
lcd_cmd(0x02); // Get back to initial address
DelayUs(5000);
lcd_msg(1, 0,"Temp(C)");
RCC->APB2ENR |= 0x201; //ADC 1 interface clock enable
ADC1->SQR3 = 2; //first transformation in regular order
ADC1->SQR1 &= ~(0xf << 20);//adc channel string length
ADC1->SMPR2 |= (0x1); //7.5 loop
//12mhz: 7.5+12.5 =20 hz ->3.3us(micro s)
ADC1->CR2 &= ~(1 << 11); // right alignment
ADC1->CR2 |= 2|1; //adc on and continuous
ADC1->CR2 |= (1<<3);// reset calibration
ADC1->CR2 |= (1<<2);// calibration
ADC1->CR2 |=1; //adc on
while(1)
{
heat = log(((40950000 / ADC1->DR) - 10000));
heat = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * heat * heat)) * heat);
temp = (heat - 273.15)*100;
int2char(temp,analog);
lcd_msg(2, 2,analog);
if(temp<1000)
{
a=3;
}
else if(temp<10000)
{
a=4;
}
else
{
a=5;
}
temp=temp%100;
int2char(temp,analog2);
lcd_msg(2, a,".");
lcd_msg(2, a+1,analog2);
lcd_msg(2, a+3," ");
DelayUs(250000);
}
}