Jump to content
Юра Махович

Attiny13 - Сон и ШИМ

Recommended Posts

Posted (edited)

Доброго времени суток!
Друг попросил сделать эму некий аппарат: пищалку, которая издает звук с определенным периодом.
Пример работы: сигнал 2 секунды, тишина 1 минуту, потом опять по новой.


Так вот, программу написал, и вроде как даже работает, но как-то не стабильно..
Иногда пропустит один цикл, иногда (почти всегда) после нескольких минут вообще перестает работать.
Использую сон ради экономии батареи, т.к. устройство автономно.

Генерирую ШИМ на ноге PB0. переключатели подсоединены к PB3 PB4.

Скрытый текст

 


#define F_CPU 128000UL
#include <avr/io.h>
#include <avr/wdt.h> // здесь организована работа с ватчдогом
#include <avr/sleep.h> // здесь описаны режимы сна
#include <avr/interrupt.h> // работа с прерываниями
#include <util/delay.h>

volatile unsigned int count = 0;
//volatile bool flag = false;
unsigned int dil = 7;

void sleep();
void beep();

ISR (WDT_vect) {

      // if (++count>=dil) {
      //   count=0;
      //   flag=true;
      //   beep();
      // }

      WDTCR |= _BV(WDTIE); // разрешаем прерывания по ватчдогу. Иначе будет резет.
}

 // запускаем ШИМ, издаем звук, останавливаем ШИМ
void beep(){
        PORTB &= ~(1 << PB0);
        TCCR0A = 0b11000011; //10 11 00 11 режим ШИМ, неинверсный сигнал на выходе OC0A, инверсный - на выходе OC0B
        TCCR0B = 2; //00000010 предделитель тактовой частоты CLK/8
       
        OCR0A=1;

        _delay_ms(20000);

        OCR0A=0;
        TCCR0A = 0; 
        TCCR0B = 0; 
        PORTB &= ~(1 << PB0);
}

void sleep(){
        //инициализация ватчдога
        wdt_reset(); // сбрасываем
        wdt_enable(WDTO_2S); // разрешаем ватчдог 1 сек
        WDTCR |= _BV(WDTIE); // разрешаем прерывания по ватчдогу. Иначе будет резет.
        sei(); // разрешаем прерывания
        
        set_sleep_mode(SLEEP_MODE_PWR_DOWN); // если спать - то на полную
}

int main() {

  	// в зависимости от конфигурации переключателей, изменяем период.
      switch ((PINB & 1100)>>2)
      {
        case 0b00:
          dil=6; //кажые 12 секнуд
          break;

        case 0b10:
          dil= 450;  // 15хв
          break;

        case 0b11:
          dil= 600;  // 20хв
          break;

        case 0b01:
          dil= 750;  // 25хв
          break;

        default:
          break;
      }


      DDRB |= (1 << PB0)|(1 << PB3)|(1 << PB4);//DDRB = _BV(PB0);
      PORTB &= ~(1 << PB0);

      TCNT0=0; // начальное значение счётчика
      OCR0A=0; // регистр совпадения A
      OCR0B=0; // регистр совпадения B

      sleep();
      
      while(1) {
                sleep_enable(); // разрешаем сон
                sleep_cpu(); // спать!
                if (++count>=dil) {
                  beep();
                  //flag=false;
                  count=0;
                }
        }
}

 

Прошу помогите найти ошибку, а то я уже не знаю что тут не так..

Edited by Юра Махович

Share this post


Link to post
Share on other sites
4 часа назад, Юра Махович сказал:

разрешаем прерывания по ватчдогу. Иначе будет резет.

а вотчдог то тут зачем??? совершенно непонятно!!! И кто у тебя процессор будит ото сна можно пояснить?

Думаю развернутые ответы на эти два вопроса решат ваши проблемы.

Share this post


Link to post
Share on other sites
3 часа назад, Юра Махович сказал:

_delay_ms(20000);

Это 20 секунд

3 часа назад, Юра Махович сказал:

сигнал 2 секунды

 

Share this post


Link to post
Share on other sites

Литиевые батарейки Fanso для систем телеметрии и дистанционного контроля

