• Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

result is not written to adc register because it has been locked.

Thread starter #1
Hello;


I am fresh here. I am working on atmega8. I want to read analog voltage from its ADC0 pin. I write code for it in mikroc pro for avr. But it gives me error that “result is not written to adc register because it has been locked.” It reads only first simple and then stopped. I don’t know how to solve it??? Anybody have any idea about it? Circuit and code are attached.


Code is:

Code:
// LCD module connections

sbit LCD_RS at PORTD0_bit;

sbit LCD_EN at PORTD1_bit;

sbit LCD_D4 at PORTD2_bit;

sbit LCD_D5 at PORTD3_bit;

sbit LCD_D6 at PORTD4_bit;

sbit LCD_D7 at PORTD5_bit;


sbit LCD_RS_Direction at DDD0_bit;

sbit LCD_EN_Direction at DDD1_bit;

sbit LCD_D4_Direction at DDD2_bit;

sbit LCD_D5_Direction at DDD3_bit;

sbit LCD_D6_Direction at DDD4_bit;

sbit LCD_D7_Direction at DDD5_bit;

// End LCD module connections


unsigned int ADC = 0,adc_result=0;

unsigned char display[7];



void main() {
   
    Lcd_Init(); // Initialize LCD
   
    Lcd_Cmd(_LCD_CLEAR); // Clear display
   
    Lcd_Cmd(_LCD_CURSOR_OFF); // Cursor off
   
   
    Lcd_Out(1,1,"ADC:"); // Write text in first row
   
   
    ADIE_bit = 1;
   
    ADEN_bit = 1;
   
    ADFR_bit = 0;
   
    ADIF_bit = 0;
   
    ADPS2_bit = 1;
   
    ADPS1_bit = 1;
   
    ADPS0_bit = 1;
   
   
   
    ADMUX = 0b01000000;
   
    while(1){
       
        //ADIE_bit = 1;
       
        ADSC_bit = 1;
       
        while(!ADIF_bit);
       
        ADIF_bit = 0;
       
        ADC = (ADCH * 256) + ADCL;
       
        IntToStr(ADC,display);
       
        Lcd_Out(2,1,display);
       
    }
   
}
i get error in uploading the circuit.
 
Last edited by a moderator:

DerStrom8

Super Moderator
Most Helpful Member
#2
Hello, Mudassir Shah, welcome to ETO!

I have placed your code inside code tags so that the formatting is preserved. Next time you post code, you can go to the "insert" button, select "code", and paste your code inside the tags. It makes things much neater and easier to read ;)

As for your question, what is the error you get? It would be very useful to know this information.

Regards,
Matt
 

Ian Rogers

User Extraordinaire
Forum Supporter
Most Helpful Member
#4
The Datasheet said:
Once the conversion starts, the channel and reference selection is locked to ensure a sufficient sampling time for the ADC
This assumes you are not allowing enough time to complete the conversion..

Place a tiny delay after the line...

ADSC_bit = 1;
 
Thread starter #5
thanks for reply.
i am not changing ADC channel and and its reference as you can see it in the code.
according to your instructions, i added 1ms delay but still i am getting the same error.
 

Ian Rogers

User Extraordinaire
Forum Supporter
Most Helpful Member
#6
We have one or two really good AVR programmers here at ETO... I'm sure one will shed some light on your problem...

The datasheet locks the ADC registers at the start of conversion, regardless of a channel change. Read the specification in the MikroC manual... I predominantly use Pic's so some AVR functions are alien to me...
 
Thread starter #10
i define the port direction according to your instruction. but still i am facing the same problem. new code is
Code:
// LCD module connections
sbit LCD_RS at PORTD0_bit;
sbit LCD_EN at PORTD1_bit;
sbit LCD_D4 at PORTD2_bit;
sbit LCD_D5 at PORTD3_bit;
sbit LCD_D6 at PORTD4_bit;
sbit LCD_D7 at PORTD5_bit;

sbit LCD_RS_Direction at DDD0_bit;
sbit LCD_EN_Direction at DDD1_bit;
sbit LCD_D4_Direction at DDD2_bit;
sbit LCD_D5_Direction at DDD3_bit;
sbit LCD_D6_Direction at DDD4_bit;
sbit LCD_D7_Direction at DDD5_bit;
// End LCD module connections

unsigned int ADC = 0,adc_result=0;
unsigned char display[7];


void main() {
  Lcd_Init();                        // Initialize LCD
  Lcd_Cmd(_LCD_CLEAR);               // Clear display
  Lcd_Cmd(_LCD_CURSOR_OFF);          // Cursor off

  Lcd_Out(1,1,"ADC:");                 // Write text in first row

       ADIE_bit = 1;
       ADEN_bit = 1;
       ADFR_bit = 0;
       ADIF_bit = 0;
       ADPS2_bit = 1;
       ADPS1_bit = 1;
       ADPS0_bit = 1;

       ADMUX = 0b01000000;
       DDRC.F0 = 0;

       while(1){
            ADSC_bit = 1;
        while(!ADIF_bit);
        ADIF_bit = 0;
        ADC = (ADCH * 256) + ADCL;
            IntToStr(ADC,display);
            Lcd_Out(2,1,display);
       }
}
 

misterT

Well-Known Member
Most Helpful Member
#12
ADC result register is 16 bit double buffered register. When you read the ADCL (low byte), the 16bit register update is locked until you read the ADCH (high byte).
If you read ADCH first and then ADCL, the register will stay locked, preventing any new conversion to be written in the result register.
(And do not use variable names like "ADC", that may already be reserved).

C:
/* Safe way to read ADC result register */
adc_result = ADCL; /* Read the low byte */
adc_result += (ADCH<<8); /* Read and add the high byte */

Also, you may have serious problem here:
ADC = (ADCH * 256) + ADCL;
The variable "ADC" may already be defined as the adc result register.. and writing to that is not allowed. Change the name of that variable.
 
Last edited:

Latest threads

EE World Online Articles

Loading

 
Top