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

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


Duhas

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

Если значение возвращается в BCD коде. Эффективностью тут и не пахнет.

Спасибо за пояснение. В даташите написано что BCD. Тогда поясните пожалуйста как правильно оформить деление?

Я вот смотрю на эту картинку и мне почему-то кажется что деление вообще не нужно... Помогите разобраться пожалуйста.

post-166404-0-61000400-1409755725_thumb.jpg

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

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

Битовыми масками, как обычно. Для старшего разряда, по таблице, отведены байты 4-6. То есть маска 0b01110000. Поскольку нас интересует именно число, а не полубайт, сдвигаем его на 4 разряда вправо. На самом деле эффективнее просто поменять разряды местами. Таким образом старший разряд можно получить следующим кодом

mov r17,r16 ;младший разряд тоже понадобится, поэтому сохраняем
andi r17,0b01110000 ;обрезаем все лишнее по маске
swap r17 ;меняем разряды местами, в данной ситуации это аналогично сдвигу на 4 разряда вправо

С младшим разрядом все проще, это просто 4 младших бита, то есть маска 0b00001111, соответственно код будет выглядеть (продолжение предыдущего) так

andi r16,0b00001111

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

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

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

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

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

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

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

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

Принцип работы с BCD по идее тот же самый что и с обычным числом, только делить надо не на 10, а на 16. Либо сделать так как приведено в посте 398.

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

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

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

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

Битовыми масками, как обычно...
Извините, но моих знаний, похоже, не достаточно чтобы это понять.

Либо сделать так как приведено в посте 398.

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

post-166404-0-86042800-1409833856_thumb.jpg

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

Без исходников можно только гадать что у вас происходит.

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

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

#include <mega8.h>
#include <stdio.h>
#include <delay.h>
// I2C Bus functions
#asm
  .equ __i2c_port=0x18 ;PORTB
  .equ __sda_bit=0
  .equ __scl_bit=1
#endasm
#include <i2c.h>
// DS1307 Real Time Clock functions
#include <ds1307.h>
char hour,min,sek;
static flash unsigned char display[]=    // масив для индикатора
{
 (0b11000000), // 0
 (0b11111001), // 1
 (0b10100100), // 2
 (0b10110000), // 3
 (0b10011001), // 4
 (0b10010010), // 5
 (0b10000010), // 6
 (0b11111000), // 7
 (0b10000000), // 8
 (0b10010000), // 9   
};
// Timer1 output compare A interrupt service routine
interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
 TCNT1H=0x00;
 TCNT1L=0x00; 
}

void show_time()
{  
unsigned char time_var[6];
rtc_get_time(&hour,&min,&sek);
time_var[0]=hour/10;
time_var[1]=hour%10;
time_var[2]=min/10;
time_var[3]=min%10;
time_var[4]=sek/10;
time_var[5]=sek%10;

PORTC.0=1;
PORTD=display[time_var[0]]; 
delay_ms(5);
PORTC.0=0;

PORTC.1=1;
PORTD=display[time_var[1]]; 
delay_ms(5);
PORTC.1=0;

PORTC.2=1;
PORTD=display[time_var[2]];  
delay_ms(5);
PORTC.2=0;

PORTC.3=1;
PORTD=display[time_var[3]];  
delay_ms(5);
PORTC.3=0;

PORTC.4=1;
PORTD=display[time_var[4]];
delay_ms(5);
PORTC.4=0;

PORTC.5=1;
PORTD=display[time_var[5]];
delay_ms(5);
PORTC.5=0;
}
void main(void)
{
PORTB=0x1C;
DDRB=0x20;
PORTC=0x00;
DDRC=0x0F;
PORTD=0x00;
DDRD=0x7F;
TCCR1A=0x00;
TCCR1B=0x05;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x1E;
OCR1AL=0x85;
OCR1BH=0x00;
OCR1BL=0x00;
TIMSK=0x10;
i2c_init();
rtc_init(0,0,0);
rtc_set_time(12,0,0);
#asm("sei")
while (1)
{
show_time();		 
};
}

