Дмитрий Мартынов

Проблема с чтением PCF8574AT (LCD/I2C)

14 сообщений в этой теме

Здравствуйте!

Пишу программу на C++ для управления LCD (HD44780) по I2C через модуль расширения портов ввода/вывода PCF8574AT.

void LCD_I2C::readBF()
{
	transmitByte(0b00001110); //transmits E, RW set to HIGH and RS, set to LOW
	_delay_ms(5);
	transmitByte(0b00001010); //transmits E, RS set to LOW and RW set to HIGH
	_delay_ms(5);
	initRestart();
	transmitAddrRW(0b01111111); //sends PCF8574AT address + SLA+R
	do
	{
		receiveDataAck();
		PORTA = storage;
	}
	while((storage & (1 << BF)) != 0); //wait until BF is 0
	initRestart();
	transmitAddrRW(0b01111110);
}

Метод void transmitByte(uint8_t data) после инициализации состояния "Старт" и отправки адреса устройства + SLA+W отправляет байт данных по TWI с ожиданием бита подтверждения (команды работают верно, проверял по регистру статуса TWI - 0x08, 0x10 и 0x24).
Метод void transmitAddrRW(uint8_t address) отправляет соответственно SLA+W/R + адрес устройства (команда работает также верно). Нареканий к работе TWI у меня нет, т.к. недавно с его помощью успешно запустил часы DS1307 с интеграцией LCD.
После передачи запроса на чтение флага занятости инициализируется состояние "ПОВСТАРТ", отправляется адрес устройства + SLA+R, далее идет цикл - запрос байта данных (состояние выводов PCF8574AT) с отправкой бита подтверждения uint8_t receiveDataAck() (команды работают также верно, возвращает storage = TWDR) и вывод storage на порт А микроконтроллера (там установлены светодиоды).
Чтение регистра данных TWDR после принятия байта данных (receiveDataAck()) дает следующий результат - 0b00000010 - установлен только бит RW микросхемы. Таким образом, флаг занятости BF = DB7 = 7й бит оказывается сразу же сброшенным, происходит мгновенный выход из цикла - контроллер дисплея не успевает скушать информацию, и инициализация не выполняется (неудачную инициализацию определяю по отсутствию курсора). Ожидалось, что флаг занятости будет установлен в единицу и произойдет несколько итераций перед выходом из цикла.
При замене метода ожидания сброса флага занятости BF на программную задержку в 250 мс везде, где это требует datasheet - инициализация происходит успешно (появляется курсор, как и должно быть).

Вопрос: что можно сделать, чтобы вместо _delay_ms(250) использовать readBF(), т.к. этот путь мне кажется более верным (уж очень не хочется использовать задержку .__.)? Возможно, проблема в микросхеме, которая неверно выдает информацию при чтении? (Имеется вторая микросхема, она вообще не работает:D)

З.Ы. На фото виден результат чтения флага BF и Adress Counter - установлен только бит RW.  

LCD_TWI.jpg

image.png

image.png

З.Ы.Ы Кому интересно - вот функция main(). Повторюсь - проблема только в методе readBF():

void LCD_I2C::init()
{
	setBitRate(20000);
	initStart();
	transmitAddrRW(0b01111110); //send PCF8574AT address + SLA+W
	_delay_ms(60);
	sendInstruction(0b00110000); //function set 8-bit operation
	_delay_ms(20);
	sendInstruction(0b00110000); //function set 8-bit operation
	_delay_ms(5);
	sendInstruction(0b00110000); //function set 8-bit operation
	_delay_ms(5);
	sendInstruction(0b00100000); //function set 4-bit operation
	readBF();
	//_delay_ms(250); //debug!!
	sendInstruction(0b00100000); //function set 4-bit operation, 2 lines, 5x8 dots
	sendInstruction(0b10000000);
	readBF();
	//_delay_ms(250); //debug!!
	sendInstruction(0b00000000); //display off, cursor off, blinking off
	sendInstruction(0b10000000);
	readBF();
	//_delay_ms(250); //debug!!
	sendInstruction(0b00000000); //display clear
	sendInstruction(0b00010000);
	readBF();
	//_delay_ms(250); //debug!!
	sendInstruction(0b00000000); //entry mode set increment, display shift off
	sendInstruction(0b01100000);
	readBF();
	//_delay_ms(250); //debug!!
	sendInstruction(0b00000000); //display on, cursor off, blinking off
	sendInstruction(0b11100000);
	readBF();/
}

 

