Jump to content

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


Duhas
 Share

Recommended Posts

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

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Link to comment
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);

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

Что может быть лучше в радиоэлектронике, чем программирование микроконтроллеров ?

Link to comment
Share on other sites

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

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

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

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

Edited by GalatZ
Link to comment
Share on other sites

Химические элементы FANSO EVE Energy для питания беспроводных датчиков
Литиевые батарейки различного химического состава и разных типоразмеров широко используются в беспроводных датчиках систем сбора данных, промышленной автоматики и систем умного дома. И в любом из многочисленных вариантов использования беспроводных датчиков основными требованиями к их работе являются автономность и бесперебойность функционирования.
Главным условием, гарантирующим такую работу, является правильный выбор элемента питания для датчика.

Подробнее >>

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

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

Что может быть лучше в радиоэлектронике, чем программирование микроконтроллеров ?

Link to comment
Share on other sites

Сравнительное тестирование алкалиновых батареек POWER FLASH 

В потребительском и промышленном сегментах российского рынка химических источников тока имеется множество щелочных (алкалиновых) батареек различных производителей и ценовых категорий. Но велика ли разница в их качестве?

Провели небольшой сравнительный тест, чтобы понять, могут ли источники тока POWER FLASH эффективно заменить продукцию таких известных производителей, как Duracell и GP, вычислить, чему равна стоимость одного часа работы батареек, а также сравнить полученные данные со значениями, указанными в технической документации.  Подробнее>>

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

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

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

тогда запись

#define example PORTB,1

arg1(example) |= 1;

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

PORTB |= 1;

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

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

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Link to comment
Share on other sites

Новые источники питания на DIN-рейку класса High End от MORNSUN
Компания MORNSUN разработала новую линейку ИП с креплением на DIN-рейку класса High End. Линейка состоит из двух семейств однофазных ИП, различающихся функционалом (LIMF и LIHF) и одного семейства на трехфазное напряжение (LITF). У всех этих ИП печатная плата с компонентами имеет лаковое покрытие. Продукция работоспособна в температурном диапазоне -40...85ºС (для однофазных) и -30...70ºС (для трехфазных). Кроме того, однофазные ИП соответствуют требованиям ATEX и могут использоваться во взрывоопасных зонах. Семейство LIMF имеет стандартный функционал (ККМ, сухой контакт реле, 150% перегрузочная способность), а семейство LIHF – максимальный функционал с доп. функциями селективной защиты (SFB) и возможностью дистанционного управления (может заменить серию QUINT от Phoenix Contact).

Подробнее >>

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

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

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

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

Что может быть лучше в радиоэлектронике, чем программирование микроконтроллеров ?

Link to comment
Share on other sites

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

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Link to comment
Share on other sites

Да, вот только по ним конкретные примеры найти непросто.
Какие примеры ? Вы о чём ? :)

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

Link to comment
Share on other sites

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

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Link to comment
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);
....

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

Link to comment
Share on other sites

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

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Link to comment
Share on other sites

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

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

А попробуйте собрать приводимый ранее пример. Будет ругаться.
Зачем же Вы тогда его приводили, если он нерабочий ? :)
Link to comment
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);
....

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

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

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

Что может быть лучше в радиоэлектронике, чем программирование микроконтроллеров ?

Link to comment
Share on other sites

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

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

#define STROB PORTA,0

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

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

Link to comment
Share on other sites

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

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

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

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Link to comment
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

Link to comment
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

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Link to comment
Share on other sites

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

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

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

Link to comment
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);    //код для проверки

   }
}

Будьте проще и люди к вам потянутся.

Link to comment
Share on other sites

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

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

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

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

Link to comment
Share on other sites

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

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

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

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Link to comment
Share on other sites

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

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

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

Учение - изучение правил. Опыт - изучение исключений.

Link to comment
Share on other sites

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

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

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

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

Будьте проще и люди к вам потянутся.

Link to comment
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
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
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...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.

×
×
  • Create New...