Jump to content
Duhas

Примеры Кода Для Avr

Recommended Posts

Вот такое сообразил, имеет право быть?
Как будто проверить сложнее, чем ждать ответа на форуме! Ладно, сами макросы синтаксически правильны, их использование, судя по приведенному куску - нет.

Share this post


Link to post
Share on other sites

Как думаете, далеко ли Вас пошлёт компилятор ? :)

Н-да, ерунда какая то получается

Вот такое сообразил, имеет право быть?

#define STB 0
#define CLK 1
#define DOUT 2
#define PORTA1(n) PORTA |= (1<<n)
#define PORTA0(n) PORTA &= ~(1<<n)
а в программе потом вызывать так:
PORTA1(stb);
PORTA0(stb);

А мой пример использовать - религия не позволяет? :)

Самый быстрый и понятный код.

Приведенный вами пример работать не будет так как в нем есть ошибки.

Вот так:

#define STB 0
#define CLK 1
#define DOUT 2
#define PORTA1(n) PORTA |= (1<<n)
#define PORTA0(n) PORTA &= ~(1<<n)
а в программе потом вызывать так:
PORTA1(CLK);
PORTA0(STB);

Работать будет.

Share this post


Link to post
Share on other sites

А мой пример использовать - религия не позволяет? :)

А как же учится, взял ваш за основу, разобрался как работает написал по своему =)

Спасибо что исправили, сам тоже проверил, забыл что в си учитывается регистр

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

Edited by GalatZ

Share this post


Link to post
Share on other sites

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

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

Подробнее

Просто не понимаю , зачем писать больше букАв если мой пример работает не хуже и совместим с любым си компилятором :)

Ваш пример требует ввода лишних символов.

Share this post


Link to post
Share on other sites

Все правильно делает - учится работать с макросами. Оптимизировать будет когда наиграется.

Могу подсказать еще макрос, с помощью которого сможете воспользоваться первой версией настроек (#define var PORTA,1)

#define _arg1(a,    a
#define arg1(x)        _arg1(x)

тогда запись

#define example PORTB,1

arg1(example) |= 1;

будет преобразована в

PORTB |= 1;

Важно! В один этап макроподстановка не работает, приходится делать двойную обертку.

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

Share this post


Link to post
Share on other sites
                     

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

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

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

Все правильно делает - учится работать с макросами. Оптимизировать будет когда наиграется.

Могу подсказать еще макрос, с помощью которого сможете воспользоваться первой версией настроек (#define var PORTA,1)

#define _arg1(a, a
#define arg1(x) _arg1(x)

Чёт я не понял как это использовать.

Share this post


Link to post
Share on other sites

#define example	 PORTB,1
arg1(example) |= 1;

:)

Это же - классика языка. Макросы.

Share this post


Link to post
Share on other sites
Чёт я не понял как это использовать.
Я же дал заготовку.
Это же - классика языка. Макросы.
Да, вот только по ним конкретные примеры найти непросто.
почему PORTB,1? А не PORTB ?
Чтобы задать одновременно и порт и номер ноги в нем. Иногда удобно задавать вывод в виде #define any_pin B,4 , а программа уже может работать с PORTB, PINB, DDRB применительно к 4-му биту. Но для этого надо применить еще "##", но оно тоже с первого раза не срабатывает.

Share this post


Link to post
Share on other sites
Да, вот только по ним конкретные примеры найти непросто.
Какие примеры ? Вы о чём ? :)

define - это же обычная замена текста. Какие могут быть тут примеры ? :)

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

Кстати, по поводу Вашего примера.

Для чего дефайнить вместе с портом ещё число, если это число потом не используется ?

Тогда уж нужно делать как-нибудь так:

#define SET_BIT(reg, bit_num) reg|=1<<(bit_num)
#define CLR_BIT(reg, bit_num) reg&=~(1<<(bit_num))

Дефайны портов:

#define STROB PORTA, 0
#define DATA PORTA, 1

Использование:

SET_BIT(DATA);
SET_BIT(STROB);
CLR_BIT(STROB);
....

И ещё не понятно про какую одну стадию Вы говорите в своём примере.

Share this post


Link to post
Share on other sites
Для чего дефайнить вместе с портом ещё число, если это число потом не используется ?
Чтобы желающие могли найти способ его применения самостоятельно.
Тогда уж нужно делать как-нибудь так:
А настройки (DDR) отдельно прописывать? У меня для этого написаны макросы PORTx(x), DDRx(x), PINx(x), num(x), где #define x B,3. Остальное вычисляется препроцессором. Удобно для настроек, на мой взгляд, я так модуль для дисплея и клавиатуры делал.
И ещё не понятно про какую одну стадию Вы говорите в своём примере.
А попробуйте собрать приводимый ранее пример. Будет ругаться.

