Обсуждаем контроллеры компании Atmel.
Ответить

Re: I2C на Attiny 13 - Попытка сквозь времена:)

Чт авг 01, 2019 21:40:46

Про отладчик точно!
Не, я все таки запутался. Все таки еще раз, если мастер у меня будет такой, просто стандартный пример Arduino Uno.
Код:
#include <Wire.h>

void setup() {
  Wire.begin();        // join i2c bus (address optional for master)
  Serial.begin(9600);  // start serial for output
}

void loop() {
  Wire.requestFrom(8, 6);    // request 6 bytes from slave device #8

  while (Wire.available()) { // slave may send less than requested
    char c = Wire.read(); // receive a byte as character
    Serial.print(c);         // print the character
  }

  delay(500);
}


Как нужно написать Slave? Я понимаю, что примерно алгоритм такой: ждать стартовый бит -> ждать команду адреса 0x08 -> ждать команду о передачи на слейв 6 байт -> Отсылаем 6 байт -> Останавливаем связь.

Re: I2C на Attiny 13 - Попытка сквозь времена:)

Сб авг 03, 2019 19:26:12

Код мастера
Спойлер
Код:
#include <Wire.h>

#define adres 0x40>>1

void setup()
{
   Wire.begin();        // подключение к шине i2c
   Serial.begin(9600);  // запуск последовательного порта
   delay(2000);            // пауза
}

void loop()
{
   Wire.requestFrom(adres, 6);    // запрос 6 байт от слейва #2

   while(Wire.available())    // пока есть, что читать
   {
     char c = Wire.read();    // получаем байт (как символ)
     Serial.print(c, HEX);         // печатает в порт
    Serial.print(" ");
   }
   Serial.print("\n\r");
   delay(500);
}
Код, это просто пример, Slave
Спойлер
Код:
#include <avr/interrupt.h>
#include "TWI.h"

#define InvBit(reg, bit)   reg ^= (1<<(bit))
#define ClearBit(reg, bit)       reg &= (~(1<<(bit)))
#define SetBit(reg, bit)          reg |= (1<<(bit))
#define BitIsSet(reg, bit)       ((reg & (1<<bit)) != 0)

extern volatile unsigned char  outgoingBuffer[6];

volatile uint32_t value1 = 0x00;

int main( void )


  sei();   //!< Enable global interrupts.

  twi_slave_init();
  twi_slave_enable();
 
   for(int i=0; i<6; outgoingBuffer[i++]=0) {}            // очистка передающего буфера
 
   while (1)
  {   
   value1++;
   
outgoingBuffer[3] = (value1 & 0xff000000) >> 24;
outgoingBuffer[2] = (value1 & 0x00ff0000) >> 16;
outgoingBuffer[1] = (value1 & 0x0000ff00) >> 8;
outgoingBuffer[0] = (value1 & 0x000000ff);
   
  }
   
}

Re: I2C на Attiny 13 - Попытка сквозь времена:)

Вс авг 04, 2019 19:07:17

Почему Outgoing Buffer может не находиться? В коде есть строка #include "TWI.h"
Но, кстати, почему того буффера не обозначено в TWI.h?
Спойлер#ifndef __TWI_H
#define __TWI_H

#include <avr/io.h>
#include <avr/interrupt.h>

/*! \brief Definition of pin used as SDA. */
#define SDA PB1

/*! \brief Definition of pin used as SCL. */
#define SCL PB0

/*! \brief Definition of 7 bit slave address. */
#define SLAVE_ADDRESS 0x5D


#define INITIALIZE_SDA() ( DDRB &= ~ (1 << SDA) ) //!< Clear port.
#define READ_SDA() ( (PINB & (1 << SDA)?1:0) ) //!< read pin value
#define READ_SCL() ( (PINB & (1 << SCL))?1:0 )

//SDA and SCL bit in PORT variable must be 0!
#define SETSDA() ( DDRB &= ~(1 << SDA) ) //Tristate
#define CLRSDA() ( DDRB |= (1 << SDA) ) //Pull it low

#define SETSCL() ( DDRB &= ~(1 << SCL) ) //Tristate
#define CLRSCL() ( DDRB |= (1 << SCL) ) //Pull it low

/* External interrupt macros. These are device dependent. */
#define INITIALIZE_TWI_INTERRUPT() (MCUCR |= (1<<ISC01)) //!< Sets falling edge of SDA generates interrupt.
#define ENABLE_TWI_INTERRUPT() (GIMSK |= (1<<INT0)) //!< Enables SDA interrupt.
#define DISABLE_TWI_INTERRUPT() (GIMSK &= ~(1<<INT0)) //!< Disables SDA interrupt.
#define CLEAR_TWI_INTERRUPT_FLAG() (GIFR = (1<<INTF0)) //!< Clears interrupt flag.

#define SDA_vector INT0_vect //!< Interrupt vector for SDA pin

// Dedicated general purpose registers.
register unsigned char TWSR asm("r2");;
register unsigned char TWDR asm("r3");;
register unsigned char TWEA asm("r4");;

//! \name macros for twi state machine
//! @{
# define TWI_SLA_REQ_W_ACK_RTD 0x60
# define TWI_SLA_DATA_RCV_ACK_RTD 0x80
# define TWI_SLA_DATA_RCV_NACK_RTD 0x88

