Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

ADC interfacing

Status
Not open for further replies.

DANXIA

Junior Member level 2
Joined
Oct 20, 2020
Messages
20
Helped
0
Reputation
0
Reaction score
0
Trophy points
11
Activity points
169
hello...

i am using STM8s003f3 to read a voltages from channel 2.

but my readings are fluctuating. cann't understand the problems. i think i have done mistake in registors.
my adc is 10 bit and i am trting to measure +-200v. please guide .

i am quoting some part of code which is related to ADC


Code:
void ADC__Initialization (void)
  {
     ADC1->CR1_BitFields.ADON=1;
     ADC1->CR2_BitFields.ALIGN=1;
     ADC1->TDR=0xFFFF;
  }

uint16_t ADC__ReadChannel (uint8_t Channel)
  {
     unsigned int val=0;
     
     ADC1->CSR_BitFields.CH=Channel;
     ADC1->CR1_BitFields.ADON=1;
      do
      {
         _asm("nop");
         _asm("nop");
         _asm("nop");
      }
     while (ADC1->CSR_BitFields.EOC==0);
     val |= ADC1->DRL;
     val |= ADC1->DRH<<8;
     ADC1->CSR_BitFields.EOC=0;
     val &= 0x03ff;
     return (val);
  }


here is define all the register

struct _ADCx_Structure
{
    uint16_t const volatile DB[10];
    uint8_t const volatile RESERVED1[12];
    union
    {
        //ADCx Control/Status Register
        uint8_t volatile CSR;
        //CSR Bits Definition
        struct
        {
            uint8_t CH:    0x04;
            uint8_t AWDIE: 0x01;
            uint8_t EOCIE: 0x01;
            uint8_t AWD:   0x01;
            uint8_t EOC:   0x01;
        } volatile CSR_BitFields;
    };
    union
    {
        //ADCx Configuration Register 1
        uint8_t volatile CR1;
        //CR1 Bits Definition
        struct
        {
            uint8_t ADON:      0x01;
            uint8_t CONT:      0x01;
            uint8_t RESERVED0: 0x02;
            uint8_t SPSEL:     0x03;
            uint8_t RESERVED1: 0x01;
        } volatile CR1_BitFields;
    };
    union
    {
        //ADCx Configuration Register 2
        uint8_t volatile CR2;
        //CR2 Bits Definition
        struct
        {
            uint8_t RESERVED0: 0x01;
            uint8_t SCAN:      0x01;
            uint8_t RESERVED1: 0x01;
            uint8_t ALIGN:     0x01;
            uint8_t EXTSEL:    0x02;
            uint8_t EXTTRIG:   0x01;
            uint8_t RESERVED2: 0x01;
        } volatile CR2_BitFields;
    };
    union
    {
        //ADCx Configuration Register 3
        uint8_t volatile CR3;
        //CR3 Bits Definition
        struct
        {
            uint8_t RESERVED0: 0x06;
            uint8_t OVR:       0x01;
            uint8_t DBUF:      0x01;
        } volatile CR3_BitFields;
    };