Кстати, этот код нормально работает, но вот говорят что так не правильно... И кнопки не могу прикрутить...

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

Вот так как раз ничего не работает
В даташите написано

1. Объясните, а для чего Вы полезли в даташит, если используете библиотечные функции ? Для чего это низкоуровневое ковыряние ?

2. Вы используете функцию rtc_get_time. А Вы разобрались как она работает, что делает, в каком формате укладывает данные ?

Полагаю, что нет. Отсюда следующий вопрос:

3. Как же Вы тогда её вообще используете, не разобравшись ? Как вообще можно совать в код то, о чём совершенно не знаешь ? Это как пихать в рот пищу что-то вслепую, не ощущая вкуса и запаха... А потом бежать к доктору (на форум) и жаловаться на скручивание живота (ничего не работает, помогите !!!) и понос (на индикаторе какая то лажа).

Итог - 2 страницы всяческих говносоветов (не ко всем относится) и экстрасенсо-разбирательств. А всё из-за того, что Вы, задав вопрос "как разложить переменные на части", даже не удосужились рассказать нам в каком формате хранятся данные в этих переменных.

И кнопки не могу прикрутить...
Как понять "не могу" ? Физически ? Попробуйте взять шуруповёрт, им легче крутить.

ЗЫ: Ну в четвёртых. Вы в курсе вообще, для чего эта тема создавалась ? Или Вы не любите читать темы также, как и всяческую документацию ? Типо - "Во, какая то тема, дай ка я в неё напишу...".

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

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

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

Возник маленький вопрос по ассемблеру для AVR, точнее по написанию для него макросов. В разных контроллерах одна и та же переферия может называться по-разному. Например, регистры UART в ATmega8 называются UCSRA-UCSRC, а в ATmega88 - UCSR0A-UCSR0C. В аналогичной ситуации в Си я писал такой макрос

#ifndef UCSRA
   #ifdef UCSR0A
       #define UART_NUM    0
   #endif
#else
   #define UART_NUM
#endif
//UART_NUM - номер используемого UART'а. Может быть пустым, может 0. В некоторых контроллерах есть только UART1, но для демонстрации принципа это не важно.
#define _concat3(a,b,c)    a##b##c
#define concat3(a,b,c)    _concat3(a,b,c)

#define UCSRxA    concat3(UCSR,UART_NUM,A)

В Сишном препроцессоре макроподстановка выполняется в 2 этапа, то есть concat3(UCSR,UART_NUM,A) -> _concat3(UCSR,0,A) -> UCSR0A. Препроцессор ассемблера допускает аналогичные макросы, но вот подстановку 0 вместо UART_NUM делать отказывается, из-за чего компилятор начинает ругаться на UCSRUART_NUMA. Может кто знает, как это победить?

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

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

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

компилятор начинает ругаться на UCSRUART_NUMA
Ну и СИшный компилятор обматерит за такую строку. Для конкатенации строк препроцессора нужно использовать символ "##".

ЗЫ: Не досмотрел, Вы используете макрос concat3. Пардон :rolleyes:

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

  • 2 месяца спустя...

Друзья! Помогите пожалуйста. Нужна библиотека (файлы с расширением .с, .h) для работы с дисплеем LCD 1602 (winstar тот же) в IDE Atmel Studio 6.2. Устал искать уже.

Находил по code vision avr и под другие IDE, но вот нужно под эту на языке "СИ". Заранее спасибо. Если что то не корректно написал, прошу прощения, только начал осваивать эту науку.

Спасибо!

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

1. На форумах обычно не приветствуется кросс-постинг.

2. Перед тем, как задать вопрос, надо было погуглить. Запросы "1602 lcd avr-gcc" и "1602 lcd winavr" выдают примеры первой или второй ссылкой.

3. Если не устроили результаты поиска (мало ли чего там могли понаписать в коде тех же библиотек), стоит указать на рассмотренные библиотеки и обнаруженные недостатки.

