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

Вопросы от начинающих по МК


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

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

  • Ответов
  • Создана
  • Последний ответ

Топ авторов темы

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

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

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

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

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

Подскажите у меня на Arduino UNO потенциал 1,5 вольта на пинах 1 и 0 (PORTD). Вообще уно использую для удобства подключения пока изучаю программирование ВЛИ. Пишу в Atmel Studio программирую МК и питаю USBasp-ом, у ВЛИ своё питание земли объеденены. Код залит такой:

#define F_CPU  8000000
#include <avr/io.h>
#include <util/delay.h>

int main(void)
{
   PORTB=0b0000000;
   PORTD=0b0000000;
 
    while (1) 
    {
    }
}

Из за этого потенциала открывается транзисторы BC847 двух сегментов и я не могу их зажечь. Этот потенциал что это неисправен контроллер? Или если так должно быть как решить проблему аппаратно? Я понимаю что не использовать эти пины самое простое но всё же. Резистор анодный 68 кОм

Скрытый текст

DSC08689.thumb.JPG.270ceb99db9370134777f68e02ebcb0b.JPG

 

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

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

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

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

Все привет! Возник такой вопрос. Осваиваю I2C шину. Для этого использовал эту статью

Подключил по шине часы DS3231. Часы заработали исправно, НО возник такой момент. Если устройство на шине отсутствует то контроллер зависает на строке "while (!TW_READY);". Точнее застревает в цикле. 

Как можно избежать этого момента? Есть какие ни будь приемы?

#define TW_SEND 0x84
#define TW_READY (TWCR & 0x80)
#define TW_STATUS (TWSR & 0xF8)

char I2C_SendAddr(char addr)// Послать адрес шины для подчиненного устройства.
{
   TWDR = addr;               // загрузка адреса устройства
   TWCR = TW_SEND;            // и отправка его
   while (!TW_READY);         // ожидание завершения <-----------------------------------------
   return (TW_STATUS==0x18);  // возврат 1, если устройство найдено, иначе возврат 0
}

И второй вопрос. Пытаюсь подключить микросхему EEPROM 24с32, но тоже не получается. Постоянно выдает значение 255. Как я понимаю из даташита нужно отправлять адрес микросхемы - потом 2 адреса ячейки - а потом данные. 

Скорее всего я не правильно шлю адрес ячейки. Есть ли какой ни будь толковый пример по работе с этой микросхемой?

 

Clock.rar

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

30 минут назад, LEVV2006 сказал:

Как можно избежать этого момента? Есть какие ни будь приемы?

Существует такое понятие, как "таймаут". Это - отсчёт определённого времени и выход по нему из циклов (ну или других операций).
Таймаут можно сделать на таймере, а можно на простом инкременте(декременте) переменной.

Например, написав такой код :

int		timeout_count;
....
....
timeout_count = 100;
while (!TW_READY && --timeout_count)	continue;

мы убережёмся от зависания.

Далее, проверка, вышли по таймауту, или по условию :

if(!timeout_count){		// Вышли по таймауту
  i2c_flag_error = 1;
  return;
}

 

30 минут назад, LEVV2006 сказал:

Постоянно выдает значение 255

Это 0xFF. То, что записано в памяти по-умолчанию.
Может всё работает ? Попробуйте что-нибудь в неё записать.

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

Прием с тайм аутом интересен! Большое спасибо! Его нужно будет добавить в код.

48 minutes ago, Alex said:

Может всё работает ? Попробуйте что-нибудь в неё записать.

Так я записываю и сразу считываю.

#define AT24C32 0xAE 
void I2C_WriteP(char busAddr, char deviceRegister, char data) //Запись
{
	I2C_Start();
	I2C_SendAddr(busAddr);      
	I2C_Write(deviceRegister>>8); 
	I2C_Write(deviceRegister); 
	I2C_Write(data);          
	I2C_Stop();
}

