Перейти к содержанию

Шим Для Atmega


Sounds

Рекомендуемые сообщения

Народ помогите разобраться с ШИМ на Atmega8L. Я читал http://forum.cxem.net и не совсем всё понял. Вот я хочу сделать регулировку яркости светодиода, который я подключаю к PB1 плюсом, а минус к GND. Внутренний RC генератор настроен на 8Мгц.

Что я делаю:

#include <mega8.h> // Подключаю библиотеку для работы с atmega8.
DDRB=0x02; //Ножку PB1 настраиваю на 1 
PORTB = 0x00; // Устанавливаю 0 на всех портах B

Компилятор CodeVisionAVR.

Теперь я в тупике, я не особо понимаю что должно быть дальше.

Помогите разобраться.

Ссылка на комментарий
Поделиться на другие сайты

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

Может чтобы лучше и проще понять "что делать" для начала обойдетесь без ШИМа? Если согласны, тогда сделайте несложный цикл, в котором будет зажигаться и гаснуть светодиод, кромеп того, в цикле должна быть задержка. Далее, меняя параметры задержки, смотрите, как это повлияет на яркость светодиода. Если тут все станет понятно, тогда и с ШИМом разберетесь

С уважением,

Ваган Саруханов

Ссылка на комментарий
Поделиться на другие сайты

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

Да я не против, я только за!

Вы мне сможете помочь из стандартного кода сделать ШИМ через делей?

#include <mega8.h> 
#include <delay.h>
void main(void)
{		
PORTD=0x00;
DDRD=0xFF;
while (1)
  {

  PORTD.0=1;

  delay_ms(20);

  PORTD.0=0;

  delay_ms(20);

  };

}

Спасибо вам за помощь!

Ссылка на комментарий
Поделиться на другие сайты

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Из стандартного кода ШИМ делать не будем :)

Для начала исключите константы в функциях задержек и перейдите на пременную, которую можете программно менять.

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

С уважением,

Ваган Саруханов

Ссылка на комментарий
Поделиться на другие сайты

Это очень здорово что вы согласились помочь, спасибо Вам!

Давайте вначале на простом коде

Вот код с переделанной задержкой.

#include <mega8.h> 
#include <delay.h>
void main(void)
{		
PORTD=0x00;
DDRD=0xFF;
Int ms=20;
while (1)
  {
   PORTD.0=1;
  delay_ms(ms);
  PORTD.0=0;
  delay_ms(ms);
  };
}

Ссылка на комментарий
Поделиться на другие сайты

Уже поздновато, но если у Вас есть желание продолжить, для начала обратите внимание на то, что в соседней ветке есть похожая тема с примерами по ШИМу для МК здесь. Если этого будет недостаточно, продолжим завтра.

С уважением,

Ваган Саруханов

Ссылка на комментарий
Поделиться на другие сайты

Если решите продолжить, то для начала сделайте следующее:

1) необходимо иметь платку с МК + светодиод + две кнопки

2) сделайте функцию с одним параметром, определяющим задержку; функция зажигает светодиод и держит включенным в течение времени, определенном параметром-задержкой; в конце функции светодиод гасится, задержки нет после выключения

3) сделайте пару функций обработки двух кнопок: если одну нажали и держим, глобальная переменная-задержка увеличивается; во второй функции - обратный процесс - переменная-задержка уменьшается

4) в основном цикле while(1) {} сделайте опрос нажатия кнопок и при нажатии вызов соответствующих функций обработчиков; здесь же в основном цикле вызов процедуры зажигания светодиода, в качестве входного параметра используйте ту глобальную переменную-задержки

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

В результате Вы должны получить программу, которая позволит, управляя кнопками, менять яркость светодиода. Если не очень понятно, за счет чего это получится, дайте знать

С уважением,

Ваган Саруханов

Ссылка на комментарий
Поделиться на другие сайты

Добрый день!

Жакетку я собрал, так что первый пункт выполнен.

И код я сделал, я надеюсь он правильный.

