Например TDA7294

Форум РадиоКот • Просмотр темы - Atmega 328 и аппаратный I2C
Форум РадиоКот
Здесь можно немножко помяукать :)





Текущее время: Вт июл 15, 2025 12:20:46

Часовой пояс: UTC + 3 часа


ПРЯМО СЕЙЧАС:



Начать новую тему Ответить на тему  [ Сообщений: 22 ]  1,  
Автор Сообщение
Не в сети
 Заголовок сообщения: Atmega 328 и аппаратный I2C
СообщениеДобавлено: Пт авг 30, 2024 11:32:22 
Родился

Зарегистрирован: Вс фев 27, 2022 12:28:01
Сообщений: 11
Рейтинг сообщения: 0
Всем привет! Решил просканировать шину I2С и при этом не использовать ардуиновских продуктов - с ними и так все понятно и просто . Выбрал аппаратную реализацию и ...не могу найти проблему - сообщает код состояния шины 0х48 ( т.е. адрес отправлен и ACK не получен)
Код:
/*atmega 328
 * 2708.cpp
 *27/08/24 настроил uart
 * Created: 27.08.2024 21:34:56
 * Author : Павел
 */
#define F_CPU 8000000UL                                 // Тактовая частота микроконтроллера
#include <avr/io.h>
#include <util/delay.h>                                 // Библиотека программной задержки
#define   BAUD         9600UL                           // Задание скорости обмена по UART
#define SPEED         ((F_CPU+BAUD*8)/(BAUD*16)-1)
#define F_I2C 100000UL
#define TWBR_VALUE (((F_CPU)/(F_I2C)-16)/2)
void   out_UART      (uint8_t);
void Init_i2c(void)         // Настройка режима мастера
{
   PORTC |=( 1<<PC5|1<<PC4);   // Включим подтяжку на ноги, вдруг юзер на резисторы пожмотился
   DDRC &=~(1<<PC5|1<<PC4);
   
   TWBR = TWBR_VALUE;                  // Настроим битрейт
   TWSR = (0<<TWPS1)|(0<<TWPS0);
}



int main(void)
{
   UCSR0B = (1<<TXEN0);                                 // Настройка UART на передачу
   UCSR0C = (0<<UMSEL00|1<<UCSZ01|1<<UCSZ00);
   UBRR0L = SPEED & 0xFF;
   UBRR0H = SPEED >> 8;
   
   for(uint8_t adress=0;adress<127;adress++)
   {
      /*формируем состояние СТАРТ*/
      TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
      while(!(TWCR & (1<<TWINT)));
      
      /*выдаем на шину пакет SLA-R*/
      TWDR = (adress<<1)|1;
      TWCR = (1<<TWINT)|(1<<TWEN);
      while(!(TWCR & (1<<TWINT)));
      uint8_t a=TWSR;
      //if(a==0x08){
      while(!(UCSR0A&(1<<UDRE0)));                           // Ожидание готовности UART к передаче
      UDR0 = a;
      //}
      //while(!(UCSR0A&(1<<UDRE0)));                           // Ожидание готовности UART к передаче
      //UDR0 =0xFF;
      _delay_ms(100);
   }
   

   
    /* Replace with your application code */
    while (1)
    {
    }
}

////////////////////////////////////////////////////////////
//            ПРИЕМ/ПЕРЕДАЧА ДАННЫХ UART
////////////////////////////////////////////////////////////
void out_UART(uint8_t data){                           // Передача байта через UART
   while(!(UCSR0A&(1<<UDRE0)));                           // Ожидание готовности UART к передаче
   UDR0 = data;                                       // Запись в регистр UDR байта данных начинает процесс передачи
}



Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Atmega 328 и аппаратный I2C
СообщениеДобавлено: Пт авг 30, 2024 12:03:55 
Мучитель микросхем
Аватар пользователя

Карма: 1
Рейтинг сообщений: 38
Зарегистрирован: Ср янв 11, 2012 18:20:26
Сообщений: 473
Рейтинг сообщения: 0
p7070 писал(а):
PORTC |=( 1<<PC5|1<<PC4);   // Включим подтяжку на ноги, вдруг юзер на резисторы пожмотился

