Однократное и непрерывное измерение ADC: различия между версиями

Материал из MIK32 микроконтроллер
Нет описания правки
(закомментировал код. добавил подключение UARTa. пронумеровал рисунки (начиная с 3))
Строка 17: Строка 17:


== Использование библиотеки HAL_ADC ==
== Использование библиотеки HAL_ADC ==
В сгенерированном проекте в файле main.c должна быть функция ADC_Init, в которой будут заданы настройки для ADC. Выглядит она так:<syntaxhighlight lang="c" line="1">
В сгенерированном проекте в файле main.c должна быть функция ADC_Init, в которой будут заданы настройки для ADC. Выглядит она так:
{{#spoiler:show=Развернуть код|hide=Свернуть код|
<syntaxhighlight lang="c" line="1">
static void ADC_Init(void)
static void ADC_Init(void)
{
{
Строка 28: Строка 30:
     HAL_ADC_Init(&hadc);
     HAL_ADC_Init(&hadc);
}
}
</syntaxhighlight>Кроме этого в функции SystemClock_Config приведены настройки для тактирования. Убедитесь что в PeriphClkInit.PMClockAPB_P присутствует PM_CLOCK_ANALOG_REG_M. Для смены функции вывода на аналоговую должен быть затактирован контроллер выводов (в PeriphClkInit.PMClockAPB_M должен быть PM_CLOCK_PAD_CONFIG_M или PMCLOCKAPB_M_DEFAULT).  Сама функция должна выглядеть примерно так:
</syntaxhighlight>
 
}}
Кроме этого в функции SystemClock_Config приведены настройки для тактирования. Убедитесь что в PeriphClkInit.PMClockAPB_P присутствует PM_CLOCK_ANALOG_REG_M. Для смены функции вывода на аналоговую должен быть затактирован контроллер выводов (в PeriphClkInit.PMClockAPB_M должен быть PM_CLOCK_PAD_CONFIG_M или PMCLOCKAPB_M_DEFAULT).  Сама функция должна выглядеть примерно так:
{{#spoiler:show=Развернуть код|hide=Свернуть код|
<syntaxhighlight lang="c" line="1">
<syntaxhighlight lang="c" line="1">
void SystemClock_Config(void)
void SystemClock_Config(void)
Строка 52: Строка 56:
     HAL_RCC_ClockConfig(&PeriphClkInit);
     HAL_RCC_ClockConfig(&PeriphClkInit);
}
}
</syntaxhighlight>Для демонстрации вывода текста в PeriphClkInit.PMClockAPB_P присутствует PM_CLOCK_UART_0_M. У вас его может не быть так как UART нужно включить отдельно.  
</syntaxhighlight>
}}
Для демонстрации вывода текста в PeriphClkInit.PMClockAPB_P присутствует PM_CLOCK_UART_0_M. У вас его может не быть так как UART нужно включить отдельно. Для этого нужно подключить библиотеки uart_lib и xprintf.
{{#spoiler:show=Развернуть код|hide=Свернуть код|
<syntaxhighlight lang="c" line="1">
#include "mik32_hal_rcc.h"
#include "mik32_hal_adc.h"


В начале main.c можно видеть объявление структуры с набором настроек для АЦП, которую использует функция инициализации ADC_Init.<syntaxhighlight lang="c" line="1">
#include "uart_lib.h"
#include "xprintf.h"
</syntaxhighlight>
}}
Для инициализации UART в функции main, после функции тактирования SystemClock_Config, следует написать:
<syntaxhighlight lang="c" line="1" start="1">
UART_Init(UART_0, 3333, UART_CONTROL1_TE_M | UART_CONTROL1_M_8BIT_M, 0, 0);
</syntaxhighlight>
Скорость UART задается делителем во втором аргументе функции. При такой записи скорость будет 9600 бод.
 
В начале main.c можно видеть объявление структуры с набором настроек для АЦП, которую использует функция инициализации ADC_Init.
{{#spoiler:show=Развернуть код|hide=Свернуть код|
<syntaxhighlight lang="c" line="1">
ADC_HandleTypeDef hadc;
ADC_HandleTypeDef hadc;


void SystemClock_Config(void);
void SystemClock_Config(void);
static void ADC_Init(void);
static void ADC_Init(void);
</syntaxhighlight>Для запуска однократного измерения следует использовать функцию HAL_ADC_Single. Для получения значения используйте функцию HAL_ADC_WaitAndGetValue.
</syntaxhighlight>
}}
Для запуска однократного измерения следует использовать функцию HAL_ADC_Single. Для получения значения используйте функцию HAL_ADC_WaitAndGetValue.