# define TWI_SLA_REQ_R_ACK_RTD 0xA8
# define TWI_SLA_DATA_SND_ACK_RCV 0xB8
# define TWI_SLA_DATA_SND_NACK_RCV 0xC0
# define TWI_SLA_LAST_DATA_SND_ACK_RCV 0xC8

# define TWI_SLA_REPEAT_START 0xA0
# define TWI_SLA_STOP 0x68
# define I2C_IDLE 0x00
//! @}

unsigned char readI2Cslavebyte(void);
void twi_slave_init( void );
void twi_slave_enable( void );

void twi_slave_disable( void );
void receivedata(void);
void senddata(void);
void TWI_state_machine(void);
void GetStartCondition(void);


#endif //__TWI_H


Добавлено after 5 minutes 34 seconds:
Извиняюсь, только сейчас посмотрел, что его надо объявить сначала. Все отлично скомпилировалось, только ANSI C - пришлось счетчик i объявить до условия if.

Добавлено after 1 hour 5 minutes 5 seconds:
Все сделал, но с первого раза не запустилось. Помогите понять, в чем ошибка. Скорее всего с тактовыми частотами проблема, но я не совсем это понимаю.

1. Соединил PB0 с A5 Arduino, PB1 с A4 Arduino. GND с GND.
2. Master
Спойлер#include <Wire.h>

#define adres 0x5D

void setup()
{
Wire.begin(); // подключение к шине i2c
Serial.begin(9600); // запуск последовательного порта
delay(2000); // пауза
}

void loop()
{
Wire.requestFrom(adres, 6); // запрос 6 байт от слейва #2

while(Wire.available()) // пока есть, что читать
{
char c = Wire.read(); // получаем байт (как символ)
Serial.print(c, HEX); // печатает в порт
Serial.print(" ");

}
Serial.print("\n\r");
Serial.print("dat");
delay(500);
}


3. Slave
Спойлер//#include <avr/io.h> //for debug
#include <avr/interrupt.h>
#include "TWI.h"


#define InvBit(reg, bit) reg ^= (1<<(bit))
#define ClearBit(reg, bit) reg &= (~(1<<(bit)))
#define SetBit(reg, bit) reg |= (1<<(bit))
#define BitIsSet(reg, bit) ((reg & (1<<bit)) != 0)

#define InvBit(reg, bit) reg ^= (1<<(bit))
#define ClearBit(reg, bit) reg &= (~(1<<(bit)))
#define SetBit(reg, bit) reg |= (1<<(bit))
#define BitIsSet(reg, bit) ((reg & (1<<bit)) != 0)

extern volatile unsigned char outgoingBuffer[6];

volatile uint32_t value1 = 0x00;


int main( void )
{
sei(); //!< Enable global interrupts.

twi_slave_init();
twi_slave_enable();

int i;

for(i=0; i<6; outgoingBuffer[i++]=0) {} // очистка передающего буфера

while (1)
{
value1++;

outgoingBuffer[3] = (value1 & 0xff000000) >> 24;
outgoingBuffer[2] = (value1 & 0x00ff0000) >> 16;
outgoingBuffer[1] = (value1 & 0x0000ff00) >> 8;
outgoingBuffer[0] = (value1 & 0x000000ff);

}


}


4. MakeFile
Спойлер# Hey Emacs, this is a -*- makefile -*-
#----------
# WinAVR Makefile Template written by Eric B. Weddington, Jцrg Wunsch, et al.
#
# Released to the Public Domain
#
# Additional material for this makefile was written by:
# Peter Fleury
# Tim Henigan
# Colin O'Flynn
# Reiner Patommel
# Markus Pfaff
# Sander Pool
# Frederik Rouleau
# Carlos Lamas
#
#----------
# On command line:
#
# make all = Make software.
#
# make clean = Clean out built project files.
#
# make coff = Convert ELF to AVR COFF.
#
# make extcoff = Convert ELF to AVR Extended COFF.
#
# make program = Download the hex file to the device, using avrdude.
# Please customize the avrdude settings below first!
#
# make debug = Start either simulavr or avarice as specified for debugging,
# with avr-gdb or avr-insight as the front end for debugging.
#
# make filename.s = Just compile filename.c into the assembler code only.
#
# make filename.i = Create a preprocessed source file for use in submitting
# bug reports to the GCC project.
#
# To rebuild project do "make clean" then "make all".
#----------


# MCU name
MCU = attiny13


# Processor frequency.
# This will define a symbol, F_CPU, in all source code files equal to the
# processor frequency. You can then use this symbol in your source code to
# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
# automatically to create a 32-bit value in your source code.
# Typical values are:
# F_CPU = 1000000
# F_CPU = 1843200
# F_CPU = 2000000
# F_CPU = 3686400
# F_CPU = 4000000
# F_CPU = 7372800
# F_CPU = 8000000
# F_CPU = 11059200
# F_CPU = 14745600
# F_CPU = 16000000
# F_CPU = 18432000
# F_CPU = 20000000
F_CPU = 9600000


# Output format. (can be srec, ihex, binary)
FORMAT = ihex


# Target file name (without extension).
TARGET = main


# Object files directory
# To put object files in current directory, use a dot (.), do NOT make
# this an empty or blank macro!
OBJDIR = .


# List C source files here. (C dependencies are automatically generated.)
SRC = $(TARGET).c TWI.c


# List C++ source files here. (C dependencies are automatically generated.)
CPPSRC =