как это спасёт от отсутствия подтяжки на линии? :shock:


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Atmega 328 и аппаратный I2C
СообщениеДобавлено: Пт авг 30, 2024 12:20:22 
Грызет канифоль
Аватар пользователя

Карма: 3
Рейтинг сообщений: 69
Зарегистрирован: Ср сен 02, 2015 07:47:20
Сообщений: 262
Рейтинг сообщения: 0
p7070 писал(а):
PORTC |=( 1<<PC5|1<<PC4);   // Включим подтяжку на ноги, вдруг юзер на резисторы пожмотился

как это спасёт от отсутствия подтяжки на линии? :shock:

Порт у МК устроен так, что когда он настроен на вход его регистр вывода своей лог.1 включает подтяжку к VCC.
Изображение

_________________
Репозиторий STM32: https://cloud.mail.ru/public/2i19/Y4w8kKEiZ
Актуальность репозитория: 1 июля 2025 года
Если чего-то не хватает с сайта st.com - пишите, докачаю.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Atmega 328 и аппаратный I2C
СообщениеДобавлено: Пт авг 30, 2024 12:37:23 
Мучитель микросхем
Аватар пользователя

Карма: 1
Рейтинг сообщений: 38
Зарегистрирован: Ср янв 11, 2012 18:20:26
Сообщений: 473
Рейтинг сообщения: 0
HardWareMan писал(а):
Порт у МК устроен так, что когда он настроен на вход его регистр вывода своей лог.1 включает подтяжку к VCC.

то есть внешняя подтяжка для TWI интерфейса для atmega328p не нужна? :shock:


Вернуться наверх
 
Выбираем индустриальные и медицинские источники питания MEAN WELL в открытом исполнении

Использование модульных источников питания открытого типа широко распространено в современных устройствах. Присущие им компактность, гибкость в интеграции и высокая эффективность делают их отличным решением для систем промышленной автоматизации, телекоммуникационного оборудования, медицинской техники, устройств «умного дома» и прочих приложений. Рассмотрим подробнее характеристики и особенности трех самых популярных вариантов AC/DC-преобразователей MW открытого типа, подходящих для применения в промышленных устройствах - серий EPS, EPP и RPS представленных на Meanwell.market.

Подробнее>>
Не в сети
 Заголовок сообщения: Re: Atmega 328 и аппаратный I2C
СообщениеДобавлено: Пт авг 30, 2024 12:57:37 
Родился

Зарегистрирован: Вс фев 27, 2022 12:28:01
Сообщений: 11
Рейтинг сообщения: 0
p7070 писал(а):
PORTC |=( 1<<PC5|1<<PC4);   // Включим подтяжку на ноги, вдруг юзер на резисторы пожмотился

как это спасёт от отсутствия подтяжки на линии? :shock:

Не, не! не пожмотился - на отладочной плате PinBoard они есть и я их задействовал

Добавлено after 3 minutes 4 seconds:
Были мысли, что хватаю данные из регистра состояния до того , как ведомый успел подать сигнал на шину и для этого еще одну задержку ввел после отправки адреса

Добавлено after 1 minute 18 seconds:
еще вот тут поправил
Код:
#define TWBR_VALUE (((F_CPU)/(F_I2C)-16)/2)


делитель на 2 заменил на 8 - итого вышло :
Код:
#define TWBR_VALUE (((F_CPU)/(F_I2C)-16)/8)


Добавлено after 45 seconds:
HardWareMan писал(а):
Порт у МК устроен так, что когда он настроен на вход его регистр вывода своей лог.1 включает подтяжку к VCC.

то есть внешняя подтяжка для TWI интерфейса для atmega328p не нужна? :shock:

нужна - обязательно нужна


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Atmega 328 и аппаратный I2C
СообщениеДобавлено: Пт авг 30, 2024 13:09:08 
Сверлит текстолит когтями

Карма: 12
Рейтинг сообщений: 124
Зарегистрирован: Вт июн 07, 2011 08:03:18
Сообщений: 1213
Рейтинг сообщения: 0
Бывало экономил. Работает и на внутренней подтяжке.


