Project

General

Profile

PWM — хотелки

Added by mouse over 10 years ago

Первое, что хочется увидеть в будущих версиях PWM — это выбор условия для выработки прерывания:

  1. По достижению CNTVAL значения периода CNT (при работе в режиме increment, 00)
  2. По достижению CNTVAL нулевого значения (при работе в режиме decrement, 01)
  3. По достижению CNTVAL значения CMPx (в любом режиме)
  4. По смене направления отсчёта (режим up-down, 10)

Для работы с шаговым двигателем нужен первый вариант — выработка прерывания по периоду. Пока попробую так. В работе задействованы все четыре канала, т.ч. воспользоваться одним из каналов для генерации по CMPx = CNT не получится.

По мере продвижения с алгоритмом, буду дописывать свои наблюдения.


Replies (26)

RE: PWM — хотелки - Added by mouse over 10 years ago

Не получается включить PWM:

    GPIOC->BPS  = 0x0F0; // PWM0..3
    // Init PWM
#define SYSTEM_FREQUENCY 80  // MHz
#define ISR_FREQUENCY    10  // kHz

    PWM->CNT = SYSTEM_FREQUENCY*1000000*(0.001*ISR_FREQUENCY)/2;
    PWM->CMPCH0 = PWM->CNT - 1;
    PWM->CMPCH1 = PWM->CNT - 1;
    PWM->CMPCH2 = PWM->CNT - 1;
    PWM->CMPCH3 = PWM->CNT - 1;

    PWM_InitStructure.Single_mode_en = 0;
    PWM_InitStructure.Change_period_en = 1;
    PWM_InitStructure.Select_mode = 00;
    PWM_InitStructure.Irq_full_en = 1;
    PWM_InitStructure.CH0_en = 1;
    PWM_InitStructure.CH1_en = 1;
    PWM_InitStructure.CH2_en = 1;
    PWM_InitStructure.CH3_en = 1;
    PWM_InitStructure.Set_na_off_lvl_CH0 = 0;
    PWM_InitStructure.Set_na_off_lvl_CH1 = 0;
    PWM_InitStructure.Set_na_off_lvl_CH2 = 0;
    PWM_InitStructure.Set_na_off_lvl_CH3 = 0;
    PWM_InitStructure.Irq_CH0_en = 1;
    PWM_InitStructure.Irq_CH1_en = 0;
    PWM_InitStructure.Irq_CH2_en = 0;
    PWM_InitStructure.Irq_CH3_en = 0;
    PWM_InitStructure.Set_a_on_lvl_CH0 = 1;
    PWM_InitStructure.Set_a_on_lvl_CH1 = 1;
    PWM_InitStructure.Set_a_on_lvl_CH2 = 1;
    PWM_InitStructure.Set_a_on_lvl_CH3 = 1;

    pwm_init(&PWM_InitStructure);
После выполнения pwm_init() регистр PWMxCR имеет нулевое значение. Попытался заполнить его, как в ассемблерном примере:
    PWM->PSC = 0x0;
    PWM->CR = 0x00100104;

    uart_send_str("\r\nPWMxINT=", UART3);
    uart_send_str(itoa(PWM->INT, 16), UART3);
    uart_send_str(" PWMxCR=", UART3);
    uart_send_str(itoa(PWM->CR, 16), UART3);
    uart_send_str("\r\n", UART3);
Результат тот же.
Как правильно готовить PWM?

RE: PWM — хотелки - Added by krufter_multiclet over 10 years ago

Странно, что регистр управления нулевой, посмотрю библиотеку(какой даты у вас библиотека pwm, должна быть от 15.01.2013).
Вот этой программой крутил двигатель для квадрокоптера через регулятор:

//Pwm test
#include <HDL51001_ccf.h>
#include <pwm.h>

void pause(unsigned int a)
{
  unsigned int i;
  for(i=a;i>0;i--);
  for(i=a;i>0;i--);
}

void main()
{
    PWM_InitTypeDef PWM_InitStructure;

    GPIOC->BPS = 0x00000010; //alternative port function for pwm

    PWM->CNT = 0x00000FFFF;
    PWM->CMPCH0 = 0x0000F2FA;
    PWM->PSC = 0x00000018;
    PWM_InitStructure.Select_mode = 1;
    PWM_InitStructure.CH0_en = 1;
    PWM_InitStructure.Set_a_on_lvl_CH0 = 1;

    pwm_init(&PWM_InitStructure);

    GPIOD->DIR = 0x1000;
    GPIOD->OUT = 0x1000;

    pause(1500000);
    //wait 2 sec

    GPIOD->DIR = 0x0000;
    GPIOD->OUT = 0x0000;

    //PWM->CMPCH0 = 0x0000F2FA; // 0.75 ms

    pause(1500000);
    pause(1500000);
    pause(1500000);

    PWM->CMPCH0 = 0x0000EC77; // 1.125 ms        
}
libpwm.a (6.09 KB) libpwm.a библиотека pwm

