Автомобили

Как только он поступил в продажу, многие захотели понять — новый это или просто переделанный автомобиль? Конечно, можно долго ломать голову, но нам интересны другие характеристики этой модели. Говоря простым языком, Лада Приора седан — это сейчас тот автомобиль, который тянет весь великий и могучий АВТОВАЗ.

 

  • Доллар - 30.4199
  • Евро   -  39.2173
Авто за рубежом » Автомобили »

Цифровой резистор AD8400. Немного про HAL

Опубликовано: 05.09.2018

видео Цифровой резистор AD8400. Немного про HAL

Arduino + AD8400 resistor

Как то совпало, что с момента начала моего более серьезного ковыряния STM32, ST electronics решили отказаться от библиотеки SPL, которую я использовал в предыдущих статьях. Думаю инфа не первой свежести. Тем не менее, ковырять новое детище решил не сразу, поэтому в последнее время просто наблюдал за развитием ситуации.


Цифровой регулятор громкости на микросхеме DS1669

Для тех кто не в курсе. На текущий момент для инициализации и работы периферии имеются следующие варианты:

1. Использовать регистры (CMSIS)

2. Продолжать использовать SPL

3. Использовать HAL

4. Изобретать свой велосипед

1. В принципе идея такая же, как используется в AVR, т.е. есть портD нужно включить 12 ножку, то делаем так:

GPIOD -> BSRRL = GPIO_BSRR_BS_12 ;

Но это еще более менее понятная запись, обычно начинающим выносят мозг такие записи:

RCC -> AHB1ENR |= RCC_AHB1ENR_GPIODEN ;

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

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

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

2. Хоть SPL и не рекомендуется к употреблению, но с ее использованием написано уже много примеров и она есть для основных для меня 103 и 407 серии. Ее подход мне вполне понятен, на ней проще учиться. Для рядового радиолюбителя, который планирует использовать ограниченный потенциал микроконтроллера в принципе большего и не надо. Но опять же столкнулся с тем, что перенос кода между 103 и 407 требует внимательной правки ручками и долбления в даташит.

3. Новое детище ST, которое пришло на смену SPL. Где то видел мнение, что HAL это обертка над SPL. Ради интереса поковырялся, некоторые куски действительно похожи, но в большинстве своем совершенно разные. Хорош HAL тем, что он используется с Cube Mx — генератором кода для STM, некий аналог CAVR для AVR, т.е. проект можно сгенерить парой кликов мышки. Тогда почему просто не использовать HAL? Проще всего ответить на этот вопрос так: сгенерируй проект и посмотри на код, если нет рвотных позывов, то милости просим. Лично по мне, наворочено много лишнего, там где это не нужно, хотя это скорее дело привычки.

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

В итоге, можно считать, что ситуация закончилась победой HAL, ибо Keil и Cocox полностью избавились от SPL. Понемногу появляются статьи с использованием HAL. Но в общем то кто как хочет, тот так и .. программирует. Честно сказать, то что генерирует Cube Mx это нечто монстроидальное, тяжело тупить в такой код.

Тем не менее, решил потихоньку вливаться в мейнстрим, исключительно ради спортивного интереса. Но чтобы не начинать снова со 100500 мигания светодиодом, затарился парочкой простых микросхем. Первой из них и самым простым будет цифровой резистор AD8400. Почему именно он? Да хз, что было то и взял.

Вкратце что это такое? Похоже очень на простой резистор, у которого есть два крайних вывода A1 и B2 между которыми постоянное сопротивление, и щетка W1 положение которой мы можем изменять.

Управляется он по SPI протоколу. Поэтому я подключил его так, чтобы с W1 можно было снимать напряжение:

Тот резистор, что есть у меня одноканальный, т.е. в одном корпусе один резистор, но есть такие же с двумя и четырьмя резисторами в одном корпусе. Бывают на 1, 10, 50, 100кОм. Хоть и было заявлено номинальное сопротивление 10кОм, на практике оно оказалось 8кОм, прозвонить его можно только когда подано питание. После включения на щетке будет рандомное значение.

