Pull to refresh

Измерение ВАХ транзистора с помощью микроконтроллера Cypress

Reading time 8 min
Views 20K

Шаг 1: Исходные материалы


Из исходных материалов дома были:
1. Микроконтроллер фирмы Cypress “CY8C29466 – 24PXI" и отладочная плата “PSoCEVAL1 RevE”
image image
2. Программатор PSoC MiniProg и USB-miniUSB провод для него
image image
3. Мультиметр и LCD дисплей (очень пригодятся при отладке)
image image

Шаг 2: Схема включения


Первым делом надо было прикинуть схему включения. Напомню, что задача стоит измерение вольт-амперной характеристики полевого транзистора. А именно зависимости Iси (тока сток-исток) от напряжения Uз(у затвора). Так как обычно аналого-цифровые преобразователи завязаны на измерении напряжения, нужна была схема для косвенного измерения тока по известному напряжению. И после небольших рассуждений на свет появилась следующая схема.
imageГде:
Vdd — напряжение питания микроконтроллёра и платы
R1 — рабочая нагрузка
Q1 — полевой транзистор
DAC и ADC — соответственно цифро-аналоговый и аналого-цифровой преобразователи.

Шаг 3: Выбор транзистора


В мануалах было найдено, что напряжение платы Vdd = 5В, и рабочий диапазон цифро-аналогового преобразователя колеблется примерно от 0 до 5В. Исходя из этих данных, подбирался транзистор(Q1) и рабочие сопротивление(R1). Выбор упал на КП103М и сопротивление в 50 Ом.

Технические характеристики транзистора КП103М:

• Структура транзистора: с p-n-переходом и p-каналом;
• Рси max — Рассеиваемая мощность сток-исток: 120 мВт;
• Uзи отс — Напряжение отсечки транзистора — напряжение между затвором и истоком: 2,8...7 В;
• Uси max — Максимальное напряжение сток-исток: 10 В;
• Iс нач — Начальный ток стока: 3… 12 мА;
• S — Крутизна характеристики: более 1,3… 4,4 мА/В;
• С11и — Входная емкость транзистора — емкость между затвором и истоком: 20 пФ;
• С12и — Емкость обратной связи в схеме с общим истоком при коротком замыкании на входе по переменному току: 8 пФ;
• Кш — Коэффициент шума транзистора: не более 3 дБ на частоте 1 кГц.

Полдня на рынке и были куплены следующие вещи.
1. Полевой транзистор КП103М и рабочие сопротивление 50 Ом
image image
2. Кабель RS 232, пригодиться для транспортировки данных на комп (хотел купить RS232-USB но цена сыграла свою роль, да ещё побоялся работать с виртуальными com-портами)
image

Шаг 4: Программирование микроконтроллера.


0. Введение

Программирование в среде PSoC Designer 5.3 осуществлено на достаточно высоком уровне (хотя и программированием это назвать с уверенностью нельзя, это что-то среднее между программированием и моделированием). Основное рабочие пространство среды представляет собой схему чипа. На которой располагаются свободные блоки (а если вы уже что то добавили то не свободные) для установки модулей микроконтроллера. Это могут быть, различные ЦАП, АЦП, контроллеры дисплея, трансиверы данных, программируемые усилители, таймеры, счетчики, датчики температуры (имеется ввиду встроенные в микросхему), пользовательские блоки, и так далее. Цифровые модули располагаются в верней части рабочего пространства, аналоговые в нижней. В рабочую зону входят также шины, на которые вешаются входы и выходы аналоговых и цифровых модулей, которые в свою очередь связываются с портами(так называемые ноги микроконтроллера). Простым притягиванием и кликами мышки можно установить любой из модулей и привязать его к портам, при условии что для него есть свободная позиция.