Системы телеметрии находят все более широкое применение во многих отраслях на промышленных и коммунальных объектах. Требования, предъявляемые к условиям эксплуатации приборов телеметрии и, как следствие, источников питания для них, могут быть довольно жесткими. Fanso предоставляет широкую линейку продукции, рассчитанной на различные условия эксплуатации, что позволяет подобрать батарейку для каждого конкретного применения, в том числе и для устройств телеметрии.

Подробнее

7 минут назад, ruhi сказал:

а вотчдог то тут зачем??? совершенно непонятно!!! И кто у тебя процессор будит ото сна можно пояснить?

Собака и будит.

Share this post


Link to post
Share on other sites
20 минут назад, Геннадий сказал:

Собака и будит.

я бы убедился тогда что из сна оно на ресет не уходит, а только прерывание выполняет.

Потом, слип и ватчдог могут состояние ног как то поменять - там очень внимательно надо пдф-ки читать, и даже то что кажется понятным проверять практическими экспериментами.

Поэтому их надо по отдельности отлаживать, а лучше вообще будить таймером, например.

Share this post


Link to post
Share on other sites
                     

Приглашаем на вебинар Решения для построения ультразвуковых счетчиков жидкостей и газов на базе MSP430

Компэл совместно с Texas Instruments 23 октября 2019 приглашают на вебинар, посвященный системам-на-кристалле для построения ультразвуковых расходомеров жидкостей и газов на базе ядра MSP430. Вебинар проводит Йоханн Ципперер – эксперт по ультразвуковым технологиям, непосредственно участвовавший в создании данного решения. На вебинаре компания Texas Instruments представит однокристальное решение, позволяющее создавать точные недорогие счетчики жидкостей и газов.

Подробнее...

Posted (edited)

Когда-то делал подобную хрень - просто вел подсчет сбросов от WDT, так и отсчитывал долгие интервалы. С прерываниями от WDT и не заморачивался никогда.

Edited by ARV

Share this post


Link to post
Share on other sites
Posted (edited)
2 часа назад, ARV сказал:

Когда-то делал подобную хрень - просто вел подсчет сбросов от WDT, так и отсчитывал долгие интервалы. С прерываниями от WDT и не заморачивался никогда.

Как вы так сделали? У меня по сути тоже идёт подщет, в прерывании по сути ничего и не происходит. Но проблема в том, что оно как-то не стабильно работает, пропускает период время от времени, иногда вообще зависает...  Думаю может после успешного генерирования сигнала делать резет, чтоб оно хоть как-то работало .

Edited by Юра Махович

Share this post


Link to post
Share on other sites
28 минут назад, ARV сказал:

Проект, где я это делал, можно скачать здесь: https://radiokot.ru/circuit/digital/game/14/

Я так понимаю собака жмёт резет каждую секунду, записывая количество включений в необнуляжмую память ?

Share this post


Link to post
Share on other sites

Смысл использования собаки в данном проекте?

Share this post


Link to post
Share on other sites
Только что, Юра Махович сказал:

собака жмёт резет каждую секунду, записывая количество включений в необнуляжмую память ?

Ну как-то так, да.

Только что, BARS_ сказал:

Смысл использования собаки в данном проекте?

Экономия электроэнергии

Share this post


Link to post
Share on other sites

Тогда надо проверить отдельно собаку. Взять сделать простую прошивку, которая будет просто мигать диодом при пробуждении МК. И почему в цикле условие стоит после отправки МК в спячку?

 

Share this post


Link to post
Share on other sites
Posted (edited)
20 минут назад, BARS_ сказал:

Тогда надо проверить отдельно собаку.

Пример с морганием светодиода работает как надо, в этом и нюанс..

20 минут назад, BARS_ сказал:

И почему в цикле условие стоит после отправки МК в спячку?

МК засыпает, собака его будит, он прибавляет единицу в переменную, и когда она станет больше или равно необходимой, происходит beep(); и обнуляется счётчик. Собственно. ничего бы не изменилось если условия было до сна, т.к. оно находиться в бесконечном цикле.

Edited by Юра Махович

Share this post


Link to post
Share on other sites

beep у вас по коду 20 секунд, а вы пишите 2. Что-то тут не так.

Share this post


Link to post
Share on other sites
7 минут назад, Юра Махович сказал:

