Вопросы по С/С++ (СИ)

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить
Модератор
Аватара пользователя
Сообщения: 4618
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

SfS, да вроде уже несколько раз ему про memset сказали. Думаю, он уже понял :)
SfS писал(а):Если вместо 0 поставить 32, то забьет массив пробелами.
Ага, и без нулей в конце строк :)))
Реклама
Мудрый кот
Сообщения: 1856
Зарегистрирован: Вт авг 15, 2017 10:51:13

Сообщение jcxz »

[uquote="Аlex",url="/forum/viewtopic.php?p=4155962#p4155962"]Ага, и без нулей в концах строк :)))[/uquote]Там же не указано что все эти id,car,time - в формате ASCIIZ. А значит 0 в конце возможно и не нужен. А если массивы большие (много элементов), то выкидывание ненужных нулей позволяет хорошо экономить память. Я обычно так и делаю.
Реклама
Модератор
Аватара пользователя
Сообщения: 4618
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

jcxz писал(а):Там же не указано что все эти id,car,time - в формате ASCIIZ
Судя по strcpy в коде автора - можно предположить.
Ну, а вообще, там совсем всё как-то мутно. И автор молчит на вопросы :dont_know:
SfS
Друг Кота
Сообщения: 19797
Зарегистрирован: Пт янв 12, 2007 11:21:39
Откуда: Томск

Сообщение SfS »

[uquote="Аlex",url="/forum/viewtopic.php?p=4155962#p4155962"]SfS, да вроде уже несколько раз ему про memset сказали. Думаю, он уже понял :)
SfS писал(а):Если вместо 0 поставить 32, то забьет массив пробелами.
Ага, и без нулей в конце строк :)))[/uquote]

Ну это уж как ему угодно. Строки могут храниться и не в asciiz формате:)
Реклама
Эиком - электронные компоненты и радиодетали
Встал на лапы
Аватара пользователя
Сообщения: 104
Зарегистрирован: Пн ноя 04, 2019 09:58:29
Откуда: г. Нижний Тагил Свердл. обл.

Сообщение Эйлер Леонард »

Добрый день. В целом с библиотекой от Adafruit Industries разобрался - spi hardware. Далее намерен привести весь код к стандарту С++14. Наперво - дефайны. (их там как тараканов за баней) Т.е. заменить это:
#define SSD1306_LCDWIDTH 128
#define SSD1306_LCDHEIGHT 64
#define sizeBuff (SSD1306_LCDHEIGHT * SSD1306_LCDWIDTH /8 ) ;

на это, с безопасным приведением типов:
static constexpr uint8_t SSD1306_LCDWIDTH = 128;
static constexpr uint8_t SSD1306_LCDHEIGHT = 64;
static constexpr uint8_t sizeBuff = static_cast<uint8_t>(SSD1306_LCDHEIGHT * SSD1306_LCDWIDTH /8 ) ;

Максимум вычислений на этапе компиляции и не тратить память по пустякам.
(монстр изрядно покоцан и моя лапа у него на груди) :tea: :sleep:
Реклама
SfS
Друг Кота
Сообщения: 19797
Зарегистрирован: Пт янв 12, 2007 11:21:39
Откуда: Томск

Сообщение SfS »

[uquote="Эйлер Леонард",url="/forum/viewtopic.php?p=4156716#p4156716"]Добрый день. В целом с библиотекой от Adafruit Industries разобрался - spi hardware. Далее намерен привести весь код к стандарту С++14. Наперво - дефайны. (их там как тараканов за баней) Т.е. заменить это:
#define SSD1306_LCDWIDTH 128
#define SSD1306_LCDHEIGHT 64
#define sizeBuff (SSD1306_LCDHEIGHT * SSD1306_LCDWIDTH /8 ) ;

на это, с безопасным приведением типов:
static constexpr uint8_t SSD1306_LCDWIDTH = 128;
static constexpr uint8_t SSD1306_LCDHEIGHT = 64;
static constexpr uint8_t sizeBuff = static_cast<uint8_t>(SSD1306_LCDHEIGHT * SSD1306_LCDWIDTH /8 ) ;

