Continue to Site

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.

  • 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.

Status
Not open for further replies.

mudassir shah

New Member
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:
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
 
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;
 
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.
 
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...
 
Are you using atmel studio for this, or some other toolchain? Can you debug the device over jtag?
 
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);
       }
}
 
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:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top