a small Pointers through Functions question from a noob.. please help

Go To Last Post
12 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi

so I wrote some function ( or better say copied) for USART 

I want to design a function that i pass to it a string or an array via pointers and it send it by usart

 

first .. my code :

/*
 * Learn.c
 *
 * Created: 3/15/2019 7:07:23 PM
 * Author : AbDoO_
 */ 

#define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h>

//ADC Vars :
unsigned int sensor_value,adh,adl;
//Conversion Vars :
unsigned char txt[6]; 

//USART Functions :
void Usart_Init(unsigned int USART_BAUDRATE);
void Usart_Write(unsigned char Data2Write);
unsigned char Usart_Read();

void int2str(unsigned int d);

int main(void)
{
	DDRB =0xff;
	DDRC =0x00;
	Usart_Init(4800);
	char x =0;
	ADCSRA |= (0 << ADPS2) | (1 << ADPS1) | (1 << ADPS0); // SET ADC PRESCALAR TO 8 - 125KHZ SAMPLE RATE @ 1MHZ

	ADMUX |= (1 << REFS0); // SET ADC REFERENCE TO AVCC
	//ADMUX |= (1 << ADLAR); // LEFT ADJUST ADC RESULT TO ALLOW EASY 8 BIT READING

	// NO MUX VALUES NEEDED TO BE CHANGED TO USE ADC0

	ADCSRA |= (1 << ADFR);  // SET ADC TO FREE-RUNNING MODE

	ADCSRA |= (1 << ADEN);  // ENABLE ADC
	ADCSRA |= (1 << ADSC);  // START A2D CONVERSIONS

    while (1)
    {
		_delay_ms(100);
		adl= ADCL;
		adh = ADCH;
		sensor_value= (adh<<8) | adl ;

		int2str(sensor_value);

		// the code section i want to replace with a function
                x=0;
		while(txt[x] != 0 ){
			Usart_Write(txt[x]);
			x++;
		}

		Usart_Write(0x0d);

    }
}

void int2str(unsigned int d)
{
	txt[0] = (d/10000) + 48 ;
	d = d - (d/10000)*10000;

	txt[1] = (d/1000) + 48 ;
	d = d - (d/1000)*1000;

	txt[2] = (d/100) + 48 ;
	d = d - (d/100)*100;

	txt[3] = (d/10) + 48 ;
	d = d - (d/10)*10;

	txt[4] = (d/1) + 48 ;
	d = d - (d/1)*1;

	txt[5] = 0;
}

void Usart_Init(unsigned int USART_BAUDRATE)
{
	unsigned int BAUD_PRESCALE;
	BAUD_PRESCALE = (((F_CPU / (USART_BAUDRATE * 16UL))) - 1);

	UCSRB = (1 << RXEN) | (1 << TXEN); // Turn on the transmission and reception circuitry
	UBRRH = (BAUD_PRESCALE >> 8); // Load upper 8-bits of the baud rate value into the high byte of the UBRR register
	UBRRL = BAUD_PRESCALE; // Load lower 8-bits of the baud rate value into the low byte of the UBRR register
};
void Usart_Write(unsigned char Data2Write)
{
	while ((UCSRA & (1 << UDRE)) == 0) {}; // Do nothing until UDR is ready for more data to be written to it
	UDR = Data2Write;
};
unsigned char Usart_Read()
{
	while((UCSRA & (1<<RXC)) == 0){};
	return UDR ;

};

the int2str() is for transferring the int value of the adc to a string so i can send it by usart 

Every thing works 100 percent accept(but not) for some warnings that i ignored like :
"" Warning        array subscript has type 'char' [-Wchar-subscripts] ""

but the code works perfectly

i want another function  to do this part of the code 

		x=0;
		// the code section i want to replace with a function
		while(txt[x] != 0 ){ // considering that every string sentence ends with a NULL or a 0
			Usart_Write(txt[x]);
			x++;
		}

		Usart_Write(0x0d); // add a line 

But instead of the array "txt" i want a pointer so i can pass any array or string i want  

i tried some thing like this 

 

void Usart_Write_Text(unsigned int* p){ // i tried unsigned char also
    char x=0;
    	// the code section i want to replace with a function
		while(p[x] != 0 ){ // I also tried useing *p instead of p
			Usart_Write(p[x]);// I also tried using *p instead of p
			x++;
		}

		Usart_Write(0x0d);
}

Please you are free to copy any thing ,

please modify my Usart_Write_Text(..) function and make it work

NOTE:
i want to use it somehow like this : 

Usart_Write_Text("HI test1 test 2 ");

Usart_Write_Text(txt); // or &txt you tell me 

 

(SIDE QUESTION): is this considered a bad or a good question?( i mean forum) (so i can improve how i ask in the futuer )

THANKS ALOT

This topic has a solution.

A Beam of Light out of the War

Last Edited: Wed. Apr 24, 2019 - 02:22 PM
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1
#include <avr/io.h>

void Usart_Write(unsigned char c) {
  /* ... */
  UDR0 = c; 
}


void Usart_Write_Text(unsigned char *text) {
  unsigned char c;

  while ((c = *text++) != 0) {
    Usart_Write(c);
  }
}

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for replying 

when using it should i write it 

with the '&' sign or with out it ?

 

Usart_Write_Text(&txt); //the & sign ?? 

and what about that warning message i was getting 

AbDoO_ wrote:
Every thing works 100 percent accept(but not) for some warnings that i ignored like :
"" Warning        array subscript has type 'char' [-Wchar-subscripts] ""

thanks for helping 

A Beam of Light out of the War

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 2
void Usart_Write_Text(char *text) {


  while (*text) {
    Usart_Write(*text++);
  }
}

Even simpler.

 