char I2C_ReadP(char busAddr, char deviceRegister) //Чтение
{
	char data = 0;
	I2C_Start();
	I2C_SendAddr(busAddr);      
	I2C_Write(deviceRegister>>8); 
	I2C_Write(deviceRegister); 
	I2C_Start();
	I2C_SendAddr(busAddr+1); 
	data = I2C_ReadNACK();     
	I2C_Stop();
	return data;
}

int main(void)
{
	init_USART();
	stdout = &mystdout;
	I2C_Init();
	while(1)
	{
		I2C_WriteP(AT24C32,1,16);  //Запись
		char Temp=I2C_ReadP(AT24C32,1); //Чтение
		printf("%d\n", Temp);
		_delay_ms(1000);
	}
}

 

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

Первое. После записи должна быть выдержана пауза, согласно даташиту. Обычно это около 5 мс.
Второе. При чтении, после записи адреса, необходимо сделать рестарт (стоп->старт), а не просто старт.

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

Теперь что то начало записываться и читаться! Но пока работает не верно.

Вот что пишется в порт.

7 : 0 : 0 //прочитано с EEPROM
7 : 3 : 3 //реальные часы. 
 

Spoiler

void I2C_WriteP(char busAddr, char deviceRegister, char data)
{
	I2C_Start();
	I2C_SendAddr(busAddr);      
	I2C_Write(deviceRegister>>8); 
	I2C_Write(deviceRegister); 
	I2C_Write(data);           
	I2C_Stop();
}

char I2C_ReadP(char busAddr, char deviceRegister)
{
	char data = 0;
	I2C_Start();
	I2C_SendAddr(busAddr);      
	I2C_Write(deviceRegister>>8); 
	I2C_Write(deviceRegister); 
	I2C_Stop();
	I2C_Start();
	I2C_SendAddr(busAddr+1); 
	data = I2C_ReadNACK();     
	I2C_Stop();
	return data;
}

int main(void)
{
	init_USART();
	stdout = &mystdout;
	I2C_Init();
	//I2C_WriteProtokol(DS3231,MINUTES_REGISTER,DECtoBCD(50));
	I2C_WriteProtokol(DS3231,0x0E,0x00);
	while(1)
	{
		DS_getTime();
		
		I2C_WriteP(AT24C32,1,sec);
		I2C_WriteP(AT24C32,2,min);
		I2C_WriteP(AT24C32,3,hour);
		
		_delay_ms(10);
		
		char secT=I2C_ReadP(AT24C32,1);
		char minT=I2C_ReadP(AT24C32,2);
		char hourT=I2C_ReadP(AT24C32,3);
		
		printf("%d : %d : %d\n", hourT,minT,secT);
		printf("%d : %d : %d\n", hour,min,sec);
		
		_delay_ms(1000);
	}
}

 

Quote

Второе. При чтении, после записи адреса, необходимо сделать рестарт (стоп->старт), а не просто старт.

А это со всеми устройствами надо делать? Или только конкретно с памятью? В даташите протокол отображается так. И стоп только в конце передачи.

image.png.fdcd6e8b9847d1d3a94efee7d8159c6e.png

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

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

 

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

Разобрался! Надо паузы делать между записями. 

		I2C_WriteP(AT24C32,0x00,sec);
		_delay_ms(10);
		I2C_WriteP(AT24C32,0x01,min);
		_delay_ms(10);
		I2C_WriteP(AT24C32,0x02,hour);
		
		_delay_ms(10);

		char secT=I2C_ReadP(AT24C32,0x00);
		char minT=I2C_ReadP(AT24C32,0x01);
		char hourT=I2C_ReadP(AT24C32,0x02);

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

Quote

Но, если работает только со стартом, то оставьте только его

Работает как по даташиту. Без стопов. 

Сейчас осталось самое сложное. Прикрутить к этому делу дисплей по I2C :)

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

14 часа назад, LEVV2006 сказал:

Сейчас осталось самое сложное. Прикрутить к этому делу дисплей по I2C

на Си может быть и сложно...

на ассемблере - как два пальца...

Мудрость приходит вместе с импотенцией...

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

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

Только что, Starichok сказал:

на Си может быть и сложно...

