Atmega 328 и аппаратный I2C

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

Atmega 328 и аппаратный I2C

Сообщение p7070 »

Всем привет! Решил просканировать шину 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 байта данных начинает процесс передачи
}

Реклама
Аватара пользователя
shonty
Мучитель микросхем
Сообщения: 473
Зарегистрирован: Ср янв 11, 2012 18:20:26

Re: Atmega 328 и аппаратный I2C

Сообщение shonty »

p7070 писал(а):PORTC |=( 1<<PC5|1<<PC4);   // Включим подтяжку на ноги, вдруг юзер на резисторы пожмотился
как это спасёт от отсутствия подтяжки на линии? :shock:
Реклама
Аватара пользователя
HardWareMan
Мучитель микросхем
Сообщения: 431
Зарегистрирован: Ср сен 02, 2015 07:47:20

Re: Atmega 328 и аппаратный I2C

Сообщение HardWareMan »

[uquote="shonty",url="/forum/viewtopic.php?p=4620442#p4620442"]
p7070 писал(а):PORTC |=( 1<<PC5|1<<PC4);   // Включим подтяжку на ноги, вдруг юзер на резисторы пожмотился
как это спасёт от отсутствия подтяжки на линии? :shock:[/uquote]
Порт у МК устроен так, что когда он настроен на вход его регистр вывода своей лог.1 включает подтяжку к VCC.
Изображение
Репозиторий STM32: https://cloud.mail.ru/public/2i19/Y4w8kKEiZ
Актуальность репозитория: 22 апреля 2026 года
Если чего-то не хватает с сайта st.com - пишите, докачаю.
/!\ Обновлений для STM32PowerMon и STM32PowerMon-UCPD временно не будет.
Аватара пользователя
shonty
Мучитель микросхем
Сообщения: 473
Зарегистрирован: Ср янв 11, 2012 18:20:26

Re: Atmega 328 и аппаратный I2C

Сообщение shonty »

HardWareMan писал(а):Порт у МК устроен так, что когда он настроен на вход его регистр вывода своей лог.1 включает подтяжку к VCC.
то есть внешняя подтяжка для TWI интерфейса для atmega328p не нужна? :shock:
Реклама
Эиком - электронные компоненты и радиодетали
p7070
Родился
Сообщения: 11
Зарегистрирован: Вс фев 27, 2022 12:28:01

Re: Atmega 328 и аппаратный I2C

Сообщение p7070 »

[uquote="shonty",url="/forum/viewtopic.php?p=4620442#p4620442"]
p7070 писал(а):PORTC |=( 1<<PC5|1<<PC4);   // Включим подтяжку на ноги, вдруг юзер на резисторы пожмотился
как это спасёт от отсутствия подтяжки на линии? :shock:[/uquote]
Не, не! не пожмотился - на отладочной плате 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:
[uquote="shonty",url="/forum/viewtopic.php?p=4620454#p4620454"]
HardWareMan писал(а):Порт у МК устроен так, что когда он настроен на вход его регистр вывода своей лог.1 включает подтяжку к VCC.
то есть внешняя подтяжка для TWI интерфейса для atmega328p не нужна? :shock:[/uquote]
нужна - обязательно нужна
Реклама
OKF
Это не хвост, это антенна
Сообщения: 1393
Зарегистрирован: Вт июн 07, 2011 08:03:18

Re: Atmega 328 и аппаратный I2C

Сообщение OKF »

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

Re: Atmega 328 и аппаратный I2C

Сообщение p7070 »

[uquote="OKF",url="/forum/viewtopic.php?p=4620465#p4620465"]Бывало экономил. Работает и на внутренней подтяжке.[/uquote]
а при написании кода всегда библиотеками пользовался, или аппаратными средствами так же получалось?
OKF
Это не хвост, это антенна
Сообщения: 1393
Зарегистрирован: Вт июн 07, 2011 08:03:18

Re: Atmega 328 и аппаратный I2C