image
image
В главной рабочей закладке присутствует также немаловажная панель «Global resources». В которой, располагаются основные рабочие характеристики чипа, таки как: рабочая частота, режим питания, некоторые глобальные переменные делители частоты, нужные для работы некоторых цифровых и аналоговых блоков.
Красным выделены те свойства, которые были изменены в ходе выполнения работы. Ref Mux — это диапазон напряжений, для аналоговых блоков микросхемы. VC — это системные делители тактовой частоты процессора микроконтроллера, нужны для синхронизированной работы цифровых блоков и блоков ЦАП АЦП.

1. DAC

Первым делом надо было установить на микроконтроллер модуль DAC8(что означает 8bit Digital-to-Analog Converter), что означает 8ми битный цифро-аналоговый преобразователь. Разрядность в 8мь бит значит, что наименьшая единица изменения напряжения будет (Vmax-Vmin)/256, для нашего случая 5В/256. Точности для измерения более чем достаточно. Выход DAC'ка был выведен на шину AnalogOutBus_0. А сама шина выведена на один из свободных портов контроллера, у меня DAC выведен на Port_0_3, увы, на скриншоте его не видно, но поверти мне на слово, он там есть. Таким образом, получилась примерно следующая картина.
image
Далее надо было написать небольшой код для запуска микроконтроллера и ЦАП'па. Важным замечанием будет что, устройство поддерживает Си и Assembly.
#include <m8c.h>        // part specific constants and macros
#include "PSoCAPI.h"    // PSoC API definitions for all User Modules

void main(void)
{
	DAC8_1_Start(DAC8_1_HIGHPOWER);
	M8C_EnableGInt ; // Uncomment this line to enable Global Interrupts
	while(1)
	{
		DAC8_1_WriteBlind(255);// от 0 до 255 так как ЦАП 8ми битный значения получим в диапазонах от 0 до примерно 5В
	}
}

                                       Собираем плату в соответствии со схемой приведенной в шаге 2.

image
Прошиваем микроконтроллера. Дебажим тестером, при разных значениях функции DAC8_1_WriteBlind(); если показатели являются адекватными и линейно зависимыми, идем дальше и разбираемся с ЦАП блоком.

2. ADC

Не сказать, что ЦАП’ом дела пошли намного легче. Для его реализации понадобилось целых 3 модуля микроконтроллера. Во-первых, это PGA (Programmable Gain Amplifier), программируемый операционный усилитель. Он нужен не столько для усиления (если честно коэффициент усиления в нем выставлен 1, да к тому же он не способен выдать напряжение большие чем напряжение питания) сколько для повышения входного сопротивления. Что бы величина текущего тока в цепи не влияла на точность измерения. Один вход, которого был, воткнут в землю, а второй повешен на port_0_1. Вторым модулем стал непосредственно сам ЦАП, полное название элемента ADCINC12. Разрядность, которого составляет 12bit, что есть 4096 шагов квантования по входному сигналу. Один из входов ЦАП'па был соединён с выходом PGA, второй по умолчанию соединён с землёй. Так же следует заметит что, все эти штуки (включая DAC'ка) для синхронной работы, должны садиться на один тактовый генератор, а если быть точнее делитель тактовой частоты процессора. Аналоговые блоки посажаны на делитель тактовой частоты VC1 равной SysClock/8(24МГц/8). Всё выше сказанное имеет примерно следующий вид.
image
Последний модуль, про который ещё ничего не сказали, это модуль LCD, интерфейс для работы с дисплеем. А нужен он нам для отладки работы ADC и PGA, так как извне проверить корректность работы этих модулей нам не удастся. К счастью пространство на рабочей схеме он не занимает, и из настроек у него только один параметр это LCDPort, нам нужен Port_2, который уже имеется на нашей отладочной плате.
На случай если что упустил, приведу скриншоты настроек выше описанных блоков
imageimageimage
Модифицируем код:
#include <m8c.h>        // part specific constants and macros
#include "PSoCAPI.h"    // PSoC API definitions for all User Modules