RE: PWM — хотелки - Added by mouse over 10 years ago

Файл pwm_init.o с точностью до md5sum совпадает с тем, что в SDK.
Что-то всё равно не выходит. Более того, я посмотрел на все регистры после их установки. Вообще всё по нулям:

PWMxINT=0 PWMxCR=0 PWMxPSC=0 PWMxCNT=0 PWMxCMPCH0=0

Адрес PWM_BASE, вроде, верный: 0x0xC0012000.

RE: PWM — хотелки - Added by krufter_multiclet over 10 years ago

ШИМ должен работать, однако регистры на чтение не доступны. Предложения по модернизации текущей версии ШИМ ещё принимаются.

RE: PWM — хотелки - Added by mouse over 10 years ago

Хочется иметь раздельные ШИМ с одним или двумя счётками на каждый, чтобы можно было независимо управлять несколькими устройствами с различным периодом. Сейчас период на четыре счётчика один. Например, двумя ШД или ШД и подстветкой с ШИМ уже не поуправляешь.
В целом, ШИМ работает, продолжаю экспериментировать.

RE: PWM — хотелки - Added by mouse over 10 years ago

Вообще, было бы неплохо добавить побольше автоматизированных тестов.
Например, сравнивать вывод и изменение состояния модели (регистры, флаги, переходы) и реального железа (через jtag) пошагово. И проверять тестами контрольные точки и там, и там, дабы исключить возможность ошибок и в самой модели, кои тоже имели место быть.
Можно ещё всякого рода периферию "закольцевать" на свои же GPIO (или GPIO соседней платы) или же периферийные входы, например, один SPI завернуть на другой SPI. Разбавить всё это тестами с известными ошибками.

RE: PWM — хотелки - Added by krufter_multiclet over 10 years ago

Примем к сведению постараемся выпустить хороший продукт, без старых ошибок. ШИМ постараемся модернизировать с учётом ваших пожеланий, поскольку это действительно необходимо.

RE: PWM — хотелки - Added by mouse over 10 years ago

    PWM->CNT = 0x00000FFFF;
    PWM->CMPCH0 = 0x0000F2FA;
    PWM->PSC = 0x00000018;

    //PWM->CMPCH0 = 0x0000F2FA; // 0.75 ms

    PWM->CMPCH0 = 0x0000EC77; // 1.125 ms

Есть ли какие-то формуля для расчёта периода (относительно частоты процессора)?
Вроде как получается:

(1.125-0.75)/(0xF2FA-0xEC77)/1000 = 225^10-9 — это сколько секунд в одном изменении счётчика.

По идее, надо бы домножить полученное значение на PSC, но разница между 80 MHz и 4.45MHz в 18 раз, а значение предделителя 0x18 или 24, т.е. порядка 106 MHz. Опечатка или я не так считаю?

RE: PWM — хотелки - Added by mouse over 10 years ago

Ещё замечено, что в HDL50001_systimer.h у прототипа initSysTimer() первый аргумент объявлен как bool. Сам тип bool нигде не объявлен и при компиляции выдаёт ошибку.

RE: PWM — хотелки - Added by mouse over 10 years ago

Ещё какие-то непонятки при линковке перегруженных weak-символов. Линковщик без ошибок просто выходит, не создавая файла. Пример в аттаче.

make # сгенерирует image.bin
make clean all CFLAGS="-DTEST1" # пустой вывод линковщика

Ещё линкер не печатает имя дублирующихся функций:

main.o: (.text+0x13d8): multiple definition of '(null)'
crt0.o: (.data+0x80): first defined here

RE: PWM — хотелки - Added by mouse over 10 years ago

Удалось получить циклограмму полушага для open-loop'a. Попробую подцепить драйвер.

RE: PWM — хотелки - Added by krufter_multiclet over 10 years ago

Формула для расчёта периода ШИМ в документации актуальна. Для 80МГц период будет 12,5 нс. Для перевода из тактов в реальное время необходимо такты процессора умножить на 12,5 нс.

RE: PWM — хотелки - Added by mouse over 10 years ago

Тогда получается, что в примере с PSC = 0x18 опечатка? Должно быть 0x12 или же значения CMP в мс будут другими.

