0

This is my first program for AVR. While building, the code is showing error: conflicting types for 'Encode' implicit declaration of 'Encode'

I have written the following code:

#include <avr/io.h>
#include <util/delay.h>
#include <stdlib.h>

#define SegDataPort PORTC
#define SegDataPin PINC
#define SegDataDDR DDRC

#define SegCntrlPort PORTD
#define SegCntrlPin PIND
#define SegCntrlDDR DDRD

int main(void)
{
   SegDataDDR = 0xFF;
   SegCntrlDDR = 0xF3;
   SegCntrlPort = 0xF3;
   SegDataPort = 0x00;
   unsigned char adc_value;
   float volt = adc_value/1023;
   int temp = floor(volt*10 + 0.5);

   SegDataPort = Encode(temp1%10);

   //^^^^ implicit declaration of 'Encode' 

   SegCntrlPort = ~0x01;
   SegDataPort = Encode((temp1/10)%10);
   SegCntrlPort = ~0x02;
   SegDataPort = Encode(temp1/100);
   SegCntrlPort = ~0x04;
}

unsigned char Encode(int digit)
{
   unsigned char val;
   switch(digit)
   {
      case 0 : Val = 0b00111111;
      case 1 : val = 0b00000110;

      /// so on till case 9
   }
   return val;
}

I am using ATmega16 as microcontroller. I have also added much more libraries such as math for floor function and others. I have tried changing int to unsigned int, unsigned char and others but it is still not working and showing same error. Please help me.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
Yash
  • 145
  • 9
  • @mathematician1975 AFAIK, `PORTx` are AVR specific registers which can be used as normal c variables. Please correct me if i'm wrong. – Sourav Ghosh Jun 02 '15 at 06:51

2 Answers2

2

implicit declaration of 'Encode'

In C a function needs to be either declared or defined before it has been used (called).

Either

  • Move the definition of Encode() function before main()
  • Add a forward declaration to Encode() before main().

That said, floor() is a function, defined in math.h and defined in the math library. To use that, you need to #include <math.h> and link with -lm at compilation time.


About the programmic logic used here,

unsigned char adc_value;
float volt = adc_value/1023;
int temp = floor(volt*10 + 0.5);

are pretty problematic, because

  1. adc_value is used uninitialized, which leads to undefined behaviour.
  2. adc_value is of type char. Dividing it by a value of 1023 will always give a result of 0 as the division will take place as an integer division and won't produce a float result itself, as you migh have expected.

My suggestions, change that code block to

int adc_value = <some value to initialize>;  //or some input function
float volt = (float)adc_value/1023;          //enforce floating point division
int temp = floor(volt*10 + 0.5);
Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
  • It worked. Thank you. But can you tell me why the function has to be called before in C. As this was not the case for C++ or Java or Python – Yash Jun 02 '15 at 06:50
  • @Yash called before? no, it's the other way, it has to be _declared_ before _called_. You can check [here](http://stackoverflow.com/q/2575153/2173917) for more info on this. – Sourav Ghosh Jun 02 '15 at 06:54
0

First mistake:

 unsigned char adc_value;
 float volt = adc_value/1023;

You defind adc_value as an unsigned char and in the next line you tried to divide it by 1023 and assigned the result to a float type variable. You can't do these in C language. (More over you didn't assign any value to adc_value! it will be zero or a random value)

Second mistake:

Your second problem is that you defined your Encode function after calling it in main(). You must move the whole function before main() function or just add its prototype before the main() function.

i.e add unsigned char Encode(int digit); before main()

Thirst mistake:

You tried to assign some values to those variables that you declared with #define:

#define SegDataPort PORTC
#define SegDataPin PINC
#define SegDataDDR DDRC

#define SegCntrlPort PORTD
#define SegCntrlPin PIND
#define SegCntrlDDR DDRD

int main(void)
{
   SegDataDDR = 0xFF;
   SegCntrlDDR = 0xF3;
   SegCntrlPort = 0xF3;
   SegDataPort = 0x00;
   .
   .
   .

This is illegal also. those variables that is defined with #define, are constant and you must not try to change them in the program body.

Ebrahim Ghasemi
  • 5,850
  • 10
  • 52
  • 113
  • adc_value is my analog input. SO, it ranges from 0 to 1023. – Yash Jun 02 '15 at 06:52
  • With all due respect, would you mind checking your third point once more? – Sourav Ghosh Jun 02 '15 at 06:55
  • I'm not very sure, No experiece of AVR. Please verify [this](http://stackoverflow.com/questions/30589109/implicit-declaration-of-function-and-conflicting-type-avr/30589168#comment49247557_30589109) once. – Sourav Ghosh Jun 02 '15 at 06:59
  • 1
    @Yash Its defined as an `unsigned char` so its value can be from `0` to `255`. (it has 8 bit length.) why you didn't defined it as `int`? – Ebrahim Ghasemi Jun 02 '15 at 06:59
  • So, how can I say that ports of my microcontroller are input or output. I have found only this way while surfing. – Yash Jun 02 '15 at 07:00
  • I am reading its value directly from microcontroller input, I think that the input is of the form of 'char' only. Correct me if I'm wrong !! – Yash Jun 02 '15 at 07:04
  • @Yash `PORTx` and `DDRx` are two different variable. the first specify the voltage of output and the latter specify the direction. – Ebrahim Ghasemi Jun 02 '15 at 07:07
  • @Yash For example when `DDRD=0xff` then D is output and for output ports `PORTD=0xff` means all the pins are 5 volt. and `PORTD=0x00` means all the pins of this port are 0 volt. When `DDRD=0x00` the D is input and tor input ports `PORTD=0xFF` means that all the pins are pulled-up with inner resistors, while `PORTD=0x00` means that they are not pulled-up. – Ebrahim Ghasemi Jun 02 '15 at 07:11
  • the #define is NOT creating a variable, rather it is a 'text substitution' that occurs at beginning of the compile operation. so, wherever one of those #define names is used, it is actually (in this case) an access to the associated hardware register. – user3629249 Jun 03 '15 at 15:37
  • regarding 'first mistake' There is a second problem in the same code lines. When working with 'float' values, the literals need to be of the format that includes a '.' and is trailed by 'f'. The '.' to make the literal non-integer and the 'f' to make it float. without the 'f' it is a double. – user3629249 Jun 03 '15 at 15:40