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?
 
On the MikroC forum the only reference to locked registers is if the port hasn't been set up correctly..

Check the port direction registers
 
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);
       }
}
 
Post your problem on the MikroC forum!!

Why don't you just use the inbuilt function "readAdc()"
 
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.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…