Вернуться наверх
 
Распродажа паяльного оборудования ATTEN!
Паяльные станции, паяльники и аксессуары по самой выгодной цене.

По промокоду radiokot скидка 10%
Не в сети
 Заголовок сообщения: Re: Atmega 328 и аппаратный I2C
СообщениеДобавлено: Пт авг 30, 2024 13:14:08 
Родился

Зарегистрирован: Вс фев 27, 2022 12:28:01
Сообщений: 11
Рейтинг сообщения: 0
Бывало экономил. Работает и на внутренней подтяжке.

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


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Atmega 328 и аппаратный I2C
СообщениеДобавлено: Пт авг 30, 2024 13:53:40 
Сверлит текстолит когтями

Карма: 12
Рейтинг сообщений: 124
Зарегистрирован: Вт июн 07, 2011 08:03:18
Сообщений: 1213
Рейтинг сообщения: 0
Нет, без библиотек. Всё своё, по минимуму). А, извиняюсь.( I2C на мастере программный.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Atmega 328 и аппаратный I2C
СообщениеДобавлено: Пт авг 30, 2024 14:10:58 
Родился

Зарегистрирован: Вс фев 27, 2022 12:28:01
Сообщений: 11
Рейтинг сообщения: 0
Нет, без библиотек. Всё своё, по минимуму). А, извиняюсь.( I2C на мастере программный.

можете мне пример из вашего готового с вариантом опроса шины avr скинуть в тексте кода? - я бы сравнил, что не так у меня . Даташит перевел, все прочитал и даже вроде все понятно, кроме того брал за основу готовый пример, где понимаю все "до винтика" - но в моем варианте не заработало


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Atmega 328 и аппаратный I2C
СообщениеДобавлено: Пт авг 30, 2024 14:25:40 
Мучитель микросхем
Аватар пользователя

Карма: 1
Рейтинг сообщений: 38
Зарегистрирован: Ср янв 11, 2012 18:20:26
Сообщений: 473
Рейтинг сообщения: 0
p7070 писал(а):
Были мысли, что хватаю данные из регистра состояния до того , как ведомый успел подать сигнал на шину и для этого еще одну задержку ввел после отправки адреса

задержка вряд ли.. ACK на 9-м такте формируется..
p7070 писал(а):
готовый пример
ну точно, DI HALT же, судя по реплике))

если что, то мой код на асме, и он один в один из даташита (Table 26-2) и без проверок статуса


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Atmega 328 и аппаратный I2C
СообщениеДобавлено: Пт авг 30, 2024 14:33:47 
Сверлит текстолит когтями

Карма: 12
Рейтинг сообщений: 124
Зарегистрирован: Вт июн 07, 2011 08:03:18
Сообщений: 1213
Рейтинг сообщения: 0
Так софтовый же). И в/в по хитрому. Но логика должна быть понятна.
soft_i2c.h
Спойлер
Код:
// software i2c master (don`t check i2c bus state!)
#include "main.h"


#define I2C_SDA           A,0,H
#define I2C_SCL           A,1,H
#define INTERNAL_PULLUP   1
#define SCL_PULLUP        0
#define I2C_DELAY         1             //4 uS, standard mode, else nop, nop

#define DEVICE            0xd0          //DS1307

typedef uint8_t addr_t;


// return: true/false
void i2cInit();
bool i2cReadRandom(addr_t address, uint8_t *buffer);
bool i2cReadCurrentAddress(uint8_t *buffer);
bool i2cReadSequential(uint8_t *buffer, uint16_t size);
bool i2cReadBlock(addr_t address, uint8_t *buffer, uint16_t size);

bool i2cWriteByte(addr_t address, uint8_t data);
bool i2cWriteBlock(addr_t address, uint8_t *buffer, uint8_t size);

soft_i2c.cpp
Спойлер
Код:
#include "soft_i2c.h"
#include "ds1307.h"                     //BINARY_DATA

enum {LOW, HIGH};
enum {WRITE, READ};                     // operation bit
enum {NAK, ACK};                        // I2cRead(argument)


