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

Видеокурс по AVR-микроконтроллерам для начинающих


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

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

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

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

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

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

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

4ippers , очевидно неправильно написано условие. Но поскольку вы его не привели, сказать что-то конкретное невозможно.

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

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

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

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

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

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

/////////////////////////////////////////////////
char MasS[4][4] = {{1,1,1,1} , {1,1,1,1}};
////////////////////////////////////////////////
for (int i=1; i<5; i++)
{
MasS[i][1] = eeprom_read_byte(&eeprom_var[1+i*4]);
MasS[i][2] = eeprom_read_byte(&eeprom_var[2+i*4]);
MasS[i][3] = eeprom_read_byte(&eeprom_var[3+i*4]);
MasS[i][4] = eeprom_read_byte(&eeprom_var[4+i*4]);
}

А правильно ли я пишу массив из памяти?? :blink:

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

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

Что значит "пишу массив" ? Это как ? Из какой памяти ? Куда пишите ? Что по Вашему может означать "правильно" и что "неправильно" ?

Неужели нельзя задать вопрос так, чтобы он был доходчив ?

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

si4karuk

charMasS[4][4]={{1,1,1,1},{1,1,1,1}}

вот здесь вы обозначаете что у вас 4 масива, в каждом по 4 байта, это до знака =

а после знака = вы записываете 2 масива по 4 байта, остальные два имеют мусор или 0

и если у вас чтото неправильно работает то все очевидно

Не знаеш как? Спроси у Google'а !!!

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

И элементы массива в Си адресуются с 0-ого, а не с 1-ого.

ЗЫ: В общем, как всегда, нужно включать экстрасенсорику, чтобы понять что нужно человеку.

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

И элементы массива в Си адресуются с 0-ого, а не с 1-ого.

ЗЫ: В общем, как всегда, нужно включать экстрасенсорику, чтобы понять что нужно человеку.

И тут я попался...

А про экстрасенсорику...

Мне нужно было заранее инициализировать массив.

А вообще, я пытался записать массив в епром.

Вот что получилось

#include <avr/io.h>
#include <stdio.h>
#include <avr/eeprom.h>
EEMEM unsigned char eeprom_var[107];
/////////////////////////////////////////////////
char MasS[4][4] = {{1,1,1,1} , {1,1,1,1} , {1,1,1,1} , {1,1,1,1}};
////////////////////////////////////////////////
int main(void)
{
int l=1;

for (int i=0; i<4; i++)
{
for (int j=0; j<4; j++)
{
MasS[i][j]=l;
l++;
}
}
//////////////////////////////////////////////////////////////////////////
for (int i=0; i<4; i++)
{
eeprom_write_byte(&eeprom_var[1+i*4], MasS[i][0]);
eeprom_write_byte(&eeprom_var[2+i*4], MasS[i][1]);
eeprom_write_byte(&eeprom_var[3+i*4], MasS[i][2]);
eeprom_write_byte(&eeprom_var[4+i*4], MasS[i][3]);
}
//////////////////////////////////////////////////////////////////////////
for (int i=0; i<4; i++)
{
for (int j=0; j<4; j++)
{
MasS[i][j]=7;
}
}
//////////////////////////////////////////////////////////////////////////
for (int i=0; i<4; i++)
{
MasS[i][0] = eeprom_read_byte(&eeprom_var[1+i*4]);
MasS[i][1] = eeprom_read_byte(&eeprom_var[2+i*4]);
MasS[i][2] = eeprom_read_byte(&eeprom_var[3+i*4]);
MasS[i][3] = eeprom_read_byte(&eeprom_var[4+i*4]);
}

asm ("nop");

while(1)
{

}
}

В итоге, я получил

J3EmbvpQMmA.jpg

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

В итоге, я получил

Ну, вроде всё норм. Сначала пишете в еепром числа с 1 по 16, потом читаете обратно в массив.

Всё работает :)

И инициализация во время объявления тут совсем не причём :)

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

Можно вообще так сделать :

char* p_arr = MasS;
EEMEM unsigned char* p_ee = &eeprom_var[0]; // Индекс (0) указан намеренно, для адресации начальной ячейки.
unsigned char i;

for(i=0;i<sizeof(MasS);i++) eeprom_write_byte(p_ee++, *p_arr++);

Это запись.

Должен записаться весь массив MasS в еепром.

Но я тут не уверен, как компилятор отреагирует на указатель со спецификатором EEMEM. Хотя, по логике, всё должно работать.

PS: Чтение, соответственно, в обратном направлении.

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

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

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

Помогите пожалуйста начинающему! Имеется следующий код:

//AtMega8A
#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
void presets()
{

DDRC=0xFF; //касяк ???????
PORTC=0x00;
DDRB=0xFF; //порт настроен на выход
PORTB=0x00; //низкий уровень порта
}

int main(void)
{
presets();
int stat_button=0; // переменная состояния кнопки
while(1)
{
if (PINC&(1<<PC0)&(stat_button==0))
{
PORTB=0xFF;
stat_button=1;
_delay_ms(20);
}
else if (PINC&(1<<PC0)&(stat_button==1))
{
PORTB=0x00;
stat_button=0;
_delay_ms(20);
}
}
}

