Jump to content

Recommended Posts

3 часа назад, Дмитрий Вас сказал:

в таком случае если я напишу такой код в ISR?

Я догадываюсь, что вы хотите по нажатию кнопки плавно уменьшить значение OCR1A, чтобы что-то там у вас плавно изменило яркость или нечто подобное - так?

Теперь смотрите, каков должен быть алгоритм. "Плавно изменять" означает буквально "каждые N миллисекунд уменшать OCR1A на величину X, пока OCR1A не станет равно нулю". Нельзя уменьшать OCR1A в цикле while(OCR1A) OCR1A--; потому что цикл этот не завершится, пока не обнулится OCR1А, а произойдет это очень быстро, буквально за несколько милисекунд - вы не заметите никакой "плавности".

Поэтому ваш алгоритм (код) не будет выполнять нужую функцию, куда бы вы его не поместили.

Прерывание по таймеру, возникающее каждые N миллисекунд - это уже аналог цикла с нужной скоростью! Поэтому достаточно сделать так: в главном цикле проверить нажатие кнопки, и, если она нажата, установить флаг. В обработчике прерывания смотреть на этот флаг, и, если он установлен, проверять OCR1А на равенство нулю, после чего, если оно нулю не равно, уменьшать его. То есть как-то так:

volatile uint8_t flag; // это будет флаг плавного уменьшения

ISR(TIMER1_OVF_vect){ // это обработчик прерывания по переполнению таймера, вызываемый, допустим, каждые 10 мс, т.е. 100 раз в секунду
  if(flag){ // когда стоит флаг
    if(OCR1A) OCR1A--; // если OCR1A не нулевое, то уменьшаем его
  	else flag = 0; // а если уже обнулилось - снимаем флаг
  }
}

// где-то в главном цикле вы проверяете кнопку и устанавливаете флаг:
if((PIND & (1<<BD5)) == 0) flag = 1;

Я исходил из предпосылки, кто кнопка при нажатии замыкает пин МК на общий.

3 часа назад, Дмитрий Вас сказал:

я правильно понял?

Нет, не правильно. Задает значение левому операнду только оператор =, остальные операторы только возвращают значение. Ну, можно исключить ++ и -- и другие типа += или *=, которые на самом деле являются упрощенной записью сразу двух операторов, поэтому и меняют, и возвращают одновременно.

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

volatile uint16_t new_ocr;

ISR(TIMER1_OVF_vect){
  int8_t delta = 0;
  if(OCR1A < new_ocr) delta = 1;
  if(OCR1A > new_ocr) delta = -1;
  OCR1A += delta;
}

// контроль кнопки делаем макросом
#define pressed_button(x) ((PIND & (1<<(x))) == 0)

// где-то в главном цикле анализируете кнопки
if(pressed_button(PD5)) new_ocr = 0x01FF; // максимум яркости
else if(pressed_button(PD4)) new_ocr = 0; // минимум яркости

 


Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

Share this post


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

Задает значение левому операнду только оператор =, остальные операторы только возвращают значение

Это похоже на издевательство над совершенно дезориентированным человеком @Дмитрий Вас, он даже не понимает различий между языками программирования, а вы ему советы по азам одного из языков даете, как будто чтобы понаблюдать как он вывернет это новое ЗНАНИЕ себе вовред.

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

Edited by ruhi
дополнил

Можно сделать все! Но чем больше можно, тем больше нельзя!

Share this post


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

Это похоже на издевательство над совершенно дезориентированным человеком

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


Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

Share this post


Link to post
Share on other sites

Запускаем новый BLE 5.2-чип BlueNRG-LP от STMicroelectronics

Любая разработка начинается с чтения документации и изучения доступных средств разработки. Данный материал целиком посвящен средствам разработки, включая детальные инструкции по запуску вашего первого приложения на BlueNRG-LP. Описана работа с отладкой STEVAL-IDB011V1, набором инструментов и пакетом ПО позволяющим разработчику быстро войти в курс дела.

Подробнее

4 часа назад, Дмитрий Вас сказал:

вот этому обьяснения я не находил, выходит логическое <= ВОЗВРАЩАЕТ значение? а  <   задает? 

Смотрите,  кратенько... 

"=" это оператор присваивания, он присваевает леву то что справа.

Термин "возвращает" - относится к некой внешней процедуре (функции),  и происходит от оператора RETURN, которым обычно заканчиваются  внешние функции (неважно какого языка). То есть некая функция берет аргументы, колдует с ними и возвращает результат своего действия ( RETURN Result)

Поэтому операция сравнения, это тоже можно сказать некоторая функция, которая вернула результат сравнения. (Его можно присвоить  оператором присваивания какой либо переменной для дальнейшего использования, а можно и не присваивать).