#if INTERNAL_PULLUP
#define set_sda_1()       (in(I2C_SDA),  pullup(I2C_SDA))
#define set_sda_0()       (off(I2C_SDA), out(I2C_SDA)   )
 #if SCL_PULLUP
#define set_scl_1()       (in(I2C_SCL),  pullup(I2C_SCL))
#define set_scl_0()       (off(I2C_SCL), out(I2C_SCL)   )
 #else
#define set_scl_1()       on(I2C_SCL)
#define set_scl_0()       off(I2C_SCL)
 #endif
#else
#define set_sda_1()       in(I2C_SDA)
#define set_sda_0()       out(I2C_SDA)
#define set_scl_1()       in(I2C_SCL)
#define set_scl_0()       out(I2C_SCL)
#endif


static bool i2cWrite(uint8_t data);


// Initialize SCL/SDA pins and set the bus high - NOT USED!
// out: SDA = 1  SCL = 1 (open draw)
void i2cInit() {
  #if INTERNAL_PULLUP
  pullup(I2C_SDA);
   #if SCL_PULLUP
  pullup(I2C_SCL);
   #else
  off(I2C_SCL); out(I2C_SCL);
   #endif
  #else
  off(I2C_SDA);                         // low level to output mode
  off(I2C_SCL);                         
  #endif
}


#if I2C_DELAY
void i2c_delay()
{
  _delay_us(I2C_DELAY);
}

#else
#define i2c_delay() asm volatile( "nop \n nop \n" )
#endif


// set start condition, device address and mode
// out: SDA = 1 SCL = 0, if return true
static bool i2c_start(uint8_t device) { //+ R/W mode
  uint8_t i = 0;                        //timeout

  i2c_delay();
  set_sda_1();
  set_scl_1();
  do                                    // check i2c bus
    if (!--i)
      return false;
  #if SCL_PULLUP
  while (!pin(I2C_SDA) || !pin(I2C_SCL));
  #else
  while (!pin(I2C_SDA));
  #endif
  i2c_delay();
  set_sda_0();
  i2c_delay();
  set_scl_0();
  set_sda_1();
  return i2cWrite(device);
}


// Stop condition, set the bus high
// out: SDA = 1 SCL = 1
static void i2c_stop() {
  i2c_delay();
  set_sda_0();
  i2c_delay();
  set_scl_1();
  i2c_delay();                          // tSU_STO: 4,0 0,6
  set_sda_1();
  i2c_delay();
}                                       // tBUF:    4,7 1,3


// Read a byte, send Ack if more reads follow, Nak to terminate read
// in/out: SDA = 1 SCL = 0
static uint8_t i2cRead(uint8_t ack) {
  uint8_t data = 0;

  for (uint8_t i = 0; i < 8; i++) {
    data <<= 1;
    i2c_delay();                        // tLOW:    4,7 1,3
    set_scl_1();
    if (pin(I2C_SDA))
      data |= 1<<0;
    i2c_delay();                        // tHIGH:   4,0 0,6
    set_scl_0();
  }
  set_sda_1();
  if (ack)
    set_sda_0();
  i2c_delay();                          // tLOW:    4,7 1,3
  set_scl_1();
  i2c_delay();                          // tHIGH:   4,0 0,6
  set_scl_0();
  set_sda_1();
  return data;
}


// Write a byte. Return: ACK == true
// in/out: SDA = 1 SCL = 0
static bool i2cWrite(uint8_t data) {
  for (uint8_t m = 1<<7; m; m >>= 1) {
    if (m & data)
      set_sda_1();
    else
      set_sda_0();
    i2c_delay();                        // /2
    set_scl_1();
    i2c_delay();                        // tHIGH:   4,0 0,6
    set_scl_0();
  }
  i2c_delay();                          // tLOW:    4,7 1,3
  set_scl_1();                          // get Ack or Nak
  i2c_delay();                          // tHIGH:   4,0 0,6
  bool ack = pin(I2C_SDA);
  set_scl_0();
  set_sda_1();
  return !ack;
}