Управление хоть и SPI, но по факту железный spi задействовать не удастся, ибо вначале идут 2 бита адреса, а затем 8 бит данных. В итоге за один раз нужно передавать 10бит. Весь диапазон резистора разбит на 256 значений, для 10кОм шаг будет в ~40 Ом.

Алгоритм работы будет следующий:

1. Прижимаем ножку CS к земле

2. С каждым тактом CLK выдаем 2 нуля на ножке MOSI

3. C каждым тактом CLK выдаем 8 бит данных на ножке MOSI

4. Поднимаем ножку CS

Для управления использовал программный spi. Сгенерил проект в Cube — тупо настроил PB13-PB15 как выходы. Лень было заморачиваться, поэтому сразу после включения, однократно посылаем байт на резистор. Для желающих можно, включить фантазию, например регулировать уровень звука с помощью энкодера или кнопки. Привожу два варианта кода, для SPL и HAL исключительно для сравнения, в последующих статья планирую юзать только HAL. Исходники прикреплять не буду, ибо 35мб для пустого кода больно жирновато. Тестировалось на STM32F4Discovery.

Для SPL

#include <stm32f4xx.h> #include <stm32f4xx_gpio.h> #include <stm32f4xx_rcc.h> //1.B1 - GND //2.GND //3.CS - PB14 //4.SDI(MOSI) - PB15 //5.CLK - PB13 //6.VDD - //7.W1 - test point //8.A1 - VCC // режим SPI / SPI MODE = 0 // назначение выводов порта #define SPI_SCK GPIO_Pin_13 // выход - SCLK #define SPI_SDI GPIO_Pin_15 // выход - MOSI #define SPI_SS GPIO_Pin_14 // выход - Chip Select #define SPI_PORT GPIOB // порт spi void _spi_start ( void ) { GPIO_ResetBits (SPI_PORT ,SPI_SCK ) ; // SPI_MODE = 0 GPIO_ResetBits (SPI_PORT ,SPI_SS ) ; // Chip Select - Enable } void _spi_stop ( void ) { GPIO_SetBits (SPI_PORT ,SPI_SS ) ; // Chip Select - Disable GPIO_ResetBits (SPI_PORT ,SPI_SCK ) ; // SPI_MODE = 0 } void _spi_init ( void ) { RCC_AHB1PeriphClockCmd (RCC_AHB1Periph_GPIOB ,ENABLE ) ; GPIO_InitTypeDef s_SDI ; s_SDI. GPIO_Mode = GPIO_Mode_OUT ; s_SDI. GPIO_OType = GPIO_OType_PP ; s_SDI. GPIO_Pin = SPI_SDI ; s_SDI. GPIO_Speed = GPIO_Speed_2MHz ; GPIO_Init (SPI_PORT , & s_SDI ) ; GPIO_InitTypeDef s_SCK ; s_SCK. GPIO_Mode = GPIO_Mode_OUT ; s_SCK. GPIO_OType = GPIO_OType_PP ; s_SCK. GPIO_Pin = SPI_SCK ; s_SCK. GPIO_Speed = GPIO_Speed_2MHz ; GPIO_Init (SPI_PORT , & s_SCK ) ; GPIO_InitTypeDef s_SS ; s_SS. GPIO_Mode = GPIO_Mode_OUT ; s_SS. GPIO_OType = GPIO_OType_PP ; s_SS. GPIO_Pin = SPI_SS ; s_SS. GPIO_Speed = GPIO_Speed_2MHz ; GPIO_Init (SPI_PORT , & s_SS ) ; } void _spi_sendbyte ( unsigned char a ) { unsigned char i ; // отправить адрес 00 for ( i= 0 ; i < 2 ; i ++ ) { GPIO_ResetBits (SPI_PORT ,SPI_SDI ) ; GPIO_SetBits (SPI_PORT ,SPI_SCK ) ; GPIO_ResetBits (SPI_PORT ,SPI_SCK ) ; } for ( i= 0 ; i < 8 ; i ++ ) { if ( a & 0x80 ) { GPIO_SetBits (SPI_PORT ,SPI_SDI ) ; } else { GPIO_ResetBits (SPI_PORT ,SPI_SDI ) ; } GPIO_SetBits (SPI_PORT ,SPI_SCK ) ; a <<= 1 ; GPIO_ResetBits (SPI_PORT ,SPI_SCK ) ; } } int main ( void ) { _spi_init ( ) ; _spi_start ( ) ; _spi_sendbyte ( 127 ) ; _spi_stop ( ) ; while ( 1 ) ; }

