STM8L-Цифро-Аналоговый преобразователь (ЦАП) и блок коммутации аналоговых сигналов (Routing interface)

28 Января 2011 К комментариям

Не удалось все таки мне избежать изготовления пробной печатной платы для STM8L151K6, так как появилась задача для которой он лучше всего подходит. Задача очень простая – необходимо обеспечить поддержание температуры на заданном уровне в автономном блоке. В блоке имеется аналоговый термодатчик сигнал с которого необходимо оцифровать и  в зависимости от полученного значения снизить или повысить уровень охлаждения. Для охлаждения используется модуль Пельтье.

020

Первое что мне было нужно попробовать это ЦАП. Так как ни каких сложностей мне не нужно будет рассмотрен простой режим работы ЦАП.

Коммутатор сигналов

Прежде чем перейти к блоку ЦАП необходимо рассмотреть один очень важный блок – коммутатор сигналов (в моей интерпретации, в оригинале Routing interface (RI)).

Данный блок осуществляет коммутацию сигналов между аналоговыми блоками и линиями ввода-вывода.

Я хочу рассмотреть его в первую очередь потому что у микроконтроллеров в корпусах TQFP32 выход ЦАП не связан напрямую с линией ввода-вывода и поэтому прежде чем использовать ЦАП необходимо указать к какой линии необходимо подключить выход ЦАП. К сожалению подключить можно только к одной из трех предопределенных линий.

Функциональная схема блока:

image

Согласно схеме линии ввода-выводы сгруппированы в восемь групп по три линии в каждой. Для блока ЦАП отведено три линии PB4-PB6.

На своей плате я бы хотел использовать линию PB4, сделать это очень просто достаточно включить соответствующий переключатель:

RI->IOSR3 |= BIT(4);

Однако получить сигнал на выходе мне не удалось. Первая мысль необходимо подать тактирование, но в разделе Clock control (CLK) описывающим блок управления тактовыми сигналами про данный блок ни слуху ни духу :(. Перечитав несколько раз описание я подумал что неверно сконфигурировал сам ЦАП и решил проверить блок коммутации на чем то попроще. Самым простым оказался источник опорного напряжения. Включив его и подключив его к линии PD6 (так как бит VREFOUTEN расположен в регистре компаратора я подал тактовый сигнал и на него) убедился что коммутатор работает и именно так как я думаю. Но встал вопрос из-за чего же не работает ЦАП, и вот тут мне повезло в основном проверку ЦАП я осуществлял при помощи циклической записи в регистр ЦАП инкрементирующийся восьми битной переменной и при проверке блока коммутации не закомментировал код, как же я удивился когда решил проверить что же на выходе ЦАП, а там … а там всё работало. В результате разбора выяснилось что для работы блока коммутации необходимо разрешить тактирования компаратора. Первые грабли на которые я наступил при изучении, а ещё толком и не попробовал ни чего :(. Повторное чтение документации не помогло решить сей феномен. Следовательно перед работой с блоком коммутации необходимо разрешить тактирование компаратора:

CLK->PCKENR2 |= CLK_PCKENR2_COMP;

Ну вот теперь можно переходить к ЦАП.

ЦАП

Линейка микроконтроллеров STM8L15x содержит от одного до двух 12-битных цифро-аналоговых преобразователя (ЦАП).

Основные характеристики:

  • восьми или двенадцати битный режим работы
  • правое или левое выравнивание в двенадцати битном режиме
  • возможность синхронного обновления
  • поддержка прямого доступа к памяти (DMA)
  • поддержка нескольких источников синхронизации
  • возможность использования внешнего опорного напряжения
  • авто-генерация треугольного или “шумового” сигнала (только в MD+ и HD)
  • максимальное время установление сигнала 12 мкс, при малом изменении выходного сигнала 1 мкс
  • </ul> Функциональная схема блока АЦП (medium density devices): image Более подробно можно прочитать в руководстве RM0031 STM8L15x and STM8L16x microcontroller family. Для работы ЦАП необходимо:
    • разрешить тактирование
    • сконфигурировать необходимый режим работы
    Разрешим тактирование модуля:
    CLK->PCKENR1 |= CLK_PCKENR1_DAC;
    Выходной сигнал с ЦАП может поступать не напрямую, а через буферный усилитель. Это позволяет использовать более низкоомную нагрузку (5 кОм), однако проводит к снижению выходного диапазона напряжений (от 0,2 до Vref-0,2 Вольт), меня эти ограничения устраивают, следовательно я буду использовать буферный усилитель. На данный момент меня интересует программная запись значений в выходной регистр ЦАП, однако напрямую записать нужное значение в выходной регистр нельзя необходимо использовать один из методов:
    1. записать необходимое значение в соответствующий регистр хранения, и через один такт ЦПУ значение будет записано в выходной регистр
    2. записать значение и в нужный момент времени используя программный триггер инициировать запись.
    Такие сложности только потому что модуль ЦАП может работать в 8-ми и 12-ти битных режимах, при чем в 12-т битном режиме возможно левое и правое выравнивание, которые необходимы для оптимальной работы с блоком прямого доспута к памяти (DMA). Под каждый из режимов выделены свои регистры, т.е. если вам достаточно восемь бит вы пишите всего лишь в один 8-ми битный регистр. Решил начать со второго режима, т.е. буду использовать программный триггер. Ну и на основании выше изложенного конфигурируем ЦАП:
    DAC->CH1CR1 = DAC_CR1_TEN | DAC_CR1_BOFF | DAC_CR1_TSEL_SWTRIG;
    и разрешаем работу:
    DAC->CH1CR1 |= DAC_CR1_EN;
    Вроде ни чего не забыл :) Небольшая демка:
     /*
     * File: main.c
     * Date: 28.01.2011
     */
    
    #include "main.h"
    
    //-----------------------------------------------------------------------------
    void delay_ms(uint16_t time)
    {
    	volatile uint32_t i;
    
    	while (time-- > 0)
    	{
    		i = 30;
    		while (i-- > 0)
    		{
    		}
    	}
    }
    
    //------------------------------------------------------------------------------
    int main(void)
    {
    	uint8_t tDAC;
    
    	CLK->PCKENR1 |= CLK_PCKENR1_DAC;
    	CLK->PCKENR2 |= CLK_PCKENR2_COMP;
    
    	RI->IOSR3 |= BIT(4);
    
    	DAC->CH1CR1 = DAC_CR1_TEN | DAC_CR1_BOFF | DAC_CR1_TSEL_SWTRIG;
    	DAC->CH1CR1 |= DAC_CR1_EN;
    
    	tDAC = 0;
    	
    	while (1)
    	{
    		DAC->CH1DHR8 = tDAC++;
    
    		DAC->SWTRIGR |= DAC_SWTRIGR_SWTRIG1;
    
    		delay_ms(1);
    	}
    
    	return 0;
    }
    На этом пока всё. Печатная плата: 2011-01-27-demo-stm8l151k6


comments powered by Disqus