giphy.gif

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

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

15 часов назад, LEVV2006 сказал:

Разобрался! Надо паузы делать между записями. 

В 14.12.2017 в 23:40, Alex сказал:

Первое. После записи должна быть выдержана пауза, согласно даташиту. Обычно это около 5 мс.

<_<
 

15 часов назад, LEVV2006 сказал:

И думаю надо добавить между чтением для надежности.

Ни к чему. Чтение с еепрома происходит очень быстро.

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

ARV, глядя на его мучения, это у меня был такой прикол...

Мудрость приходит вместе с импотенцией...

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

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

Потратил 8 часов. Разобрался с подключением дисплея :). Теперь все работает!!! Пользовался статьями: Сайт1 (самая полезная по описанию команд) и Сайт2 (взял код за основу. Но с ходу он не заработал. Многое правил и самое главное это я возился с инициализацией дисплея.)

Прикреплю файл проекта. Может кому то будет полезно.

AVR+I2C_DS3132+I2C_EEPROM24c32+I2C_LCD1602b-yyh-ctk

Но это только начало проекта! :) Возни ещё много. 

Clock.rar

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

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

Есть USB-HOST Arduino (+ сам МК) (но вопрос в целом), которая успешно "видит" некоторые подключенные устройства и делает обмен. Но если устройство определяется компом как несколько ЮСБ интерфейсов, то как указать хосту по какому работать?  Какой участок кода смотреть? В Винде это просто выбор мышкой, а тут как? 

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

4 часа назад, dim3740 сказал:

Есть USB-HOST Arduino (+ сам МК) (но вопрос в целом), которая успешно "видит" некоторые подключенные устройства и делает обмен. Но если устройство определяется компом как несколько ЮСБ интерфейсов, то как указать хосту по какому работать?  Какой участок кода смотреть? В Винде это просто выбор мышкой, а тут как? 

Это как? 

USB Host, в отличии от USB Hub, может увидеть ТОЛЬКО ОДНО устройство. 

戦う前に相手のベルトの色に注目

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

Физическое устройство, конечно, одно. Но у него же через один разъем ЮСБ можно увидеть несколько портов что-ли... Я пока мало понимаю тут(((( Думаю, надо разбираться что такое дискриптор, но главное, как модифицировать библиотеку, чтоб обратиться к другому порту... хотя бы в какой части кода это анализируется найти.... 

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

HID USB отличается от других классов USB тем, что в дескрипторах в явном виде указан функционал передаваемых данных. Если конечно юзер будет следовать этому протоколу. Что совершенно необязательно. Но это одно устройство. Просто ЕДИНЫЙ массив передаваемых/принимаемых данных парсится в соответствии с дескрипторами устройства.

Парсится массив в приложении юзера, оно обычно в стеке выглядит как функция в main с именем начинающемся с App_...

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

戦う前に相手のベルトの色に注目

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

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

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

Это называется составное устройство. Нигде в программе не указывается с каким из устройств в составе составного работать, ибо в этом нет смысла - если надо MIDI-порт, то просто ИСПОЛЬЗУЙТЕ его как миди, а не при помощи драйвера звукового устройства.

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

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

Как же мне это раскрутить:(((? Давайте еще раз, если можно... Я думал так: при подключении ЮСБ девайса программа делает к ему некий запрос, считывает и понимает что это за устройство: мышка (HID), МИДИ, аудио и т.п. Далее можно (но не нужно) написать универсальный код, который в зависимости от типа вызывает соответстсвующую программу.  Вы говорите, что если юзер знает, что в этом составном уст-ве есть МИДИ, то сразу обращаться с ним как с МИДИ. Что я имею: если у меня девайс определяется в Винде только как МИДИ - то мой юзб хост работает с ним без проблем. Если как составное (но тоже имеет МИДИ), то совсем не работает. И причина, не в том, что просто надо "сделать МИДИ- как по умолчанию, а не Аудио", а в том, что типовая библиотека не может "пробиться" к МИДИ. Так?

 

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

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

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

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

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

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

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

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

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

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

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

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