RE: PWM — хотелки - Added by mouse over 10 years ago

Только вот период самого ШИМ как-то не хочет изменяться. Пробовал менять значение CMPCHx от 1/16 PRD до половины PRD. Картинка не меняется. В циклограмме имеем строенный импульс по 100 мкс без признаков изменения скважности у каждого из трёх.

RE: PWM — хотелки - Added by krufter_multiclet over 10 years ago

mouse wrote:

Тогда получается, что в примере с PSC = 0x18 опечатка? Должно быть 0x12 или же значения CMP в мс будут другими.

В примере всё верно, PSC учитывается в формуле в документации на процессор, стр.79.

RE: PWM — хотелки - Added by mouse over 10 years ago

Тогда я не очень понимаю, как былы получены значения 0.75 ms и 1.125 ms для:
CNT = 0xFFFF
PSC = 0x18
CMP1 = 0xF2FA
CMP2 = 0xEC77

Если считать по формуле, то получается:

(0xFFFF - 0xF2FA) * 12.5 * (0x18 + 1) / 10^9 = 3333 * 300 * 10^-9 = 1.042 ms
(0xFFFF - 0xEC77) * 12.5 * (0x18 + 1) / 10^9 = 5000 * 300 * 10^-9 = 1.563 ms

Если же считать не по приведённой формуле и с учётом, что 0x18 — это просто 18:

(0xFFFF - 0xF2FA) * 12.5 * 0x12 / 10^9 = 3333 * 225 * 10^-9 = 0.75 ms
(0xFFFF - 0xEC77) * 12.5 * 0x12 / 10^9 = 5000 * 225 * 10^-9 = 1.125 ms

RE: PWM — хотелки - Added by krufter_multiclet over 10 years ago

Почти всё верно(только надо учесть, что 0x18 это опечатка и это просто 18 или 0x12, ну и далее расчёт по формуле с учётом PSC + 1), пример который быстро добавил был много раз модифицирован при работе с двигателем, комментарии поправить не успел.

RE: PWM — хотелки - Added by mouse over 10 years ago

Ещё есть одно предложение, но сам я этой фичей только единожды игрался и то — по ошибке :)
Добавить поддержку фазового сдвига, чтобы разные каналы начинали выдавать импульсы с заданным сдвигом. Сейчас начало каждого канала синхронизированно друг с другом. Фазовый сдвиг применим для управления трёхфазными преобразователями.

RE: PWM — хотелки - Added by trott over 10 years ago

Поддерживаю предложение "Добавить поддержку фазового сдвига". Можно организовать с помощью старта канала с некоторой задержкой.

RE: PWM — хотелки - Added by mouse over 10 years ago

Для наглядности:

EPWM2: PHSDIR = TB_DOWN (отсчёт "вниз" в момент синхронизации)
EPWM3: PHSDIR = TB_UP
Из документации spru791f.pdf (стр. 89).

RE: PWM — хотелки - Added by krufter_multiclet over 10 years ago

Ну т.е. в результате мы должны увидеть ШИМ с 4-мя регистрами для счётчиков каналов и с 4-мя регистрами для счётчиков задержки фазы. Реализовать EPWM как в TMS сможем, только по спецзаказу. Сейчас пока постараемся учесть ваши пожелания и как будет окончательная версия напишем что получилось.

RE: PWM — хотелки - Added by trott over 10 years ago

Если учесть RED и FED, которые есть на картинке и о которых mouse писал в http://multiclet.com/community/boards/4/topics/334?r=344#message-344 то регистров может понадобиться больше. (У TM для этого 3 регистра DBCTL, DBRED, DBFED). Пока я обхожусь аппаратными драйверами (IR2132) в электрической схеме, но такие задержки на передней и задней части фронта непосредственно в контроллере выглядят привлекательными.

RE: PWM — хотелки - Added by krufter_multiclet over 10 years ago

Т.е. по 3 регистра на каждый канал, получится 8 регистров под счётчики и ещё 12 под дополнительные регистры. DBCTL то какую функцию выполняет?
Прерывания, которые просили в начале темы все должны будут работать.

RE: PWM — хотелки - Added by trott over 10 years ago

судя по фигуре 2-28(стр 52) в http://www.ti.com/lit/ug/spru791f/spru791f.pdf включает задержки RED и FED

RE: PWM — хотелки - Added by trott over 10 years ago

немного сложнее: регистр состоит из трех значений: выбор канала, включение задержки RED и FED, контроль полярности.

(1-25/26)