Изменено пользователем Дмитрий Мартынов
Дополнил функцией main()

Поделиться сообщением


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

Зачем тебе читать Busy Flag? Пока ты его прочитаешь, его там не будет. Дисплей HD44780 не такой тормоз, как о нем пишут мифы.

Ставишь 4 бита режим, R/W на массу, толкаешь по 32 байта из озу сразу обновляя весь дисплей по прерыванию таймера или вызываешь функцию обновления индикации. 

Поделиться сообщением


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

init_lcd:              // Инициализация ЖКИ     тайминги важны
cbi     LCD,rw         // RW  --> 0
cbi     LCD,e          // E   --> 0
cbi     LCD,rs         // RS  --> 0
rcall   wait_20ms      // ждем 20 милисекунд
ldi     data,0x28      // 4 бита режим 5 х 7 точек 2 строки
rcall   lcd_cmd_i      // передаем команду в ЖКИ
rcall   wait_20ms      // ждем 20 милисекунд 
ldi     data,0x0C      // 4 бита режим 5 х 7 точек 2 строки
rcall   lcd_cmd_i      // передаем команду в ЖКИ
rcall   wait_20ms      // ждем 20 милисекунд
ldi     data,0x28      // 4 бита режим 5 х 7 точек 2 строки
rcall   lcd_cmd_i      // передаем команду в ЖКИ
rcall   wait_20ms      // ждем 20 милисекунд
rcall   clr_lcd        // очищаем жки 
sbi     LCD,led        // включаем подсветку
ret                    // выход

 

 

Поделиться сообщением


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

Значит предлагается использовать задержку в 20 мс, я это учту и попробую. Хочется, конечно, читать BF, вдруг он сбрасывается не за 20, а за 2 мс:)

Однако, видимо время обмена по TWI превышает время, за которое сбрасывается BF, поэтому на частоте в 1МГц думаю это уже не так важно. Для более высоких частот проверка BF будет более востребована.

Изменено пользователем Дмитрий Мартынов

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Andras    18

20мс много, дисплею хватает 2мс за глаза, хота ничего не мешает поэкспериментировать.

и вообще, вот вам рабочий код инициализации этого дисплея.

void pcf_write(unsigned char data)						// Функция записи в PCF8574a
{
	i2c_start_write(0x3f);// старт записи с адресом ведомого (pcf8574a)
	i2c_write(data+LIGHT);//запись байта. тут отправка ячейки памяти не нужна, по этому пропускаем процедуру и сразу пишем байт
}

void lcd_init(void)
{
	_delay_ms(1);
	lcd_bufer = 0b00110000;//берем байт
	pcf_write(lcd_bufer);//передаем по i2c
	lcd_bufer |= E;//дрыгаем ногой E
	pcf_write(lcd_bufer);// ---||---
	lcd_bufer &= ~E;// ---||---
	pcf_write(lcd_bufer);
	_delay_ms(5);
	lcd_bufer |= E;
	pcf_write(lcd_bufer);
	lcd_bufer &= ~E;
	pcf_write(lcd_bufer);
	_delay_us(100);
	lcd_bufer |= E;
	pcf_write(lcd_bufer);
	lcd_bufer &= ~E;
	pcf_write(lcd_bufer);
	_delay_us(100);
	lcd_bufer = 0b00100000;
	pcf_write(lcd_bufer);
	lcd_bufer |= E;
	pcf_write(lcd_bufer);
	lcd_bufer &= ~E;
	pcf_write(lcd_bufer);
	_delay_us(100);
	lcd_com(0x01); // очистка дисплея
	lcd_com(0x0C); // включение дисплея, курсор не видим
}