Share this post


Link to post
Share on other sites
А настройки (DDR) отдельно прописывать?
Конечно отдельно. Не буду же я сейчас всё тут расписывать под каждую ситуацию :)

Я просто привел пример использования дефайна с регистром и номером бита через запятую.

А попробуйте собрать приводимый ранее пример. Будет ругаться.
Зачем же Вы тогда его приводили, если он нерабочий ? :)

Share this post


Link to post
Share on other sites

Кстати, по поводу Вашего примера.

Для чего дефайнить вместе с портом ещё число, если это число потом не используется ?

Тогда уж нужно делать как-нибудь так:

#define SET_BIT(reg, bit_num) reg|=1<<(bit_num)
#define CLR_BIT(reg, bit_num) reg&=~(1<<(bit_num))

Дефайны портов:

#define STROB PORTA, 0
#define DATA PORTA, 1

Использование:

SET_BIT(DATA);
SET_BIT(STROB);
CLR_BIT(STROB);
....

И ещё не понятно про какую одну стадию Вы говорите в своём примере.

Зачем велосипед изобретать? ))

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

Share this post


Link to post
Share on other sites

Что он тоже самое делает ? :)

Как в твоём примере, объявив дефайн, типа:

#define STROB PORTA,0

, устанавливать/сбрасывать бит порта, используя "STROB" ?

Это совершенно 2 разных примера, и они не одинаковые и делают не тоже самое :)

Share this post


Link to post
Share on other sites
Зачем же Вы тогда его приводили, если он нерабочий ? :)
Значит так и не проверили. Код рабочий, но оберток пришлось делать две - _arg1() + arg1(), с одной не работает, про что я и писал.
Зачем велосипед изобретать? ))

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

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

Share this post


Link to post
Share on other sites

#define arg1(a,  a
#define arg2(a,  b

arg1(PORTA, 0) |= 1<<arg2(PORTA, 0);

Всё компилируется и работает (устанавливается 0-вой бит порта А), без всяких двойных обёрток.

Компилятор MCC18 для PIC'ов. На других лень проверять, ибо сейчас открыт рабочий проект и на нём проверить недолго...

Докозательства :) :

post-48853-0-84376100-1417881566_thumb.png

post-48853-0-48416600-1417881570_thumb.png

Share this post


Link to post
Share on other sites

#include <avr/io.h>
#define _arg1(a,	 a
#define arg1(x)		 _arg1(x)
#define example	 PORTB,1
int main(){
arg1(example) |= 1;
_arg1(example) |= 1;
}

Если оставить только arg1() то компилируется без проблем, в если _arg1() то ругается, что макрос хочет 2 аргумента, а передают 1.

$ avr-gcc test.c -mmcu=atmega8

test.c: In function ‘main’:

test.c:6:15: error: macro "_arg1" requires 2 arguments, but only 1 given

_arg1(example) |= 1;

А смысл от подобных макросов в записи arg1(PORTA,0) ?

P.S. Не надо меня пытаться подловить на самопротиворечии, свой код я обычно проверяю хотя бы на компилируемость. Когда не проверяю, обычно прямо об этом говорю.

Edited by COKPOWEHEU

Share this post


Link to post
Share on other sites

Я и не пытаюсь Вас ни на чём поймать. Обычная дискуссия :)

А смысл от подобных макросов в записи arg1(PORTA,0) ?
Ну PORTA,0 можно в дефайн запихнуть, тогда смысл появится - назначение вывода и лёгкой его замены на другой.

Да и причём тут смысл вообще ? Я просто проверил Ваш вариант, как Вы и хотели. У меня всё скомпилировалось и заработало...

Share this post


Link to post
Share on other sites

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

Ладно, не судите строго я с авр вообще только начал знакомиться, приветствуются всяческие замечания, исправления, тыканье носом в косяки, короче надо создать всем народом, нормальную, понятную, библиотеку для управления 7-ми сегментными индикаторами. Только не надо мне предлагать перейти на ЖК индикатор, конечно у него много плюсов и для него проще писать программу, но на улице в мороз лучше 7-ми сегментного индикатора никто ничего ещё не придумал, но речь не об этом.

Код:

