I have made my custom serial(UART) library. So I made uart.h and uart.cpp files as following.
uart.h
#ifndef UART_H
#define UART_H
#include <avr/io.h>
#include <stdlib.h>
//creating class named uart
class uart{
public:
// creating constructor
uart(void);
//function to start uart at given baudrate
void start(int baudrate);
// function to read uart input
unsigned char read();
// function to print data on serial monitor
void print(unsigned char data);
// function to print string on serial monitor
void print(char *string);
// function to print data with given base
void print(unsigned char data,unsigned int base);
//function to print data like printf
void print(char* str,unsigned char data);
// function to read data by printing string
unsigned char read(char* string);
};
#endif
uart.cpp
#include "uart.h"
uart::uart(void);
void uart::start(int baudrate){
long BAUDRATE = ((F_CPU)/(baudrate*16UL)-1);
UBRR0H = (BAUDRATE >> 8);
UBRR0L = BAUDRATE;
// enable recieve and transmit
UCSR0B |= 1 << RXEN0 | 1 << TXEN0;
// data size is equal to 8 bits
UCSR0C |= 1 << UCSZ00 | 1 << UCSZ01;
}
unsigned char uart::read(){
//wait until receive complete.
while(!(UCSR0A & (1 << RXC0)));
// return received byte
return UDR0;
}
void uart::print(unsigned char data){
// wait until UDR is empty
while(!(UCSR0A & (1 << UDRE0)));
//place data into UDR
UDR0 = data;
}
void uart::print(unsigned char* string){
int index = 0;
// print string character by character
while(string[index] != '0円'){
print(string[index]);
index++;
}
}
void uart::print(unsigned char data,unsigned int base){
//buffer to store converted data
char buffer[10];
//convert data to ascii
itoa(data,buffer,base);
//print converted data
print(buffer);
}
// function to print data like printf(%d,data);
void uart::print(char* str,unsigned char data){
int index = 0;
// print string character by character
while(str[index] != '0円'){
if(str[index] == '%'){
index++;
if(str[index]=='d') print(data,10);
else if(str[index] == 'b') print(data,2);
else if(str[index] == 'x') print(data,16);
index++;
}
print(str[index]);
index++;
}
}
unsigned char uart::read(unsigned char* string){
// print given string
print(string);
// return read char
return(read());
}
test.cpp
#include "uart.h"
int main(){
uart.start(9600);
uart.print("Hello world\n");
}
Now all of above function works if i write all function and declations in single .h file and don't divide my header file in .h and .cpp file. if i compile this given program i get following error.
Error
src/uart.cpp
src/uart.cpp:3:16: error: declaration of 'uart::uart()' outside of class is not definition [-fpermissive]
uart::uart(void);
^
src/uart.cpp:39:6: error: prototype for 'void uart::print(unsigned char*)' does not match any in class 'uart'
void uart::print(unsigned char* string){
^
In file included from src/uart.cpp:1:0:
src/uart.h:31:7: error: candidates are: void uart::print(char*, unsigned char)
void print(char* str,unsigned char data);
^
src/uart.h:28:7: error: void uart::print(unsigned char, unsigned int)
void print(unsigned char data,unsigned int base);
^
src/uart.h:25:7: error: void uart::print(char*)
void print(char *string);
^
src/uart.cpp:30:6: error: void uart::print(unsigned char)
void uart::print(unsigned char data){
^
src/uart.cpp:91:15: error: prototype for 'unsigned char uart::read(unsigned char*)' does not match any in class 'uart'
unsigned char uart::read(unsigned char* string){
^
In file included from src/uart.cpp:1:0:
src/uart.h:34:16: error: candidates are: unsigned char uart::read(char*)
unsigned char read(char* string);
^
src/uart.cpp:20:15: error: unsigned char uart::read()
unsigned char uart::read(){
^
.build/uno/Makefile:166: recipe for target '.build/uno/src/uart.o' failed
make: *** [.build/uno/src/uart.o] Error 1
Make failed with code 2
PS: I use
inotool
to compile and upload my programs to arduino and it works great. So you will findsrc/
in error.
Please help me. I'm stuck here.
1 Answer 1
uart::uart(void);
That's a prototype, not a function. It needs a body. Also, using "void" to say "no parameters" is really confusing. Better to leave it out all together.
uart::uart() {
}
uart.start(9600);
uart.print("Hello world\n");
uart
is a class, not an instance. You should be using uart::start(9600)
if you first set your functions to be static
, or create an instance from the uart
class:
uart myUart;
int main() {
myUart.begin(9600);
myUart.print("Hello world\n");
}
Watch your random unsigned
entries...
uart.h:
unsigned char read(char* string);
uart.c:
unsigned char uart::read(unsigned char* string){
... There may be others too.
-
Thank you for your reply.i will correct my mistakes as you mentioned.and let me see if it works or not.Mohit Tank– Mohit Tank2015年06月13日 14:36:30 +00:00Commented Jun 13, 2015 at 14:36
-
It may take a few iterations. Can't see the wood for the trees at the moment ;) Get rid of these errors first and we'll see where we can go from there.Majenko– Majenko2015年06月13日 14:37:11 +00:00Commented Jun 13, 2015 at 14:37
-
is it mandatory to use constructor in class,in my case
uart::uart(){ }
.Mohit Tank– Mohit Tank2015年06月13日 14:56:22 +00:00Commented Jun 13, 2015 at 14:56 -
If you don't specify a constructor a "default" empty constructor will be provided. It's good to be explicit and provide one thought. You could have it all in the header file though for simplicity...
uart() {}
Majenko– Majenko2015年06月13日 14:57:05 +00:00Commented Jun 13, 2015 at 14:57 -
thank you so much @Majenko ,now my header file is working.thank you so so so much..i was stuck from past two days on this errorMohit Tank– Mohit Tank2015年06月13日 15:07:23 +00:00Commented Jun 13, 2015 at 15:07
print()
, you should just subclassPrint
and only implementsize_t write(uint8_t)
. This way you avoid code duplication, as there are many classes in the Arduino libraries inheritingPrint
.