Суть данного кода, чтобы при нажатии на кнопку загорались светодиоды, при повторном нажатии на кнопку потухали. Пользуюсь Atmel Studio 6.2. При вышеупомянутом коде все работает как надо на живом кристалле. Если же заменить DDRC=0xFF; PORTC=0x00; на DDRC=0x00; и PORTC=0xFF; соответственно, то светодиоды начинают просто мигать. Ведь судя по урокам регистр DDR отвечает за направление порта, если 0, то на вход, единица на выход. В Протеусе работает и так и сяк. Подскажите, что происходит и в чем мой косяк?

post-189746-0-75422600-1431730277_thumb.png

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

Возможно это потому что PINx определяет реальный логический уровень, независимо от направления порта. В случае DDRC=0xFF; PORTC=0x00 порт соединен с землей выходным каскадом (это комплементарная пара МОП-транзисторов). Их сопротивление в открытом состоянии хоть и небольшое, но у кнопки еще меньше. То есть через n-канальный транзистор (это тот, который соединяет с землей) идет ток, ограниченный только его сопротивлением канала. Реальный контроллер такого надругательства может и не выдержать, а виртуальному без разницы. И падения напряжения на транзисторе может хватать для сигнализации о высоком лог. уровне.

DDRC=0xFF; //касяк ???????

Да, "касяк". В орфографии.
if (PINC&(1<<PC0)&(stat_button==0))

Если надо менять состояние кнопки именно по нажатию, лучше фронт и ловить:

if( PINC & (1<<PC0) ){ //если кнопка нажата
while ( PINC & (1<<PC0) ){ //пока кнопка нажата
 _delay_ms(100); //ждем пока не отпустят. ИМХО 100-200 мс вполне достаточно для человеческой реакции и подавления дребезга
}
PORTB =~PORTB; //меняем состояние порта на противоположное
}

Это лобовое решение для конкретной задачи. Расширять его довольно сложно из-за зацикливания при ожидании кнопки.

unsigned char lbutton=0;
unsigned char edge_flag=0;
...
while(1){
if( PINC & (1<<0) ){ //если кнопка нажата
 lbutton = 1; //взводим флаг, что предыдущее состояние было "нажата"
}else{ //если же кнопка отпущена
 if( lbutton ){ //проверяем ее предыдущее состояние
  edge_flag=1; //если она была нажата (а теперь отпущена), выставляем флаг, что поймали фронт (сбрасываться будет при обработке)
 } //если же она и была отпущена - не делаем ничего
 lbutton =0; //и в любом отмечаем, что ее предыдущее состояние - отпущена.
} //этот блок относится только к обработке кнопки. Антидребезг реализуется за счет времени одного бесконечного цикла. Именно для данной задачи его не хватит и придется добавить delay.
//дальше идут другие блоки. Например, процедура при нажатии кнопки (сам факт нажатия поймали, теперь надо обработать)
if( edge_flag ){
 PORTB ^= 0xFF; //меняем выходы на противоположные.
}
}

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

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

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

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

Я собрал все на макетной плате, рисунок снизу. Написал банальный код как в уроках.

//AtMega8A
#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
void presets()
{

DDRC=0x00;
PORTC=0xFF;
DDRB=0xFF;
PORTB=0x00;
}

int main(void)
{
presets();

while(1)
{
if (PINC&(1<<PC0))
{
PORTB=0xFF;

}
else {
PORTB=0x00;
}
}
}

При настройках порта DDRC=0x00; PORTC=0xFF: светодиод вообще горит постоянно, если изменить настройки данного порта на противоположные, то все работает как надо, нажимаешь кнопку светодиод загорается. Пробовал на двух контроллерах. Эффект один и тот же. В протеосе все нормально. Что я не так делаю?

post-189746-0-36528300-1431782566_thumb.jpg

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

Что-то я не вижу подтягивающего резистора для кнопки на вашей макетке, возможно вход кнопки ловит помехи от соседской микроволновки

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

Не знаеш как? Спроси у Google'а !!!

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

Что-то я не вижу подтягивающего резистора для кнопки на вашей макетке, возможно вход кнопки ловит помехи от соседской микроволновки

Пробовал и с подтягивающим резистором, толку 0. Эффект есть только когда меняешь направление порта кнопки на выход.

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

Это уже на сегодня второй вопрос с аналогичной проблемой.

http://forum.cxem.net/index.php?showtopic=150904&hl=

А как у вас с питанием? По наружной стороне макетки конечно понять сложно, но на фото получается, что вывод VCC (7 нога) идет на общую шину (-). Туда же подключен второй вывод кнопки. А с плюсовой шины черный провод идет на GND (8 нога)

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

Это уже на сегодня второй вопрос с аналогичной проблемой.

http://forum.cxem.ne...opic=150904&hl=

А как у вас с питанием? По наружной стороне макетки конечно понять сложно, но на фото получается, что вывод VCC (7 нога) идет на общую шину (-). Туда же подключен второй вывод кнопки. А с плюсовой шины черный провод идет на GND (8 нога)

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

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

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

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

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

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

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

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

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

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

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

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

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