Share this post


Link to post
Share on other sites

Революция в силовой электронике. Начало

Что привлекает в SiC по сравнению с кремнием, и какие особенности делают компоненты SiC часто используемыми, несмотря на более высокую стоимость в сравнении с кремниевыми высоковольтными устройствами? – Объясняет специалист ведущего разработчика силовых приборов из карбида кремния, компании Infineon.

Подробнее

4 часа назад, Дмитрий Вас сказал:

я правильно понял?

Попробую зайти с другого конца. Пока забудьте о программировании и Си.

Пусть имеется следующее арифметическое выражение:  (A+B)/B, где A=6, B=2

Чему равно это выражение?  Очевидно, что 4. Так же очевидно, что ни А, ни В  не равны 4. Тогда кто равен 4? ... ВЫРАЖЕНИЕ. Был получен результат, который просто у нас в уме.

А вот если мы запишем Х=(A+B)/B, тогда мы то, что у нас в уме присвоим Х.

Таким образом, получение некоего результата выражения - это возврат значения этим выражением.

И это возвращенное значение мы присвоили конкретной переменной Х.

А теперь вернемся к Си. Одиночный знак = является оператором присвоения значения возвращенного правым от этого оператора выражением переменной расположенной слева от этого оператора.

Всё. Другого способа присвоения в Си нет. Только через одиночный знак =.

Обратное так же справедливо - если вы где то написали одиночное =, значит вы произвели присвоение. Все остальные арифметические и логические операции способны только возвращать значение.

Физически - возврат значения - это получение результата выражения в некоем временном регистре. Обычно регистре общего назначения (РОН). РОНы отличаются от остальной памяти тем, что доступ к ним не требует занятия шины данных/адреса ОЗУ. Потому что РОНы - это часть арифметико-логического устройства процессора. Так называемая СВЕРХОПЕРАТИВНАЯ память - СОЗУ. При обращении к РОНам адрес РОНа очень короткий (3...5  бит) и содержится прямо за кодом операции инструкции процессора.

Edited by my504

Share this post


Link to post
Share on other sites

Материалы вебинара Практическое использование TrustZone в STM32L5

Материалы вебинара, посвященного экосистеме безопасности и возможностях, которые дает новая технология TrustZone в МК STM32L5, содержат две подробные практические работы: создание простого приложения с изоляцией в TrustZone, и пример отладки и тестирования TFM-SBSFU. Программа рассчитана на технических специалистов и тех, кто уже знаком с основами защиты ПО в STM32.

Подробнее

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

Попробую зайти с другого конца. Пока забудьте о программировании и Си.

:umnik2::shok::i-m_so_happy:

 

2 минуты назад, my504 сказал:

 теперь вернемся к Си.

Я не понимаю в СИ ...Но @my504 обяснил так что аж захотелось понимать )))

Share this post


Link to post
Share on other sites
11 часов назад, ARV сказал:

Не пойму, в чем вы видите издевательство: я предельно просто (насколько могу) объясняю эти самые азы

Там по моему надо начинать с объяснения необходимости использования букв (вместо цифр) в математических выражениях, поэтому то что вы объясняете это далеко не азы для данного конкретного специалиста, мне кажется.

У меня кстати несколько лет назад сын, в 4-5 классе, возмущался очень переходом на буквы в математике :) , я поэтому знаю что такой переход может быть серьезной проблемой для понимания.


Можно сделать все! Но чем больше можно, тем больше нельзя!

Share this post


Link to post
Share on other sites
22 часа назад, ARV сказал:

// где-то в главном цикле вы проверяете кнопку и устанавливаете флаг: if((PIND & (1<<BD5)) == 0) flag = 1;

а как же дребезг?