# List Assembler source files here.
# Make them always end in a capital .S. Files ending in a lowercase .s
# will not be considered source files but generated files (assembler
# output from the compiler), and will be deleted upon "make clean"!
# Even though the DOS/Win* filesystem matches both .s and .S the same,
# it will preserve the spelling of the filenames, and gcc itself does
# care about how the name is spelled on its command-line.
ASRC =


# Optimization level, can be [0, 1, 2, 3, s].
# 0 = turn off optimization. s = optimize for size.
# (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
OPT = s


# Debugging format.
# Native formats for AVR-GCC's -g are dwarf-2 [default] or stabs.
# AVR Studio 4.10 requires dwarf-2.
# AVR [Extended] COFF format requires stabs, plus an avr-objcopy run.
DEBUG = dwarf-2


# List any extra directories to look for include files here.
# Each directory must be seperated by a space.
# Use forward slashes for directory separators.
# For a directory that has spaces, enclose it in quotes.
EXTRAINCDIRS =


# Compiler flag to set the C Standard level.
# c89 = "ANSI" C
# gnu89 = c89 plus GCC extensions
# c99 = ISO C99 standard (not yet fully implemented)
# gnu99 = c99 plus GCC extensions
CSTANDARD = -std=gnu99


# Place -D or -U options here for C sources
CDEFS = -DF_CPU=$(F_CPU)UL


# Place -D or -U options here for ASM sources
ADEFS = -DF_CPU=$(F_CPU)


# Place -D or -U options here for C++ sources
CPPDEFS = -DF_CPU=$(F_CPU)UL
#CPPDEFS += -D__STDC_LIMIT_MACROS
#CPPDEFS += -D__STDC_CONSTANT_MACROS



#---------- Compiler Options C ----------
# -g*: generate debugging information
# -O*: optimization level
# -f...: tuning, see GCC manual and avr-libc documentation
# -Wall...: warning level
# -Wa,...: tell GCC to pass this to the assembler.
# -adhlns...: create assembler listing
CFLAGS = -g$(DEBUG)
CFLAGS += $(CDEFS)
CFLAGS += -O$(OPT)
CFLAGS += -funsigned-char
CFLAGS += -funsigned-bitfields
CFLAGS += -fpack-struct
CFLAGS += -fshort-enums
CFLAGS += -Wall
CFLAGS += -Wstrict-prototypes
#CFLAGS += -mshort-calls
#CFLAGS += -fno-unit-at-a-time
#CFLAGS += -Wundef
#CFLAGS += -Wunreachable-code
#CFLAGS += -Wsign-compare
CFLAGS += -Wa,-adhlns=$(<:%.c=$(OBJDIR)/%.lst)
CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
CFLAGS += $(CSTANDARD)


#---------- Compiler Options C++ ----------
# -g*: generate debugging information
# -O*: optimization level
# -f...: tuning, see GCC manual and avr-libc documentation
# -Wall...: warning level
# -Wa,...: tell GCC to pass this to the assembler.
# -adhlns...: create assembler listing
CPPFLAGS = -g$(DEBUG)
CPPFLAGS += $(CPPDEFS)
CPPFLAGS += -O$(OPT)
CPPFLAGS += -funsigned-char
CPPFLAGS += -funsigned-bitfields
CPPFLAGS += -fpack-struct
CPPFLAGS += -fshort-enums
CPPFLAGS += -fno-exceptions
CPPFLAGS += -Wall
CPPFLAGS += -Wundef
#CPPFLAGS += -mshort-calls
#CPPFLAGS += -fno-unit-at-a-time
#CPPFLAGS += -Wstrict-prototypes
#CPPFLAGS += -Wunreachable-code
#CPPFLAGS += -Wsign-compare
CPPFLAGS += -Wa,-adhlns=$(<:%.cpp=$(OBJDIR)/%.lst)
CPPFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
#CPPFLAGS += $(CSTANDARD)


#---------- Assembler Options ----------
# -Wa,...: tell GCC to pass this to the assembler.
# -adhlns: create listing
# -gstabs: have the assembler create line number information; note that
# for use in COFF files, additional information about filenames
# and function names needs to be present in the assembler source
# files -- see avr-libc docs [FIXME: not yet described there]
# -listing-cont-lines: Sets the maximum number of continuation lines of hex
# dump that will be displayed for a given single line of source input.
ASFLAGS = $(ADEFS) -Wa,-adhlns=$(<:%.S=$(OBJDIR)/%.lst),-gstabs,--listing-cont-lines=100


#---------- Library Options ----------
# Minimalistic printf version
PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min

# Floating point printf version (requires MATH_LIB = -lm below)
PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt

# If this is left blank, then it will use the Standard printf version.
PRINTF_LIB =
#PRINTF_LIB = $(PRINTF_LIB_MIN)
#PRINTF_LIB = $(PRINTF_LIB_FLOAT)


# Minimalistic scanf version
SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min

# Floating point + %[ scanf version (requires MATH_LIB = -lm below)
SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt

# If this is left blank, then it will use the Standard scanf version.
SCANF_LIB =
#SCANF_LIB = $(SCANF_LIB_MIN)
#SCANF_LIB = $(SCANF_LIB_FLOAT)


MATH_LIB = -lm


# List any extra directories to look for libraries here.
# Each directory must be seperated by a space.
# Use forward slashes for directory separators.
# For a directory that has spaces, enclose it in quotes.
EXTRALIBDIRS =



#---------- External Memory Options ----------

# 64 KB of external RAM, starting after internal RAM (ATmega128!),
# used for variables (.data/.bss) and heap (malloc()).
#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff

# 64 KB of external RAM, starting after internal RAM (ATmega128!),
# only used for heap (malloc()).
#EXTMEMOPTS = -Wl,--section-start,.data=0x801100,--defsym=__heap_end=0x80ffff

EXTMEMOPTS =



#---------- Linker Options ----------
# -Wl,...: tell GCC to pass this to linker.
# -Map: create map file
# --cref: add cross reference to map file
LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
LDFLAGS += $(EXTMEMOPTS)
LDFLAGS += $(patsubst %,-L%,$(EXTRALIBDIRS))
LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)
#LDFLAGS += -T linker_script.x



#---------- Programming Options (avrdude) ----------

# Programming hardware
# Type: avrdude -c ?
# to get a full listing.
#
AVRDUDE_PROGRAMMER = avrispv2

# com1 = serial port. Use lpt1 to connect to parallel port.
AVRDUDE_PORT = usb

AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep


# Uncomment the following if you want avrdude's erase cycle counter.
# Note that this counter needs to be initialized first using -Yn,
# see avrdude manual.
#AVRDUDE_ERASE_COUNTER = -y

# Uncomment the following if you do /not/ wish a verification to be
# performed after programming the device.
#AVRDUDE_NO_VERIFY = -V

# Increase verbosity level. Please use this when submitting bug
# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude>
# to submit bug reports.
#AVRDUDE_VERBOSE = -v -v

AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY)
AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE)
AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)



#---------- Debugging Options ----------

# For simulavr only - target MCU frequency.
DEBUG_MFREQ = $(F_CPU)

# Set the DEBUG_UI to either gdb or insight.
# DEBUG_UI = gdb
DEBUG_UI = insight

# Set the debugging back-end to either avarice, simulavr.
DEBUG_BACKEND = avarice
#DEBUG_BACKEND = simulavr

# GDB Init Filename.
GDBINIT_FILE = __avr_gdbinit

# When using avarice settings for the JTAG
JTAG_DEV = /dev/com1

# Debugging port used to communicate between GDB / avarice / simulavr.
DEBUG_PORT = 4242

# Debugging host used to communicate between GDB / avarice / simulavr, normally
# just set to localhost unless doing some sort of crazy debugging when
# avarice is running on a different computer.
DEBUG_HOST = localhost



#======================


# Define programs and commands.
SHELL = sh
CC = avr-gcc
OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump
SIZE = avr-size
AR = avr-ar rcs
NM = avr-nm
AVRDUDE = avrdude
REMOVE = rm -f
REMOVEDIR = rm -rf
COPY = cp
WINSHELL = cmd


# Define Messages
# English
MSG_ERRORS_NONE = Errors: none
MSG_BEGIN = -------- begin --------
MSG_END = -------- end --------
MSG_SIZE_BEFORE = Size before:
MSG_SIZE_AFTER = Size after:
MSG_COFF = Converting to AVR COFF:
MSG_EXTENDED_COFF = Converting to AVR Extended COFF:
MSG_FLASH = Creating load file for Flash:
MSG_EEPROM = Creating load file for EEPROM:
MSG_EXTENDED_LISTING = Creating Extended Listing:
MSG_SYMBOL_TABLE = Creating Symbol Table:
MSG_LINKING = Linking:
MSG_COMPILING = Compiling C:
MSG_COMPILING_CPP = Compiling C++:
MSG_ASSEMBLING = Assembling:
MSG_CLEANING = Cleaning project:
MSG_CREATING_LIBRARY = Creating library:




# Define all object files.
OBJ = $(SRC:%.c=$(OBJDIR)/%.o) $(CPPSRC:%.cpp=$(OBJDIR)/%.o) $(ASRC:%.S=$(OBJDIR)/%.o)

# Define all listing files.
LST = $(SRC:%.c=$(OBJDIR)/%.lst) $(CPPSRC:%.cpp=$(OBJDIR)/%.lst) $(ASRC:%.S=$(OBJDIR)/%.lst)


# Compiler flags to generate dependency files.
GENDEPFLAGS = -MMD -MP -MF .dep/$(@F).d


# Combine all necessary flags and optional flags.
# Add target processor to flags.
ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS)
ALL_CPPFLAGS = -mmcu=$(MCU) -I. -x c++ $(CPPFLAGS) $(GENDEPFLAGS)
ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)





# Default target.
all: begin gccversion sizebefore build sizeafter end

# Change the build target to build a HEX file or a library.
build: elf hex eep lss sym
#build: lib


elf: $(TARGET).elf
hex: $(TARGET).hex
eep: $(TARGET).eep
lss: $(TARGET).lss
sym: $(TARGET).sym
LIBNAME=lib$(TARGET).a
lib: $(LIBNAME)



# Eye candy.
# AVR Studio 3.x does not check make's exit code but relies on
# the following magic strings to be generated by the compile job.
begin:
@echo
@echo $(MSG_BEGIN)

end:
@echo $(MSG_END)
@echo


# Display size of file.
HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex
ELFSIZE = $(SIZE) --mcu=$(MCU) --format=avr $(TARGET).elf

sizebefore:
@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); \
2>/dev/null; echo; fi

sizeafter:
@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); \
2>/dev/null; echo; fi



# Display compiler version information.
gccversion :
@$(CC) --version



# Program the device.
program: $(TARGET).hex $(TARGET).eep
$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)