Сообщение OKF »

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

Re: Atmega 328 и аппаратный I2C

Сообщение p7070 »

[uquote="OKF",url="/forum/viewtopic.php?p=4620475#p4620475"]Нет, без библиотек. Всё своё, по минимуму). А, извиняюсь.( I2C на мастере программный.[/uquote]
можете мне пример из вашего готового с вариантом опроса шины avr скинуть в тексте кода? - я бы сравнил, что не так у меня . Даташит перевел, все прочитал и даже вроде все понятно, кроме того брал за основу готовый пример, где понимаю все "до винтика" - но в моем варианте не заработало
Аватара пользователя
shonty
Мучитель микросхем
Сообщения: 473
Зарегистрирован: Ср янв 11, 2012 18:20:26

Re: Atmega 328 и аппаратный I2C

Сообщение shonty »

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

если что, то мой код на асме, и он один в один из даташита (Table 26-2) и без проверок статуса
OKF
Это не хвост, это антенна
Сообщения: 1393
Зарегистрирован: Вт июн 07, 2011 08:03:18

Re: Atmega 328 и аппаратный I2C

Сообщение OKF »

Так софтовый же). И в/в по хитрому. Но логика должна быть понятна.
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;
}
p7070
Родился
Сообщения: 11
Зарегистрирован: Вс фев 27, 2022 12:28:01

Re: Atmega 328 и аппаратный I2C

Сообщение p7070 »

[uquote="OKF",url="/forum/viewtopic.php?p=4620491#p4620491"]Так софтовый же)...... Но логика должна быть понятна.
[/code][/spoiler][/uquote]
бегло просмотрел - вечерком изучу внимательнее, но и с первого взгляда все читается - должен разобраться - записано удобно
Аватара пользователя
HardWareMan
Мучитель микросхем
Сообщения: 431
Зарегистрирован: Ср сен 02, 2015 07:47:20

Re: Atmega 328 и аппаратный I2C

Сообщение HardWareMan »

[uquote="shonty",url="/forum/viewtopic.php?p=4620454#p4620454"]то есть внешняя подтяжка для TWI интерфейса для atmega328p не нужна? :shock:[/uquote]
В контексте TWI/I2C зависит от скорости, на которой хочется работать.

[uquote="OKF",url="/forum/viewtopic.php?p=4620465#p4620465"]Бывало экономил. Работает и на внутренней подтяжке.[/uquote]
На какой скорости пробовали?

[uquote="OKF",url="/forum/viewtopic.php?p=4620491#p4620491"]Так софтовый же). И в/в по хитрому. Но логика должна быть понятна.[/uquote]
А, софтовый, ок, понятно. Я тоже в одном проекте не захотел обрабатывать кучу ошибок в аппаратнос I2C (только уже на STM32F4) и написал простой программный мастер. Т.к. слейв один и это обычная флешка всё работает стабильно. Но я всё равно подстраховался и подтянул снаружи 4,7к. Скорости порядка 500кГц.
Репозиторий STM32: https://cloud.mail.ru/public/2i19/Y4w8kKEiZ
Актуальность репозитория: 22 апреля 2026 года
Если чего-то не хватает с сайта st.com - пишите, докачаю.
/!\ Обновлений для STM32PowerMon и STM32PowerMon-UCPD временно не будет.
OKF
Это не хвост, это антенна
Сообщения: 1393
Зарегистрирован: Вт июн 07, 2011 08:03:18

Re: Atmega 328 и аппаратный I2C

Сообщение OKF »

[uquote="HardWareMan",url="/forum/viewtopic.php?p=4620509#p4620509"]На какой скорости пробовали?[/uquote]
100 кгц. ds1307 потому что.)
p7070
Родился
Сообщения: 11
Зарегистрирован: Вс фев 27, 2022 12:28:01

Re: Atmega 328 и аппаратный I2C

Сообщение p7070 »

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