#include <mega8.h> 
#include <delay.h>
void main(void)
{	 
int a=1;  
PORTD=0x00;
DDRD=0xFF;
PORTB=0xFF; 
DDRB=0x00;
 while(1)   
	{ 
	if(PINB.1==1 && PINB.2==1){a=50;}
	if(PINB.1==0){  
   a++;
   PORTD.0=1; 
   delay_ms(a); 
   PORTD.0=0; 
   delay_ms(a);	   
			}			   
	 if(PINB.2==0) {  
	  a--;
	  if(a==0){a=1;}
	  PORTD.0=1; 
	  delay_ms(a); 
	  PORTD.0=0; 
	  delay_ms(a);  
	} 
}

Ссылка на комментарий
Поделиться на другие сайты

Предалагю повысить читабельность программы и, добавив небольшую избыточность, повысить переносимость ее на другие платформы. Не подумайте, я не придираюсь, просто дальше будет легче и нагляднее вносить модификации, а в конечном результате, с малыми переделками прогу можно будет запустить на различных МК.

1) Как водится, сделайте hw_init() или просто init() и уберите туда все аппаратнозависимые настройки.

2) Сделайте отдельные функции для обработки нажатия кнопок и засветки светодиода

3) Напомню, в функции засветки светодиода после его выключения мы не используем задержку

4) Останется в main() в основной суперпетле while(1) добавить что-то типа следующего:

void main(void)
{
  int on_ms=DEFAULT_ON, off_ms=DEFAULT_OFF;

  init();
  while(1){
     if (button_pressed(1)) value_up(&on_ms);
     if (button_pressed(2)) value_down(&on_ms);
     led_on(on_ms);
     delay_ms(off_ms);
  }
}

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

P.S. В конце суперпетли введена задержка, чтобы приблизить Вас к желаемому ШИМу, этим параметром Вы сможете задать в будущем частоту. Параметры по-умолчанию Вы подберете опытным путем из собственных соображений

Изменено пользователем wagan

С уважением,

Ваган Саруханов

Ссылка на комментарий
Поделиться на другие сайты

Делаем функцию init() из фрагмента Вашего кода:

1) создаем каркас функции

void init(void)

{

}

2) копируем Ваш фрагмент

void init(void)

{

PORTD=0x00;

DDRD=0xFF;

PORTB=0xFF;

DDRB=0x00;

}

Размещаем код этой функции перед main(), в таком случае нам не понадобится отдельно описывать ее.

Если разместить эту функцию в отдельном файле, то потребуется:

1) сделать инклюдник, в котором необходимо дать описание новой функции:

void init(void);

2) включить инклюдник в основной или иной сишный файл проекта, из которого будут происходить вызовы этой функции, то есть:

#include "имя_инклюдного_файл"

3) включить исходник, содержащий эту функцию, в проект

С уважением,

Ваган Саруханов

Ссылка на комментарий
Поделиться на другие сайты

Спасибо за помощь! а как я могу перенести переменные которые содержатся в функции init(); в основную функцию main();

например:

void init(){
int ina=5;
}
void main(){
init();
delay_ms(a);	   
}

У меня по какой то причине переменная ina не передаётся в основную функцию main() и delay_ms().

Что Вы можете посоветовать?

Спасибо!!!

Ссылка на комментарий
Поделиться на другие сайты

Несколько способов использования переменных разлиными функциями.

1) Глобальные переменные. Это те переменные, которые описаны вне функций

Пример.

#include <mega8.h> 
#include <delay.h>

int ina=5;

void init(void)
{
...
}

void main(void)
{
...
}

В этом примере переменная ina описана вне всех функций и доступна для использования внутри init() и main()

2) Передача параметров при вызове функции

Хотим, чтобы из main() вызывалась init() с заданным параметром

описываем init иначе, чем ранее:

void init(int x)

{

...

что-то делаем с переменной x

...

}

Такую функцию вызываем из main() так:

void main(void)

{

init(15)

...

}

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

Даже если Вы все это знаете и просто хотите покуражиться, у меня терпения хватит Вам ответить, может еще кому-то будет полезно, вот только времени вряд ли будет достаточно :)

С уважением,

Ваган Саруханов

Ссылка на комментарий
Поделиться на другие сайты

Если бы я знал то я не тратил бы столько время. :)

Вот вроде что то получалось:

#include <mega8.h> 
#include <delay.h>
int a=1;
void ports ()
{
PORTD=0x00;
DDRD=0xFF;
PORTB=0xFF; 
DDRB=0x00;
}
void delay()
{
if(PINB.0==1 && PINB.1==1){a=50;}
if(PINB.0==0){  
   a++;
   delay_ms(a);
		}			   
	 if(PINB.1==0){  
	  a--;
	  if(a==0){a=1;}
	  delay_ms(a);  
	} 
}
void main(void)
{
ports();
while(1){
  PORTD.0=1;
   delay();
	PORTD.0=0;
	  delay();
	   }	
	   }

Что дальше необходимо сделать?

Изменено пользователем Sounds
Ссылка на комментарий
Поделиться на другие сайты

Можно свои 5 копеек вставить, я вот тут тоже разбирался с программным шимом и накидал маленькую программу 3-х канального шима с плавным изменением яркости 3-х каналов , яркость меняеться автоматически. Первоначальные параметры работы каждого канала задаються переменными К,Т,С.

#include <mega8.h>
#include <delay.h>

// Declare your global variables here

void main(void)
{
// Declare your local variables here


PORTB=0x00;
DDRB=0xFF;

PORTC=0x00;
DDRC=0x00;

PORTD=0x00;
DDRD=0x00;


while (1)
     {
int n,t,c,m,k,v;  // обьявляем переменные
k=1;
t=100;
c=200;
m=0;
v=255;             // максимальное значение ШИМ


// ШИМ********************************* 
while (1)
{                
PORTB=0x07;                     //обнуляем порт В(выклюыаем шим)

for(n=0; n<=v; n++)            //запускаем цикл ШИМа
{
if(n==k) PORTB.0=0;             //включаем ШИМ по 0 выводу
if(n==t) PORTB.1=0;             //включаем ШИМ по 1 выводу
if(n==c) PORTB.2=0;             //включаем ШИМ по 2 выводу
}                                // выход из цикла ШИМа

//*************************************  
//минимальное значение ШИМ-0
//максимальное значение ШИМ-254

// программа плавного изменения ШИМа по выходам 0*1*2
m++;                             //подсчет количество повторов цикла ШИМа
if(m>=5) {k++; t++; c++; m=0;}  //изменение переменнох значение ШИМа при достижении М==10
if(k==v) k=0;                 // проверка переменных ШИМа -
if(t==v) t=0;                 //
if(c==v) c=0;                 // 


};


     };
}

Ссылка на комментарий
Поделиться на другие сайты

  • 2 недели спустя...

Народ, вы все чё реально неумете юзать аппаратный ШИМ? Он проц вообще не грузит и там можно широко частоту и скважность крутить. А что будет если понадобиться ШИМ запустить на частоте около 1МГц, или вообще на 64МГц - а ведь AVR на то способны и с нулевой загрузкой ЦПУ!!!

В квавре есть генератор начального кода - и там можно его настроить :)

для меги8 :)

Да на ноге B.1 действительно есть выход аппаратного ШИМа

а запускается он так

void main(void)

{

PORTB=0x00;

DDRB=0x02;

// Timer/Counter 1 initialization

// Clock source: System Clock

// Clock value: 1000,000 kHz

// Mode: Fast PWM top=ICR1

// OC1A output: Non-Inv.

// OC1B output: Discon.

// Noise Canceler: Off

// Input Capture on Falling Edge

// Timer 1 Overflow Interrupt: Off

// Input Capture Interrupt: Off

// Compare A Match Interrupt: Off

// Compare B Match Interrupt: Off

TCCR1A=0x82;

TCCR1B=0x19;

TCNT1H=0x00;

TCNT1L=0x00;

ICR1H=0x02;

ICR1L=0x00;

OCR1AH=0x00;

OCR1AL=0x00;

OCR1BH=0x00;

OCR1BL=0x00;

.....

}

юзать его так:

OCR1AH - старший байт

OCR1AL - млажший байт

если крутить эти байты будет изменяться яркость свечения светодиода :) и мигания вообще невидно будет

ICR1H

ICR1L

этими байтами можно покрутить частоту ШИМа

в коде стоит 2 в старшем байте. при тактовой в 16МГц частота будет около 30кГц

Вообщем если что пишите :)

_____________________________

http://andrei-sela.homelinux.com:8081 - пока в стадии разработки

LINUX SERVER больше информации на моей домашней страничке... - пока в стадии разработки, но у него есть 2 UART порта доступных по web-интерфейсу и стоит этот сервак у меня дома :)

Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...