// Write address
// in/out: SDA = 1 SCL = 0
static bool i2cWriteAddress(addr_t address) {
  return i2cWrite(address);
}


//----------
// in/out: SDA = 1 SCL = 1 (open draw) - the bus high
// return: false/true

// Read byte @Random address
bool i2cReadRandom(addr_t address, uint8_t *buffer) {
  if (!i2c_start(DEVICE | WRITE))
    return false;
  if (!i2cWriteAddress(address))
    return false;
  return i2cReadCurrentAddress(buffer);
}


// Read byte @Current address
bool i2cReadCurrentAddress(uint8_t *buffer) {
  if (!i2c_start(DEVICE | READ))
    return false;
  *buffer = i2cRead(NAK);               //single byte
  i2c_stop();
  return true;
}


// Sequental Read @Current address
bool i2cReadSequential(uint8_t *buffer, uint16_t size) {
  if (!i2c_start(DEVICE | READ))
    return false;
  do
    *buffer++ = i2cRead(--size);
  while (size);
  i2c_stop();
  return true;
}


// Read block
bool i2cReadBlock(addr_t address, uint8_t *buffer, uint16_t size) {
  if (!i2c_start(DEVICE | WRITE))
    return false;
  if (!i2cWriteAddress(address))
    return false;
  return i2cReadSequential(buffer, size);
}


// Write byte
bool i2cWriteByte(addr_t address, uint8_t data) {
  if (!i2c_start(DEVICE | WRITE))
    return false;
  if (!i2cWriteAddress(address))
    return false;
  bool ack = i2cWrite(data);
  i2c_stop();
  return ack;
}


// Write block
bool i2cWriteBlock(addr_t address, uint8_t *buffer, uint8_t size) {
  bool ack;

  if (!i2c_start(DEVICE | WRITE))
    return false;
  if (!i2cWriteAddress(address))
    return false;
  do
    ack = i2cWrite(*buffer++);
  while (--size);
  i2c_stop();
  return ack;
}


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Atmega 328 и аппаратный I2C
СообщениеДобавлено: Пт авг 30, 2024 14:50:05 
Родился

Зарегистрирован: Вс фев 27, 2022 12:28:01
Сообщений: 11
Рейтинг сообщения: 0
Так софтовый же)...... Но логика должна быть понятна.
[/code][/spoiler]

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


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Atmega 328 и аппаратный I2C
СообщениеДобавлено: Пт авг 30, 2024 15:56:59 
Грызет канифоль
Аватар пользователя

Карма: 3
Рейтинг сообщений: 69
Зарегистрирован: Ср сен 02, 2015 07:47:20
Сообщений: 262
Рейтинг сообщения: 0
то есть внешняя подтяжка для TWI интерфейса для atmega328p не нужна? :shock:

В контексте TWI/I2C зависит от скорости, на которой хочется работать.

Бывало экономил. Работает и на внутренней подтяжке.

На какой скорости пробовали?

Так софтовый же). И в/в по хитрому. Но логика должна быть понятна.

А, софтовый, ок, понятно. Я тоже в одном проекте не захотел обрабатывать кучу ошибок в аппаратнос I2C (только уже на STM32F4) и написал простой программный мастер. Т.к. слейв один и это обычная флешка всё работает стабильно. Но я всё равно подстраховался и подтянул снаружи 4,7к. Скорости порядка 500кГц.

_________________
Репозиторий STM32: https://cloud.mail.ru/public/2i19/Y4w8kKEiZ
Актуальность репозитория: 1 июля 2025 года
Если чего-то не хватает с сайта st.com - пишите, докачаю.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Atmega 328 и аппаратный I2C
СообщениеДобавлено: Пт авг 30, 2024 16:58:25 
Сверлит текстолит когтями

Карма: 12
Рейтинг сообщений: 124
Зарегистрирован: Вт июн 07, 2011 08:03:18
Сообщений: 1213
Рейтинг сообщения: 0
На какой скорости пробовали?

100 кгц. ds1307 потому что.)


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Atmega 328 и аппаратный I2C
СообщениеДобавлено: Пт авг 30, 2024 21:44:56 
Родился