For an array, the array name is the pointer, so no & required.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Don't use `&'.   When the C compiler sees an array as function argument, it passes the pointer to the first element.   So foo(txt) is the same as foo(&txt[0]), but foo(&txt) can get you into trouble (if you mix arrays and pointers).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

AbDoO_ wrote:

AbDoO_ wrote:

Every thing works 100 percent accept(but not) for some warnings that i ignored like :
"" Warning        array subscript has type 'char' [-Wchar-subscripts] ""

 

 

 

Exactly what it says -

 

you had char x = 0

then used x as an array subscript

 

p[x] 

so the compiler was warning you. If you had int x = 0; then the compiler would not have issued a warning.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

AbDoO_ wrote:

Warning        array subscript has type 'char' [-Wchar-subscripts]

 

This is just because the C language standard does not specify if char is signed or not. This might cause unexpected errors when used as an array index, so the compiler is warning you to use a type which has a well defined sign, for example, unsigned char.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Kartman wrote:

void Usart_Write_Text(char *text) {

  while (*text) {
    Usart_Write(*text++);
  }
}

Even simpler.

 

Yup.  But this form can get you into trouble in cases where Usart_Write turns out to be a macro.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Macros can get you into a lot of trouble anyways. Just say 'no'!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
        adl= ADCL;
		adh = ADCH;
		sensor_value= (adh<<8) | adl ;

		int2str(sensor_value);
		
		can be simplified to :
		
		int2str(ADC);   //let the compiler manage ADCH/L

and another stylistic issue:

void int2str(unsigned int d)
{
	txt[0] = (d/10000) + 48 ;
	d = d - (d/10000)*10000;

	txt[1] = (d/1000) + 48 ;
	d = d - (d/1000)*1000;

	txt[2] = (d/100) + 48 ;
	d = d - (d/100)*100;

	txt[3] = (d/10) + 48 ;
	d = d - (d/10)*10;

	txt[4] = (d/1) + 48 ;
	d = d - (d/1)*1;

	txt[5] = 0;
}

don't use magic numbers:

void int2str(unsigned int d)
{
	txt[0] = (d/10000) + '0' ;
	d = d - (d/10000)*10000;

	txt[1] = (d/1000) + '0' ;
	d = d - (d/1000)*1000;

	txt[2] = (d/100) + '0' ;
	d = d - (d/100)*100;

	txt[3] = (d/10) + '0';
	d = d - (d/10)*10;

	txt[4] = (d/1) + '0' ;
	d = d - (d/1);

	txt[5] = 0;
}

avoid using globals:

void int2str(unsigned int d, char *str)
{
	str[0] = (d/10000) + '0' ;
	d = d - (d/10000)*10000;

	str[1] = (d/1000) + '0' ;
	d = d - (d/1000)*1000;

	str[2] = (d/100) + '0' ;
	d = d - (d/100)*100;

	str[3] = (d/10) + '0' ;
	d = d - (d/10)*10;

	str[4] = (d/1) + '0' ;
	d = d - (d/1)*1;

	str[5] = 0;
}

or simply use the itoa() function

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

El Tangas wrote:

 

This is just because the C language standard does not specify if char is signed or not. This might cause unexpected errors when used as an array index, so the compiler is warning you to use a type which has a well defined sign, for example, unsigned char.

 

ahh.. after typing unsigned char instead of char  the warning disappeared .. thanks you very much

 

 

Kartman wrote:
and another stylistic issue:

dude this is pure gold.. thank you .. 

but i googled about ( integer to string functions in c) alot but couldn't find any thing .. so i wrote that function

I would be very greatfull if you can provide a source for available functions or some kind of  a list 

 

THANKS FOR ALL

A Beam of Light out of the War

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

AbDoO_ wrote:
I would be very greatfull if you can provide a source for available functions or some kind of  a list 
I find cplusplus.com to be a good resource. The name C++ maybe suggests it only covers C++ but C is just a subset of C++ anyway so it is implicitly covered. In the C++ world the C version of the "standard" headers like stdio.h, stlib.h and so on are actually known as cstdio (no .h), cstdlib, etc. So you find things like:

 

http://www.cplusplus.com/reference/cstdlib/

http://www.cplusplus.com/reference/cstring/

etc.

 

For GCC there is also a manual for the C library that comes with it (generally known as "AVR-LibC") that you will find here:

 

https://www.nongnu.org/avr-libc/user-manual/modules.html

 

that has pages very similar (though not as much detail and few/any examples compared to cplusplus.com) such as:

 

https://www.nongnu.org/avr-libc/user-manual/group__avr__stdlib.html

https://www.nongnu.org/avr-libc/user-manual/group__avr__string.html

etc.

 

You will spot some things there that are not in the "standard" headers (as found at cplusplus) such as the fact that AVR-LibC has itoa():

 

https://www.nongnu.org/avr-libc/user-manual/group__avr__stdlib.html#gaa571de9e773dde59b0550a5ca4bd2f00

 

when this is not standard.

 

Bottom line - for anything in "standard C" I'd look at cplusplus.com, for anything very specific to avr-gcc I'd look at the AVR-LibC manual.

 

EDIT: actually it turns out that cplusplus also knows of the non-standard itoa():

 

http://www.cplusplus.com/reference/cstdlib/itoa/?kw=itoa

 

That surprises me because itoa() is not standard and there can be multiple interpretations for how it behaves. AVR-LibC and cplusplus both talk about an itoa() with 3 parameters where the 3rd is "radix" so by setting to 2, 10 or 16 (for example) you can have the result in binary, decimal or hex. But a compiler such as Codevision for AVR also has an itoa() but that one fixes the radix at 10 to make a simpler to call 2 parameter version with a fixed to decimal result.

Last Edited: Wed. Apr 24, 2019 - 02:57 PM