Error in function with pointer

Status
Not open for further replies.

djc

Advanced Member level 1
Joined
Jan 27, 2013
Messages
402
Helped
3
Reputation
6
Reaction score
2
Trophy points
1,298
Location
India
Visit site
Activity points
4,554
Hi,
Here is my code for ATMEGA8 using Codevision for AVR for LCD programming,
Code:
/*****************************************************
This program was produced by the
CodeWizardAVR V2.03.4 Standard
Automatic Program Generator
© Copyright 1998-2008 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com

Project : 
Version : 
Date    : 3/18/2014
Author  : 
Company : 
Comments: 


Chip type           : ATmega8
Program type        : Application
Clock frequency     : 8.000000 MHz
Memory model        : Small
External RAM size   : 0
Data Stack size     : 256
*****************************************************/

#include <mega8.h>
#include <delay.h>
#include <string.h>
#include <stdio.h>

#define LCD PORTC
#define RS  PORTC.4
#define EN  PORTC.5

void disp_cmd(unsigned char cmdout){
    LCD = cmdout;
    RS = 0;
    EN = 1;
    delay_us(10);
    EN = 0;    
}

void disp_dat(int dataout){
    LCD = dataout;
    RS = 1;
    EN = 1;
    delay_us(10);
    EN = 0; 
}
void LCD_Cmd(unsigned char data){
    unsigned char val;  
    val = (data & 0xF0);
    disp_cmd(val);
    delay_us(10);
    val = ((data<<4) & 0xF0);
    disp_cmd(val);
    delay_us(10);   
}

void LCD_Dat(char data_1){
    unsigned char val_1;
    val_1 = (data_1 & 0xF0);
    disp_dat(val_1);
    delay_us(100);
    val_1 = ((data_1<<4) & 0xF0);
    disp_dat(val_1);
    delay_us(100);
}

void LCD_Init(){
    LCD_Cmd(0x01);      //clear the screen
    delay_ms(1);
    LCD_Cmd(0x28);      //4bit,2ine,5*7matrix
    delay_us(100);
    LCD_Cmd(0x02);      //Cursor to top left character position
    delay_ms(1);
    LCD_Cmd(0x0F);      //Turn On visible blinking block cursor
    delay_us(100);
    LCD_Cmd(0x06);
    delay_us(100);
} 

void Print_LCD(char *cptr){
    while(*cptr != '\0'){
        LCD_Dat(*cptr);
        delay_us(100);
        cptr++;
        
    }
}

// Declare your global variables here

void main(void)
{
// Declare your local variables here

// Input/Output Ports initialization
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTB=0x00;
DDRB=0x00;

// Port C initialization
// Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out 
// State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0 
PORTC=0x00;
DDRC=0x7F;

// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTD=0x00;
DDRD=0x00;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
TCCR0=0x00;
TCNT0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
MCUCR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;
LCD_Init();
delay_ms(40);
while (1)
      {
      // Place your code here
      
      Print_LCD("w"); /////////////////////Error line///////////////////////
      };
}

However its giving an error in mentioned line that
function argument #1 of type 'flash unsigned char[2]' is incompatible with required parameter of type 'unsigned char'. What should be done for it.
 

Some changes.


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void LCD_Dat(char data_1){
    
    disp_dat((data_1 & 0xF0));
    delay_us(100);
    disp_dat(((data_1<<4) & 0xF0));
    delay_us(100);
}
 
void Print_LCD(char *cptr){
    while(*cptr){
        LCD_Dat(*cptr++);
        delay_us(100);       
        
    }
}
 
void disp_dat(char dataout){
    LCD = dataout;
    RS = 1;
    EN = 1;
    delay_us(10);
    EN = 0; 
}

 

However its giving an error in mentioned line that
function argument #1 of type 'flash unsigned char[2]' is incompatible with required parameter of type 'unsigned char'. What should be done for it.
Did you quote the error message correctly? I would expect "required parameter of type 'unsigned char *'"