  //ADCx Data Register
    uint8_t const volatile DRL;
    uint8_t const volatile DRH;


please give some solution as soon as possible. i really need it.
Thanks!
 
Last edited by a moderator:

KlausST

Super Moderator
Staff member
Joined
Apr 17, 2014
Messages
23,017
Helped
4,715
Reputation
9,446
Reaction score
5,087
Trophy points
1,393
Activity points
152,501
Hi,

Fluctuating values does not mean there is a software problem.

Show us your schematic, PCB layout and test conditions.

For example a not connected ADC input may cause fluctuating values.

Klaus
 

DANXIA

Junior Member level 2
Joined
Oct 20, 2020
Messages
20
Helped
0
Reputation
0
Reaction score
0
Trophy points
11
Activity points
169
Hi,

Fluctuating values does not mean there is a software problem.

Show us your schematic, PCB layout and test conditions.

For example a not connected ADC input may cause fluctuating values.

Klaus
but when i used other hex file on same hardware then it give me very smoot output.
i observe the output n i feel like there is some issue in reading adc value.coz some time it give output and some time it remain constant and some times it give very random output and again if used other hex file.then i got again fine output.
 

KlausST

Super Moderator
Staff member
Joined
Apr 17, 2014
Messages
23,017
Helped
4,715
Reputation
9,446
Reaction score
5,087
Trophy points
1,393
Activity points
152,501
Hi,

You don't give much useful informations. I can't see how I can help with the given informations.

If you don't show the trst conditions, the sample values, the other code...
We have to leave it on you to find out the difference to the other code.

I like to help ... but can't see how...

Klaus
 

DANXIA

Junior Member level 2
Joined
Oct 20, 2020
Messages
20
Helped
0
Reputation
0
Reaction score
0
Trophy points
11
Activity points
169
Hi,

You don't give much useful informations. I can't see how I can help with the given informations.

If you don't show the trst conditions, the sample values, the other code...
We have to leave it on you to find out the difference to the other code.

I like to help ... but can't see how...

Klaus
ok.

there is my main file...

Code:
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "ADC.h"
#include "SevenSegmentDisplays.h"
#include "GeneralPurposeIO.h"

double fabs(double x)
{
    if(x<0) return -x;
    else return x;
}

uint8_t test_variable = 1;
volatile uint8_t global_value =0;

void delay (void) //Function Definition 
  {
     int i =0 ;
   int j=0;
   for (i=0; i<=1000; i++)
    {
     for (j=0; j<100; j++) // Nop = Fosc/4
     _asm("nop"); //Perform no operation assembly code 
      }
  }

static float VoltageMapping(float ADC_ChannelReading, float MinimumInputVoltage, float MaximumInputVoltage,double CalibrationVoltage)
{ return(ADC_ChannelReading-0x0200)*(MaximumInputVoltage-MinimumInputVoltage)/1023+CalibrationVoltage;} // output equation.
//

int main()
  {
     float voltage=0;    
   float ChannelReading = 0;
   float ChannelVoltage = 0;        
    
     GPIOD->DDR |=  (1<<1);
     GPIOD->CR1 |=  (1<<1); // LED is connect on PD1 for negative voltage
     GPIOD->CR2 |=  (0x00);
     
     ADC__Initialization();
    
     SevenSegmentDisplays__Initialization();
     
     GPIOD->ODR &= (uint8_t)(0x02);
     
     while (1)
      {
            calib_key();//this functiom for calibration
            if(cal_busy==0)
            {
             ChannelReading=ADC__ReadChannel(2); //whaere is func??         
           voltage=VoltageMapping(ChannelReading,-1000.0,1000.0,0);
             ChannelVoltage=voltage/1.95;
             
           if(ChannelVoltage <= -2)
            {
               global_value = 0x02;
               GPIOD->ODR &= (uint8_t)(~0x02);
              }
           else
              {
               global_value = 0x02;
               GPIOD->ODR |= (uint8_t)(0x02);
              }
           SevenSegmentDisplays__Display(fabs(ChannelVoltage));
    
    

and here is ADC.c



void ADC__Initialization (void)
  {
     ADC1->CR1_BitFields.ADON=1;
     ADC1->CR2_BitFields.ALIGN=1;
     ADC1->TDR=0xFFFF;
  }

float ADC__ReadChannel (uint8_t Channel)        
  {
     unsigned int val=0;
     
     ADC1->CSR_BitFields.CH=Channel;
     ADC1->CR1_BitFields.ADON=1;
     do
      {
         _asm("nop");
         _asm("nop");
         _asm("nop");
      }
     while (ADC1->CSR_BitFields.EOC==0);
     val |= ADC1->DRL;
     val |= ADC1->DRH<<8;
     ADC1->CSR_BitFields.EOC=0;
     val &= 0x03ff;
     return (val);
     //return ADC1->DR;
  }

and already shared adc reg.file. looking for a solution.hoping a nice guidence from ur knowledge.
THANK!!!
 
Last edited by a moderator:

danadakk

Advanced Member level 5
Joined
Mar 26, 2018
Messages
2,203
Helped
343
Reputation
704
Reaction score
509
Trophy points
113
Activity points
9,756
As Klaus points out A/D performance is more than just code.

If the HW/Code was producing stable readings and now suddenly not so
much one might suspect -

1) Something has changed in HW, like grounding, input lead routing, change in
bypassing, adjacent signals changed on pin that are physically next to A/D
input pins.

2) Coding in other parts of design changed, like adding PWM and other switching activity.
Not unheard of to shut off, in code, other processes while performing an A/D conversion.
That helps to reduce internal supply rail noise.

Keep in min, if Vref is 1V then a LSB is 1 mV in a 10 bit system. It does not take much switching
activity to produce 1 mV in a typical design. Set your scope up for infinite persistence, AC
coupled, high gain, and look at supply rail. Not uncommon to see a couple hundred mV of
noise on the rail. If your Vref is internal, a Vdd based Vref that noise is seen by the reference.
If its a bandgap Vref thats better, but needs to be bypassed (if option to do so at a pin).

3) Environment changed, like fluorescent lights, motors, actuators.

4) Preferably differential measurements better, because of the CMR that a diff front end
provides. Key to this is the diff input external routing roughly same route path so that no
imbalances created to external noise coupling into A/D.

5) Not all Caps equal in bypass performance for same value of cap. Polymer tants best for
bulk, ceramic and MLCC for HF stuff. A parallel combination of both.....Check datasheet of
caps being used to see how good their ESR performance is.

1611400362438.png


6) If your system has interrupt processes does manufacturer have any recommendations about
that while using A/D....Is A/D itself dependent on interrupts, then its priority probably matters. Was
another process added that affected particular architecture of onboard A/D.

General considerations in A/D work (ignore part specific info, the general considerations are the focus) -






As an aside when you post code use the code tags to make code more readable.
Also no comments on code, sad, makes it even more difficult to read the code.

1611404024224.png



Regards, Dana.
 
Last edited:

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Top