он прибавляет единицу в переменную

Да. Но ведь логичнее это делать в прерывании по собаке

Share this post


Link to post
Share on other sites
Только что, BARS_ сказал:

Да. Но ведь логичнее это делать в прерывании по собаке

Я и делал,  еще остались закоментированные строки.

 

3 минуты назад, ARV сказал:

20 секунд, а вы пишите 2

Меня тоже это смутило, но пищит оно 2 секунды, я сам до конца не понимаю как так.
Период поставил 3 секунды, собаку завел на 500мс.

Как мне кажеться прерывания срабатывают во время задержки на генерацию звука, от чего она прекращается.. Оно некоторое время работает как надо, но потом оно зависает примерно на минуту две, и опять начинает нормально работать, и так по кругу...

Скрытый текст

IMG_20190403_145801.thumb.jpg.c905d1bc45ea3a62be5161bcf86ad021.jpgIMG_20190403_145704.thumb.jpg.f29cd6c52d2763c0a55892b8738b82c6.jpg

 

Share this post


Link to post
Share on other sites
3 минуты назад, Юра Махович сказал:

Меня тоже это смутило, но пищит оно 2 секунды

Все просто. В настройках проекта неправильно задана частота ядра, вот он и считает криво задержку.

 

5 минут назад, Юра Махович сказал:

Как мне кажеться прерывания срабатывают во время задержки на генерацию звука

Ну так надо собаку отключать перед началом генерации и включать после окончания.

Share this post


Link to post
Share on other sites
3 минуты назад, BARS_ сказал:

Ну так надо собаку отключать перед началом генерации и включать после окончания.

А как правильно ее выключать? А то я пробовал, и оно вообще не работает...

Share this post


Link to post
Share on other sites