Код: Выделить всё

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:
ВСЁ!!! нашёл ошибку - и исправил - код подтверждения получен - сейчас программу поправлю, чтоб при успешном отклике адрес устройства выводила
Аватара пользователя
Starichok51
Модератор
Сообщения: 19053
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

Re: Atmega 328 и аппаратный I2C

Сообщение Starichok51 »

во-первых, в приведенном тобой коде проверки кода подтверждения не видать.
во-вторых, где была ошибка?рассказывай, не интригуй нас.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Аватара пользователя
Eats
Потрогал лапой паяльник
Сообщения: 309
Зарегистрирован: Сб фев 18, 2023 21:51:01
Откуда: Санкт-Петербург

Re: Atmega 328 и аппаратный I2C

Сообщение Eats »

[uquote="HardWareMan",url="/forum/viewtopic.php?p=4620509#p4620509"]слейв один и это обычная флешка всё работает стабильно. Но я всё равно подстраховался и подтянул снаружи 4,7к. Скорости порядка 500кГц.[/uquote]У меня на 40 кГцах работало нестабильно с резисторами по 10к. Но там питание было грязное, а 3-вольтовый слейв понимал логическую единицу примерно от 2.7В и выше. Пришлось поставить 4.7к, причём линии клока оказалось достаточно. Осциллографом я видел сильно заваленные (дальше середины тактового импульса) фронты клока, которые стали заметно круче с резистором на 4к7. На 80 кГцах оно после этого заработало (по паспорту оно 100-килогерцовое), но мне так быстро и не надо было, 40 вполне достаточно. В общем, я бы на резисторах не экономил. На спичках больше сэкономишь! :-)
Всего доброго.
Евгений.
p7070
Родился
Сообщения: 11
Зарегистрирован: Вс фев 27, 2022 12:28:01

Re: Atmega 328 и аппаратный I2C

Сообщение p7070 »

[uquote="Starichok51",url="/forum/viewtopic.php?p=4620650#p4620650"]во-первых, в приведенном тобой коде проверки кода подтверждения не видать.
во-вторых, где была ошибка?рассказывай, не интригуй нас.[/uquote]

какая уж тут интрига? сперва я частоту задранную понизил 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 и пока так же есть трудности.пробую без готовых библиотек по даташиту
Аватара пользователя
Starichok51
Модератор
Сообщения: 19053
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

Re: Atmega 328 и аппаратный I2C

Сообщение Starichok51 »

p7070 писал(а):хотя в даташите читал. что нужно без учета младших байтов
не байтов, а битов. байт - это все 8 битов регистра.
p7070 писал(а):код должен быть 0Х08 при отправке адреса
во-первых, 0х08 - это код старта, а не отправки адреса. когда ты перебираешь адреса, повторный старт дает код 0х10. поэтому нужно проверять оба кода. а при отправке адреса успешный код равен 0х18, а не успешный код адреса равен 0х20. и здесь нужно проверять на успешную отправку адреса и неуспешную.
если на отправку адреса получишь 0х18, значит устройство найдено и ответило.
а если получишь 0х20, то адрес был неверный.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
p7070
Родился
Сообщения: 11
Зарегистрирован: Вс фев 27, 2022 12:28:01

Re: Atmega 328 и аппаратный I2C

Сообщение p7070 »

[uquote="Starichok51",url="/forum/viewtopic.php?p=4621446#p4621446"][quote="p7070"]
если на отправку адреса получишь 0х18, значит устройство найдено и ответило.
а если получишь 0х20, то адрес был неверный.[/uquote]
Да - перепроверил, причем выводил и по-парно "адрес устройства - статус" и после по услочию только адрес "откликнувшийся" на запрос, причем адреса уже знал и перебором по порядку еще раз их обнаружил ( ранее тест на ардуино) . Но это не всё - далее решил соединить уже проверенный код запуска дисплея 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 КБ) 78 скачиваний
2.jpg
(134.37 КБ) 69 скачиваний
Ответить

Вернуться в «AVR»