void main(void)
{
	DAC8_1_Start(DAC8_1_HIGHPOWER);			
	PGA_1_Start(PGA_1_HIGHPOWER);			
	ADCINC12_1_Start(ADCINC12_1_HIGHPOWER);	
	ADCINC12_1_GetSamples(0);     			//установка режима семплирования - постоянная
	LCD_Start();							
	LCD_Position(1,0);						//позиция для отрисовки
	M8C_EnableGInt ; // Uncomment this line to enable Global Interrupts
	while(1)
	{
		DAC8_1_WriteBlind(255);// от 0 до 255 так как ЦАП 8ми битный значения получим в диапазонах от 0 до примерно 5В
		result = ADCINC12_1_iGetData() + 2048;
		ADCINC12_1_ClearFlag();
		LCD_Position(1,0);
		LCD_PrHexInt(result);
	}
}

Экране появились цифры в диапазоне от 0 до 0x0FFF, в зависимости от поданного напряжения.Ура! Всё работает нормально. Двигаемся дальше.
image

3. UART

UART это протокол передачи данных. Наиболее известный по интерфейсу RS232. Нужно было выташить блок UART на схему. Модуль UART занимает два цифровых блока, один для RX принимающая линия, второй для TX, передающая линию. Выходы этих блоков были соединены с определёнными портами, специально отведенными для транспортировки данных. Port_2_7 для выхода, Port_1_6 для входа. Устройство UART должно работать на тактовом генераторе VC3 = SysClock/156, тем самым позволяя передавать данные с битрейтом 19200. Для передачи будет использоваться функция UART_1_PutSHexInt().
Ну и наконец финальным штрихом было изменение цикл с бесконечного на while(i<255). Что бы можно было варьировать значениями, подаваемыми в DAC и каждый раз снимать новое напряжение.
Финальная версия кода для микроконтроллера выглядит так:
Финальная версия кода
//----------------------------------------------------------------------------
// C main line
//----------------------------------------------------------------------------

#include <m8c.h>        // part specific constants and macros
#include "PSoCAPI.h"    // PSoC API definitions for all User Modules

int result;
int i;

void main(void)
{
	DAC8_1_Start(DAC8_1_HIGHPOWER);
	PGA_1_Start(PGA_1_HIGHPOWER);
	ADCINC12_1_Start(ADCINC12_1_HIGHPOWER);
	ADCINC12_1_GetSamples(0);     
	LCD_Start();
	LCD_Position(1,0);
	
	UART_1_Start(UART_PARITY_NONE);      

	M8C_EnableGInt ; // Uncomment this line to enable Global Interrupts
	while(i<255)
	{
		DAC8_1_WriteBlind(i);
		if(ADCINC12_1_fIsDataAvailable() != 0)
		{
			result = ADCINC12_1_iGetData() + 2048;
			ADCINC12_1_ClearFlag();
			LCD_Position(1,0);
			LCD_PrHexInt(result);
			
			UART_1_PutSHexInt(result);    /* Print result to UART */
			
			i++;
		}
	}
}


Шаг 5: Прослушка COM-порта


image
Как же проверить действительно, ли поступают данные на комп? Для начала надо проверить включён и работает ли на вашем компьютере com-порт. Для windows 7 -> правой кнопкой Мой Компьютер -> диспетчер устройств -> и мы должны видеть картину расспаложенну справа от текста. Если этого не случилось com-порт скорее всего отключен, и включить его следует в BIOS.

Теперь его нужно настроить.

Выставляем поля
Bit per second — 19200
Data bits — 8
Parity — None
Stop bits — 1
Flow control — none

image

Скачиваем прогу HyperTerminal или что либо похоже, возможно даже есть что то стандартное. Запускаем её. Выбираем наш порт COM1.
И получаем безумные последовательности байтов.
image
Трансмиттер работает.

Шаг 6: C# клиент