# Generate avr-gdb config/init file which does the following:
# define the reset signal, load the target file, connect to target, and set
# a breakpoint at main().
gdb-config:
@$(REMOVE) $(GDBINIT_FILE)
@echo define reset >> $(GDBINIT_FILE)
@echo SIGNAL SIGHUP >> $(GDBINIT_FILE)
@echo end >> $(GDBINIT_FILE)
@echo file $(TARGET).elf >> $(GDBINIT_FILE)
@echo target remote $(DEBUG_HOST):$(DEBUG_PORT) >> $(GDBINIT_FILE)
ifeq ($(DEBUG_BACKEND),simulavr)
@echo load >> $(GDBINIT_FILE)
endif
@echo break main >> $(GDBINIT_FILE)

debug: gdb-config $(TARGET).elf
ifeq ($(DEBUG_BACKEND), avarice)
@echo Starting AVaRICE - Press enter when "waiting to connect" message displays.
@$(WINSHELL) /c start avarice --jtag $(JTAG_DEV) --erase --program --file \
$(TARGET).elf $(DEBUG_HOST):$(DEBUG_PORT)
@$(WINSHELL) /c pause

else
@$(WINSHELL) /c start simulavr --gdbserver --device $(MCU) --clock-freq \
$(DEBUG_MFREQ) --port $(DEBUG_PORT)
endif
@$(WINSHELL) /c start avr-$(DEBUG_UI) --command=$(GDBINIT_FILE)




# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.
COFFCONVERT = $(OBJCOPY) --debugging
COFFCONVERT += --change-section-address .data-0x800000
COFFCONVERT += --change-section-address .bss-0x800000
COFFCONVERT += --change-section-address .noinit-0x800000
COFFCONVERT += --change-section-address .eeprom-0x810000



coff: $(TARGET).elf
@echo
@echo $(MSG_COFF) $(TARGET).cof
$(COFFCONVERT) -O coff-avr $< $(TARGET).cof


extcoff: $(TARGET).elf
@echo
@echo $(MSG_EXTENDED_COFF) $(TARGET).cof
$(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof



# Create final output files (.hex, .eep) from ELF output file.
%.hex: %.elf
@echo
@echo $(MSG_FLASH) $@
$(OBJCOPY) -O $(FORMAT) -R .eeprom -R .fuse -R .lock $< $@

%.eep: %.elf
@echo
@echo $(MSG_EEPROM) $@
-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
--change-section-lma .eeprom=0 --no-change-warnings -O $(FORMAT) $< $@ || exit 0

# Create extended listing file from ELF output file.
%.lss: %.elf
@echo
@echo $(MSG_EXTENDED_LISTING) $@
$(OBJDUMP) -h -S -z $< > $@

# Create a symbol table from ELF output file.
%.sym: %.elf
@echo
@echo $(MSG_SYMBOL_TABLE) $@
$(NM) -n $< > $@



# Create library from object files.
.SECONDARY : $(TARGET).a
.PRECIOUS : $(OBJ)
%.a: $(OBJ)
@echo
@echo $(MSG_CREATING_LIBRARY) $@
$(AR) $@ $(OBJ)


# Link: create ELF output file from object files.
.SECONDARY : $(TARGET).elf
.PRECIOUS : $(OBJ)
%.elf: $(OBJ)
@echo
@echo $(MSG_LINKING) $@
$(CC) $(ALL_CFLAGS) $^ --output $@ $(LDFLAGS)


# Compile: create object files from C source files.
$(OBJDIR)/%.o : %.c
@echo
@echo $(MSG_COMPILING) $<
$(CC) -c $(ALL_CFLAGS) $< -o $@


# Compile: create object files from C++ source files.
$(OBJDIR)/%.o : %.cpp
@echo
@echo $(MSG_COMPILING_CPP) $<
$(CC) -c $(ALL_CPPFLAGS) $< -o $@


# Compile: create assembler files from C source files.
%.s : %.c
$(CC) -S $(ALL_CFLAGS) $< -o $@


# Compile: create assembler files from C++ source files.
%.s : %.cpp
$(CC) -S $(ALL_CPPFLAGS) $< -o $@


# Assemble: create object files from assembler source files.
$(OBJDIR)/%.o : %.S
@echo
@echo $(MSG_ASSEMBLING) $<
$(CC) -c $(ALL_ASFLAGS) $< -o $@


# Create preprocessed source for use in sending a bug report.
%.i : %.c
$(CC) -E -mmcu=$(MCU) -I. $(CFLAGS) $< -o $@


# Target: clean project.
clean: begin clean_list end

clean_list :
@echo
@echo $(MSG_CLEANING)
$(REMOVE) $(TARGET).hex
$(REMOVE) $(TARGET).eep
$(REMOVE) $(TARGET).cof
$(REMOVE) $(TARGET).elf
$(REMOVE) $(TARGET).map
$(REMOVE) $(TARGET).sym
$(REMOVE) $(TARGET).lss
$(REMOVE) $(SRC:%.c=$(OBJDIR)/%.o)
$(REMOVE) $(SRC:%.c=$(OBJDIR)/%.lst)
$(REMOVE) $(SRC:.c=.s)
$(REMOVE) $(SRC:.c=.d)
$(REMOVE) $(SRC:.c=.i)
$(REMOVEDIR) .dep


# Create object files directory
$(shell mkdir $(OBJDIR) 2>/dev/null)


# Include the dependency files.
-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)