ISR(TIMER1_COMPA_vect)
{
if(button==1) //если нажата кнопка 
    {
    if(f_button==0) //проверяем была ли она нажата ранее, это флаг кнопки
        {
        f_button=1;//если нажато не было то ставим флаг 
        PCTL2 = (1<<PRUN2);//запускаем шим
        while(OCR1A<200) //плавный запуск будет до 200 (частоту нужно подсчитать)
        {OCR1A=OCR1A+5;}
      if(f_button==1)//если кнопка была нажата ранее 
          {
          f_button=0;//снимаем флаг              
          while(OCR1A) //останавливаем пока OCR1A не упадет до нуля
          {OCR1A=OCR1A-5;}
          PCTL2 &=~ (1<<PRUN2);//останавливаем шим
          }
    }
  }

ну у мня почти тоже самое

Share this post


Link to post
Share on other sites
Только что, Дмитрий Вас сказал:

ну у мня почти тоже самое

Даже и близко не то. У вас нет разделения на задачу, решаемую по прерываниям, т.е. частями периодически, и задачу, решаемую последовательно, т.е. "непрерывно". Вы зачем-то то включаете, то выключаете ШИМ... Вопрос: зачем? Я не исключаю, что могут быть причины... но хотелось бы знать. Я просто помню, как я пытался объяснить вам, как модулировать ШИМ синусом... И, не смотря на мои объяснения, вы все равно сделали по-своему, с большим количеством бессмысленных действий.

Только что, Дмитрий Вас сказал:

а как же дребезг?

Вопрос дребезга я не затраивал.


Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

Share this post


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

большим количеством бессмысленных действий.

подождите может вы меня не полностью поняли. синус генерируется и моделируется и даже меняется частота синуса энкодером. я теперь хочу кнопкой на энкодере включать/выключать с плавным пуском и плавным остановом. 

Share this post


Link to post
Share on other sites
5 минут назад, Дмитрий Вас сказал:

вы меня не полностью поняли

Я вас отлично понял, я видел ваш код, генерирующий синус - он рабочий, но избыточный примерно на 80%. Это говорит о том, что вы не понимаете, как он работает, и довольствуетесь тем, что "как-то работает". Так и в этом случае: я вам подробно описал, как должно работать "на словах", привел пример кода - и что я вижу? Снова код с циклами внутри обработчика прерываний! Это работать не будет!

Edited by ARV

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

Share this post


Link to post
Share on other sites
23 часа назад, ARV сказал:

Снова код с циклами внутри обработчика прерываний!

хоть убейте но не нашел почему этого нельзя делать. ну да ладно а если сделать так?

ISR(TIMER1_COMPA_vect)
{
	if(!(PIND&(1<<5))) //если нажата кнопка
	{
		switch(f_button)//изначально f_button=0
		{
			case 0://выполняется это условие т.е. включение
			{
				f_button=1;//если нажато не было то ставим флаг
				PCTL2 = (1<<PRUN2);//запускаем шим
				while(OCR0A<200) //плавный запуск будет до 200 (частоту нужно подсчитать)
				{OCR0A=OCR0A+5;}
			}
			case 1://при повторном нажатии на кнопку f_button уже будет = 0
			{
				f_button=0;//снимаем флаг
				while(OCR0A) //останавливаем пока OCR0A не упадет до нуля
				{OCR0A=OCR0A-5;}
				PCTL2 &=~ (1<<PRUN2);//останавливаем шим
			}
		}
	
    }

 

break; не вставил

Share this post


Link to post
Share on other sites
Только что, Дмитрий Вас сказал:

хоть убейте но не нашел почему этого нельзя делать

Еще раз: цикл while не завершится, пока не обнулит OCR1A. Изменение этого регистра он будет делать примерно со скоростью несколько дестков тысяч вычитаний в секунду. Таким образом, когда вам надо будет "плавно" изменить регистр, ваш код изменит его за сотую долю секунды, что ббудет вно "мгновенно", а не "плавно". 

Делать можно вообще все, даже молотком по пальцам бить, но всегда надо завать себе вопрос: это то самое, что я хочу?

Есть и другие проблемы в вашем коде. Например, while(OCR0A<200) {OCR0A=OCR0A+5;} будет вообще "корректно" работать только для исходнх значений OCR1A, кратных пяти. Стоит начать этот цикл при значении OCR1A, например, 254, и вы получите такую цветомузыку... ПОнимаете, почему?

Есть и другие проблемы в вашем коде. Например, while(OCR0A<200) {OCR0A=OCR0A+5;} будет вообще "корректно" работать только для исходнх значений OCR1A, кратных пяти. Стоит начать этот цикл при значении OCR1A, например, 254, и вы получите такую цветомузыку... ПОнимаете, почему?


Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

Share this post


Link to post
Share on other sites
1 час назад, Дмитрий Вас сказал:

даже если он записан в обработчике?

Вход в обработчик происходит по сбросу таймера. Скорость выполнения в обработчике ничем не отличается от скорости основного цикла. Программа входит в обработчик и выполняет код в обработчике пока его не завершит. Если обработчик не будет завершен до следующего прерывания таймера, то прерывание будет исполнено сразу после выхода из текущего обработчика.

Share this post


Link to post
Share on other sites

у меня таймер 0 генерирует синус, а 1й проверяет энкодер. что если я в первом буду проверять кнопку типа  if(!(PIND&(1<<5)) {f_button^=0;} меняем флаг на противоположный. а в таймере 0 уже if(f_button&&OCR0A) {OCR0A--;} else.... не придумал еще как наращивать при запуске

Share this post


Link to post
Share on other sites
1 hour ago, Дмитрий Вас said:

1й проверяет энкодер

Я бы сделал вот так: добавил бы два флага go_up и go_down для указания процесса "плавно вверх" и "плавно вниз". В прерывании таймера 1 не спеша бы проверял флаги и нажатие кнопки.

ISR(TIMER1_COMPA_vect)
{
    if(go_up)
    {
        if(OCR0A < 200) //плавный запуск будет до 200 (частоту нужно подсчитать)
            OCR0A = OCR0A + 5;
        else
        {
            go_up = 0; //  останавливаем плавно вверх
            OCR0A = 200; // включено на полную катушку
        }
    }
    else
    if(go_down)    
    {
        if(OCR0A > 5) //останавливаем пока OCR0A не упадет до нуля
            OCR0A = OCR0A - 5;
        else
        {
            go_down = 0; // останавливаем плавно вниз
            OCR0A = 0;   // полностью выключено
        }
    }

    if(!(PIND&(1<<5))) //если нажата кнопка
    {
        if(OCR0A == 0) // было выключено, плавно включаем
            go_up = 1;

        if(OCR0A == 200) // было включено, начинаем плавно выключать 
            go_down = 1;
    }
}

 

Share this post


Link to post
Share on other sites

#include <stdio.h>

if(!(pind5==1))
{
    f_button ^=0;//флаг станет единицей
}
if(f_button==0)//проверка для старта
    {
        OCR0A ++;
    }
   
else//проверка для стоп
    {
        if(OCR0A)//если OCR0A имеет любое значение больше нуля
        {
            OCR0A --;
        }
        if(OCR0A ==0)//если OCR0A достиг нуля
        {
            f_button =0;//сбрасываем флаг
        }
       
    }

int main() {
    return 0;
}

Вот набросал, должно работать. Но остались вопросы. Если я пишу f_button^=0; это придаст первоначальное значение  ноль которое потом поменяет на 1? Или нужно uchar f_button=0; 

 И второй вопрос как бы OCR0A ++; увеличивалось бы только до 200, а потом можно было её менять энкодером?

П.с. код будет в обработчика ISR дабы избежать дребезга

Share this post


Link to post
Share on other sites
1 час назад, Дмитрий Мамедиев сказал:

Вот набросал, должно работать

Это вряд ли.

1 час назад, Дмитрий Мамедиев сказал:

Если я пишу f_button^=0; это придаст первоначальное значение  ноль которое потом поменяет на 1?

То, что вы написали, вообще никак не поменяет f_button. Вообще никогда никак.

1 час назад, Дмитрий Мамедиев сказал:

if(!(pind5==1))

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

1 час назад, Дмитрий Мамедиев сказал:

int main() {
    return 0;
}

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

Edited by ARV

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

Share this post


Link to post
Share on other sites
16 часов назад, ARV сказал:

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

А я предупреждал ! :)


Можно сделать все! Но чем больше можно, тем больше нельзя!

Share this post


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

предупреждал

Вы предупреждали в отношении совсем другого начинающего. Так что не факт, что ваше возмущение уместно.


Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

Share this post


Link to post
Share on other sites
11 часов назад, ARV сказал:

Так что не факт, что ваше возмущение уместно.

Да где ж я возмущался то?

Вот согласитесь, посмотреть как работает операция:

 f_button^=0; это придаст первоначальное значение  ноль которое потом поменяет на 1

лучше всего в консольном С-приложении на компе, для начала, там же можно походить в дебаге - посмотреть значения переменных хочешь в десятичном виде- хочешь в хексе (прежде чем в контроллеры лезть)?

Ну это же глупо (по моему) на форумах выяснять?


Можно сделать все! Но чем больше можно, тем больше нельзя!

Share this post


Link to post
Share on other sites

Здравствуйте! Подскажите мне пожалуйста, как собрать микросхему АЦП в Proteus? Я тут написал код 

//Atmega8
//Укажем частоту
#define F_CPU 8000000
#include <avr/io.h>
#include <util/delay.h>
//Инициализируем библиотеку для работы с дисплеем
#include "n5110.h"
#include <stdlib.h>

//Предварительные настройки
void presets(){
//Инициализируем дисплей
    Lcd_init();
//Настройки АЦП
//ADCSRA
ADCSRA |= (1<<ADEN) //Задействовать АЦП
| (1<<ADPS2) | (1<<ADPS2) | (1<<ADPS2) ; //Делитель 128 = 64 кГц

//ADMUX	
ADMUX |= (1<<REFS1)|(1<<REFS0) //Опорное напряжение 2.56 В внутреннее
| (0<<MUX3) | (0<<MUX2) | (0<<MUX1) | (1<<MUX0); //Выбор вывода
}

int readADC(){
    ADCSRA |= (1<<ADCSRA); //Запуск преобразования	
	while ((ADCSRA &(1<<ADSC))); //Ожидание окончания преобразования
	return ADC;
}


int main(void)
{
    presets();
    while (1) 
    {
		Lcd_clear();
		char buff[5];
		itoa(readADC(), buff, 10);
		Lcd_print(0,1, FONT_1X, (unsigned char*)buff);
		Lcd_update();
		_delay_ms(200);
		
		
		
    }
}

 набросал схему и почему-то у меня показывает 0

New Project.pdsprj GccApplication7.hex n5110.c n5110.h

Edited by Андрей Протаскин

Share this post


Link to post
Share on other sites

Join the conversation

You are posting as a guest. 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

    • Guest Moonlight
      By Guest Moonlight
      Нужна помощь в выборе перспективной дипломной работы ( не просто тяп ляп лишь бы выпустили). Хотелось бы сконструировать беспилотник или просто разработать небольшое устройство (развести и напечатать плату, закинуть прошивку на микроконтроллер). И если бы ещё это все было взаимосвязано с авиацией, то было бы супер, так как авиационный вуз оканчиваю. Из того что умею, это писать на Си, плюс минус хорошо ориентируюсь в дисциплинах связанных с антеннами и радиолокаторами, был небольшой опыт конструирования. Хочется сделать проект, который будет не стыдно показать на собеседовании)). Буду очень благодарен, если поможете определиться с темой!)
    • By Evgenii53
      Здравствуйте.
      Нужна прошивка на микроконтроллер 12F629/675.
      Схема скачана в интернете и предназначена для освещения курятника лампами накаливания 220 вольт с имитацией «восхода и заката».
       Временные интервалы «восхода и заката» выбраны 6 утра и 21 час вечера.
      Длительность «восхода и заката» по 20 минут (лампы медленно загораются или гаснут под управлением симистора).
      Если в дневное время срабатывает датчик освещённости (фоторезистор HER –  GL5528), лампы не включаются и включаются, когда он разрешит, в ночное время фоторезистор бездействует. Фоторезистор можно (или нужно?) переключить на 5 ногу.
      Нужно установить программное ограничение на срабатывание датчика освещения от кратковременного изменения освещённости (например падение света фар движущегося автомобиля на датчик и т.д). Фоторезистор устанавливается на кабеле длинной около 2 метра.
      Логика работы кнопки: длительное нажатие (больше 3 секунд), устанавливает внутренние часы на полдень.  Время синхронизируется от сети 50Гц.
      Светодиод отображает наличие питания сети. Если сеть есть, он всё время светится и раз в 2 секунды кратко моргает. Если сети нет и устройство питается от батарей, светодиод погашен и раз в 2 секунды вспыхивает. При установке времени полдня светодиод несколько раз моргает.
      Схема рабочая, я проверял в работе (без фоторезистора) на тестовой прошивке, работает нормально.
      По оплате, думаю договоримся.

    • By HHHIII
      Сломался пульт управления беговой дорожки. Теперь хочу с помощью Ардуино управлять мотором, но не понятно как происходит управление. к панели идёт 4 контакта: чёрный красный белый зелёный. на плате 5 контактов, но 1 не используется. Как происходит управление скоростью?

    • By DANY Lee
      Здравствуйте ! помогите пожалуйста в написании прошивки для ATTINY2313a _ дело в Том что есть семисегментный, 6 разрядный индикатор _ Хочу сделать себе дублирующий табло для весов _ о семисегментных индикаторах есть какие то понятия но на практике не когда не дедал дуб. табло_  проблема возникает при написании кода _ веси передает данные через порт RS232  ................. что делать ? буду рад к любому совету ,,, спасибо заранее ..... 
    • Guest Юрий
      By Guest Юрий
      Добрый день. Возможно ли читать с gpio данные с частотой 198 МГц при частоте шины AHB 240 МГц посредством DMA burst? Мне кажется нельзя, но хотелось бы знать, что это не сможет работать как конвейер. В App note к stm32f7 написано, что передача по шине с dma осуществляется за 2 цикла шины. Но я не смог найти подобной информации для stm32h7. 
      И правильно я понимаю,  что для чтения порта через ядро,  один такт тратится на защелкивание во входном регистре порта, а второй такт уходит на запись в регистр общего назначения? 
×
×
  • Create New...