Зарегистрирован: Вс фев 27, 2022 12:28:01
Сообщений: 11
Рейтинг сообщения: 0
Даже не сомневаюсь, что будут работать примеры - уже проверял чужие реализации, но хочеться вернуться к вопросу,а то уже обсуждение пошло в самостоятельное плавание:
есть фрагмент кода, который перебирает адреса, сдвигает их и формирует блок "адрес устройства + сигнал на чтение", все регистры настроены и есть старт + передача блока адреса в шину - но почему при передоре адресов не откликнулся ни один номер ? чьл не так?

Код:
for(uint8_t adress=0;adress<127;adress++)
   {
      /*формируем состояние СТАРТ*/
      TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
      while(!(TWCR & (1<<TWINT)));
     
      /*выдаем на шину пакет SLA-R*/
      TWDR = (adress<<1)|1;
      TWCR = (1<<TWINT)|(1<<TWEN);
      while(!(TWCR & (1<<TWINT)));
      uint8_t a=TWSR;
            while(!(UCSR0A&(1<<UDRE0)));                           // Ожидание готовности UART к передаче
      UDR0 = a;
      }


Добавлено after 44 minutes 34 seconds:
ВСЁ!!! нашёл ошибку - и исправил - код подтверждения получен - сейчас программу поправлю, чтоб при успешном отклике адрес устройства выводила


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Atmega 328 и аппаратный I2C
СообщениеДобавлено: Сб авг 31, 2024 08:12:15 
Модератор
Аватар пользователя

Карма: 153
Рейтинг сообщений: 2917
Зарегистрирован: Сб авг 14, 2010 15:05:51
Сообщений: 18739
Откуда: г. Озерск, Челябинская обл.
Рейтинг сообщения: 0
Медали: 1
Лучший человек Форума 2017 (1)
во-первых, в приведенном тобой коде проверки кода подтверждения не видать.
во-вторых, где была ошибка?рассказывай, не интригуй нас.

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


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Atmega 328 и аппаратный I2C
СообщениеДобавлено: Сб авг 31, 2024 17:00:09 
Потрогал лапой паяльник
Аватар пользователя

Карма: 4
Рейтинг сообщений: 79
Зарегистрирован: Сб фев 18, 2023 21:51:01
Сообщений: 306
Откуда: Санкт-Петербург
Рейтинг сообщения: 0
слейв один и это обычная флешка всё работает стабильно. Но я всё равно подстраховался и подтянул снаружи 4,7к. Скорости порядка 500кГц.
У меня на 40 кГцах работало нестабильно с резисторами по 10к. Но там питание было грязное, а 3-вольтовый слейв понимал логическую единицу примерно от 2.7В и выше. Пришлось поставить 4.7к, причём линии клока оказалось достаточно. Осциллографом я видел сильно заваленные (дальше середины тактового импульса) фронты клока, которые стали заметно круче с резистором на 4к7. На 80 кГцах оно после этого заработало (по паспорту оно 100-килогерцовое), но мне так быстро и не надо было, 40 вполне достаточно. В общем, я бы на резисторах не экономил. На спичках больше сэкономишь! :-)

_________________
Всего доброго.
Евгений.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Atmega 328 и аппаратный I2C
СообщениеДобавлено: Вс сен 01, 2024 07:34:26 
Родился

Зарегистрирован: Вс фев 27, 2022 12:28:01
Сообщений: 11
Рейтинг сообщения: 0
во-первых, в приведенном тобой коде проверки кода подтверждения не видать.
во-вторых, где была ошибка?рассказывай, не интригуй нас.


какая уж тут интрига? сперва я частоту задранную понизил TWBR - было с ошибкой:
Код:
#define TWBR_VALUE (((F_CPU)/(F_I2C)-16)/2)

сделал:
Код:
#define TWBR_VALUE (((F_CPU)/(F_I2C)-16)/8)


далее проверял TWSR не верно - хотя в даташите читал. что нужно без учета младших байтов (т.е. без предделителя) - и я поступил так:
Код:
 uint8_t a=TWSR>>3;