# Listing of phony targets.
.PHONY : all begin finish end sizebefore sizeafter gccversion \
build elf hex eep lss sym coff extcoff \
clean clean_list program debug gdb-config


5. Кварц я не использую. То есть у меня контроллер светодиодом до этого прекрасно помигал, микроконтроллер рабочий, но работает от внутреннего стандарта частоты. В Makefile оставил 9600000 Гц, как видно по содержимому.

6. Все загрузилось успешно, вроде ошибок нигде нет. Но не передает данные просто. Адрес Слейва вроде и там и там постарался одинаковый поставить, может еще с ним что не так?
Вложения
111.png
(87.27 KiB) Скачиваний: 220

Re: I2C на Attiny 13 - Попытка сквозь времена:)

Пн авг 05, 2019 06:56:15

kras писал(а):Адрес Слейва вроде и там и там постарался одинаковый поставить, может еще с ним что не так?
Могли бы сначала мой пример повторить, а потом свое изобретать.
Да и 0x5D не будет работать.
Пишите так
Мастер
Код:
#define adres 0x5C>>1
а в Slave, что бы вам не путаться, в файле TWI.h укажите
Код:
#define SLAVE_ADDRESS 0x5C>>1

Re: I2C на Attiny 13 - Попытка сквозь времена:)

Пн авг 05, 2019 16:26:04

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

Ок, гипотеза с тем, что адрес не тот, не помогла. Поменял строки с адресом и в Мастере, и в Слейве (и там и там теперь >>1). На Мастере в сериал выводится текст, который для теста сам написал
Код:
Serial.print("dat");
, но со слейва ничего не приходит. А если внутри цикла
Код:
while(Wire.available())
пробую строку вывести с сериал - не выводит, поэтому, получается, ничего не приходит.

Еще идеи, где ошибся? Мне кажется, все таки скорости не соответствуют, но я плаваю в этих моментах, поэтому прошу поддержки.

Кстати. Когда на PB1 и на PB0 висит A4 и A5 с Ардуино, то AVR MKII программатор не хочет загружать прошивку. Но я так понимаю, что это связано с тем, что эти порты используются для программирования, и их и надо отключать перед загрузкой программы в Attiny13, так?

Re: I2C на Attiny 13 - Попытка сквозь времена:)

Пн авг 05, 2019 16:39:04

kras писал(а):1. Соединил PB0 с A5 Arduino, PB1 с A4 Arduino. GND с GND.
Резисторы стоят?

Re: I2C на Attiny 13 - Попытка сквозь времена:)

Пн авг 05, 2019 19:58:56

Нет, резисторы не ставил.

Re: I2C на Attiny 13 - Попытка сквозь времена:)

Вт авг 06, 2019 07:11:30

Нет, резисторы не ставил.

Уж не хотите ли вы сказать, что пытаетесь отлаживать линию I^2C без положенных по стандарту резисторов подтяжки? А потом удивляетесь глюкам?

Re: I2C на Attiny 13 - Попытка сквозь времена:)

Вт авг 06, 2019 13:58:31

Так не работает передача от слова совсем. То есть я бы рад был бы, если бы хоть что-то получил)
Хорошо, еще раз, по I2C я фактически соединяю Arduino Uno с микроконтроллером Attiny 13. Правильно ли я понимаю, надо поставить 2 резистора на 4.7 кОм, как на фото, и тогда должно заработать, так? Я отпишусь по результату, но может все таки еще какой-то косяк?

По фото, кстати, понял фишку с адресом, он по умолчанию 7 бит, так?) Поэтому >>1 сдвиг на 1 бит? Ну вообще интересно, я то обычно просто задавал hex типа 0x5D и все работало. Или библиотека обычно сама сдвигает? Или там настройка адреса была, что он получался 8 бит? Для меня это не было раньше понятно, ведь получается, что нельзя задать любой Hex адрес, компилятор, выходит, все равно обрежет 1 бит, так?

Безымянный.png
(79.19 KiB) Скачиваний: 287


Добавлено after 18 minutes 8 seconds:
Подтянул SDA и SCL к +5В через резисторы 4.7 кОм, все равно данные не принимаются. Что еще можно проверить? Объясните, в любом случае, по поводу тактовых частот еще раз.

1. Я же на Аттини 9.6 МГц задаю в Makefile. Но кварц внешний не использую, то есть внутренний там не может прифигеть и поставить автоматом другую частоту?

2. Скорость передачи и скорость приема могут не совпадать? Тактовые частоты мастера и слейва могут не совпадать, где
это перепроверить?

Re: I2C на Attiny 13 - Попытка сквозь времена:)

Вт авг 06, 2019 17:41:00

kras писал(а):По фото, кстати, понял фишку с адресом, он по умолчанию 7 бит, так?) Поэтому >>1 сдвиг на 1 бит? Ну вообще интересно, я то обычно просто задавал hex типа 0x5D и все работало.
Нет, это был просто эксперимент.
kras писал(а):Или библиотека обычно сама сдвигает? Или там настройка адреса была, что он получался 8 бит? Для меня это не было раньше понятно, ведь получается, что нельзя задать любой Hex адрес, компилятор, выходит, все равно обрежет 1 бит, так?
Не знаю что там Ардуино делает, но Slave
Код:
  //!Send ACK, SCL is low now
  if((val & 0xFE) == (SLAVE_ADDRESS << 1))