Переписал программу, взяв за основу проект @ARV `а, и все так-же, некоторое время работает нормально, потом опять.. Поставил период 10сек. 

Код:

Скрытый текст

#define F_CPU 600000UL
#include <avr/io.h>
#include <avr/wdt.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include <avr/sleep.h>

static uint16_t	__attribute__((section(".noinit"))) next_timeout;

static void __attribute__((naked, used, section(".init2"))) on_reset(void){
	if(MCUSR & _BV(PORF)){
		// переменные инициализируются только при включении питания!!!
		next_timeout = 1;

	}
	// действия при любом сбросе:
	MCUSR = 0;					// подавление флагов
					// холостой вызов генератора случайных чисел
	wdt_enable(WDTO_1S);		// запуск WDT
}

/** БИП
 * Функция издает писк заданной длительности.
 * @param ms10 длительность звука в десятках миллисекунд
 */
static void beep(uint8_t ms10){
	// запуск таймера на генерацию меандра
	DDRB = _BV(PB0);
	// TCCR0A = _BV(COM0A1) | _BV(COM0B0) | _BV(COM0B1) | _BV(WGM01) | _BV(WGM00);
	// TCCR0B = _BV(CS01);

  PORTB &= ~(1 << PB0);
  TCCR0A = 0b10000011; //10 11 00 11 режим ШИМ, неинверсный сигнал на выходе OC0A, инверсный - на выходе OC0B
  TCCR0B = 2;


	// требуемая задержка
	for(; ms10; ms10--){
		_delay_ms(10);
		wdt_reset();
	}
	// выключение таймера

	TCCR0B = 0;
	TCCR0A = 0;
	DDRB = 0;
	PORTB = 0;

}

/// главная функция программы
int __attribute__((OS_main)) main(void){
	// инициализация периферии

	OCR0A = 127;
	// OCR0B = 127;

	// обработка СБРОСА
	if(next_timeout){
		// пока очередной интервал не истек - не делается ничего
		next_timeout--;
	} else {
		// когда интервал истек - воспроизводится один из 8 возможных сигналов
		
    beep(200);
    
    // int dil = 0;
    //  switch ((PINB & 1100)>>2)
    //   {
    //     case 0b00:          
    //       beep(100);
    //       dil=8; //кожні 2 секнуди
    //       break;

    //     case 0b10:
    //       dil= 450;  // 15хв
    //       break;

    //     case 0b11:
    //       dil= 600;  // 20хв
    //       break;

    //     case 0b01:
    //       dil= 750;  // 25хв
    //       break;

    //     default:
    //       break;
    //   }



		next_timeout = 10;//dil;
	}
	// отработав событие сброса, МК усыпляется в самый экономичный режим
	set_sleep_mode(SLEEP_MODE_PWR_DOWN);
	sleep_mode();
}

 

Осциллограмма:

Скрытый текст

IMG_20190403_183804.thumb.jpg.615f68a0d621cf3570fb05646305df2d.jpg

 

Share this post


Link to post
Share on other sites

И питается схема как? Ощущение такое, что питание пропадает или проваливается.

Share this post


Link to post
Share on other sites
Posted (edited)
28 минут назад, Геннадий сказал:

В Вашей схеме вывод Reset подтянут к +Uпит.

Нет, она не подключена. (Во время теста, была подключена к usbASP свистку, как и все остальное).

Питается схема все от того же свистка (во время теста).

Странно, отключил провода, и запустил напрямую от батареи, все работает замечательно... Видимо в нем и была вся проблема.

P.S. Какие значение нужно указать в DDRB чтобы PB3 PB4 стали входами ?

Edited by Юра Махович

Share this post


Link to post
Share on other sites
16 минут назад, Юра Махович сказал:

Какие значение нужно указать в DDRB чтобы PB3 PB4 стали входами ?

Нули в соответствующих битах сделают пины входами. После сброса они все входы.

Share this post


Link to post
Share on other sites

Поставил период на 15 минут (900 секунд), а по факту получил 17 с половиной минут. Есть ли какой-то способ повысить точность отсчета ?

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Similar Content

    • By Павел Лопатин
      Добрый день!
      Подскажите, пожалуйста, можно ли вынести переменный резистор 16K1-B10K, L20KC, 10 кОм с ШИМ регулятора на отдельную плату? 
      Какие провода лучше использовать? На какое расстояние можно вынести (длина провода) и изменятся ли от этого характеристики? (все-таки, как я понимаю, появится дополнительное сопротивление от провода)
      ШИМ покупной в RDC2-0024 - фото и схема в аттаче
      DOC002726141.pdf
    • By Kirillius Labutin
      Добрый день!
      Имеется готовый лазерный модуль с драйвером (стабилизатор тока и, наверное, напряжения). 
      Хочу регулировать яркость лазера с помощью ШИМ с МК, гугл сказал что лучший вариант - шунтирование лазера. Но драйвер устроен таким образом, что в нём с питанием напрямую не связан ни "+" ни земля лазера. Набросал такую схемку, чтобы реализовать это через оптопару.

      Внимание, вопрос)
      1. Заработает ли такая схема?
      2. Какой посоветуете транзистор Q1 и оптопару? Макс. напряжение в цепи - 5В, ток - 0.5А Я думаю что-нибудь вроде IRLL014TRPBF
      3. Какой выбрать номинал резистора R1 для разряда Q1? Частота ШИМ планируется в районе 1кгц.
    • By SigmA
      Доброго времени суток всем. Для своей новой жены захотелось мне сделать сердечко на atmega8, с кучей эффектов и т.д. Так вот, разные мигалки-переключалки св-диодов я написал, использовал delay. Но мне этого стало мало и я решил подключить шим программный. Отдельно от всей программы шим работает как нужно, так же и переключалки работают отдельно от шим, но вот когда я соединяю это всё воедино то работает только шим и не переходит дальше по коду.Я так понимаю, что таймеры и delay вместе работать не могут? Но если могут, то как?
      #include <mega8.h> #include <delay.h> #define GREEN PORTC.1=PORTC.2=PORTC.3=PORTC.0 unsigned char i, s,; unsigned char green=255; unsigned char green_b; //переменные, для буферизации значений скважности ШИМ unsigned char count; //переменная- счетчик вызовов обработчика прерываний unsigned char temp=1; interrupt [TIM0_OVF] void timer0_ovf_isr(void) { count++; if (count == 0){ //если счетчик переполнился и принял значение 0 green_b = green; GREEN = 1; } if (green_b == count) { GREEN = 0;} } void main(void) { PORTC=0x0F; //конфигурируем порт DDRC=0x0F; TCCR0=0x01; //настраиваем таймер TCNT0=0x00; TIMSK=0x01; //разрешаем генерацию прерывания по переполнению таймера T0 #asm("sei") //глобально разрешаем прерывания while (1) { for (i=0;i<3;i++) { if (temp==1) {if (green < 255) green += 1; else temp = 2;} if (temp==2) {if (green > 0) green -= 1; else temp = 1;} delay_ms(1000); }; s=7; for (i=0;i<=s;i++) { PORTC.0=1; delay_ms(200); PORTC.0=0; PORTC.1=1; delay_ms(200); PORTC.1=0; PORTC.2=1; delay_ms(200); PORTC.2=0; PORTC.3=1; delay_ms(200); PORTC.3=0; } for (i=0;i<=s;i++) { PORTC.3=1; delay_ms(200); PORTC.3=0; PORTC.2=1; delay_ms(200); PORTC.2=0; PORTC.1=1; delay_ms(200); PORTC.1=0; PORTC.0=1; delay_ms(200); PORTC.0=0; } for (i=0;i<=s;i++) { PORTC.3=1; delay_ms(200); PORTC.2=1; delay_ms(200); ; PORTC.1=1; delay_ms(200); PORTC.0=1; delay_ms(200); PORTC.3=0; delay_ms(200); PORTC.2=0; delay_ms(200); PORTC.1=0; delay_ms(200); PORTC.0=0; delay_ms(200); } for (i=0;i<=s;i++) { PORTC.0=1; delay_ms(200); PORTC.1=1; delay_ms(200); ; PORTC.2=1; delay_ms(200); PORTC.3=1; delay_ms(200); PORTC.0=0; delay_ms(200); PORTC.1=0; delay_ms(200); PORTC.2=0; delay_ms(200); PORTC.3=0; delay_ms(200); } for (i=0;i<=s;i++) { PORTC=0x01; delay_ms(200); PORTC=0x02; delay_ms(200); PORTC=0x04; delay_ms(200); PORTC=0x08; delay_ms(200); PORTC=0x09; delay_ms(200); PORTC=0x0A; delay_ms(200); PORTC=0x0C; delay_ms(200); PORTC=0x0D; delay_ms(200); PORTC=0x0E; delay_ms(200); PORTC=0x0F; delay_ms(200); PORTC=0x07; delay_ms(150); PORTC=0x0B; delay_ms(200); PORTC=0x03; delay_ms(250); PORTC=0x05; delay_ms(300); PORTC=0x09; delay_ms(350); PORTC=0x01; delay_ms(400); PORTC=0x02; delay_ms(200); PORTC=0x04; delay_ms(200); PORTC=0x08; delay_ms(200); PORTC=0x00; delay_ms(200); } for (i=0;i<=5;i++) { PORTC=0x0f; delay_ms(100); PORTC=0x00; delay_ms(100); PORTC=0x0f; delay_ms(100); PORTC=0x00; delay_ms(100); PORTC=0x0f; delay_ms(100); PORTC=0x00; delay_ms(150); PORTC=0x0f; delay_ms(300); PORTC=0x00; delay_ms(100); PORTC=0x0f; delay_ms(300); PORTC=0x00; delay_ms(100); PORTC=0x0f; delay_ms(300); PORTC=0x00; delay_ms(150); PORTC=0x0f; delay_ms(100); PORTC=0x00; delay_ms(100); PORTC=0x0f; delay_ms(100); PORTC=0x00; delay_ms(100); PORTC=0x0f; delay_ms(100); PORTC=0x00; delay_ms(1000); } } }  
    • By mr_smit
      Вынес то что не получается в упрощенной форме в отдельный проект. Среда разработки CooCox 1.7.8, микроконтроллер STM32F103C8T6.
      Нужно раз в ~100 мсек формировать на ножке МК, например,такую последовательность:

      Стартовую длительность формирует таймер, в первом же своем прерывании по совпадению активирует DMA и дальше уже DMA по запросу таймера загружает значение CCR из массива. Что то похожее на управление светодиодами WS2812B. То что я сочинил выдает на пин:

      Но только один раз при первом вызове. При последующих вызовах данные из массива выдаются без первоначальной длительности в 150 мкс.
      Не могу найти ошибку. 
       
      #include <stm32f10x.h> #include <stm32f10x_conf.h> #include <stm32f10x_gpio.h> #include <stm32f10x_rcc.h> #include <stm32f10x_tim.h> #include <stm32f10x_dma.h> GPIO_InitTypeDef PIN; TIM_TimeBaseInitTypeDef TIM_Config; TIM_OCInitTypeDef TIM_OCConfig; DMA_InitTypeDef DMA_Setting; uint8_t Test_Buf[] = {15,30,30,30,15}; void delay_ms(uint32_t ms) { volatile uint32_t nCount; RCC_ClocksTypeDef RCC_Clocks; RCC_GetClocksFreq (&RCC_Clocks); nCount = (RCC_Clocks.HCLK_Frequency/10000)*ms; for (; nCount != 0; nCount--); } void Init_GPIO(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); PIN.GPIO_Pin = GPIO_Pin_11; // PA11 -> TIM1 Channel4 PIN.GPIO_Mode = GPIO_Mode_AF_PP; PIN.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &PIN); } void Init_TIM_Transmit(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); TIM_TimeBaseStructInit(&TIM_Config); // настройки по дефолту TIM_Config.TIM_Prescaler = 72-1; // Запускаем таймер на тактовой частоте 1 MHz (72000000/(72-1)) TIM_Config.TIM_Period = 150-1; // Период - 150 мкс TIM_Config.TIM_ClockDivision = 0; // частоту дополнительно не делим TIM_Config.TIM_CounterMode = TIM_CounterMode_Up; // считаем вверх TIM_TimeBaseInit(TIM1, &TIM_Config); // Инициализируем TIM1 TIM_OCStructInit(&TIM_OCConfig); // настройки по дефолту TIM_OCConfig.TIM_OCMode = TIM_OCMode_PWM1; // Конфигурируем как ШИМ (выравнивание по границе) TIM_OCConfig.TIM_OutputState = TIM_OutputState_Enable; // Включаем выход TIM_OCConfig.TIM_Pulse = 0; // CCR до старта пока нулевой TIM_OCConfig.TIM_OCPolarity = TIM_OCPolarity_High; // Полярность TIM_OCConfig.TIM_OCIdleState = TIM_OCIdleState_Reset; // состояние выхода по совпадению CCR (сброс) TIM_OC4Init(TIM1, &TIM_OCConfig); // Инициализируем 4-й выход таймера, это PA11 TIM_ARRPreloadConfig(TIM1,ENABLE); // Предзагрузка периода (ARR) TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable); // Предзагрузка длины импульса CCR 4-го канала // (даем досчитать до конца и только потом значение меняется на новое) TIM_DMACmd(TIM1,TIM_DMA_CC4,DISABLE); // выключаем пока запрос к DMA от таймера TIM1 по достижении CCR) TIM_CtrlPWMOutputs(TIM1, ENABLE); // включаем выходы (это только для TIM1) TIM_CCxCmd(TIM1,TIM_Channel_4,TIM_CCx_Enable); // разрешаем таймеру управлять выводом PA11 TIM_ITConfig(TIM1, TIM_IT_CC4, DISABLE); // запрещаем пока таймеру генерировать прерывание по совпадению NVIC_EnableIRQ(TIM1_CC_IRQn); // разрешаем прерывания TIM_Cmd(TIM1, DISABLE); // Выключаем таймер (пока ждем) } void TIM1_CC_IRQHandler(void) // прошло 130 мкс { if (TIM_GetITStatus(TIM1, TIM_IT_CC4) != RESET) { // по совпадению TIM_ClearITPendingBit(TIM1,TIM_IT_CC4); // сбрасываем флаг прерывания TIM1 по совпадению } NVIC_EnableIRQ(TIM1_CC_IRQn); // выключаем прерывания от таймера TIM_ITConfig(TIM1, TIM_IT_CC4, DISABLE); // TIM1->ARR = 40-1; // устанавливаем период 40 мкс TIM1->CCR4 = Test_Buf[0]; // ширину из массива для следующего импульса DMA1_Channel4->CNDTR = 4; // длина данных для DMA на 1 меньше т.к. уже установили выше 1 элемент TIM_DMACmd(TIM1,TIM_DMA_CC4,ENABLE); // разрешаем таймеру делать запрос к DMA по совпадению CCR DMA_Cmd(DMA1_Channel4, ENABLE); // включаем DMA } void Init_DMA(void) { RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); // включаем тактирование DMA1 DMA_Setting.DMA_PeripheralBaseAddr = (uint32_t) &TIM1->CCR4; // куда копировать DMA_Setting.DMA_MemoryBaseAddr = (uint32_t) &Test_Buf[1]; // что копировать DMA_Setting.DMA_DIR = DMA_DIR_PeripheralDST; // копируем в периферию (Peripheral Destination, точка назначения - периферия) DMA_Setting.DMA_BufferSize = 0; // количество передаваемых данных DMA_Setting.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // адрес периферии постоянный DMA_Setting.DMA_MemoryInc = DMA_MemoryInc_Enable; // адрес в памяти увеличиваем DMA_Setting.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; // периферия 16 бит DMA_Setting.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; // массив 8 бит DMA_Setting.DMA_Mode = DMA_Mode_Normal; // режим обычный DMA_Setting.DMA_Priority = DMA_Priority_Medium; // приоритет средний DMA_Setting.DMA_M2M = DMA_M2M_Disable; // MemoryToMemory откл. DMA_Init(DMA1_Channel4, &DMA_Setting); // TIM1_CH4 относится к 4-му каналу DMA1 DMA_ITConfig(DMA1_Channel4, DMA_IT_TC, ENABLE); // настраиваем прерывание по окончанию передачи NVIC_EnableIRQ(DMA1_Channel4_IRQn); // включаем прерывания от 4-го канала DMA1 DMA_Cmd(DMA1_Channel4, DISABLE); // пока выключаем 4-ый канал DMA1 } void DMA1_Channel4_IRQHandler(void) // закончили передавать { if (DMA_GetITStatus(DMA1_IT_TC4) != RESET) { // по совпадению DMA_ClearITPendingBit(DMA1_IT_TC4); // сбрасываем флаг прерывания DMA1 Channel4 transfer complete } if (TIM_GetITStatus(TIM1, TIM_IT_CC4) != RESET) { // по совпадению TIM_ClearITPendingBit(TIM1,TIM_IT_CC4); // сбрасываем флаг прерывания TIM1 на всякий случай } TIM1->ARR = 150-1; // вновь настраиваем на период 150 мкс TIM1->CCR4 = 0; // и ждем следующею передачу TIM1->CNT = 0; // TIM_DMACmd(TIM1,TIM_DMA_CC4,DISABLE); // всё выключаем DMA_Cmd(DMA1_Channel4, DISABLE); // TIM_Cmd(TIM1, DISABLE); // TIM_ITConfig(TIM1, TIM_IT_CC4, DISABLE); // TIM_CCxCmd(TIM1,TIM_Channel_4,TIM_CCx_Disable); } int main(void) { Init_GPIO(); Init_TIM_Transmit(); Init_DMA(); delay_ms(1000); while(1) { TIM1->CCR4 = 130-1; // до включения линия удерживается в 0 (CCR=0) TIM_ITConfig(TIM1, TIM_IT_CC4, ENABLE); TIM_CCxCmd(TIM1,TIM_Channel_4,TIM_CCx_Enable); TIM_Cmd(TIM1, ENABLE); delay_ms(100); } }  
      TEST_TIM_DMA.zip
    • By Serega4789
      Добрый день всем помогите разобраться со схемой сварочного инвертора , горят транзисторы на максимальном токе !!! Imma-315 инвертор трёх фазный...


      Управляющие импульсы шим приходят на полевые транзисторы затем с них на первый и второй трансформаторы , далее на комплиментарные пары 8050 и 8550
      Импульсы приходят на затворы igbt с 2ух выходов  2 плеча ,задействованы 2 выхода и 4 igbt транзистора fgl40, на мертвое время sg3525 стоит 100 ом резистор , трансформаторы, я так понял нужны для гальванической развязки осциллограммы сброшу позже , без силы 
      Исправны только 2 транзистора ..
      Хочу изменить максимальный выходной  ток , уменьшить...
  • Сообщения

  • Покупай!

×
×
  • Create New...