void lcd_com(unsigned char value)							// Функция передачи команды в LCD
{
	lcd_bufer = value & 0xF0;//старш тетрада
	lcd_bufer &= ~RS;
	lcd_bufer |= E;
	pcf_write(lcd_bufer);
	lcd_bufer &= ~E;
	pcf_write(lcd_bufer);
	_delay_us(10);
	lcd_bufer = (value & 0x0F)<<4;//младш тетрада
	lcd_bufer &= ~RS;
	lcd_bufer |= E;
	pcf_write(lcd_bufer);
	lcd_bufer &= ~E;
	pcf_write(lcd_bufer);
	if(value & 0b11111100)
	_delay_us(10);
	else _delay_ms(2);
}

void lcd_data(unsigned char value)							// Функция передачи данных в LCD
{
	lcd_bufer = value & 0xf0;
	lcd_bufer |= RS;
	lcd_bufer |= E;
	pcf_write(lcd_bufer);
	lcd_bufer &= ~E;
	pcf_write(lcd_bufer);
	_delay_us(10);
	lcd_bufer = (value & 0x0F)<<4;
	lcd_bufer |= RS;
	lcd_bufer |= E;
	pcf_write(lcd_bufer);
	lcd_bufer &= ~E;
	pcf_write(lcd_bufer);
	_delay_ms(2);
}

 

забыл добавить это для 20*4, для 16*2 надо в ините поправить байтики

Изменено пользователем Andras
  • Лайк 1

Поделиться сообщением


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

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

Скорость тактирования по линии SCL микроконтроллера составляет fSCL = 20000Гц, а значит передача байта осуществляется за 0.4 мс. Т.к. режим передачи 4х битовый, на отправку команды требуется 0.8 мс (2 байта).

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

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

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

Ведь, по сути, мой метод readBF() - это такая же задержка, но она ждет конкретной готовности контроллера. Раз флаг читается нулем - значит контроллер готов. Почему тогда не происходит верной инициализации????

void LCD_I2C::readBF()
{
	transmitByte(0b00001110); //transmits E, RW set to HIGH and RS, set to LOW
	transmitByte(0b00001010); //transmits E, RS set to LOW and RW set to HIGH
	initRestart(); //initilizes RESTART state
	transmitAddrRW(0b01111111); //sends PCF8574AT address + SLA+R
	do
	{
		receiveDataAck(); //read BF (get data to storage register)
	}
	while((storage & (1 << BF)) != 0); //wait until BF is 0
	initRestart(); //initialiazes RESTART state
	transmitAddrRW(0b01111110); //sends PCF8574AT + SLA+W
}

 

Изменено пользователем Дмитрий Мартынов
Дополнил кодом метода readBF() с комментариями команд

Поделиться сообщением


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

Если с английским проблемы, есть русская дока на HD44780.

1 - пройди инициализацию! Не надо никуда торопиться. Сейчас очень много китайских дисплеев, и тайминги могут быть иными, поэтому задержки обязательны в момент инициализации.

2 - читай самое первое сообщение.

3 - пиши свой код, который тебе понятен. Данные передаются в 2 захода, старший ниббл и младший ниббл.

Как это выглядит наглядно. 

В твоем случае LCD - это регистр PCF8574,  переменная uint8

3 бита RS, RW, E 

4 бита D7...D4

1 бит резерв или подсветка, я вникал.

send_nibble:           // Передача полубайта в ЖКИ
sbi     LCD,e          // E --> 1
in      tmp,LCD        // прочитать содержимое порта (в твоем случае байт который ты суешь в PCF8574)
andi    tmp,0x0F       // и выделить старшую тетраду
andi    data,0xF0      // выделить младшую тетраду в регистре 
or      data,tmp       // смешать регистр с данными
out     LCD,data       // выдать в порт ЖКИ результат
cbi     LCD,e          // E --> 0 
ret                    // выход

 

Удачи.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
5 часов назад, pavel-pervomaysk сказал:

Если с английским проблемы, есть русская дока на HD44780.

1 - пройди инициализацию! Не надо никуда торопиться. Сейчас очень много китайских дисплеев, и тайминги могут быть иными, поэтому задержки обязательны в момент инициализации.

2 - читай самое первое сообщение.

3 - пиши свой код, который тебе понятен. Данные передаются в 2 захода, старший ниббл и младший ниббл.

Как это выглядит наглядно. 

В твоем случае LCD - это регистр PCF8574,  переменная uint8