я специально адрес в 6 бит превратил. Потом бы разобрались с адресом.
kras писал(а):1. Я же на Аттини 9.6 МГц задаю в Makefile. Но кварц внешний не использую, то есть внутренний там не может прифигеть и поставить автоматом другую частоту?
Смотря чем программируете, если с makefile настройки берете, то в разделе Programming Options (avrdude) я не вижу что бы фьюзы программировали, как там на счет фьюзов?
kras писал(а):2. Скорость передачи и скорость приема могут не совпадать? Тактовые частоты мастера и слейва могут не совпадать, где
это перепроверить?
Что там на рисунке за STM32?
Программный i2c работает до 100кГц, проверите фьюзы attiny13, далее можно глянуть осциллографом что там stm32 шлет, на какой частоте,
можно параллельно i2c подключить заведомо рабочую ну что там у вас есть 24lc16 часы ртс лсд-экран, проверить что шина i2c работает.

Re: I2C на Attiny 13 - Попытка сквозь времена:)

Ср авг 07, 2019 10:42:27

1. Программирую AVR ISP MKII. Я честно немного забыл про фьюзы. Как конкретно тогда должно быть прописано по фьюзам в MakeFile? И напомните смысл, почему их надо трогать, почему без них может не работать? Напомните, как в WinAVR посмотреть текущее значение фьюзов?
2. Получается, что на Slave тогда сдвигать не надо, только на Master?
3. А может вспомогательный код добавить? Например, светодиодом мигать в определенные моменты? Ну просто я не понимаю, все таки, как лучше отследить, идут ли данные и почему не принимаются в итоге. Осциллографом попробую, кстати.

STM32 - это просто я первый попавшийся рисунок в Интернете нашел, у меня просто Arduino Uno с Atmega 328.

Re: I2C на Attiny 13 - Попытка сквозь времена:)

Ср авг 07, 2019 20:50:43

kras писал(а):Программирую AVR ISP MKII.
Ни о чем это мне не говорит, я программирую через
СпойлерИзображение
может так будет понятно.
kras писал(а):Я честно немного забыл про фьюзы.
Придется вам вспомнить.
kras писал(а):И напомните смысл, почему их надо трогать, почему без них может не работать?
Текущая частота 9,6МГц, можете написать обыкновенную "моргалку" с заранее вам известной частотой, зашить в контроллер и определить примерно на какой частоте он работает.
kras писал(а):Как конкретно тогда должно быть прописано по фьюзам в MakeFile? Напомните, как в WinAVR посмотреть текущее значение фьюзов?
Без понятия как там в MakeFile, выше я уже написал через что программирую.
kras писал(а):2. Получается, что на Slave тогда сдвигать не надо, только на Master?
Вам что 6 битного адреса мало что ли?
kras писал(а):А может вспомогательный код добавить? Например, светодиодом мигать в определенные моменты? Ну просто я не понимаю, все таки, как лучше отследить, идут ли данные и почему не принимаются в итоге. Осциллографом попробую, кстати.
Осциллограф вам здесь не поможет, разве что логический анализатор.
Начните с определения рабочей частоты контроллера, если не хотите фьюзы вспоминать, грузите "моргалку".

Re: I2C на Attiny 13 - Попытка сквозь времена:)

Чт авг 08, 2019 17:07:48

А мигая светодиодом можно решить многие проблемы, однако))

Смотрите. В общем, этот код работает отлично:
Код:
#define F_CPU 960000UL // Указываем тактовую частоту МК
#define LED PB4         // Используем светодиод, подключенный к PB2 (7 пин)
#include <avr/io.h>     // Подключаем определения ввода/вывода
#include <util/delay.h> // Подключаем библиотеку функций задержки

int main(void)
{
  // Светодиод
  DDRB |= (1<<LED);     // конфигурируем пин как выход
  PORTB &= ~(1<<LED);   // по умолчанию светодиод выключен
  // Основной цикл
  while (1)
  {
    _delay_ms (1000);    // задержка 500 мс
    PORTB ^= (1<<LED);  // инвертируем состояние пина
  }
}


Я специально использовал тот же самый Makefile, что и в программе с TWI, просто не стал включать TWI.c

Светодиод переключается раз в секунду.
Какая тут частота в дефайне, 0,96 МГц?

Так вот, когда я в дефайне CPU увеличиваю частоту в 10 раз (+ нолик), то начинается фигня, светодиод мигает очень долго.
Когда я комментирую дефайн CPU совсем (//#define F_CPU 960000UL), светодиод также мигает очень долго.

В принципе тогда я понял возможную проблему, но плохо понимаю, как было бы лучше ее устранить. Можно и дефайном CPU, но тогда подскажите, какую частоту лучше поставить, будет ли это, все таки, 0,96 МГц или же +9,6 МГц? Для I2C есть разница (для TWI), какая тактовая частота используется?

Re: I2C на Attiny 13 - Попытка сквозь времена:)

Чт авг 08, 2019 17:52:57

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

Re: I2C на Attiny 13 - Попытка сквозь времена:)

Чт авг 08, 2019 19:39:36

kras писал(а):Светодиод переключается раз в секунду.
Какая тут частота в дефайне, 0,96 МГц?