Максимум вычислений на этапе компиляции и не тратить память по пустякам.
(монстр изрядно покоцан и моя лапа у него на груди) :tea: :sleep:[/uquote]

А зачем? Выигрыша в скорости нет. Дефайны и так на этапе препроцессора выполняются.

Разве что для красоты.
Реклама
Встал на лапы
Аватара пользователя
Сообщения: 104
Зарегистрирован: Пн ноя 04, 2019 09:58:29
Откуда: г. Нижний Тагил Свердл. обл.

Сообщение Эйлер Леонард »

Гуглил я по этому вопросу. Но честно говоря однозначного ответа не нашел. Напр. здесь(ссылка). Пока оставлю этот вопрос как не столь актуальный.
SfS
Друг Кота
Сообщения: 19797
Зарегистрирован: Пт янв 12, 2007 11:21:39
Откуда: Томск

Сообщение SfS »

[uquote="Эйлер Леонард",url="/forum/viewtopic.php?p=4156998#p4156998"]Гуглил я по этому вопросу. Но честно говоря однозначного ответа не нашел. Напр. здесь(ссылка). Пока оставлю этот вопрос как не столь актуальный.[/uquote]

constexpr хорош с функциями.

Но в данном случае вроде просто константы и выигрыша от него нет. ИМХО. Могу чегото не доглядеть.
Грызет канифоль
Аватара пользователя
Сообщения: 287
Зарегистрирован: Сб янв 23, 2016 00:59:59
Откуда: Чебоксары

Сообщение ROMan2947 »

Здравствуйте! захотелось в регистр GPIOA_MODER с адресом 0x4002 0000 записать число 1024. как это должно выглядеть на С.
Друг Кота
Аватара пользователя
Сообщения: 4906
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

GPIOA->MODER = 1024; если библиотеки CMSIS подключены
*((uint32_t *)0x40020000) = 1024; или как-то так, если нет
Контактная информация:
SfS
Друг Кота
Сообщения: 19797
Зарегистрирован: Пт янв 12, 2007 11:21:39
Откуда: Томск

Сообщение SfS »

[uquote="WiseLord",url="/forum/viewtopic.php?p=4157063#p4157063"]GPIOA->MODER = 1024; если библиотеки CMSIS подключены
*((uint32_t *)0x40020000) = 1024; или как-то так, если нет[/uquote]

volatile забыли)

*((volatile uint32_t *)0x40020000) = 1024;
Друг Кота
Аватара пользователя
Сообщения: 4906
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

Несущественно, сработает и без volatile.
Контактная информация:
Грызет канифоль
Аватара пользователя
Сообщения: 287
Зарегистрирован: Сб янв 23, 2016 00:59:59
Откуда: Чебоксары

Сообщение ROMan2947 »

[uquote="WiseLord",url="/forum/viewtopic.php?p=4157063#p4157063"]
*((uint32_t *)0x40020000) = 1024;
или как-то так, если нет[/uquote]

то что нужно!
этот же вариант использует CMSIS, т. е . самый низкий уровень не считая асм.

я так пытался сделать:

Код: Выделить всё


uint32_t *GPIOA_MODER = 0x40020000UL;
 &GPIOA_MODER=1024;

не работает.
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

Вот так сработает

Код: Выделить всё

volatile uint32_t *GPIOA_MODER = (uint32_t *)0x40020000UL;
*GPIOA_MODER = 1024;
Но лучше не страдать ерундой и использовать заголовочный файл контроллера.
Грызет канифоль
Аватара пользователя
Сообщения: 287
Зарегистрирован: Сб янв 23, 2016 00:59:59
Откуда: Чебоксары

Сообщение ROMan2947 »

[uquote="VladislavS",url="/forum/viewtopic.php?p=4157199#p4157199"]Но лучше не страдать ерундой и использовать заголовочный файл контроллера.[/uquote]
Я же пока осваиваюсь, хочется понять всю эту магию. HAL штука удобная, но это для пользователя, а не для программиста.