С использованием HAL

#include "stm32f4xx_hal.h" void SystemClock_Config ( void ) ; static void MX_GPIO_Init ( void ) ; #define SPI_SCK GPIO_PIN_13 //SCLK #define SPI_SDI GPIO_PIN_15 //MOSI #define SPI_SS GPIO_PIN_14 //Chip Select #define SPI_PORT GPIOB //spi void _spi_start ( void ) { HAL_GPIO_WritePin (SPI_PORT ,SPI_SCK ,GPIO_PIN_RESET ) ; HAL_GPIO_WritePin (SPI_PORT ,SPI_SS ,GPIO_PIN_RESET ) ; } void _spi_stop ( void ) { HAL_GPIO_WritePin (SPI_PORT ,SPI_SS ,GPIO_PIN_SET ) ; HAL_GPIO_WritePin (SPI_PORT ,SPI_SCK ,GPIO_PIN_RESET ) ; } void _spi_sendbyte ( unsigned char d ) { unsigned char i ; for ( i= 0 ; i < 2 ; i ++ ) { HAL_GPIO_WritePin (SPI_PORT ,SPI_SDI ,GPIO_PIN_RESET ) ; HAL_GPIO_WritePin (SPI_PORT ,SPI_SCK ,GPIO_PIN_SET ) ; HAL_GPIO_WritePin (SPI_PORT ,SPI_SCK ,GPIO_PIN_RESET ) ; } for ( i= 0 ; i < 8 ; i ++ ) { if ( d & 0x80 ) { HAL_GPIO_WritePin (SPI_PORT ,SPI_SDI ,GPIO_PIN_SET ) ; } else { HAL_GPIO_WritePin (SPI_PORT ,SPI_SDI ,GPIO_PIN_RESET ) ; } HAL_GPIO_WritePin (SPI_PORT ,SPI_SCK ,GPIO_PIN_SET ) ; d <<= 1 ; HAL_GPIO_WritePin (SPI_PORT ,SPI_SCK ,GPIO_PIN_RESET ) ; } } int main ( void ) { HAL_Init ( ) ; SystemClock_Config ( ) ; MX_GPIO_Init ( ) ; _spi_start ( ) ; _spi_sendbyte ( 64 ) ; _spi_stop ( ) ; while ( 1 ) ; } void SystemClock_Config ( void ) { RCC_OscInitTypeDef RCC_OscInitStruct ; RCC_ClkInitTypeDef RCC_ClkInitStruct ; __PWR_CLK_ENABLE ( ) ; __HAL_PWR_VOLTAGESCALING_CONFIG (PWR_REGULATOR_VOLTAGE_SCALE2 ) ; RCC_OscInitStruct. OscillatorType = RCC_OSCILLATORTYPE_HSE ; RCC_OscInitStruct. HSEState = RCC_HSE_ON ; RCC_OscInitStruct. PLL .PLLState = RCC_PLL_NONE ; HAL_RCC_OscConfig ( & RCC_OscInitStruct ) ; RCC_ClkInitStruct. ClockType = RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2 ; RCC_ClkInitStruct. SYSCLKSource = RCC_SYSCLKSOURCE_HSE ; RCC_ClkInitStruct. AHBCLKDivider = RCC_SYSCLK_DIV1 ; RCC_ClkInitStruct. APB1CLKDivider = RCC_HCLK_DIV4 ; RCC_ClkInitStruct. APB2CLKDivider = RCC_HCLK_DIV2 ; HAL_RCC_ClockConfig ( & RCC_ClkInitStruct , FLASH_LATENCY_0 ) ; } void MX_GPIO_Init ( void ) { GPIO_InitTypeDef GPIO_InitStruct ; /* GPIO Ports Clock Enable */ __GPIOB_CLK_ENABLE ( ) ; /*Configure GPIO pins : PB12 PB13 PB14 PB15 */ GPIO_InitStruct. Pin = GPIO_PIN_12 |GPIO_PIN_13 |GPIO_PIN_14 |GPIO_PIN_15 ; GPIO_InitStruct. Mode = GPIO_MODE_OUTPUT_PP ; GPIO_InitStruct. Pull = GPIO_NOPULL ; GPIO_InitStruct. Speed = GPIO_SPEED_LOW ; HAL_GPIO_Init (GPIOB , & GPIO_InitStruct ) ; }