/*
* _1111.c
*
* Created: 06.12.2014 22:32:48
* Author: a_sergeevich
* МК: Atmega8A
* Код для вывода на светодиодные 7-ми сегментные индикаторы чисел, положительных, отрицательных, целых, дробных.
* Т.к код писался под 4-х разрядный индикатор то диапазон выводимых чисел ограничен для целых -999...999
* для дробных -99.9..99.9, ограничение связано с тем, что первый разряд используется для знака.
* Данный код подходит для создания вольт -амперметров, термометров и др устройств где
* выводимые диапазоны чисел не превышают указанные выше диапазоны. Если в вашем устройстве нету
* дробных и отрицательных чисел, код легко переделывается для вывода чисел в диапазоне от 0...9999.
* Так же можно доделать код для вывода чисел в диапазоне от -999..9999 и -99.9..999.9, но мне не охота 
*/
//текст программы написан для индикатора с ОА для переделки под индикатор с ОК смотри комментарии ниже
#define F_CPU 4000000UL //задаём частоту работы МК 4 МГц
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
//объявляем массив цифр для вывода на индикатор, значения приведены для индикатора с ОК
unsigned char segment [] = {0x3f, 0x6, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x7, 0x7f, 0x6f, 0x40, 0x00};
//объявляем глобальные переменные для хранения разложенного числа по разрядам
unsigned char raz1, raz2, raz3,raz4;
//флаг отрицательного числа
unsigned char minus;
//переключатель разрядов, флаг точки
unsigned char count, column;
//объявляем вектор прерывания таймера Т0 по переполнению
ISR (TIMER0_OVF_vect) {
 //тут мы очищаем PORTB,включаем разряд PORTD и записываем в PORTB значение. Для индикатора с ОК убрать
 //инвертирование в строке ~segment[razХ], а строку PORTD=Х наоборот проинвертировать, например, PORTD=~8
 //также изменить строку PORTB|=127 на PORTB &=~(127)

 if(count==0) {  PORTD=8; PORTB = ~segment[raz1]; }
 if((count==1)&&(column==1)) {  PORTD=4; PORTB = ~segment[raz2]; PORTB &=~(1<<PB7);}
 if((count==1)&&(column==0)) {  PORTD=4; PORTB = ~segment[raz2];}
 if(count==2) {  PORTD=2; PORTB = ~segment[raz3]; } 
 if(count==3) {  PORTD=1; PORTB = ~segment[raz4]; } //это строка отвечает за минус


 count+=1; //счетчик разрядов

 if(count==4) count = 0;
}
//функция инициализации портов
void Init_port ( void ) {
//PORTB на выход
DDRB = 0xFF;
//Записываем в PORTB нули
PORTB = 0x00;
// PD0,PD1,PD2,PD3 на выход при необходимости использовать остальные пины, сконфигурируйте их как вам надо
DDRD = 0xF;
//Записываем в PORTD нули
PORTD = 0x00;
}
//инициализация таймера Т0
void Init_timer ( void ) {
//устанавливаем предделитель в 8
TCCR0 = 0x2;
//разрешаем прерывание по переполнению
TIMSK = 0x1;

}
//функция разложения числа на единицы, десятки, сотни
void Pereschet ( int tmp ) {

//раскладываем число на отдельные разряды  
raz1 = tmp % 10;
raz2 = ( tmp % 100 ) / 10;
raz3 = ( tmp % 1000 ) / 100;


//гасим не используемые разряды для целых положительных чисел
if ((raz2==0)&&(raz3==0)&&(minus==0)&&(column==0)) {raz2=11;raz3=11;raz4=11;}
if ((raz3==0)&&(minus==0)&&(column==0)) {raz3=11; raz4=11;}
if ((tmp >= 100)&&(minus==0)&&(column==0)) raz4 = 11;
//гасим не используемые разряды и двигаем знак минуса для целых отрицательных чисел
if ((raz2==0)&&(raz3==0)&&(minus==1)&&(column==0)) {raz2=10;raz3=11;raz4=11;}
if ((raz3==0)&&(minus==1)&&(column==0)) {raz3=10; raz4=11;}
if ((tmp >= 100)&&(minus==1)&&(column==0)) raz4 = 10;
//гасим не используемые разряды для дробных положительных чисел
if ((raz3==0)&&(raz2==0)&&(column==1)&&(minus==0)) {raz4=11;raz3=11;raz2=0;}
if ((raz3==0)&&(minus==0)&&(column==1)) {raz3=11; raz4=11;}
if ((tmp >= 99.9)&&(minus==0)&&(column==1)) raz4 = 11;
//гасим не используемые разряды и двигаем минус для дробных отрицательных чисел
if ((raz3==0)&&(raz2==0)&&(column==1)&&(minus==1)) {raz4=11;raz3=10;raz2=0;}
if ((raz3==0)&&(minus==1)&&(column==1)) {raz3=10; raz4=11;}
if ((tmp >= 99.9)&&(minus==1)&&(column==1)) raz4 = 10;




}
//в этой функции проверяется дробное число или целое, если дробное то число умножается на 10 и выставляется флаг
//для зажигания точки. Точность будет до 1 знака после запятой.Также проверяем отрицательное число или положительное.
int proverka ( float chislo ) {

if (((int)(chislo))== chislo) column = 0;

 else {

  column = 1;
  chislo = chislo * 10;
  }

unsigned char flag = 0;
//проверяем отрицательное число или положительное
if ( chislo < 0 ) {chislo = chislo * -1; minus = 1; flag = 1;}
if (( chislo >= 0)&&(flag==0)) minus = 0;




return (int)(chislo);
}
int main(void)
{
Init_port();
Init_timer();
//разрешаем глобальные прерывания
sei();
float a = 994; //код для проверки
int b;		 //код для проверки
   while(1)
   {




  b = proverka(a);	 //код для проверки
  if (b > 999 ) {a =0; b=0;} //код для проверки
  Pereschet(;
  a = a + 1;    //код для проверки  
  //_delay_ms(500);    //код для проверки

   }
}

Share this post


Link to post
Share on other sites
но ничего не нашёл, только примеры, которых просто тьма
Потому что её нет смысла создавать на все случаи жизни. Кому то нужно просто цыферки выводить, кому то сегментами по-отдельности управлять,кто то захочет через буфер выводить данные, кому то пофиг как, кому то нужно убирать незначащие нули, кому то - нет, кому то нужно 2 индикатора, кому то 10, .....

Не создашь универсального кода. Либо создашь, но он будет таким, что всякие любители повыёб...ся будут говорить - я сделал динамику и она у меня заняла в 10 раз меньше ресурсов, а у вас - быдлобиблиотека...

Это уже пройденный этап...

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

Share this post


Link to post
Share on other sites

Тем более что динамическая индикация - штука простая, а вывод чисел с самой индикацией почти не связан. Это просто перевод из числа в строку, методов для которого довольно много.

Потому что её нет смысла создавать на все случаи жизни.

Ну, именно для перевода - printf / sprintf на все случаи жизни. printf может сразу в семисегментном формате выводить, если правильно настроить. Вот только весят они...

Share this post


Link to post
Share on other sites

Надо правильно произвести декомпозицию задачи. У вас оно как-то сумбурно, может поэтому и не работает - фиг отследишь.

В первую очередь надо сделать всего одну вещь - код который умеет выводить содержимое ячеек памяти на индикатор - т.е. он будет просто перебирать знакоместа по очереди и загружать туда напрямую из соответствующих ячеек памяти состояние зажженных сегментов. Этот код достаточно прост чтобы там сильно накосячить - если он заработает то будет работать стабильно.

Вторая часть задачи - это сделать код который будет разбирать число на цифры и ставить в нужном месте точку... и кажется, его изобрели 20 лет назад и он называется... функция printf... один недостаток - много места занимает.

Share this post


Link to post
Share on other sites

Надо правильно произвести декомпозицию задачи. У вас оно как-то сумбурно, может поэтому и не работает - фиг отследишь.

В первую очередь надо сделать всего одну вещь - код который умеет выводить содержимое ячеек памяти на индикатор - т.е. он будет просто перебирать знакоместа по очереди и загружать туда напрямую из соответствующих ячеек памяти состояние зажженных сегментов. Этот код достаточно прост чтобы там сильно накосячить - если он заработает то будет работать стабильно.

Вторая часть задачи - это сделать код который будет разбирать число на цифры и ставить в нужном месте точку... и кажется, его изобрели 20 лет назад и он называется... функция printf... один недостаток - много места занимает.

Код, представленный выше полностью рабочий. Я имел ввиду, что может стоило бы оформить код для семисегментника в подключаемую библиотеку ну и может то, что я привёл выше, можно написать как-то лучше. А библиотеку сделать стоит, ведь делают библиотеки для ЖК, ну и другим людям проще будет. Тема как я понимаю именно для этого создана. Ну и самое главное я не прошу кого-то всю работу сделать, давайте вместе отшлифуем код который выше и сделаем библиотеку. И хватит рассуждать о тонких материях, или делаем или нет. Сразу о затруднения своих, я не знаю как вообще делать библиотеки. Давайте, гуру, подключайтесь не гос.тайну раскрывает :)

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 Anton Bondarenko
      Всем привет
      Прошу не ругать, впервые подобный вопрос задаю.
      Хочу сделать прибор, который будет посылать сигнал, когда возле прибора будет проходить металлический предмет. 
      — угол отслеживания до 30° а лучше прямая линия, траектория
      — время реакции очень высокое до 100 мс
      — ширина проема в котором нужно сканировать от 10 до 20метров,
      — передача сигнала через вифи
      Может есть готовые решения, или отдельные компоненты.
      Подскажите пжл в каком направлении искать.
      Смотрел датчики движения, но главная проблема — время реакции.
      Спасибо
       
    • By Вячеслав_НС
      Здравствуйте ! подскажите , какую лучше библиотеку использовать (и где ее взять) для управления i2c atmega8 в atmel studio 7  .  задача - управлять atmega8 по i2c ,  цап  PCF8591T .
      понимаю , в интернете много примеров и библиотек , но хотелось бы пример максимально простой и точно рабочий . т.к. пока что все мои попытки не привели к успеху ... то Atmel Studio 7 при компиляции ругается на несуществующий файл ( к примеру - "stream.h") при использовании библиотеки i2c , то еще какие то грабли .
    • By Sofia Vin
      Предлагаем проектную работу в Москве:
      Микроконтроллер STM32F103.
        
      Есть встроенный код с использованием функций библиотеки FreeRTOS, код имеет описанный протокол для связи с внешним миром.
        
      Необходимо проводить доработку кода под задачи программиста верхнего уровня и его тестирование в составе оборудования. 
      Работа в лаборатории (м.Университет) и удаленно. 
      Оплата по договоренности.
      Если Вы обладаете опытом схемотехнического проектирования и программирования микроконтроллеров, и Вас заинтересовала данная возможность, ждем Ваши отклики по контактным данным:
      8 (925) 023-60-02   Алексей
      E-mail: nassa@marathon.ru
       
    • By Антон Плюшкин
      В общем есть небольшая тривиальная задача - сделать свитюльку. Контроллер управляет светодиодиками, цвета меняются, людишки довольны.
      Схема проста: Attiny44a -> 2n3904 x3 -> RGB-светодиод.
      Собрал, протестил, всё норм, но!
      Как только в коде я использую функцию задержки - _delay_ms (util/delay.h) - контроллер повисает!
      #define F_CPU 16000000UL #include <avr/io.h> #include <util/delay.h> int main(void) { // Input/Output Ports initialization // Port A initialization // Function: Bit7=Out Bit6=Out Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In DDRA=(1<<DDA7) | (1<<DDA6) | (0<<DDA5) | (0<<DDA4) | (0<<DDA3) | (0<<DDA2) | (0<<DDA1) | (0<<DDA0); // State: Bit7=0 Bit6=0 Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T PORTA=(0<<PORTA7) | (0<<PORTA6) | (0<<PORTA5) | (0<<PORTA4) | (0<<PORTA3) | (0<<PORTA2) | (0<<PORTA1) | (0<<PORTA0); // Port B initialization // Function: Bit3=In Bit2=Out Bit1=In Bit0=In DDRB=(0<<DDB3) | (1<<DDB2) | (0<<DDB1) | (0<<DDB0); // State: Bit3=T Bit2=0 Bit1=T Bit0=T PORTB=(0<<PORTB3) | (0<<PORTB2) | (0<<PORTB1) | (0<<PORTB0); // Timer/Counter 0 initialization // Clock source: System Clock // Clock value: 16000,000 kHz // Mode: Phase correct PWM top=0xFF // OC0A output: Non-Inverted PWM // OC0B output: Non-Inverted PWM // Timer Period: 0,031875 ms // Output Pulse(s): // OC0A Period: 0,031875 ms Width: 0 us // OC0B Period: 0,031875 ms Width: 0 us TCCR0A=(1<<COM0A1) | (0<<COM0A0) | (1<<COM0B1) | (0<<COM0B0) | (0<<WGM01) | (1<<WGM00); TCCR0B=(0<<WGM02) | (0<<CS02) | (0<<CS01) | (1<<CS00); TCNT0=0x00; OCR0A=0x00; OCR0B=0x00; // Timer/Counter 1 initialization // Clock source: System Clock // Clock value: 16000,000 kHz // Mode: Ph. correct PWM top=0x00FF // OC1A output: Non-Inverted PWM // OC1B output: Disconnected // Noise Canceler: Off // Input Capture on Falling Edge // Timer Period: 0,031875 ms // Output Pulse(s): // OC1A Period: 0,031875 ms Width: 0 us // Timer1 Overflow Interrupt: Off // Input Capture Interrupt: Off // Compare A Match Interrupt: Off // Compare B Match Interrupt: Off TCCR1A=(1<<COM1A1) | (0<<COM1A0) | (0<<COM1B1) | (0<<COM1B0) | (0<<WGM11) | (1<<WGM10); TCCR1B=(0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (0<<WGM12) | (0<<CS12) | (0<<CS11) | (1<<CS10); TCNT1H=0x00; TCNT1L=0x00; ICR1H=0x00; ICR1L=0x00; OCR1AH=0x00; OCR1AL=0x00; OCR1BH=0x00; OCR1BL=0x00; // Timer/Counter 0 Interrupt(s) initialization TIMSK0=(0<<OCIE0B) | (0<<OCIE0A) | (0<<TOIE0); // Timer/Counter 1 Interrupt(s) initialization TIMSK1=(0<<ICIE1) | (0<<OCIE1B) | (0<<OCIE1A) | (0<<TOIE1); // External Interrupt(s) initialization // INT0: Off // Interrupt on any change on pins PCINT0-7: Off // Interrupt on any change on pins PCINT8-11: Off MCUCR=(0<<ISC01) | (0<<ISC00); GIMSK=(0<<INT0) | (0<<PCIE1) | (0<<PCIE0); // USI initialization // Mode: Disabled // Clock source: Register & Counter=no clk. // USI Counter Overflow Interrupt: Off USICR=(0<<USISIE) | (0<<USIOIE) | (0<<USIWM1) | (0<<USIWM0) | (0<<USICS1) | (0<<USICS0) | (0<<USICLK) | (0<<USITC); // Analog Comparator initialization // Analog Comparator: Off // The Analog Comparator's positive input is // connected to the AIN0 pin // The Analog Comparator's negative input is // connected to the AIN1 pin ACSR=(1<<ACD) | (0<<ACBG) | (0<<ACO) | (0<<ACI) | (0<<ACIE) | (0<<ACIC) | (0<<ACIS1) | (0<<ACIS0); ADCSRB=(0<<ACME); // Digital input buffer on AIN0: On // Digital input buffer on AIN1: On DIDR0=(0<<ADC1D) | (0<<ADC2D); // ADC initialization // ADC disabled ADCSRA=(0<<ADEN) | (0<<ADSC) | (0<<ADATE) | (0<<ADIF) | (0<<ADIE) | (0<<ADPS2) | (0<<ADPS1) | (0<<ADPS0); unsigned char VL_OCR0A = 0, VL_OCR0B = 0, VL_OCR1A = 0; OCR0A = 0; OCR0B = 0; OCR1A = 0; while(1) { _delay_ms( 100 ); VL_OCR0A = VL_OCR0A + 1; VL_OCR0B = VL_OCR0B + 1; VL_OCR1A = VL_OCR1A + 1; if( VL_OCR0A >= 250 ){ VL_OCR0A = 0; } if( VL_OCR0B >= 250 ){ VL_OCR0B = 0; } if( VL_OCR1A >= 250 ){ VL_OCR1A = 0; } OCR0A = VL_OCR0A; OCR0B = VL_OCR0B; OCR1A = VL_OCR1A; } } Т.е. если указать задержку в начале цикла, то светодиод не светится вообще.
      Если задержку убрать - светодиод немного подсвечивает всеми цветами.
      while(1) { _delay_ms( 100 ); // <--- ЗАДЕРЖКА --- VL_OCR0A = VL_OCR0A + 1; VL_OCR0B = VL_OCR0B + 1; VL_OCR1A = VL_OCR1A + 1; if( VL_OCR0A >= 250 ){ VL_OCR0A = 0; } if( VL_OCR0B >= 250 ){ VL_OCR0B = 0; } if( VL_OCR1A >= 250 ){ VL_OCR1A = 0; } OCR0A = VL_OCR0A; OCR0B = VL_OCR0B; OCR1A = VL_OCR1A; } Где я накосячил?
      З.Ы.: Замечаний по поводу оптимизации кода, излишних переменных и п.р. прошу не писать - изощряюсь как могу ибо не пойму почему не работает
×
×
  • Create New...