Чего больше придерживаться HAL или CMSIS?
Держит паяльник хвостом
Сообщения: 923
Зарегистрирован: Пн сен 10, 2018 19:16:28

Сообщение linkov1959 »

uint32_t *ptr = 0x40020000; // объявляем указатель
*ptr = 1024; // по адресу указателя пишем новое значение.
Друг Кота
Аватара пользователя
Сообщения: 4906
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

[uquote="ROMan2947",url="/forum/viewtopic.php?p=4157207#p4157207"]Чего больше придерживаться HAL или CMSIS?[/uquote]
Тут "или" не совсем корректно. HAL сам по себе тоже использует заголовочные файлы CMSIS.

По сути, есть несколько вариантов:

1) Вообще без CMSIS, используяэти самые приведения типов, *((volatile uint8_t*)0x40020000) = 1024). Смысла и читабельности кода мало.

2) Подключить библиотеки CMSIS, и писать GPIOA->MODER = 1024;. Выглядит уже понятнее, разницы в размере кода и скорости выполнения не будет.

3) Использовать LL (+CMSIS) (тот же CubeMS позволяет легко выбрать эту альтернативу HAL). Пример может выглядеть уже так: LL_GPIO_SetPinMode(GPIOA, LL_GPIO_PIN_5, LL_GPIO_MODE_OUTPUT); Выглядит ещё понятнее и переносимее между разными МК от STM32. Разницы в размере кода и скорости выполнения не будет.

4) Использовать HAL (+CMSIS). То есть, инициализировать пин через HAL_GPIO_Init(), предварительно прописав все нужные параметры в структуру GPIO_InitTypeDef. Выглядит тоже понятно, максимально переносимо между разными МК от STM32, но за счёт различных внутренних проверок на корректность внутри функции инициализации - гораздо медленнее выполняется и даст больший размер кода. В принципе, для функций инициализации это не так критично.

Я лично для себя пока выбрал вариант 3.

5) Ещё, конечно, можно выбрать альтернативу CMSIS от STM32, вроде того же libopencm3. Потенциально, более легко переносимо между разными семействами ARM Cortex M, но нужно вникать "с нуля".
Контактная информация:
Держит паяльник хвостом
Аватара пользователя
Сообщения: 961
Зарегистрирован: Вс дек 02, 2012 16:58:33
Откуда: от туда

Сообщение GARMIN »

Есть ещё один вариант.
Немножко дописать заголовочный файл, и инициализировать весь порт сразу за четыре команды.
Вот пример:
Спойлер

Код: Выделить всё

