Всем привет! Понадобилось добавить библиотеку в проект, но пишу AVRStudio 7 и для atmega8a, столкнулся с некоторыми проблемами… Библиотека для радио передатчика 433MHz, и суть такова что с начало в лоб хотел её вставить, но выхватил тут же ошибку:
Severity Code Description Project File Line
Error multiple definition of `fastRead(unsigned char)' Fe_wate_house_atmega8_433MHz G:\FastIO.h 31
Error multiple definition of `fastWrite(unsigned char, bool)' Fe_wate_house_atmega8_433MHz G:\FastIO.h 31
Error multiple definition of `G433_crc8_byte(unsigned char&, unsigned char)' Fe_wate_house_atmega8_433MHz G:\FastIO.h 31
Error multiple definition of `G433_crc8(unsigned char*, unsigned char)' Fe_wate_house_atmega8_433MHz G:\FastIO.h 31
Error multiple definition of `G433_crc_xor(unsigned char*, unsigned char)' Fe_wate_house_atmega8_433MHz G:\FastIO.h 31
Сами два файла библиотеки:
FastIO.h
#ifndef FastIO_H_
#define FastIO_H_
#define bitRead(value, bit) (((value) >> (bit)) & 0x01)
#define bitSet(value, bit) ((value) |= (1UL << (bit)))
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
#define bitToggle(value, bit) ((value) ^= (1UL << (bit)))
#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit))
#define bit(b) (1UL << (b))
bool fastRead(const uint8_t pin); // быстрое чтение пина
void fastWrite(const uint8_t pin, bool val); // быстрая запись
// ================================================================
bool fastRead(const uint8_t pin) {
#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__) || defined (__AVR_ATmega8A__)
if (pin < 8) return bitRead(PIND, pin);
else if (pin < 14) return bitRead(PINB, pin - 8);
else if (pin < 20) return bitRead(PINC, pin - 14);
#elif defined(__AVR_ATtiny85__) || defined(__AVR_ATtiny13__)
return bitRead(PINB, pin);
#endif
return 0;
}
void fastWrite(const uint8_t pin, bool val) {
#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__) || defined (__AVR_ATmega8A__)
if (pin < 8) bitWrite(PORTD, pin, val);
else if (pin < 14) bitWrite(PORTB, (pin - 8), val);
else if (pin < 20) bitWrite(PORTC, (pin - 14), val);
#elif defined(__AVR_ATtiny85__) || defined(__AVR_ATtiny13__)
bitWrite(PORTB, pin, val);
#endif
}
#endif /*FastIO_H_*/
Gyver433.h
#ifndef Gyver433_H_
#define Gyver433_H_
#include "main.h"
#include "FastIO.h"
uint8_t G433_crc8(uint8_t *buffer, uint8_t size); // ручной CRC8
uint8_t G433_crc_xor(uint8_t *buffer, uint8_t size); // ручной CRC XOR
#define TRAINING_TIME_SLOW (500000UL) // время синхронизации для SLOW_MODE
// =========================================================================
#ifndef G433_SPEED
#define G433_SPEED 1000
#endif
// тайминги интерфейса
#define FRAME_TIME (1000000UL / G433_SPEED) // время фрейма (либо HIGH) 1000000/2000=500
#define HALF_FRAME (FRAME_TIME / 2) // полфрейма (либо LOW) 500/2=250
#define START_PULSE (FRAME_TIME * 2) // стартовый импульс 500*2=1000
// окно времени для обработки импульса
#define START_MIN (START_PULSE * 3 / 4) //1000*3/4=750
#define START_MAX (START_PULSE * 5 / 4) //1000*5/4=1250
#define FRAME_MIN (FRAME_TIME * 3 / 4) //500*3/4=375
#define FRAME_MAX (FRAME_TIME * 5 / 4) //500*5/4=625
#define HALF_FRAME_MIN (HALF_FRAME * 3 / 4) //250*3/4=187,5
#define HALF_FRAME_MAX (HALF_FRAME * 5 / 4) //250*5/4=312,5
// жоский delay для avr
#ifdef AVR
#define G433_DELAY _delay_us
// #else
// #define G433_DELAY delayMicroseconds0
#endif
// режимы CRC
#define G433_NOCRC 0
#define G433_CRC8 1
#define G433_XOR 2
// количество синхроимпульсов
#if defined(G433_FAST)
#define TRAINING_PULSES 10
#elif defined(G433_MEDIUM)
#define TRAINING_PULSES 50
#elif defined(G433_SLOW)
#define TRAINING_PULSES (TRAINING_TIME_SLOW / FRAME_TIME / 2)
#else
#define TRAINING_PULSES 50
#endif
//extern volatile unsigned long millis, micros;
// crc8 один байт
void G433_crc8_byte(uint8_t &crc, uint8_t data);
// ============ ============
template <uint8_t TX_PIN, uint16_t TX_BUF = 64, uint8_t CRC_MODE = G433_CRC8>
class Gyver433_TX {
public:
// отправка, блокирующая. Кушает любой тип данных
template <typename T>
bool sendData(T &data) {
if (sizeof(T) > TX_BUF) return 0;
const uint8_t *ptr = (const uint8_t*) &data;
for (uint16_t i = 0; i < sizeof(T); i++) buffer[i] = *ptr++;
if (CRC_MODE == G433_CRC8) {
buffer[sizeof(T)] = G433_crc8(buffer, sizeof(T));
write(buffer, sizeof(T) + 1);
} else if (CRC_MODE == G433_XOR) {
buffer[sizeof(T)] = G433_crc_xor(buffer, sizeof(T));
write(buffer, sizeof(T) + 1);
} else {
write(buffer, sizeof(T));
}
return 1;
}
// отправка сырого набора байтов
void write(uint8_t* buf, uint16_t size) {
for (uint16_t i = 0; i < TRAINING_PULSES; i++) {
fastWrite(TX_PIN, 1);
G433_DELAY(FRAME_TIME);
fastWrite(TX_PIN, 0);
G433_DELAY(FRAME_TIME);
}
fastWrite(TX_PIN, 1); // старт
G433_DELAY(START_PULSE); // ждём
fastWrite(TX_PIN, 0); // старт бит
#ifdef G433_MANCHESTER
G433_DELAY(HALF_FRAME); // ждём
for (uint16_t n = 0; n < size; n++) {
uint8_t data = buf[n];
for (uint8_t b = 0; b < 8; b++) {
fastWrite(TX_PIN, !(data & 1));
G433_DELAY(HALF_FRAME);
fastWrite(TX_PIN, (data & 1));
G433_DELAY(HALF_FRAME);
data >>= 1;
}
}
fastWrite(TX_PIN, 0); // конец передачи
#else
bool flag = 0;
for (uint16_t n = 0; n < size; n++) {
uint8_t data = buf[n];
for (uint8_t b = 0; b < 8; b++) {
if (data & 1) G433_DELAY(FRAME_TIME);
else G433_DELAY(HALF_FRAME);
fastWrite(TX_PIN, flag = !flag);
data >>= 1;
}
}
#endif
}
// доступ к буферу
uint8_t buffer[TX_BUF + !!CRC_MODE];
private:
};
// ===== CRC =====
void G433_crc8_byte(uint8_t &crc, uint8_t data) {
#if defined (__AVR__)
// резкий алгоритм для AVR
uint8_t counter;
uint8_t buffer;
asm volatile (
"EOR %[crc_out], %[data_in] \n\t"
"LDI %[counter], 8 \n\t"
"LDI %[buffer], 0x8C \n\t"
"_loop_start_%=: \n\t"
"LSR %[crc_out] \n\t"
"BRCC _loop_end_%= \n\t"
"EOR %[crc_out], %[buffer] \n\t"
"_loop_end_%=: \n\t"
"DEC %[counter] \n\t"
"BRNE _loop_start_%="
: [crc_out]"=r" (crc), [counter]"=d" (counter), [buffer]"=d" (buffer)
: [crc_in]"0" (crc), [data_in]"r" (data)
);
#else
// обычный для всех остальных
uint8_t i = 8;
while (i--) {
crc = ((crc ^ data) & 1) ? (crc >> 1) ^ 0x8C : (crc >> 1);
data >>= 1;
}
#endif
}
uint8_t G433_crc8(uint8_t *buffer, uint8_t size) {
uint8_t crc = 0;
for (uint8_t i = 0; i < size; i++) G433_crc8_byte(crc, buffer[i]);
return crc;
}
uint8_t G433_crc_xor(uint8_t *buffer, uint8_t size) {
uint8_t crc = 0;
for (uint8_t i = 0; i < size; i++) crc ^= buffer[i];
return crc;
}
#endif /*Gyver433_H_*/
После чего решил объявления оставить в .h, а основной код отправить в .cpp, и тогда FastIO у меня вообще проблем не возникло, а вот с Gyver433.cpp да, и проблема именно с шаблоном класса, когда объявляешь объект класса в основном файле main.cpp
Gyver433_TX <RADIO_DATA, RADIO_BUF_SIZE, G433_XOR> tx;
то лезет ошибка
Severity | Code | Description | Project | File | Line |
---|---|---|---|---|---|
Error | ‘Gyver433_TX’ does not name a type | atmega8_433MHz | G:\main.cpp | 80 |
ну и основной код который отправил в .cpp
Gyver433.cpp
#include "Gyver433.h"
// ============ ПЕРЕДАТЧИК ============
template <uint8_t TX_PIN, uint16_t TX_BUF = 64, uint8_t CRC_MODE = G433_CRC8>
class Gyver433_TX {
public:
// Gyver433_TX() {
// pinMode(TX_PIN, OUTPUT); // не нужно т.к. будеи обращатьс сразу напрямую через fastRead(),
// // просто пишем номер порта как в ардуино, далее fastRead() или fastWrite() сами разберутся
// }
// отправка, блокирующая. Кушает любой тип данных
template <typename T>
bool sendData(T &data) {
if (sizeof(T) > TX_BUF) return 0;
const uint8_t *ptr = (const uint8_t*) &data;
for (uint16_t i = 0; i < sizeof(T); i++) buffer[i] = *ptr++;
if (CRC_MODE == G433_CRC8) {
buffer[sizeof(T)] = G433_crc8(buffer, sizeof(T));
write(buffer, sizeof(T) + 1);
} else if (CRC_MODE == G433_XOR) {
buffer[sizeof(T)] = G433_crc_xor(buffer, sizeof(T));
write(buffer, sizeof(T) + 1);
} else {
write(buffer, sizeof(T));
}
return 1;
}
// отправка сырого набора байтов
void write(uint8_t* buf, uint16_t size) {
for (uint16_t i = 0; i < TRAINING_PULSES; i++) {
fastWrite(TX_PIN, 1);
G433_DELAY(FRAME_TIME);
fastWrite(TX_PIN, 0);
G433_DELAY(FRAME_TIME);
}
fastWrite(TX_PIN, 1); // старт
G433_DELAY(START_PULSE); // ждём
fastWrite(TX_PIN, 0); // старт бит
#ifdef G433_MANCHESTER
G433_DELAY(HALF_FRAME); // ждём
for (uint16_t n = 0; n < size; n++) {
uint8_t data = buf[n];
for (uint8_t b = 0; b < 8; b++) {
fastWrite(TX_PIN, !(data & 1));
G433_DELAY(HALF_FRAME);
fastWrite(TX_PIN, (data & 1));
G433_DELAY(HALF_FRAME);
data >>= 1;
}
}
fastWrite(TX_PIN, 0); // конец передачи
#else
bool flag = 0;
for (uint16_t n = 0; n < size; n++) {
uint8_t data = buf[n];
for (uint8_t b = 0; b < 8; b++) {
if (data & 1) G433_DELAY(FRAME_TIME);
else G433_DELAY(HALF_FRAME);
fastWrite(TX_PIN, flag = !flag);
data >>= 1;
}
}
#endif
}
// доступ к буферу
uint8_t buffer[TX_BUF + !!CRC_MODE];
private:
};
// ===== CRC =====
void G433_crc8_byte(uint8_t &crc, uint8_t data) {
#if defined (__AVR__)
// резкий алгоритм для AVR
uint8_t counter;
uint8_t buffer;
asm volatile (
"EOR %[crc_out], %[data_in] \n\t"
"LDI %[counter], 8 \n\t"
"LDI %[buffer], 0x8C \n\t"
"_loop_start_%=: \n\t"
"LSR %[crc_out] \n\t"
"BRCC _loop_end_%= \n\t"
"EOR %[crc_out], %[buffer] \n\t"
"_loop_end_%=: \n\t"
"DEC %[counter] \n\t"
"BRNE _loop_start_%="
: [crc_out]"=r" (crc), [counter]"=d" (counter), [buffer]"=d" (buffer)
: [crc_in]"0" (crc), [data_in]"r" (data)
);
#else
// обычный для всех остальных
uint8_t i = 8;
while (i--) {
crc = ((crc ^ data) & 1) ? (crc >> 1) ^ 0x8C : (crc >> 1);
data >>= 1;
}
#endif
}
uint8_t G433_crc8(uint8_t *buffer, uint8_t size) {
uint8_t crc = 0;
for (uint8_t i = 0; i < size; i++) G433_crc8_byte(crc, buffer[i]);
return crc;
}
uint8_t G433_crc_xor(uint8_t *buffer, uint8_t size) {
uint8_t crc = 0;
for (uint8_t i = 0; i < size; i++) crc ^= buffer[i];
return crc;
}
Суть вопроса что не так делаю с объектом класса, связано как с тем что объявляю в другом файле main, почему выдает ошибку не указан тип. Хотя сам объект класса Gyver_433 мне сам компилятор подсказывает ввести.