Урок 10. Типы данных языка Си для STM32.

Уроки STM32

Урок короткий, но очень важный. Разберемся в базовых типах данных STM32. Понимание этого вопроса абсолютно необходимо для разработки программ.

Предыдущий урок     Список уроков     Следующий урок

Все действия в программе мы производим над переменными. Поэтому необходимо точно знать форматы, размеры переменных, диапазоны чисел, которые они способны содержать. Переменные должны быть объявлены с указанием типа данных до использования в программе. Тип данных и задает параметры переменных.

 

Все это мы знаем из уроков Ардуино. Но базовые типы данных системы Ардуино и компилятора C для STM32 отличаются. Формальное применение знаний, полученных из курса Ардуино, может привести к фатальным последствиям для программ STM32. Давайте переучиваться.

Некоторые базовые типы данных стандартов языка программирования Си зависят от используемого микроконтроллера. В значительной мере от разрядности данных, с которыми он оперирует. Например, для 8ми разрядного микроконтроллера Ардуино тип int это 16 разрядов. Тот же тип для STM32 составляет 32 разряда.

Я не буду рассказывать о принципах, по которым стандарт языка Си определяет форматы базовых типов данных. Я буду освещать этот вопрос применительно к нашему микроконтроллеру STM32, нашей среде программирования.

Выделим из стандарта C99 языка программирования Си следующие базовые типы данных.

Тип данных Пояснение Разрядность
бит (байт)
Диапазон чисел
char
int8_t
Целочисленный знаковый тип. 8 (1) - 128 … 127
unsigned char
uint8_t
Целочисленный беззнаковый тип. 8 (1) 0 … 255
short
int16_t
Целочисленный знаковый тип. 16 (2) - 32768 … 32768
unsigned short
uint16_t
Целочисленный беззнаковый тип. 16 (2) 0 … 65535
int
int32_t
Целочисленный знаковый тип. 32 (4) - 2147483648 …  2147483647
unsigned int
uint32_t
Целочисленный
беззнаковый тип.
32 (4) 0 … 4294967295
long
int32_t
Целочисленный знаковый тип. 32 (4) - 2147483648 …  2147483647
unsigned long
uint32_t
Целочисленный беззнаковый тип. 32 (4) 0 … 4294967295
long long
int64_t
Целочисленный знаковый тип. 64 (8) - 9223372036854775808

9223372036854775807
unsigned long long
uint64_t
Целочисленный беззнаковый тип. 64 (8) 0 … 18446744073709551615
float Формат с плавающей запятой одинарной точности. 32 (4) ± (3,4 * 10 -38

3,4 * 10 +38)
double Формат с плавающей запятой двойной точности. 64 (8) ± (1,7 * 10 -308

1,7 * 10 +308)
long double Формат с плавающей запятой повышенной точности. 64 (8) ± (1,7 * 10 -308

1,7 * 10 +308)
_Bool Логический тип. 8 (1) 0 (ложь)  или 1 (истина)

Я подкорректировал параметры в соответствии с нашей средой программирования, поверил все эти типы данных.

 

Есть в языке Си функция, которая возвращает количество байтов необходимое для указанного в качестве аргумента типа.

int n = sizeof(long); // считать размер типа long

Я написал программу, которая определяет размеры разных типов данных и выводит их через последовательный порт. Это основной блок программы.

sprintf((char *)str,"Тип char - %u байт\r\n", sizeof(char));
outputRes();
sprintf((char *)str,"Тип short - %u байт\r\n", sizeof(short));
outputRes();
sprintf((char *)str,"Тип int - %u байт\r\n", sizeof(int));
outputRes();
sprintf((char *)str,"Тип long - %u байт\r\n", sizeof(long));
outputRes();
sprintf((char *)str,"Тип long long - %u байт\r\n", sizeof(longlong));
outputRes();
sprintf((char *)str,"Тип float - %u байт\r\n", sizeof(float));
outputRes();
sprintf((char *)str,"Тип double - %u байт\r\n", sizeof(double));
outputRes();
sprintf((char *)str,"Тип long double - %u байт\r\n", sizeof(longdouble));
outputRes();
sprintf((char *)str,"Тип _Bool - %u байт\r\n\r\n", sizeof(_Bool));
outputRes();

Вот, что показал монитор последовательного порта CoolTerm.

Окно монитора CoolTerm

Кто захочет проверить сам, полностью проект программы можно загрузить по ссылке:

  Зарегистрируйтесь и оплатите. Всего 40 руб. в месяц за доступ ко всем ресурсам сайта!  

В программах для STM32 можно пользоваться всеми типами данных из таблицы. Но я предлагаю ввести ограничения.

 

В таблице есть целочисленные типы данных с явно заданной разрядностью.

Их имена образуются из символов:

  • int –целое знаковое;
  • uint –целое беззнаковое (к int добавили u);
  • число разрядов;
  • _t – тип.

Формат таких типов данных не зависит от разрядности микроконтроллера.

  • int8_t – целое знаковое 8 разрядов;
  • uint8_t – целое беззнаковое 8 разрядов;
  • int16_t – целое знаковое 16 разрядов;
  • uint16_t – целое беззнаковое 16 разрядов;
  • int32_t – целое знаковое 32 разрядов;
  • uint32_t – целое беззнаковое 32 разрядов;
  • int64_t – целое знаковое 64 разрядов;
  • uint64_t – целое беззнаковое 64 разрядов;

Хороший стиль использовать при разработке программ для STM32 именно такие описания для целочисленных переменных. Давайте так и будем поступать в дальнейшем.

Я бы еще допустил использование типа char. Он явно указывает на назначение переменной – хранение кода символа и, в какой-то степени, улучшает читаемость программы.

Типы с плавающей запятой будем использовать из таблицы.

Думаю, вы заметили, что отсутствуют привычные логические типы данных bool и boolean.В языке Си современной редакции они заменены на тип _Bool.

Но дело не в формальном изменении имени. Переменные для него не могут принимать значения true и false. Теперь это 0 – ложно и 1 – истинно. Часто в качестве логического типа используют uint8_t.

Можно вернуть привычный логический тип boolean и значения для него, если подключить заголовочный файл stdbool.h. Переназначение имен будет происходить через макросы.

Я предлагаю отказаться от такого способа и оставить принцип описания логических переменных, заданный разработчиками стандарта языка Си.

Но, в проектах C++ тип _Bool не поддерживается. Давайте использовать для логических переменных тип uint8_t.

Конечно, все это не догма, носит рекомендательный характер.  Я выражаю свое мнение. Каждый может использовать типы данных на свое усмотрение. Но в дальнейших уроках я собираюсь придерживаться изложенных выше принципов.

Еще два слова по поводу констант. Они тоже могут иметь знак. К беззнаковой константе добавляется буквы U или u.

int x = 234U; // беззнаковое число
int x = 0x001Eu; // беззнаковое число

В противном случае (без буквы U) константа считается знаковой.

int x = 234; // знаковое число
int x = 0x001E; // знаковое число

В случае использования знаковой константы старший разряд считается знаком, и отрицательные числа воспринимаются в дополнительном коде.

 

В следующем уроке будем займемся обработкой сигналов кнопок.

Предыдущий урок     Список уроков     Следующий урок

0

Автор публикации

не в сети 7 часов

Эдуард

63
Комментарии: 1353Публикации: 152Регистрация: 13-12-2015

Один комментарий на «Урок 10. Типы данных языка Си для STM32.»

  1. uint1_t – целое беззнаковое 1 разряд; бит мне захотелось, Кейл не вкусил моего порыва…

    0

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *