Программирование трехфазного генератора с синусоидальными напряжениями со сдвигом 120° на микроконтроллере STM32 | Статья в журнале «Молодой ученый»

Отправьте статью сегодня! Журнал выйдет 28 декабря, печатный экземпляр отправим 1 января.

Опубликовать статью в журнале

Библиографическое описание:

Программирование трехфазного генератора с синусоидальными напряжениями со сдвигом 120° на микроконтроллере STM32 / А. А. Емельянов, В. В. Бесклеткин, А. Ю. Иванин [и др.]. — Текст : непосредственный // Молодой ученый. — 2017. — № 25 (159). — С. 20-27. — URL: https://moluch.ru/archive/159/44895/ (дата обращения: 19.12.2024).



Целью данной работы является программирование студентами на лабораторном стенде ШИМ-сигналов, сдвинутых на 120° [1], [2], [3]. Программирование осуществляется в среде CooCox CoIDE.

Для реализации этой цели необходимо решить следующие задачи:

‒ Формирование синусоидальных сигналов в цифровой форме с помощью задания углов, определяемых как 2π/192;

‒ Включение тактирования периферийных устройств;

‒ Ввод функции инициализации:

1) Назначение портов ввода-вывода (GPIO – General Ports Input/Outputs);

2) Инициализация таймера (TIM1);

3) Инициализация ШИМ с обязательным включением комплементарных каналов;

‒ Инициализация и настройка прямого доступа к памяти (DMA);

‒ Отправка значений массивов сигналов с помощью прямого доступа к памяти (DMA) в регистры сравнения таймера (TIM1).

Алгоритм набора кода в среде разработки CooCox CoIDE состоит в следующем:

  1. Запускаем среду программирования CooCox CoIDE.
  2. После запуска CooCox CoIDE в строке меню нажать: Project → New Project.
  3. В появившемся окне в поле «Project name» ввести имя своему проекту.
  4. Далее нужно выбрать поле с надписью «Chip».
  5. Появится окно с выпадающими списками различных фирм микроконтроллеров (рис. 1). Необходимо открыть список ST, затем из выпадающего списка открыть подсписок STM32F103x, после чего найти микроконтроллер STM32F103C8, выбрать его левым щелчком мыши и нажать Finish (рис. 2).
  6. После проделанных действий появится главное окно с репозиторием для выбора необходимых для проекта библиотек (рис. 3). Необходимо подключить следующие библиотеки:

‒ RCC – для управления тактовым генератором;

‒ GPIO – для управления портами ввода-вывода;

‒ TIM – для управления таймерами;

‒ DMA – для управления прямым доступом к памяти (DMA).

Рис. 1. Выбор фирмы микроконтроллера

Рис. 2. Выбор микроконтроллера

Рис. 3. Выбор библиотек в репозитории

  1. После выбора библиотек необходимо на панели инструментов выбрать «New file» и создать файлы «timer» и «sinDMA» с расширением «.с», а также аналогичные файлы с расширением «.h» (рис. 4).

Рис. 4. Создание файлов «timer» и «sinDMA»

  1. Следующим шагом необходимо в панели файлов открыть файл «timer.h», два раза щелкнув по нему левой кнопкой мыши, и с помощью директивы «#include <>» записать в нем все заголовочные файлы, необходимые для работы с таймером и портами ввода-вывода (рис. 5).

Рис. 5. Запись заголовочных файлов в «timer.h»

  1. Далее необходимо открыть файл «timer.c». В этом файле нужно создать функцию, в которой включить тактирование периферийных устройств, а также ввести структуры и заполнить их для инициализации портов ввода-вывода и таймера (TIM1). Содержание файла «timer.c» представлено в листинге 1.

Листинг 1. Содержание файла «timer.c»

#include

void timers(void)

{

//----------Включение тактирования-------//

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA

| RCC_APB2Periph_AFIO

| RCC_APB2Periph_TIM1, ENABLE);

//-----------Ввод структур--------------//

GPIO_InitTypeDef gpio;

GPIO_InitTypeDef gpio_1;

GPIO_InitTypeDef gpio_2;

GPIO_InitTypeDef gpio_3;

TIM_TimeBaseInitTypeDef TIM_Base_1;

TIM_OCInitTypeDef TIM_PWM;

//------Назначение GPIO-------------

GPIO_StructInit(&gpio);

gpio.GPIO_Mode = GPIO_Mode_AF_PP;

gpio.GPIO_Pin = GPIO_Pin_8;

gpio.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOA, &gpio);

//------------------------------------

GPIO_StructInit(&gpio_1);

gpio_1.GPIO_Mode = GPIO_Mode_AF_PP;

gpio_1.GPIO_Pin = GPIO_Pin_9;

gpio_1.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOA, &gpio_1);

//------------------------------------

GPIO_StructInit(&gpio_3);

gpio_3.GPIO_Mode = GPIO_Mode_AF_PP;

gpio_3.GPIO_Pin = GPIO_Pin_10;

gpio_3.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOA, &gpio_3);

//-----Назначение TIM1----------------

TIM_TimeBaseStructInit(&TIM_Base_1);

TIM_Base_1.TIM_Prescaler = 0;

TIM_Base_1.TIM_CounterMode = TIM_CounterMode_Up;

TIM_Base_1.TIM_Period = 2000;

TIM_Base_1.TIM_ClockDivision = TIM_CKD_DIV1;

TIM_TimeBaseInit(TIM1,&TIM_Base_1);

//-------Назначение ШИМ-------------------

TIM_OCStructInit(&TIM_PWM);

TIM_PWM.TIM_OCMode = TIM_OCMode_PWM1;

TIM_PWM.TIM_OutputState = TIM_OutputState_Enable;

TIM_PWM.TIM_OutputNState = TIM_OutputNState_Enable;

TIM_OC1Init(TIM1, &TIM_PWM);

TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);

TIM_OC2Init(TIM1, &TIM_PWM);

TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);

TIM_OC3Init(TIM1, &TIM_PWM);

TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);

TIM_Cmd(TIM1, ENABLE);

TIM_CtrlPWMOutputs(TIM1, ENABLE);

}

  1. После этого в файле «timer.h» записать прототип функции «timers()» (рис. 6), а также с помощью директивы «#include<>» подключить заголовочный файл «timer.h» в файле «main.c».

Рис. 6. Запись прототипа функции «timers()»

  1. Следующим шагом нужно открыть файл «sinDMA.h» и подключить заголовочные файлы, необходимые для работы с DMA (рис. 7).

Рис. 7. Подключение заголовочных файлов в «sinDMA.h»

  1. Далее необходимо открыть файл «sinDMA.c» и создать массивы для трехфазной системы с синусоидальными напряжениями, а также создать функции для передачи элементов массива с помощью DMA в регистры сравнения таймера (TIM1). Содержание файла «sinDMA.c» представлено в листинге 2.

Листинг 2. Содержание файла «sinDMA.c»

#include

//---Фаза А*---//

uint16_t sinA[192] = {56,84,113,141,169,197,225,253,281,309,337,365,392,

420,447,474,502,529,556,583,609,636,662,688,714,740,766,791,817,842,867,

891,916,940,964,988,1011,1035,1058,1080,1103,1125,1147,1169,1190,1211,

1232,1252,1272,1292,1312,1331,1350,1368,1386,1404,1422,1439,1456,1472,

1488,1504,1519,1534,1549,1563,1577,1590,1603,1616,1628,1640,1651,1662,

1673,1683,1693,1702,1711,1720,1728,1736,1743,1750,1756,1762,1768,1773,

1777,1782,1785,1789,1792,1794,1796,1798,1799,1799,1800,1799,1799,1798,

1796,1794,1792,1789,1785,1782,1777,1773,1768,1762,1756,1750,1743,1736,

1728,1720,1711,1702,1693,1683,1673,1662,1651,1640,1628,1616,1603,1590,

1577,1563,1549,1534,1519,1504,1488,1472,1456,1439,1422,1404,1386,1368,

1350,1331,1312,1292,1272,1252,1232,1211,1190,1169,1147,1125,1103,1080,

1058,1035,1011,988,964,940,916,891,867,842,817,791,766,740,714,688,662,

636,609,583,556,529,502,474,447,420,392,365,337,309,281,253,225,56};

/*********************************************************************/

//---Фаза B (+2*pi/3)---//

uint16_t sinB[192] = {1529,1514,1499,1483,1467,1450,1433,1416,1398,1380,

1362,1343,1324,1305,1286,1266,1245,1225,1204,1183,1161,1140,1118,1095,

1073,1050,1027,1003,980,956,932,908,883,858,833,808,783,757,732,706,680,

653,627,600,574,547,520,493,465,438,411,383,355,328,300,272,244,216,188,

160,131,103,75,47,18,9,37,65,94,122,150,178,206,234,262,290,318,346,374,

401,429,456,484,511,538,565,591,618,645,671,697,723,749,774,800,825,850,

875,900,924,948,972,996,1019,1042,1065,1088,1110,1132,1154,1176,1197,

1218,1239,1259,1279,1299,1318,1337,1356,1374,1392,1410,1428,1445,1461,

1478,1494,1509,1524,1539,1568,1581,1595,1608,1620,1632,1644,1655,1666,

1677,1687,1696,1705,1714,1723,1731,1745,1752,1758,1764,1769,1774,1779,

1783,1786,1790,1792,1795,1797,1798,1799,1799,1799,1799,1798,1797,1795,

1793,1791,1788,1784,1780,1776,1771,1766,1760,1748,1741,1733,1725,1717,

1708,1699,1690,1680,1670,1659,1529};

/**********************************************************************/

//---Фаза C (-2*pi/3)---//

uint16_t sinC[192] = {1599,1612,1624,1636,1648,1659,1670,1680,1690,1699,

1708,1717,1725,1733,1741,1748,1754,1760,1766,1771,1776,1780,1784,1788,

1791,1793,1795,1797,1798,1799,1799,1799,1799,1798,1797,1795,1792,1790,

1786,1783,1779,1774,1769,1764,1758,1752,1745,1738,1731,1723,1714,1705,

1696,1687,1677,1666,1655,1644,1632,1620,1608,1595,1581,1568,1554,1539,

1524,1509,1494,1478,1461,1445,1428,1410,1392,1374,1356,1337,1318,1299,

1279,1259,1239,1218,1197,1176,1154,1132,1110,1088,1065,1042,1019,996,

972,948,924,900,875,850,825,800,774,749,723,697,671,645,618,591,565,538,

511,484,456,429,401,374,346,318,290,262,234,206,178,150,122,94,65,37,9,

18,47,75,103,131,160,188,216,244,272,300,328,355,383,411,438,465,493,

520,547,574,600,627,653,680,706,732,757,783,808,833,858,883,908,932,956,

980,1003,1027,1050,1073,1095,1118,1140,1161,1183,1204,1225,1245,1266,

1286,1305,1324,1343,1362,1380,1398,1416,1433,1586,1586};

/**********************************************************************/

void sinDMA_PhaseA(void)

{

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

DMA_InitTypeDef DMA_struct;

DMA_StructInit(&DMA_struct);

DMA_struct.DMA_PeripheralBaseAddr =(uint32_t)&TIM1->CCR1;

DMA_struct.DMA_MemoryBaseAddr = (uint32_t)&sinA[0];

DMA_struct.DMA_DIR=DMA_DIR_PeripheralDST;

DMA_struct.DMA_BufferSize=192;

DMA_struct.DMA_PeripheralInc=DMA_PeripheralInc_Disable;

DMA_struct.DMA_MemoryInc=DMA_MemoryInc_Enable;

DMA_struct.DMA_PeripheralDataSize=DMA_PeripheralDataSize_HalfWord;

DMA_struct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;

DMA_struct.DMA_Mode=DMA_Mode_Circular;

DMA_Init(DMA1_Channel2,&DMA_struct);

DMA_Cmd(DMA1_Channel2, ENABLE);

TIM_DMACmd(TIM1,TIM_DMA_CC1, ENABLE);

}

void sinDMA_PhaseB(void)

{

DMA_InitTypeDef DMA_struct1;

DMA_StructInit(&DMA_struct1);

DMA_struct1.DMA_PeripheralBaseAddr =(uint32_t)&TIM1->CCR2;

DMA_struct1.DMA_MemoryBaseAddr = (uint32_t)&sinB[0];

DMA_struct1.DMA_DIR=DMA_DIR_PeripheralDST;

DMA_struct1.DMA_BufferSize=192;

DMA_struct1.DMA_PeripheralInc=DMA_PeripheralInc_Disable;

DMA_struct1.DMA_MemoryInc=DMA_MemoryInc_Enable;

DMA_struct1.DMA_PeripheralDataSize=DMA_PeripheralDataSize_HalfWord;

DMA_struct1.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;

DMA_struct1.DMA_Mode=DMA_Mode_Circular;

DMA_Init(DMA1_Channel3,&DMA_struct1);

DMA_Cmd(DMA1_Channel3, ENABLE);

TIM_DMACmd(TIM1,TIM_DMA_CC2, ENABLE);

}

void sinDMA_PhaseC(void)

{

DMA_InitTypeDef DMA_struct2;

DMA_StructInit(&DMA_struct2);

DMA_struct2.DMA_PeripheralBaseAddr =(uint32_t)&TIM1->CCR3;

DMA_struct2.DMA_MemoryBaseAddr = (uint32_t)&sinC[0];

DMA_struct2.DMA_DIR=DMA_DIR_PeripheralDST;

DMA_struct2.DMA_BufferSize=192;

DMA_struct2.DMA_PeripheralInc=DMA_PeripheralInc_Disable;

DMA_struct2.DMA_MemoryInc=DMA_MemoryInc_Enable;

DMA_struct2.DMA_PeripheralDataSize=DMA_PeripheralDataSize_HalfWord;

DMA_struct2.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;

DMA_struct2.DMA_Mode=DMA_Mode_Circular;

DMA_Init(DMA1_Channel6,&DMA_struct2);

DMA_Cmd(DMA1_Channel6, ENABLE);

TIM_DMACmd(TIM1,TIM_DMA_CC3, ENABLE);

}

  1. Следующим шагом необходимо записать прототипы функций в файл «sinDMA.h» (рис. 8), а также подключить заголовочный файл «sinDMA.h» в «main.c».

Рис. 8. Запись прототипов функций для генерации синусоидальных напряжений

  1. После того как все файлы были заполнены и подключены к «main.c», необходимо записать функции в основную функцию «main()» (рис. 9). Цикл «while(1)» в данной программе остается пустым.

Рис. 9. Содержание функции «main()»

  1. После написания кода программы, его необходимо скомпилировать. Для этого в панели инструментов нужно нажать «Build». В случае успешной компиляции в консоли появится надпись «BUILD SUCCESSFUL», а также будет указан размер программы. Если же в коде присутствуют ошибки, то в консоли будет указано, где именно находятся эти ошибки, а также появится надпись «BUILD FAILED».
  2. После завершения компиляции последним этапом станет загрузка рабочей программы в микроконтроллер. Для этого нужно через специальный кабель (удлинитель USB) подключить программатор, расположенный на лабораторном стенде, к компьютеру. После подключения в панели инструментов нажать «Download Code to Flash» и дождаться окончания загрузки. В случае удачной загрузки в консоли появятся надписи: «Erase: Done»; «Program: Done»; «Verify: Done». Если существуют проблемы с подключением платы к компьютеру, то появится надпись «Error: Connect failed, check config and cable connection». Необходимо проверить кабель, к которому подключено устройство.

Результаты программирования трехфазного генератора с синусоидальными напряжениями со сдвигом 120° даны на рис. 10.

Рис. 10. Результаты программирования сигналов AB и BC

Литература:

  1. Анучин А. С. Системы управления электроприводов: учебник для вузов / А. С. Анучин. – М.: Изд. дом МЭИ, 2015. – 373 с.
  2. Огородников И. Н. Микропроцессорная техника: введение в Cortex-M3: учеб. пособие / И. Н. Огородников. – Екатеринбург: изд-во Урал. Ун-та, 2015. – 116 с.
  3. Джозеф Ю. Ядро Cortex-M3 компании ARM. Полное руководство / Ю. Джозеф; пер. с англ. А. В. Евстифеева. – М.: Додэка-XXI, 2012. – 552 с.
Основные термины (генерируются автоматически): ENABLE, DMA, GPIO, GPIOA, файл, BUILD, содержание файла, панель инструментов, FAILED, заголовочный файл.


Похожие статьи

Программирование двухфазного генератора с синусоидальными напряжениями со сдвигом 90° на микроконтроллере STM32

Программирование линейного асинхронного двигателя (Z1 = 18) с трехфазной обмоткой индуктора с нулевым проводом

Программирование прямого и комплементарного ШИМ-сигналов с настройкой «мертвого времени» на микроконтроллере STM32

Программирование синусоидального и пилообразного сигналов с помощью цифро-аналогового преобразователя на микроконтроллере STM32

Программирование линейного асинхронного двигателя (Z1 = 6) с трехфазной обмоткой индуктора с нулевым проводом

Программирование линейного асинхронного двигателя (Z1 = 12) с трехфазной обмоткой индуктора с нулевым проводом

Моделирование синхронного неявнополюсного дугостаторного двигателя (Z1 = 12) с трехфазной обмоткой индуктора с нулевым проводом

Программирование синхронного неявнополюсного дугостаторного двигателя (Z1 = 6) с трехфазной обмоткой индуктора с нулевым проводом

Программирование синхронного явнополюсного дугостаторного двигателя (Z1 = 6) с трехфазной обмоткой индуктора с нулевым проводом

Моделирование синхронного явнополюсного дугостаторного двигателя (Z1 = 12, 2p=4) с трехфазной обмоткой индуктора с нулевым проводом

Похожие статьи

Программирование двухфазного генератора с синусоидальными напряжениями со сдвигом 90° на микроконтроллере STM32

Программирование линейного асинхронного двигателя (Z1 = 18) с трехфазной обмоткой индуктора с нулевым проводом

Программирование прямого и комплементарного ШИМ-сигналов с настройкой «мертвого времени» на микроконтроллере STM32

Программирование синусоидального и пилообразного сигналов с помощью цифро-аналогового преобразователя на микроконтроллере STM32

Программирование линейного асинхронного двигателя (Z1 = 6) с трехфазной обмоткой индуктора с нулевым проводом

Программирование линейного асинхронного двигателя (Z1 = 12) с трехфазной обмоткой индуктора с нулевым проводом

Моделирование синхронного неявнополюсного дугостаторного двигателя (Z1 = 12) с трехфазной обмоткой индуктора с нулевым проводом

Программирование синхронного неявнополюсного дугостаторного двигателя (Z1 = 6) с трехфазной обмоткой индуктора с нулевым проводом

Программирование синхронного явнополюсного дугостаторного двигателя (Z1 = 6) с трехфазной обмоткой индуктора с нулевым проводом

Моделирование синхронного явнополюсного дугостаторного двигателя (Z1 = 12, 2p=4) с трехфазной обмоткой индуктора с нулевым проводом

Задать вопрос