Вопросы по С/С++ (СИ)
- Serzh2000
- Опытный кот
- Сообщения: 867
- Зарегистрирован: Пт фев 27, 2015 12:00:53
- Откуда: Рязанская область
Re: Вопросы по С/С++ (СИ)
- Реклама
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Спойлер
Код: Выделить всё
void view_flasher_0(){
}
void view_flasher_1(){
}
void view_flasher_2(){
}
void view_flasher_3(){
}
void view_flasher_4(){
}
void view_flasher_5(){
}
typedef void (*pfun_t)(void);
pfun_t rnd_arr[] = {
view_flasher_0,
view_flasher_1,
view_flasher_2,
view_flasher_3,
view_flasher_4,
view_flasher_5,
};
#define MAX_EFFECTS (sizeof(rnd_arr)/sizeof(rnd_arr[0]))
void swap(pfun_t *val1, pfun_t *val2){
pfun_t t = *val1;
*val1 = *val2;
*val2 = t;
}
...........................
for(int i=0; i<100; i++){ // Перемешиваем
uint8_t a = rand()%MAX_EFFECTS;
uint8_t b = rand()%MAX_EFFECTS;
swap(&rnd_arr[a], &rnd_arr[b]);
}
for(uint8_t i=0; i<MAX_EFFECTS; i++){ // Вывод эффектов
rnd_arr[i]();
}
- Serzh2000
- Опытный кот
- Сообщения: 867
- Зарегистрирован: Пт фев 27, 2015 12:00:53
- Откуда: Рязанская область
Re: Вопросы по С/С++ (СИ)
не получается
#include <delay.h>
#include <stdlib.h>
#define MAX 5
uint8_t arr[MAX] = {1, 2, 3, 4, 5 };
void view_flasher_1(void) {
}
void view_flasher_2(void) {
}
void view_flasher_3(void) {
}
void view_flasher_4(void) {
}
void view_flasher_5(void) {
}
void shuffle(uint8_t *array, size_t n)
{
if (n > 1)
{
size_t i;
for (i = 0; i < n - 1; i++)
{
size_t j = i + rand() / (RAND_MAX / (n - i) + 1);
uint8_t t = array[j];
array[j] = array;
array = t;
}
}
}
//=================== main ==========
//основаня функция
void main(void){
//настройка портов
PORTB=0b00000000;
DDRB=0b00000000;
PORTC=0b00000000; //порт С 4 первые по умолчанию 1
DDRC=0b00011111; //порт С 4 первые ноги на вывод
PORTD=0b00000000; //порт D по умолчанию все ноги на 0
DDRD=0b00001111; //порт D все ноги на вывод
// -------------------------------- рабочая часть ------------------------------------------
while(1) {
shuffle(&arr, sizeof(arr));
for(uint8_t i = 0, i++, i <= MAX {
view_flasher(arr);
}
}
ругается CodeVisionAVR. на строчку uint8_t arr[MAX] = {1, 2, 3, 4, 5 }; чтобы я в скобках не писал
может в CodeVisionAVR библиотеки какой не хватает
Спойлер
#include <mega8.h>#include <delay.h>
#include <stdlib.h>
#define MAX 5
uint8_t arr[MAX] = {1, 2, 3, 4, 5 };
void view_flasher_1(void) {
}
void view_flasher_2(void) {
}
void view_flasher_3(void) {
}
void view_flasher_4(void) {
}
void view_flasher_5(void) {
}
void shuffle(uint8_t *array, size_t n)
{
if (n > 1)
{
size_t i;
for (i = 0; i < n - 1; i++)
{
size_t j = i + rand() / (RAND_MAX / (n - i) + 1);
uint8_t t = array[j];
array[j] = array;
array = t;
}
}
}
//=================== main ==========
//основаня функция
void main(void){
//настройка портов
PORTB=0b00000000;
DDRB=0b00000000;
PORTC=0b00000000; //порт С 4 первые по умолчанию 1
DDRC=0b00011111; //порт С 4 первые ноги на вывод
PORTD=0b00000000; //порт D по умолчанию все ноги на 0
DDRD=0b00001111; //порт D все ноги на вывод
// -------------------------------- рабочая часть ------------------------------------------
while(1) {
shuffle(&arr, sizeof(arr));
for(uint8_t i = 0, i++, i <= MAX {
view_flasher(arr);
}
}
ругается CodeVisionAVR. на строчку uint8_t arr[MAX] = {1, 2, 3, 4, 5 }; чтобы я в скобках не писал
может в CodeVisionAVR библиотеки какой не хватает
Re: Вопросы по С/С++ (СИ)
#include <stdint.h>
- Serzh2000
- Опытный кот
- Сообщения: 867
- Зарегистрирован: Пт фев 27, 2015 12:00:53
- Откуда: Рязанская область
Re: Вопросы по С/С++ (СИ)
void shuffle(int *array, size_t n) ругается на shuffle
- Реклама
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Покажите ругань компилятора.
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Он не понимает, что такое uint8_t. Замените на unsigned char.
Или добавьте, где-нибудь сверху:
Или добавьте, где-нибудь сверху:
Код: Выделить всё
typedef unsigned char uint8_t;Re: Вопросы по С/С++ (СИ)
он ругается на size_t
добавьте #include<stddef.h>
upd: для uint8_t - #include<stdint.h>
добавьте #include<stddef.h>
upd: для uint8_t - #include<stdint.h>
- Serzh2000
- Опытный кот
- Сообщения: 867
- Зарегистрирован: Пт фев 27, 2015 12:00:53
- Откуда: Рязанская область
Re: Вопросы по С/С++ (СИ)
сегодня примерно за час написал в ардуине. и она меня поняла, что я от нее хочу...
Спойлер
void setup() {Serial.begin(9600);
}
void loop() {
Serial.println("начало");
delay(2000);
//------------------------------
int effect[] = {0,1,2,3,4,5,6,7,8,9};
const size_t n = sizeof(effect) / sizeof(effect[0]);
for (size_t i = 0; i < n - 1; i++)
{
size_t j = random( n - i);
int t = effect;
effect = effect[j];
effect[j] = t;
}
for(uint8_t i = 0; i < n; i++) {
int ef(effect);
//-------------------------------
switch(ef)
{
case 0:
view_flasher_0();
break;
case 1:
view_flasher_1();
break;
case 2:
view_flasher_2();
break;
case 3:
view_flasher_3();
break;
case 4:
view_flasher_4();
break;
case 5:
view_flasher_5();
break;
case 6:
view_flasher_6();
break;
case 7:
view_flasher_7();
break;
case 8:
view_flasher_8();
break;
case 9:
view_flasher_9();
break;
}
}
}
void view_flasher_0() { Serial.println(0); delay(2000);}
void view_flasher_1() { Serial.println(1); delay(2000);}
void view_flasher_2() { Serial.println(2); delay(2000);}
void view_flasher_3() { Serial.println(3); delay(2000);}
void view_flasher_4() { Serial.println(4); delay(2000);}
void view_flasher_5() { Serial.println(5); delay(2000);}
void view_flasher_6() { Serial.println(6); delay(2000);}
void view_flasher_7() { Serial.println(7); delay(2000);}
void view_flasher_8() { Serial.println(8); delay(2000);}
void view_flasher_9() { Serial.println(9); delay(2000);}
у меня еще один маленький вопросик
в интернете после примеров иногда показывают результат типа виндувской командной строки
это как делается в какой-то программе или среде есть такая возможность не прошивая атмегу посмотреть результат кода?
- Эйлер Леонард
- Встал на лапы
- Сообщения: 104
- Зарегистрирован: Пн ноя 04, 2019 09:58:29
- Откуда: г. Нижний Тагил Свердл. обл.
Re: Вопросы по С/С++ (СИ)
Добрый вечер уважаемые коты. Перехожу потихоньку с С на С++. Начал с лаподрыгинга. Установил в Atmel Studio 7 поддержку С++11. Нашел вот какой class на этом форуме. Откомпилировал. Пока задача минимум - вкрутить на любой пин лампочку и да будет свет. Ну и застрял на этом. Смотрю на этот class как на новые ворота. Как создать экземпляр, как передать параметры. Пока закоментировал многоточия в исходнике. Замысловатый какой то класс, но красивый.
main.cpp
pins_0.hpp
В строке typename first_arg_type возможно необходимо заменить на осмысленый тип? uint8_t ? "тип первого аргумента, ну и т.д."
Добавлено after 10 minutes 45 seconds:
Курим typename
main.cpp
Спойлер
Код: Выделить всё
/* 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_ */Добавлено after 10 minutes 45 seconds:
Курим typename
Re: Вопросы по С/С++ (СИ)
Gcc 10 для AVR с неплохой поддержкой С++20 появился еще раньше, чем для ARM, там снято множество ограничений и все делается значительно проще. В частности вместо рекурсивной bit_mask можно использовать свертку:
И наверно если действительно хочется понимать что там происходит, то для начала нужно писать свои простенькие классы... Pin должен принимать адрес порта и номер пина, главное чтобы никакие из этих параметров не были volatile, такое после С++11 уже не работает. А с группой пинов уже работают более сложные классы оперирующие списками пинов...
Код: Выделить всё
template<uint8_t... bits>
consteval uint8_t bit_mask() { return (... | (1 << bits)); }
auto mask = bit_mask<1, 3, 4, 7>(); // 0x9A- Эйлер Леонард
- Встал на лапы
- Сообщения: 104
- Зарегистрирован: Пн ноя 04, 2019 09:58:29
- Откуда: г. Нижний Тагил Свердл. обл.
Re: Вопросы по С/С++ (СИ)
Работает! Многоточие оказывается тоже оператор. Про вариативный шаблон кратко здесь. (wiki) 
Спойлер
Код: Выделить всё
/* 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();
}
}
- Вложения
-
- PinTest.gif
- Мигатель в протеусе
- (18.31 КБ) 182 скачивания
Re: Вопросы по С/С++ (СИ)
Добрый день. вопрос новичка. Осваиваю Си для STM32(CUBEIDE, HAL). Правильно ли понимаю что Callback функция выполняется "внутри" прерывания? И соответвенно нужно стремится к минимизации кода в Callback функции.
например в " main.c" -
и в файле "stm32f0xx_it.c" - обработчик прерывания
например в " main.c" -
Код: Выделить всё
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 */
}
- Serzh2000
- Опытный кот
- Сообщения: 867
- Зарегистрирован: Пт фев 27, 2015 12:00:53
- Откуда: Рязанская область
Re: Вопросы по С/С++ (СИ)
хочу собрать метеостанцию
атмега 328, LCD 2004 (0x27,20,4), RTC DS 3231 и чип памяти: AT24C32 (32 Кб), три кнопки и т.д.
как высветить часы, дату, температуру, давление... все ясно
вопрос в седеющем:
хочу нажать кнопку "set" и увидеть четыре строчки (потому что
только четыре строчки в экране)температуры за сегодня и за предыдущее дни измеренную каждый день в назначенное время
типа

нажать кнопку "минус" список прокрутится на три строчки ранее
еще нажал - три сорочки ранее
на "плюс" список к верху
данные температуры хранить в AT24C32 за ... на сколько позволит память
нашел https://microkontroller.ru/arduino-proj ... u-arduino/ смысл тот же , только они на карту памяти , а мне на AT24C32... и не понятно закончится память
нужно с первой ячейки (Адрес RTC модуля 0х68) начинать запоминать данные , а "хвост" еще в конце.............
и как записать число, мес, год(можно и без года) время, темпер
(может двухмерный массив)???
одни вопросы ..............
может пояснит как все хотелки реализовать
атмега 328, LCD 2004 (0x27,20,4), RTC DS 3231 и чип памяти: AT24C32 (32 Кб), три кнопки и т.д.
как высветить часы, дату, температуру, давление... все ясно
вопрос в седеющем:
хочу нажать кнопку "set" и увидеть четыре строчки (потому что
типа
нажать кнопку "минус" список прокрутится на три строчки ранее
на "плюс" список к верху
данные температуры хранить в AT24C32 за ... на сколько позволит память
нашел https://microkontroller.ru/arduino-proj ... u-arduino/ смысл тот же , только они на карту памяти , а мне на AT24C32... и не понятно закончится память
нужно с первой ячейки (Адрес RTC модуля 0х68) начинать запоминать данные , а "хвост" еще в конце.............
и как записать число, мес, год(можно и без года) время, темпер
одни вопросы ..............
может пояснит как все хотелки реализовать
- WiseLord
- Друг Кота
- Сообщения: 4905
- Зарегистрирован: Чт апр 11, 2013 11:19:59
- Откуда: Минск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Думаю, тут можно просто записывать всю структуру после самой старой по времени.
Например, структура на 8 байтов (время - 4, температура - 2, давление -2.)
Измеряем, ищем в eeprom где самая старая запись (по максимальному времени), записываем измеренное со смещением в 8 байтов.
Для показа - аналогично, ищем самую последнюю, отображаем её и ещё предыдущие. При нажатии на кнопку - смещаемся назад на 24 байта.
Например, структура на 8 байтов (время - 4, температура - 2, давление -2.)
Измеряем, ищем в eeprom где самая старая запись (по максимальному времени), записываем измеренное со смещением в 8 байтов.
Для показа - аналогично, ищем самую последнюю, отображаем её и ещё предыдущие. При нажатии на кнопку - смещаемся назад на 24 байта.
- Serzh2000
- Опытный кот
- Сообщения: 867
- Зарегистрирован: Пт фев 27, 2015 12:00:53
- Откуда: Рязанская область
Re: Вопросы по С/С++ (СИ)
у меня есть умная собака она все понимает, но сказать не умеетсамая старая запись
мне бы как говориться на пальцах объяснить, доходчиво как первокласснику
понимаете я даже не знаю с чего начать...
- WiseLord
- Друг Кота
- Сообщения: 4905
- Зарегистрирован: Чт апр 11, 2013 11:19:59
- Откуда: Минск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Найти самую старую запись - это пройтись в цикле по всему eeprom с шагом в размер структуры (8 байтов в примере выше) и искать самую старую запись по полю "время".
Как-то так:
В общем, идея достаточно понятная, на мой взгляд. Главное тут - саму запись произвольных данных реализовать.
Как-то так:
Спойлер
Код: Выделить всё
// Описание структуры, с результатами измерения:
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;
}
Последний раз редактировалось WiseLord Пт апр 02, 2021 21:27:34, всего редактировалось 1 раз.
- Serzh2000
- Опытный кот
- Сообщения: 867
- Зарегистрирован: Пт фев 27, 2015 12:00:53
- Откуда: Рязанская область
Re: Вопросы по С/С++ (СИ)
да !!! подумаю
Re: Вопросы по С/С++ (СИ)
Serzh2000, В качестве дополнения.
Зная объем памяти, выделенный под буфер, для записи структур измерения и байтовый размер этой структуры, легко подсчитать количество уникальных записей в этом объеме и организовать кольцевой буфер. Указатель на адрес следующей записи я храню в ЕЕПРОМе. Т.о. знаю, что предыдущая по указателю, записанная структура содержит самые свежие данные.
Время. Я запоминаю почасовые данные, поэтому мне достаточно считать и узнавать месяц, дату и текущий час. Я объединил эти числа и удалось "вписаться" в 16-битовое слово.
В ЕЕПРОМ сохраняю только "time". Потом достаточно "воткнуть" его обратно в timechart_t и считать hours, date и month текущей структуры измерения.
Зная объем памяти, выделенный под буфер, для записи структур измерения и байтовый размер этой структуры, легко подсчитать количество уникальных записей в этом объеме и организовать кольцевой буфер. Указатель на адрес следующей записи я храню в ЕЕПРОМе. Т.о. знаю, что предыдущая по указателю, записанная структура содержит самые свежие данные.
Время. Я запоминаю почасовые данные, поэтому мне достаточно считать и узнавать месяц, дату и текущий час. Я объединил эти числа и удалось "вписаться" в 16-битовое слово.
Код: Выделить всё
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;
*/