3 бита RS, RW, E 

4 бита D7...D4

1 бит резерв или подсветка, я вникал.

send_nibble:           // Передача полубайта в ЖКИ
sbi     LCD,e          // E --> 1
in      tmp,LCD        // прочитать содержимое порта (в твоем случае байт который ты суешь в PCF8574)
andi    tmp,0x0F       // и выделить старшую тетраду
andi    data,0xF0      // выделить младшую тетраду в регистре 
or      data,tmp       // смешать регистр с данными
out     LCD,data       // выдать в порт ЖКИ результат
cbi     LCD,e          // E --> 0 
ret                    // выход

 

Удачи.

1 - для инициализации дисплея в даташите указан конкретный алгоритм, который я привел в самом первом сообщении. Все, что в нем требуется я делаю вместе с программными задержками вплоть до 4й команды. Затем там написано после 4й команды (4го отправленного полубайта): "после этой команды флаг занятости может быть прочитан". С задержками до 4й команды все нормально, к ним больше не возвращаемся.
2 - Читаю первое сообщение. "Зачем читать флаг". На высоких частотах fSCL модуля TWI будет выше, поэтому отправка команд на дисплей будет производиться быстрее сброса флага BF. Поэтому возникает ризон все же его прочитать, как написано в том самом даташите. "Пока ты его прочитаешь он уже сбросится". Ну пускай он сбросится, если сбросился, значит контроллер готов принимать следующий байт данных. Раз он сбросился , значит контроллер готов к работе, и ждет следующей команды. Так почему же он НЕ инициализируется, когда в коде присутствует команда проверки BF? Почему он инициализируется просто с задержками, во время которых флаг BF также сбрасывается, но только гораздо раньше?

ПОВТОРЮСЬ:

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

Имеется необходимость сделать правильную инициализацию с чтением флага занятости BF, исключив необходимость вслепую прописывать задержки, взятые с потолка.

Возможно я не совсем хорошо объясняю и поэтому в этом трудно разобраться.


3 - метод отправки полубайта у меня есть и он работает нормально, но все равно спасибо. Ассемблер - это хороший процедурный язык, но не в этой теме. Здесь C++.

Поделиться сообщением


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

Перфектционизм это хорошо! Давай проверим твою озадаченность и переведем ее на человеческий фактор.

Сколько раз в секунду твой глаз способен обработать 32 разных символа? Уверен это будет до 10 кадров, если тебе лет 15-20. 

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

На последок из практики: HD44780 способен давать скорость, которая превышает скорость работы самого LCD (стекла).

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Andras    18

а еще есть варианты с оттяжкой контраста к отрицательному напряжению, тогда ваще четко символы появляются :).

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

или это чисто принципиально, надо досконально разобраться? 

вот вам рабочие настроенные библиотеки на 1602 и pcf8574

нужно только поправить адрес i2c микросхемы.

в командах разберетесь.

i2c.hi2c.clcd.clcd.h

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
37 минут назад, Andras сказал:

а еще есть варианты с оттяжкой контраста к отрицательному напряжению, тогда ваще четко символы появляются :).

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

или это чисто принципиально, надо досконально разобраться? 

вот вам рабочие настроенные библиотеки на 1602 и pcf8574

нужно только поправить адрес i2c микросхемы.

в командах разберетесь.

i2c.hi2c.clcd.clcd.h

да, это все из-за любопытства, спасибо за файлы, я их посмотрю)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Andras    18

мне чего то тут подумалось, а вообще из этой pcf8574 можно читать?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
11 минуту назад, Andras сказал:

мне чего то тут подумалось, а вообще из этой pcf8574 можно читать?

 

image.png.dbbec71cd1901ac07e6c792af5e84748.png

В даташите приводится временная диаграмма для режима чтения, поэтому чтение возможно. А еще написано, что если данные на выводах микросхемы меняются быстрее, чем может прочитать микроконтроллер, то эта информация будет потеряна (на диаграмме DATA2 и DATA3 теряются).

"If the data on the input port changes faster than the master can read, this data may be lost. The DATA 2 and DATA3 are lost because these data did not meet the setup time and hold time (see Figure 9)."