Питание 2.9В, отправленный байт 64, если пересчитать (2.9*64)/256 = 0,725В весьма похоже на то, что показал прибор на выходе.

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

Новости

    Профессиональный сервисный центр
    iServicePro — это запчасти по ремонту Айфонов в Екатеринбурге. В нашем распоряжении — квалифицированные мастера, профессиональное оборудование, исключительно оригинальные материалы, большой

    Авто из европы в украину
    Ездить по стране на автомобилях с иностранными номерами теперь разрешено не более 20-ти дней. Работники таможенных служб производят конфискацию машин у украинцев с иностранными номерами в случае, если

    Газель 405 двигатель инжектор
    Двигатель ЗМЗ-405 производится ОАО «Заволжский моторный завод» - основным поставщиком силовых агрегатов для Горьковского автозавода. Этот мотор является модернизированным вариантом известного,

    Деньги под залог авто с правом
    Когда срочно нужна большая сумма денег, в банк за потребительским кредитом обращаться не хочется, а взять в долг не у кого, есть отличный выход из создавшегося положения — взять деньги под залог авто,

    Такси Пхукет
    Один из  самых быстрых способов добраться с  острова Пхукет до  одного из  островов провинции Краби  — 3-часовое путешествие на  скоростном катере или пароме. Подобные

    Замена лобового стекла ниссан
    У вас автомобиль Ниссан? И пришло время заменить лобовое стекло? Я советую вам обратиться к настоящим профессионалам своего дела. Здесь замена лобового стекла ниссан произойдёт для вас максимально быстро,

    Обязательное страхование автоцивилки в Украине
    Обязательное страхование гражданской ответственности владельцев транспортных средств регулируется Законом об ОСАГО. Закон регулирует принципы обязательного страхования в указанной сфере, условия и порядок

    Доставка груза в Анадырь
    Анадырь считается одной из самых труднодоступных региональных столиц в России. Административный центр Чукотки связан прямыми рейсами только с тремя крупными городами страны – с Москвой, Хабаровском

    Негабаритные перевозки в Ростове
    А. Герасименко, «Кин-Марк»: ГК «Кин-Марк» – это крупный перевозчик и экспедитор негабаритных, тяжеловесных и проектных грузов на территории России, стран СНГ и Европы. Г. Розе, «Востокмонтажмеханизация»:

    Штатные магнитолы
    Наш магазин специализируется на продаже и установке штатных головных устройств. В наличии есть решения под любой автомобиль.   Что же такое "штатная магнитола"?   Когда-то даже кассетная магнитола

Анекдоты

Где можно получить права на вождение танка и бронетранспортёра? Господи, катайтесь так! Кто вас остановит?!
rss