Функция main должна выглядеть примерно так:<syntaxhighlight lang="c" line="1">
Функция main должна выглядеть примерно так:
{{#spoiler:show=Развернуть код|hide=Свернуть код|
<syntaxhighlight lang="c" line="1">
int main()
int main()
{     
{     


     SystemClock_Config();
     SystemClock_Config();
      
 
     UART_Init(UART_0, 3333, UART_CONTROL1_TE_M | UART_CONTROL1_M_8BIT_M, 0, 0);
 
     ADC_Init();
     ADC_Init();


Строка 90: Строка 118:
}
}
</syntaxhighlight>
</syntaxhighlight>
[[Файл:АЦП пример 1.png|мини|Вывод UART]]
}}
[[Файл:АЦП пример 2.png|мини|Вывод UART в примере с внешнем ОИН]]
[[Файл:АЦП пример 1.png|мини|Рисунок 3 - вывод UART]]
[[Файл:АЦП пример 3.png|мини|Вывод UART в примере с АЦП в непрерывном режиме]]
[[Файл:АЦП пример 2.png|мини|Рисунок 4 - вывод UART в примере с внешнем ОИН]]
Подадим на вывод Port0.9 напряжение 0.6В. Вывод UART можно видеть на рисунке. АЦП может выводить немного другое значение, так как источники напряжения и сам АЦП имеют погрешность.
[[Файл:АЦП пример 3.png|мини|Рисунок 5 - Вывод UART в примере с АЦП в непрерывном режиме]]
Подадим на вывод Port0.9 напряжение 0.6В. Вывод UART можно видеть на рисунке 3. АЦП может выводить немного другое значение, так как источники напряжения и сам АЦП имеют погрешность.


Теперь изменим ИОН на внешний от вывода ADC_REF - Port1.10. Это можно сделать в конфигураторе, либо в функции ADC_Init, которая должна выглядеть так:<syntaxhighlight lang="c" line="1">
Теперь изменим ИОН на внешний от вывода ADC_REF - Port1.10. Это можно сделать в конфигураторе, либо в функции ADC_Init, которая должна выглядеть так:
{{#spoiler:show=Развернуть код|hide=Свернуть код|
<syntaxhighlight lang="c" line="1">
static void ADC_Init(void)
static void ADC_Init(void)
{
{
Строка 106: Строка 137:
     HAL_ADC_Init(&hadc);
     HAL_ADC_Init(&hadc);
}
}
</syntaxhighlight>Функция main без изменений.  
</syntaxhighlight>
}}
Функция main без изменений.  


Подадим на вывод ADC_REF (Port1.10 ) 1.2В, а на вывод АЦП5 (Port0.9) 0.6В. Вывод UART изображен на рисунке. АЦП может выводить немного другое значение, так как источники напряжения и сам АЦП имеют погрешность.
Подадим на вывод ADC_REF (Port1.10 ) 1.2В, а на вывод АЦП5 (Port0.9) 0.6В. Вывод UART изображен на рисунке 4. АЦП может выводить немного другое значение, так как источники напряжения и сам АЦП имеют погрешность.


Для запуска АЦП в непрерывном режиме следует использовать функцию HAL_ADC_ContiniusEnable, а для считывания результата преобразования HAL_ADC_GetValue.<syntaxhighlight lang="c" line="1">
Для запуска АЦП в непрерывном режиме следует использовать функцию HAL_ADC_ContiniusEnable, а для считывания результата преобразования HAL_ADC_GetValue.
{{#spoiler:show=Развернуть код|hide=Свернуть код|
<syntaxhighlight lang="c" line="1">
static void ADC_Init(void)
static void ADC_Init(void)
{
{
Строка 122: Строка 157:
}
}
</syntaxhighlight>
</syntaxhighlight>
 
}}
Функция main должна выглядеть примерно так:<syntaxhighlight lang="c" line="1">
Функция main должна выглядеть примерно так:
{{#spoiler:show=Развернуть код|hide=Свернуть код|
<syntaxhighlight lang="c" line="1">
int main()
int main()
{     
{     
Строка 151: Строка 188:
        
        
}
}
</syntaxhighlight>Подадим на вывод АЦП5 (Port0.9) 0.6В. Вывод UART изображен на рисунке. АЦП может выводить немного другое значение, так как источники напряжения и сам АЦП имеют погрешность.
</syntaxhighlight>
}}
Подадим на вывод АЦП5 (Port0.9) 0.6В. Вывод UART изображен на рисунке 5. АЦП может выводить немного другое значение, так как источники напряжения и сам АЦП имеют погрешность.