Так вот, когда я в дефайне CPU увеличиваю частоту в 10 раз (+ нолик), то начинается фигня, светодиод мигает очень долго.
Когда я комментирую дефайн CPU совсем (//#define F_CPU 960000UL), светодиод также мигает очень долго.
Предположительно Частота контроллера 9,6МГц + включен внутренний делитель на 8 итоговая 9,6/8=1,2МГц.
kras писал(а):В принципе тогда я понял возможную проблему, но плохо понимаю, как было бы лучше ее устранить. Можно и дефайном CPU, но тогда подскажите, какую частоту лучше поставить, будет ли это, все таки, 0,96 МГц или же +9,6 МГц?
Это не поможет. В даной программе не используются задержки. Чем выше частота, тем меньше время выполнения одного такта контроллера.
kras писал(а):Для I2C есть разница (для TWI), какая тактовая частота используется?
Для работы программы требуется 9,6МГц.

Рекомендую изучить фьюзы Attiny 13.

Re: I2C на Attiny 13 - Попытка сквозь времена:)

Пт авг 09, 2019 12:53:38

Окей, спасибо, сейчас поразбираюсь!

1. Может ли быть адрес слейва 0x00? Это для того, чтобы не запутаться, было бы удобно, дескать как ни сдвигай.
2. Допустим, адрес 0x5C. Я слабо понимаю, получается, поэтому проверьте, плиз, мою логику. В бинари: 0101 1100. Получается, как ни сдвигай, вроде должно все получиться с этим адресом. Только если случайно на 2 бита не сдвинуть) Но после <<1, как я понимаю, уйдет старший бит, а останется, таким образом, 1011100. Я прав?

Добавлено after 8 minutes 54 seconds:
Поразбирался. Помню, раньше я чем-то другим программировал фьюзы, но для удобства хочу осилить, как это сделать в WinAVR. Да, скорее всего проблема в этом, что установлен бит фьюза CLKDIV8. Я почитал, что в avrdude (на который ссылается WinAVR programmers notepad) использует команду

C:\WinAVR\bin\avrdude.exe" -p m16 -c stk200 -P lpt1 -U hfuse:w:0x89:m -U lfuse:w:0xef:m

Получается, что hfuse - это старший байт фьюз, а lfuse - младший байт.
Как я понял, именно эти значения и нужны, то есть 0x89 и 0xef, но поправьте меня, если что, чтобы не ошибся.

Если все так, дело остается только за тем, как эту информацию внести в makefile сразу. И я этого не нашел, может кто-нибудь подсказать?

Re: I2C на Attiny 13 - Попытка сквозь времена:)

Пт авг 09, 2019 16:29:32

Скачайте от сюда avrdudeprog33.
Запустите прогу AVRDUDEPROG.exe
СпойлерИзображение
Выберите тип контроллера Attiny13
Тип программатора AVR ISP mkII
Порт, на каком висит программатор, скорее всего USB будет.
Нажать кнопку "Чтение", если результат удачный, переходим на вкладку FUSES
СпойлерИзображение
Нажать кнопку "Чтение", результат (скриншот) сюда.

Re: I2C на Attiny 13 - Попытка сквозь времена:)

Пт авг 09, 2019 18:20:37

Безымянный.jpg
(228.15 KiB) Скачиваний: 285

Re: I2C на Attiny 13 - Попытка сквозь времена:)

Пт авг 09, 2019 18:39:35

Нажать кнопку "Чтение" HIGH-0xFF LOW-0x6A,
убрать галочку с CKDIV8 HIGH-0xFF LOW-0x7A,
нажать "Программировать", Нажать "Верификация".

Re: I2C на Attiny 13 - Попытка сквозь времена:)

Пт авг 09, 2019 22:25:40

Супер. Светодиод мигает теперь раз в секунду! На тактовой 9.6 МГц.

Добавлено after 3 minutes 56 seconds:
По I2C стало что-то приходить. Но пока слова заканчиваются на "что-то". Что это?)

Добавлено after 18 minutes 28 seconds:
Точнее так. Все принимается верно. Но Мастер ждет приема 6 байт данных. Каждый байт - это 0хFE - вот такое число, ведь 0xFE = 1111 1110, то есть это 8 бит.

Тогда я ожидал так: на приеме нужно ловить 6 байт, то есть 6 таких чисел. Однако я попробовал передать случайные числа, а точнее по порядку

СпойлерoutgoingBuffer[5] = 0xfe;
outgoingBuffer[4] = 0xfd;
outgoingBuffer[3] = 0xfc;
outgoingBuffer[2] = 0xfb;
outgoingBuffer[1] = 0xfa;
outgoingBuffer[0] = 0xf0;


Тогда в таком порядке они и приходят, но вместо 0хf0ss 0xfass .... я наблюдаю

СпойлерFFFFFFF0ss FFFFFFFAss FFFFFFFBss FFFFFFFCss FFFFFFFDss FFFFFFFEss


Каждый байт, таким образом, - это 4 байта!!! Это как? Ну и если я это пойму, вроде бы все ок, разобрались, наконец-то, ура!!!)

Но что еще не понравилось. Если на передаче
СпойлерoutgoingBuffer[5] = 0xff0034fe;
outgoingBuffer[4] = 0xfd;
outgoingBuffer[3] = 0xfc;
outgoingBuffer[2] = 0xfb;
outgoingBuffer[1] = 0xfa;
outgoingBuffer[0] = 0xf0;

то мастер все равно принимает
СпойлерFFFFFFF0ss FFFFFFFAss FFFFFFFBss FFFFFFFCss FFFFFFFDss FFFFFFFEss


Куда деваются эти магические 3 байта? Или же их не существует, и это просто форма отображения такая?
Вложения
Безымянный.jpg
(202.86 KiB) Скачиваний: 277
Ответить