It looks like the behaviour of a compiler where pointers to constant data in flash and RAM data aren't assignment compatible and need special handling. I'm not familiar with AVR codevision, but I see there's a chapter "4.12 Pointers" in user manual. Essentially you need a separate print function with flash char* argument, or copy the string to RAM before printing it.

Some changes.
Unrelated to the problem, I presume.
 
Reactions: djc

    djc

    Points: 2
    Helpful Answer Positive Rating
Codevision puts character literal strings in flash and uses separate flash pointers and ram pointers rather than generic memory pointers.

Change your function to expect a flash pointer as a parameter and it will work

Code:
void Print_LCD(char [COLOR="#FF0000"]flash[/COLOR] *cptr){
    while(*cptr != '\0'){
        LCD_Dat(*cptr);
        delay_us(100);
        cptr++;
        
    }
}
 
Reactions: djc

    djc

    Points: 2
    Helpful Answer Positive Rating
Yes FvM you are right, it is 'unsigned char *'. Really it was an issue of compiler. I made changes suggested by alexan. Its working now. Thanx to both of you guys.

How ever could any body of you suggest some changes in the code. Because i am not getting anything on the LCD. Not even cursor blinking. Whether i am dividing 8 bit data in 4 bit properly. GND Pin of LCD is connected to Pin 22 of Atmega8 and VCC pin of LCD to Pin 20 of Atmega8. D4,D5,D6,D7 of LCD to PC0, PC1,PC2,PC3 of Atmega8. R/W pin is grounded.
 
Last edited:

codevision includes it's own LCD library, is there a reason you want to write your own?

- - - Updated - - -

Note that the codevision library uses assembly for the majority of its functions do it should be faster that a custom library.
Maybe you are trying to write something that occupies less flash?

- - - Updated - - -

It's usually a good idea to check some of the existing LCD libraries and use them as example to write your own or do modifications.
 

Thanx alexan,

My LCD routine is working fine now. Only issue is 'Print_LCD' function is accepting only string. However i want to use DS1307 RTC now and display time and date on LCD. So made some modifications in the code. Rest of the things are same just I2C and DS1307 library. Here is the code
Code:
while (1)
      {
      // Place your code here
      /* read time from the DS1307 RTC */
        rtc_get_time(&h,&m,&s);
        time_hr = h;
        sprintf(strbuff,"%d",time_hr);
        Print_LCD("Welcome");
        LCD_Cmd(0xc0);
        Print_LCD(strbuff);//////////////////////////////Error//////////////////
      };
Now the same error appears as i have mentioned before. I have declared variables time_hr as unsigned char and strbuff[20] as char.
 


Code C - [expand]
1
2
time_hr = h;
        sprintf(strbuff,"%d",time_hr);



time_hr is unsigned char and sprintf() expects float or double.

Use sprinti() and cast time_hr to int

Code C - [expand]
1
(sprinti(strbuff,"%d",(int)time_hr);

 

Hi ,

there is no such function as SPRINTI() in codevision, i searched it. Any other option.Am i reading hour value correctly i.e
time_hr=h; is it right. Because i am getting value '0' on LCD. I took original Print_LCD function with 'char *cptr' to display 'strbuff '.
 

Declare two function, one that accept flash strings and one that accepts RAM strings
Code:
void Print_LCD(char *cptr){
    while(*cptr){
        LCD_Dat(*cptr++);
        delay_us(100);       
        
    }
}


void Print_LCD_F(char flash *cptr){
    while(*cptr){
        LCD_Dat(*cptr++);
        delay_us(100);       
        
    }
}

and use

Code:
char my_ram_string[]="something";

Print_LCD(my_ram_string);
Print_LCD_f("my flash string");
 
Reactions: djc

    djc

    Points: 2
    Helpful Answer Positive Rating
Thanx alexan, I did same. It's working now. I didn't know that we have to set the data in RTC first. Then it gives us the time value. Now its giving right time value.
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…