позже. когда перевел таблицу из даташита понял. почему код должен быть 0Х08 при отправке адреса. Нужно было исправит :
Код:
uint8_t a=TWSR&0xF8;


а далее выводить адрес и значение TWSR:

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


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Atmega 328 и аппаратный I2C
СообщениеДобавлено: Пн сен 02, 2024 18:07:23 
Модератор
Аватар пользователя

Карма: 153
Рейтинг сообщений: 2917
Зарегистрирован: Сб авг 14, 2010 15:05:51
Сообщений: 18739
Откуда: г. Озерск, Челябинская обл.
Рейтинг сообщения: 0
Медали: 1
Лучший человек Форума 2017 (1)
p7070 писал(а):
хотя в даташите читал. что нужно без учета младших байтов
не байтов, а битов. байт - это все 8 битов регистра.
p7070 писал(а):
код должен быть 0Х08 при отправке адреса
во-первых, 0х08 - это код старта, а не отправки адреса. когда ты перебираешь адреса, повторный старт дает код 0х10. поэтому нужно проверять оба кода. а при отправке адреса успешный код равен 0х18, а не успешный код адреса равен 0х20. и здесь нужно проверять на успешную отправку адреса и неуспешную.
если на отправку адреса получишь 0х18, значит устройство найдено и ответило.
а если получишь 0х20, то адрес был неверный.

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


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Atmega 328 и аппаратный I2C
СообщениеДобавлено: Чт сен 05, 2024 21:59:44 
Родился

Зарегистрирован: Вс фев 27, 2022 12:28:01
Сообщений: 11
Рейтинг сообщения: 0
[quote="p7070"]
если на отправку адреса получишь 0х18, значит устройство найдено и ответило.
а если получишь 0х20, то адрес был неверный.

Да - перепроверил, причем выводил и по-парно "адрес устройства - статус" и после по услочию только адрес "откликнувшийся" на запрос, причем адреса уже знал и перебором по порядку еще раз их обнаружил ( ранее тест на ардуино) . Но это не всё - далее решил соединить уже проверенный код запуска дисплея 1602, чтоб не мониторить посылки по терминалу ..но столкнулся с новой проблемой и пришлось вернуться к коду с дисплеем - не могу решить поблему (используя готовую библиотеку) вывод второй строки только при первом запуске и далее только после снятия питания и повторного подключения. Однако при перезапуске процессора кнопкой резет - вторая строка не выводится на дисплей. Порядок - заливка программы - вывод двух строк, далее резет и загружена только одна строка , если выкл и вновь вкл питание - две строки.
Код:
#define F_CPU 8000000UL
//#define Line "     - %d"
//#define   BAUD         9600UL                           // Задание скорости обмена по UART
//#define SPEED         ((F_CPU+BAUD*8)/(BAUD*16)-1)
//#define F_I2C 100000UL
//#define TWBR_VALUE (((F_CPU)/(F_I2C)-16)/8)

#include <avr/io.h>
#include <util/delay.h>
#include <string.h>
#include <LCD.h>






int main(void) {
   
 
  lcdInit();
  _delay_ms(1000);
  lcdClear();
 lcdSetDisplay(LCD_DISPLAY_ON);
 lcdSetCursor(LCD_CURSOR_ON);
   _delay_ms(100);
 char text[17];
 strcpy(text, "PRINT");
  lcdGotoXY(1, 0);
  lcdPuts(text);
  _delay_ms(1000);
 
  //lcdClear();
  strcpy(text, "TEXT");
  lcdGotoXY(0, 8);
  lcdPuts(text);
  _delay_ms(1000);
  while (1){}
}




Вложения:
1.jpg [98.62 KiB]
Скачиваний: 36
2.jpg [134.37 KiB]
Скачиваний: 37
Вернуться наверх
 
Показать сообщения за:  Сортировать по:  Вернуться наверх
Начать новую тему Ответить на тему  [ Сообщений: 22 ]  1,  

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: serg_svd и гости: 17


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB
Extended by Karma MOD © 2007—2012 m157y
Extended by Topic Tags MOD © 2012 m157y