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

Примеры кода для AVR


Duhas

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

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

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

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

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

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

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

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

#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);

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

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

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

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

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

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

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

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

Сравнительное тестирование аккумуляторов EVE Energy и Samsung типоразмера 18650

Инженеры КОМПЭЛ провели сравнительное тестирование аккумуляторов EVE и Samsung популярного для бытовых и индустриальных применений типоразмера 18650. 

Для теста были выбраны аккумуляторы литий-никельмарганцевой системы: по два образца одного наименования каждого производителя – и протестированы на двух значениях тока разряда: 0,5 А и 2,5 А. Испытания проводились в нормальных условиях на электронной нагрузке EBD-USB от ZKEtech, а зарядка осуществлялась от лабораторного источника питания в режиме CC+CV в соответствии с рекомендациями в даташите на определенную модель. Подробнее>>

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

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

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

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

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

Новый аккумулятор EVE серии PLM для GSM-трекеров, работающих в жёстких условиях (до -40°С)

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

Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств. Подробнее параметры и результаты тестов новой серии PLM по ссылке.

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

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

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

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

тогда запись

#define example PORTB,1

arg1(example) |= 1;

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

PORTB |= 1;

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

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

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

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

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

Литиевые батарейки и аккумуляторы от мирового лидера  EVE в Компэл

Компания Компэл, официальный дистрибьютор EVE Energy, бренда №1 по производству химических источников тока (ХИТ) в мире, предлагает продукцию EVE как со склада, так и под заказ. Компания EVE широко известна в странах Европы, Америки и Юго-Восточной Азии уже более 20 лет. Недавно EVE была объявлена поставщиком новых аккумуляторных элементов круглого формата для электрических моделей «нового класса» компании BMW.

Продукция EVE предназначена для самого широкого спектра применений – от бытового до промышленного. Подробнее>>

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

#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);
....

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

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

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

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

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

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

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

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

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

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

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

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

#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);
....

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

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

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

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

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

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

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

#define STROB PORTA,0

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

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

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

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

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

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

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

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

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

#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

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

#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. Не надо меня пытаться подловить на самопротиворечии, свой код я обычно проверяю хотя бы на компилируемость. Когда не проверяю, обычно прямо об этом говорю.

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

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

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

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

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

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

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

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

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

Ладно, не судите строго я с авр вообще только начал знакомиться, приветствуются всяческие замечания, исправления, тыканье носом в косяки, короче надо создать всем народом, нормальную, понятную, библиотеку для управления 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);    //код для проверки

   }
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

×
×
  • Создать...