Еще приводится алгоритм чтения, в моем коде выполняется все в той же последовательности, только вместо отправки бита неподтверждения и СТОП состояния посылается состояние ПОВСТАРТ:   image.png.f3669ae21c7a8ff888cfa346da004364.png

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
stalware    0

Дмитрий, вы нашли решение своего вопроса? У меня подобная ситуация. Чтение BF флага всегда возвращает ноль. У меня подключение по 8-ми битной шине напрямую мк->lcd. Трассировал в Proteus.

Поделиться сообщением


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

Создайте аккаунт или войдите в него для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!

Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас


  • Похожие публикации

    • Автор: Alexey104
      Всем привет!
      Возникла следующая проблема:
       
      Есть две ардуины 'Mega2560'. По несчастливому стечению обстоятельств данные платы попали в руки одному чуваку, который, вернув их, заявил, что они перестали работать после того, как он "чисто ради интереса" поковырял на обеих некоторые фьюзы. Есть у меня такой китайский usbasp v2 программатор:
      Подключив данный девайс к ICSP-пинам первой платы, удалось без проблем восстановить на ней загрузчик через стандартную Arduino-IDE, после чего работоспособность платы полностью восстановилась. Но вот при попытке сделать то же самое со второй платой, получаю это:
      Такое же сообщение получаю при попытке зашить загрузчик в неподключенную к программатору ардуину, то есть программатор вообще не видит МК. Плата прекрасно работала до того, как вышеупомянутый товарищ покрутил настройки фьюзов.
       
      Что я пытался предпринять:
      Замыкал пины JP3 программатора, отвечающие за понижение скорости, подключал к ардуине 5V от внешнего источника при прошивке загрузчика, - не помогло.
       
      Поиском пользоваться умею, аналогичную тему тут находил, но там проблема была в том, что парень неверно подключал программатор к контроллеру. В моём же случае всё подключено верно, повторюсь, что загрузчик первой платы этим же программатором был восстановлен успешно.
      Буду рад любым советам касательно того, как восстановить работоспособность платы.
       
       
       
    • Автор: Ru_s
      Здравствуйте. Подскажите пожалуйста, возможно ли на attiny13 реализовать такую штуку. Мне в процессе работы программы нужно поменять режим работы таймера/счетчика с fast PWM на обычный счёт, отсчитать длительный промежуток времени и опять вернутся в режим ШИМ. Т.е. я подаю на ногу сигнал ШИМ и когда он в максимальном значении, я его отключаю, и тупо подаю на ногу высокий лог. уровень. В это время Т/С по идее свободен, и мне надо посчитать время работы выхода на максимальном лог. уровне, при достижении какого-то значения времени нужно перевести т/с обратно в ШИМ. Возможно ли это? И как приблизительно это реализовать
    • Автор: ShimkoMax
      Здравствуйте. Требуется вывести данные температуры и влажности на экран. С LCD дисплеем разобрался, осталось разобраться с SHT21. Постоянно выводит 0 на дисплей:
      Main.c:
      #define F_CPU 8000000UL #include <avr/io.h> #include <avr/interrupt.h> #include <util/delay.h> #include <stdio.h> #include <stdlib.h> #include "globals.h" #include "LCD_lib.h" #include "twi.h" // I2C #include "sht21.h" int main(void) { I2C_Init(); _delay_ms(100); LCD_init(); char buffer[20]; roomAdrInit(); SHT21_reset(); while(1) { SHT21_reset(); LCD_sendString(itoa((int)get_temperature(), buffer, 10), 4, 0, 0); _delay_ms(1000); } } twi.c:
      #include <avr/io.h> #include "twi.h" void I2C_Init(void) { TWSR = 0; TWBR = 0x20; TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN); } void I2C_StartCondition(void) { TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); while(!(TWCR & (1<<TWINT))); } void I2C_StopCondition(void) { TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN); } void I2C_SendByte(uint8_t data) { TWDR = data; TWCR = (1<<TWINT) | (1<<TWEN); while(!(TWCR & (1<<TWINT))); } unsigned char I2C_ReadByteAck(void) { TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA); while(!(TWCR & (1<<TWINT))); return TWDR; } unsigned char I2C_ReadByteNak(void) { TWCR = (1<<TWINT) | (1<<TWEN); while(!(TWCR & (1<<TWINT))); return TWDR; } sht21.c:
      #define F_CPU 8000000UL #include <avr/io.h> #include <util/delay.h> #include <stdlib.h> #include <stdio.h> #include "twi.h" #include "sht21.h" void SHT21_reset() { unsigned char reg[1]; reg[0]=SHT21_reset_cmd; I2C_StartCondition(); I2C_SendByte(SHT21_i2c_write); I2C_SendByte(*reg); I2C_StopCondition(); _delay_ms(100); } uint16_t checksum(unsigned char data[],uint8_t byte, uint8_t check) { uint8_t crc=0; uint8_t bytectr,bit; for (bytectr=0; bytectr<byte;bytectr++) { crc^=(data[bytectr]); for (bit=8;bit>0;bit--) { if(crc&0x80) { crc=(crc<<1)^polynomial; } else { crc=crc<<1; } } } if (crc!=check) { return 0; } else { return data; } } void write_user_register() { unsigned char reg[3]; reg[0]=user_register_write; reg[1]=0x44; I2C_StartCondition(); I2C_SendByte(SHT21_i2c_write); I2C_SendByte(*reg); I2C_StopCondition(); } uint16_t read_value(uint8_t reg) { char data[4],crc; uint16_t result; data[0]=reg; I2C_StartCondition(); I2C_SendByte(SHT21_i2c_write); I2C_SendByte(reg); I2C_StartCondition(); I2C_SendByte(SHT21_i2c_read); data[1] = I2C_ReadByteAck(); data[2] = I2C_ReadByteAck(); crc=I2C_ReadByteNak(); I2C_StopCondition(); result=(data[1]<<8) | data[2]; checksum(result,4,crc); result &= 0xFFFC; return result; } float get_humidity() { //char buffer2[4]; uint16_t hum_value = read_value(humidity_hold_mode); return -6 + 125.0 / 65536.0 * hum_value; //dtostrf(rh,5,2,buffer2); _delay_ms(100); } float get_temperature() { //char buffer1[4]; uint16_t temp_value = read_value(temperature_hold_mode); return -46.85 + 175.72 / 65536.0 * temp_value; //dtostrf(tc,5,2,buffer1); _delay_ms(100); }  
    • Автор: GeloMik
       
      Я новичок в программировании AVR контроллеров, хотя знаю +/- C++.
      Проблема заключается в том, что я не могу написать прошивку к своему маленькому проекту. Используемый мною контроллер - ATTiny45. У него на борту имеется 1 АЦП с выходом на 4 ноги. Нужно, чтобы фактически одновременно брался замер с 3, 4 и 5 порта по АЦП, и при появлении 1 на одном из них МК должен подать 5В на 1 или 2 порты. Источник АЦП AREF. 
      Сюда прикреплю схему самого робота, если кого не затруднит помочь написать прошивку, буду очень благодарен 

    • Автор: Stratix
      Здравствуйте, у меня проблема с прошивкой разных устройств из-за программаторов. Дело в том что у меня есть некоторое количество китайских и самодельных программаторов для разных производителей, с ними постоянно какие-то проблемы, некоторые отказываются нормально работать на windows 10(другие версии ПО не устраивают), другие не работают с последними версиями сред разработки и т.д. Так же нужно прошивать схемы памяти. Хочу прошивать устройства без постоянной сборки программаторов и неудобств. Думаю о двух вариантах: взять оригинальные программаторы для всех производителей: altera, xlinx, arm, pic, avr(некоторые найти сложно, например оригинальный usb-blaster и высокая стоимость в сумме), второй вариант: взять универсальный программатор, который бы поддерживал все новые микросхемы, а вот с этим проблема, большинство универсальных программаторов не шьют stm, плис. Есть ли вообще реально универсальные программаторы? Мне было бы намного удобнее если на столе б лежал один программатор, а не куча. Смотрел список микросхем chipprog-48, пока что самый большой, к сожалению не поддерживает новые fpga, например: cyclone IV. Связывался, сказали что поддержки не будет и в будущем. Стоит ли взять chipprog-48 в 2018 году или есть программаторы лучше, с большим списком микросхем?