// init pin
	RCC->AHBENR |= RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN;  // разрешаем тактирование GPIOA и GPIOB
  
  GPIOB->MODER =  GPIO_MODER_MODER0_INPUT
                | GPIO_MODER_MODER1_INPUT
                | GPIO_MODER_MODER2_INPUT
                | GPIO_MODER_MODER3_INPUT       
                | GPIO_MODER_MODER4_INPUT
                | GPIO_MODER_MODER5_INPUT
                | GPIO_MODER_MODER6_INPUT       
                | GPIO_MODER_MODER7_INPUT
                | GPIO_MODER_MODER8_INPUT
                | GPIO_MODER_MODER9_INPUT
                | GPIO_MODER_MODER10_INPUT
                | GPIO_MODER_MODER11_INPUT
                | GPIO_MODER_MODER12_INPUT      // PinB12 - input кнопка USER
                | GPIO_MODER_MODER13_INPUT
                | GPIO_MODER_MODER14_INPUT
                | GPIO_MODER_MODER15_INPUT;
  GPIOB->OTYPER = GPIO_OTYPER_OT0_PP    // pushpull as default
                | GPIO_OTYPER_OT1_PP 
                | GPIO_OTYPER_OT2_PP 
                | GPIO_OTYPER_OT3_PP    
                | GPIO_OTYPER_OT4_PP 
                | GPIO_OTYPER_OT5_PP 
                | GPIO_OTYPER_OT6_PP    
                | GPIO_OTYPER_OT7_PP    
                | GPIO_OTYPER_OT8_PP 
                | GPIO_OTYPER_OT9_PP 
                | GPIO_OTYPER_OT10_PP
                | GPIO_OTYPER_OT11_PP
                | GPIO_OTYPER_OT12_PP   // PinB12 - pushpull
                | GPIO_OTYPER_OT13_PP
                | GPIO_OTYPER_OT14_PP
                | GPIO_OTYPER_OT15_PP;
  GPIOB->OSPEEDR = GPIO_OSPEEDR_OSPEEDR0_LOW
                |  GPIO_OSPEEDR_OSPEEDR1_LOW
                |  GPIO_OSPEEDR_OSPEEDR2_LOW
                |  GPIO_OSPEEDR_OSPEEDR3_LOW    
                |  GPIO_OSPEEDR_OSPEEDR4_LOW
                |  GPIO_OSPEEDR_OSPEEDR5_LOW
                |  GPIO_OSPEEDR_OSPEEDR6_LOW    
                |  GPIO_OSPEEDR_OSPEEDR7_LOW    
                |  GPIO_OSPEEDR_OSPEEDR8_LOW
                |  GPIO_OSPEEDR_OSPEEDR9_LOW
                |  GPIO_OSPEEDR_OSPEEDR10_LOW
                |  GPIO_OSPEEDR_OSPEEDR11_LOW
                |  GPIO_OSPEEDR_OSPEEDR12_LOW   // PinB12 speed low
                |  GPIO_OSPEEDR_OSPEEDR13_LOW
                |  GPIO_OSPEEDR_OSPEEDR14_LOW
                |  GPIO_OSPEEDR_OSPEEDR15_LOW;
  GPIOB->PUPDR =  GPIO_PUPDR_PUPDR0_NO
                | GPIO_PUPDR_PUPDR1_NO
                | GPIO_PUPDR_PUPDR2_NO
                | GPIO_PUPDR_PUPDR3_NO    
                | GPIO_PUPDR_PUPDR4_NO
                | GPIO_PUPDR_PUPDR5_NO
                | GPIO_PUPDR_PUPDR6_NO    
                | GPIO_PUPDR_PUPDR7_NO    
                | GPIO_PUPDR_PUPDR8_NO
                | GPIO_PUPDR_PUPDR9_NO
                | GPIO_PUPDR_PUPDR10_NO
                | GPIO_PUPDR_PUPDR11_NO
                | GPIO_PUPDR_PUPDR12_UP   // PinB12 подтяжка к питанию
                | GPIO_PUPDR_PUPDR13_NO
                | GPIO_PUPDR_PUPDR14_NO
                | GPIO_PUPDR_PUPDR15_NO;
Контактная информация:
Мудрый кот
Сообщения: 1856
Зарегистрирован: Вт авг 15, 2017 10:51:13

Сообщение jcxz »

[uquote="linkov1959",url="/forum/viewtopic.php?p=4157282#p4157282"]uint32_t *ptr = 0x40020000; // объявляем указатель
*ptr = 1024; // по адресу указателя пишем новое значение.[/uquote]И какой же компилятор позволяет такое безобразие? :shock:
IAR например вполне закономерно материт:

Код: Выделить всё

Error[Pe144]: a value of type "int" cannot be used to initialize an entity of type "uint32_t *" B:\WS1\main.cpp 435 
Да даже если добавить приведение типа, то всё равно компилятор имеет право выкинуть такой код как "не имеющий эффекта".
Уже сказали выше: необходим volatile.
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18813
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

jcxz писал(а):Error[Pe144]: a value of type "int" cannot be used to initialize an entity of type "uint32_t *" B:\WS1\main.cpp 435
это что ж такое выходит?! уже надо явно тип константы приводить к типу левостороннего операнда?! а если просто 1 записать или 0 - тоже ругаться будет?!
наверное, "параноидальный" режим проверки ошибок/варнингов включен...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Ответить

Вернуться в «Разные вопросы по МК»