Версия от 09:07, 24 марта 2023

В примере будут запущены измерения ADC (АЦП) в однократном и непрерывном режиме.

Работа с конфигуратором (В разработке)

Для начала настроем в конфигураторе тактирование mik32, например, от внешнего кварца 32МГц. Затем настроем делители шины. Так как АЦП тактируется от шины APB_P_CLK, то зададим делители AHB_DIV и APB_P_DIV. В данном примере оставим делители по умолчанию. В итоге вкладка с тактированием должна выглядеть так:

(Картинка тактирования из конфигуратора. В работе)

Затем перейдем к настройке самого АЦП. Для этого откроем вкладку АЦП и нажмем включить.

После этого появится настройки канала и источника опорного напряжения (ИОН). Выберем 5-й канал АЦП, которому соответствует вывод Port0.9.

Настройки ADC в конфигураторе

В АЦП есть 3 источника опорного напряжения. Внутренний считается встроенным в АЦП. Настраиваемый ИОН и источник от внешнего вывода ADC_REF считаются внешними по отношению к внутреннему ИОН АЦП. Выберем "Внутренний".

В итоге настройки таймера в конфигураторе должны выглядеть как на рисунке.

Нажимаем кнопку сохранения и генерации. В итоге у нас появится проект для PlatformIo. Далее работа идет в visual studio code.

Использование библиотеки HAL_ADC

В сгенерированном проекте в файле main.c должна быть функция ADC_Init, в которой будут заданы настройки для ADC. Выглядит она так:

Кроме этого в функции SystemClock_Config приведены настройки для тактирования. Убедитесь что в PeriphClkInit.PMClockAPB_P присутствует PM_CLOCK_ANALOG_REG_M. Для смены функции вывода на аналоговую должен быть затактирован контроллер выводов (в PeriphClkInit.PMClockAPB_M должен быть PM_CLOCK_PAD_CONFIG_M или PMCLOCKAPB_M_DEFAULT). Сама функция должна выглядеть примерно так:

Для демонстрации вывода текста в PeriphClkInit.PMClockAPB_P присутствует PM_CLOCK_UART_0_M. У вас его может не быть так как UART нужно включить отдельно. Для этого нужно подключить библиотеки uart_lib и xprintf.

Для инициализации UART в функции main, после функции тактирования SystemClock_Config, следует написать:

UART_Init(UART_0, 3333, UART_CONTROL1_TE_M | UART_CONTROL1_M_8BIT_M, 0, 0);

Скорость UART задается делителем во втором аргументе функции. При такой записи скорость будет 9600 бод.

В начале main.c можно видеть объявление структуры с набором настроек для АЦП, которую использует функция инициализации ADC_Init.

Для запуска однократного измерения следует использовать функцию HAL_ADC_Single. Для получения значения используйте функцию HAL_ADC_WaitAndGetValue.

Функция main должна выглядеть примерно так:

Рисунок 3 - вывод UART
Рисунок 4 - вывод UART в примере с внешнем ОИН
Рисунок 5 - Вывод UART в примере с АЦП в непрерывном режиме

Подадим на вывод Port0.9 напряжение 0.6В. Вывод UART можно видеть на рисунке 3. АЦП может выводить немного другое значение, так как источники напряжения и сам АЦП имеют погрешность.

Теперь изменим ИОН на внешний от вывода ADC_REF - Port1.10. Это можно сделать в конфигураторе, либо в функции ADC_Init, которая должна выглядеть так:

Функция main без изменений.

Подадим на вывод ADC_REF (Port1.10 ) 1.2В, а на вывод АЦП5 (Port0.9) 0.6В. Вывод UART изображен на рисунке 4. АЦП может выводить немного другое значение, так как источники напряжения и сам АЦП имеют погрешность.

Для запуска АЦП в непрерывном режиме следует использовать функцию HAL_ADC_ContiniusEnable, а для считывания результата преобразования HAL_ADC_GetValue.

Функция main должна выглядеть примерно так:

Подадим на вывод АЦП5 (Port0.9) 0.6В. Вывод UART изображен на рисунке 5. АЦП может выводить немного другое значение, так как источники напряжения и сам АЦП имеют погрешность.