4. Конкретно для таких дисплеев протокол достаточно простой, можно и самому написать. Если не хватает опыта - готовые решения не помогут, надо учиться.

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

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

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

Здравствуйте форумчане! Возник вопрос по определению портов

такая запись верна? и при такой записи для отправки например на вывод 0 порта а логического "один" нужно прописывать все 8 бит или можно писать 0 или 1 ?

#define VFD_STB PORTA, 0 
#define VFD_CLK PORTA, 1 
#define VFD_DOUT PORTA, 2

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

добавить уже просто нечего...

а Вы попытайтесь

может не верно вопрос поставил

мне не понятно, если я таким образом определю порт, то для подачи лог еденицы на вывод 0 можно пользоваться записью

VFD_STB = 1;

или нужно

VFD_STB = 0x01;

?

в этом "интернете" толком про такое определение ничего не нашел..

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

таким образом определю порт
Очередной раз Вас прошу - почитайте про эту директиву, дабы не позориться с подобными фразами :)

Всё там нормально написано, просто разберитесь что такое #define.

Что же все какие лентяи то, совершенно читать не хотят. Как вы программировать то собрались с таким подходом ? :)

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

Я обычно делаю так.

Работает как пулемет :)

#define SET_PORT PORTA|=(1<<0)
#define CLR_PORT PORTA&=~(1<<0)

void delay(int y)
{
for(x=0; x<y; x++);
}

// применение
// мигаем светодиодом
void main()
{
while(1)
{
SET_PORT;
delay(1000);
CLR_PORT;
delay(1000);
}
}

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

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

такая запись верна?
Синтаксически - да, ругаться на нее не будут, но вот использовать ее не всегда просто.

мне не понятно, если я таким образом определю порт, то для подачи лог еденицы на вывод 0 можно пользоваться записью

VFD_STB = 1;

или нужно

VFD_STB = 0x01;

?

Нет, оба варианта не верны. На каком диалекте пишете? В gcc можно добавить опцию -E, чтобы посмотреть код после макроподстановки и увидеть, почему именно он не работает.

Я обычно делаю так.

Я так делаю только в половине случаев. В остальных использую специальные макросы для расшифровки #define OUT_PORT C,1 в набор PORTC, PINC, DDRC, 1, (1<<1) и операции с ними. Иногда удобнее так, иногда - по-другому.

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

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

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

Я так делаю только в половине случаев. В остальных использую специальные макросы для расшифровки #define OUT_PORT C,1 в набор PORTC, PINC, DDRC, 1, (1<<1) и операции с ними. Иногда удобнее так, иногда - по-другому.

Я делаю так по той причине , что так заработает в любой среде. И это не потребует адаптации/допиливания кода при переносе в другую среду или даже мк .

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

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

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

И поняв, что define - это всего-лишь тупо замена текста, всё встанет на свои места.

Но некоторые люди - лентяи, им нужно чтобы всё быстро. Вот и начинают тыкать методом тыка, не понимая, что выбирают длинный путь.

Их стараешься направить на путь истинный, но они обижаются, приравнивая посылку в гугол к посылке на ...

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

Их стараешься направить на путь истинный, но они обижаются, приравнивая посылку в гугол к посылке на ...

Ну что вы так сразу

бывает же долго доходит

тем более еще новичок в этом деле и вопросы задаю не от лица пишушего огромный проэкт

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

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

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

Ну вот, уже лучше.

Теперь представьте, во что развернётся Ваша строка :

PORTA, 0 = 1;

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

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

Можно, конечно, извратнуться

struct bits_t{
 unsigned char _0:1;
 unsigned char _1:1;
...
 unsigned char _7:1;
};
#define VFD_STB ((struct bits_t*)&PORTA))->_0

но выглядит и работает оно хуже, чем примеры artos5.

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 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);

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

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

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

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

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

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

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

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

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

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

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

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