Запускаем любой VisualStudio С#. Создаём консольное приложение. Добавляем туда два класса. Один для работы с Com другой c Excel ( Я так их и назвал). Добавляем к проекту библиотеку для работы с Excel(правой кнопкой References -> Add Reference… -> Extensions -> Microsoft.Office.Interop.Excel). Все преобразования из Hex'ов в int'ы и из int'ов в ток, будем делать в Program.cs.
Program.cs
    class Program
    {
        public static List<double> ConvInToAmp(List<int> input)
        {
            List<double> converted = new List<double>();
            double stap = 0.00116822;
            double Vdd = 4.8;
            double R = 50;
            for (int i = 0; i < 255; i++)
            {
                converted.Add(input[i] * stap);
                converted[i] = Vdd - converted[i];
                converted[i] = converted[i] / R;
                //Console.WriteLine(converted[i]);
            }
            return converted;
        }
        public static List<double> CreateVolt()
        {
            List<double> volts = new List<double>();
            double stap = 0.0188235294117647;
            for (int i = 0; i < 255; i++)
            {
                volts.Add(i*stap);
            }
            return volts;
        }
        static void Main(string[] args)
        {
            Com port = new Com();
            port.Strart();
            while (!port.Full()) ;
            port.Stop();
            Console.WriteLine("Data transmission complite");
            List<int> input = port.GetData();
            List<double> converted = ConvInToAmp(input);
            Console.WriteLine("Conversin complite");
            Excel exel = new Excel(CreateVolt(), converted);
            Console.Read();
        }
    }

Com.cs
    class Com
    {
        private List<int> values = new List<int>();
        private SerialPort port = new SerialPort("COM1", 19200, Parity.None, 8, StopBits.One);
        private void received(object sender, SerialDataReceivedEventArgs e)
        {
            string buf;
            buf = port.ReadExisting();
            while (!String.IsNullOrEmpty(buf))
            {
                string str = buf.Substring(0, 4);
                int v = Convert.ToInt32(str, 16);
                buf = buf.Remove(0, 4);
                Console.WriteLine(v);
                values.Add(v);
            }
        }
        public void Strart()
        {
            Console.WriteLine("Incoming data:");
            port.DataReceived += new SerialDataReceivedEventHandler(received);
            port.Open();
        }
        public void Stop()
        {
            port.Close();
        }
        public bool Full()
        {
            if (values.Count == 255)
                return true;
            else
                return false;
        }
        public List<int> GetData()
        {
            return values;
        }
    }<source lang="cs">

Excel.cs
    class Excel
    {
        private List<double> xScale;
        private List<double> yScale;
        private Application exApp = new Application();
        private Sheets sheets;
        private Worksheet worksheet;
        private Range range;
        public Excel(List<double> x,List<double> y)
        {
            xScale = x;
            yScale = y;
            exApp.Visible = true;
            exApp.SheetsInNewWorkbook = 1;
            exApp.Workbooks.Add(Type.Missing);
            sheets = exApp.Worksheets;
            worksheet = (Worksheet)sheets.get_Item(1);
            for (int i = 1; i < 255; i++)
            {
                range = worksheet.get_Range("A" + Convert.ToString(i), "A" + Convert.ToString(i));
                range.Value = xScale[i];
                range = worksheet.get_Range("B" + Convert.ToString(i), "B" + Convert.ToString(i));
                range.Value = yScale[i];
            }
            ChartObjects chartObjs = (ChartObjects)worksheet.ChartObjects();
            ChartObject chartObj = chartObjs.Add(150, 20, 700,500);
            Chart xlChart = chartObj.Chart;
            xlChart.ChartType = XlChartType.xlXYScatterLinesNoMarkers;
            //PlotArea.
        
            Range xValues = worksheet.Range["A1", "A254"];
            Range values = worksheet.Range["B1", "B254"];

            SeriesCollection seriesCollection = xlChart.SeriesCollection();

            Series series1 = seriesCollection.NewSeries();
            series1.MarkerSize = 3;
            series1.XValues = xValues;
            series1.Values = values; 
        }
    }
}


Если всё правильно написано и сделано, то клиент напишет, что он принимает данные и по окончании выведет график в Excel.
image
Tags:
Hubs:
+33
Comments 8
Comments Comments 8

Articles