добавьте #include<stddef.h>
upd: для uint8_t - #include<stdint.h>
Код: Выделить всё
/* ATtiny 84 */
#include <avr/io.h>
#include <stdint.h>
#include "pins_0.hpp"
int main(void){
//Pin pin; //Ошибка отсутствия аргументов шаблона перед 'pin'
//Pin.as_output(PORTB, PB0);
//Pin.as_output(PB0);
while(1){ }
}Код: Выделить всё
/* ATtiny 84 */
#ifndef PINS_H_
#define PINS_H_
#include <stdint.h>
#include <avr/io.h>
// arbitrarly use PORT as base addres
// произвольно использовать ПОРТ как базовый адрес
enum base {
A = (const uint16_t) &PORTB,
B = (const uint16_t) &PORTB
// C = (const uint16_t) &PORTC,
// D = (const uint16_t) &PORTD
};
template <base b, uint8_t /*...*/all_args>
class Pin {
private:
// Calculate DDR and PIN offsets from PORT
// Рассчитайте смещения DDR и PIN из ПОРТА
static constexpr int8_t dir_offset = &DDRB - &PORTB;
static constexpr int8_t in_offset = &PINB - &PORTB;
// In C++11, constexpr functions can only contain one statement: return.
// В C++11 функции constexpr могут содержать только один оператор: return.
// This forces recursiveness to be used
// Это заставляет использовать рекурсивность
struct recursive {
// Funtion to terminate iteration
// Функция завершения итерации
static constexpr uint8_t bit_mask(){ return 0; }
// Recursive function
// Рекурсивная функция
// Since this function is private, it can only receive the types of "all_args...",
// that is uint8_t
// Поскольку эта функция является частной, она может получать только типы "all_args ...",
// то есть uint8_t
template <typename first_arg_type, typename /*...*/ next_args_types>
static constexpr uint8_t bit_mask(first_arg_type first_arg, next_args_types /*...*/ next_args){
return (1<<first_arg)|bit_mask(next_args/*...*/);
}
};
// This version is valid in C++14 only, constexpr functions have less limitations
// Эта версия действительна только для C++14, функции constexpr имеют меньше ограничений.
struct non_recursive { // нерекурсивный
// put variadic arguments in static constant array for easy access
// поместите вариативные аргументы в статический массив констант для облегчения доступа
static constexpr int arg_count = sizeof/*...*/(all_args);
static constexpr int params[arg_count]={ all_args /*...*/ };
static constexpr uint8_t bit_mask(){
uint8_t mask = 0;
for (unsigned int i = 0; i < arg_count; i++)
mask |= 1<<params[i];
return mask;
}
};
public:
static void set(){
*(volatile uint8_t*)b |= recursive::bit_mask(all_args/*...*/);
}
static void clear(){
*(volatile uint8_t*)b &= ~recursive::bit_mask(all_args/*...*/);
}
static void as_output(){ // как выход
*(volatile uint8_t*) (b + dir_offset) |= recursive::bit_mask(all_args/*...*/);
}
static void as_input(){
*(volatile uint8_t*) (b + dir_offset) &= ~recursive::bit_mask(all_args/*...*/);
}
static void toggle(){ // переключить
*(volatile uint8_t*) (b + in_offset) |= recursive::bit_mask(all_args/*...*/);
}
};
#endif /* PINS_H_ */Код: Выделить всё
template<uint8_t... bits>
consteval uint8_t bit_mask() { return (... | (1 << bits)); }
auto mask = bit_mask<1, 3, 4, 7>(); // 0x9AКод: Выделить всё
/* ATtiny 84 */
#define F_CPU 8000000L
#include <avr/io.h>
#include <stdint.h>
#include <util/delay.h>
enum base {
A = (const uint16_t) &PORTA,
B = (const uint16_t) &PORTB
};
template <base b, uint8_t ... all_args>
class Pin {
private:
static constexpr int8_t dir_offset = &DDRB - &PORTB;
static constexpr int8_t in_offset = &PINB - &PORTB;
struct recursive {
static constexpr uint8_t bit_mask(){ return 0; }
template <typename first_arg_type, typename ... next_args_types>
static constexpr uint8_t bit_mask(first_arg_type first_arg, next_args_types ... next_args){
return (1<<first_arg) | bit_mask(next_args ... );
}
};
struct non_recursive { // нерекурсивный
static constexpr int arg_count = sizeof ... (all_args);
static constexpr int params[arg_count]={ all_args ... };
static constexpr uint8_t bit_mask(){
uint8_t mask = 0;
for (unsigned int i = 0; i < arg_count; i++)
mask |= 1<<params[i];
return mask;
}
};
//-----------
public:
static void set(){
*(volatile uint8_t*)b |= recursive::bit_mask(all_args... );
}
static void clear(){
*(volatile uint8_t*)b &= ~recursive::bit_mask(all_args... );
}
static void as_output(){ // как выход
*(volatile uint8_t*)(b + dir_offset) |= recursive::bit_mask(all_args... );
}
static void as_input(){
*(volatile uint8_t*)(b + dir_offset) &= ~recursive::bit_mask(all_args... );
}
static void toggle(){ // переключить
*(volatile uint8_t*)(b + in_offset) |= recursive::bit_mask(all_args... );
}
};
int main(void){
Pin<A, 0> pin1;
pin1.as_output();
pin1.set();
while (1) {
_delay_ms(300);
pin1.toggle();
}
}
Код: Выделить всё
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
...
Код: Выделить всё
void EXTI0_1_IRQHandler(void)
{
/* USER CODE BEGIN EXTI0_1_IRQn 0 */
/* USER CODE END EXTI0_1_IRQn 0 */
HAL_GPIO_EXTI_IRQHandler(BTN1_Pin);
/* USER CODE BEGIN EXTI0_1_IRQn 1 */
/* USER CODE END EXTI0_1_IRQn 1 */
}
у меня есть умная собака она все понимает, но сказать не умеетсамая старая запись
Код: Выделить всё
// Описание структуры, с результатами измерения:
struct {
uint32_t time;
int16_t temperature;
unt16_t pressure;
} Data_t;
// Пишете функцию, которая умеет писать данные в eeprom по заданному адресу
void write_to_eeprom(uint16_t ee_addr, void *data, size_t size);
// Пишете функцию, которая умеет читать данные из eeprom
void read_from_eeprom(uint16_t ee_addr, void *data, size_t size);
// Функция, которая будет искать самую последнюю запись
int16_t find_last_record()
{
int16_t idx = 0;
uint32_t time = 0;
Data_t last_data;
for (int16_t i = 0; i < EEPROM_SIZE / sizeof(Data_t); i++) {
read_from_eeprom(i * sizeof(Data_t), &last_data, sizeof(Data_t));
if (last_data.time != 0xFFFFFFFF && last_data.time > time) {
idx = i;
}
}
return idx;
}
Код: Выделить всё
union timech_t{
struct{
uint8_t hours: 5;
uint8_t date: 5;
uint8_t month: 4;
}clock;
uint16_t time;
};
typedef union timech_t timechart_t;Код: Выделить всё
/*пример
timechart_t timestamp;
timestamp.clock.hours = 12;
timestamp.clock.date = 13;
timestamp.clock.month = 4;
//send to EEPROM timestamp.time;
eeprom_write_word(addr, timestamp.time);
//load timestamp from EEPROM
timestamp.time = eeprom_read_word(addr);
теперь можно показать час, дату, месяц.
...timestamp.clock.hours;
...timestamp.clock.date;
...timestamp.clock.month;
*/Размазать адрес то можно, но он пишется чтобы можно было просто(и быстро) определить последнюю запись логируемых данных, которые тоже размазываются и уже это у Serzh2000 вызывает затруднения. А так придется еще как-то определять последний записанный адрес...И запись то последовательно по кругу идёт - ещё на два порядка размазывается по всему чипу.