Программный i2c 1 МГц (для 16 МГц устройств) для AVR.

Komandir
Offline
Зарегистрирован: 18.08.2018

Размер кода 138 байт.

Можно назначить SCL и SDA на любые выводы.

Komandir
Offline
Зарегистрирован: 18.08.2018

Для ASM:

.equ		SCLPORT=PORTC
.equ		SCLPIN=PORTC5
.equ		SDAPORT=PORTC
.equ		SDAPIN=PORTC4

.CSEG

.ORG		$0
	RJMP	Start

.ORG		INT_VECTORS_SIZE
;------------------------------
i2c_init:
	CBI	SCLPORT-1,SCLPIN
	CBI	SDAPORT-1,SDAPIN
	CBI	SDAPORT,SDAPIN
	CBI	SCLPORT,SCLPIN
	RET

;------------------------------
i2c_start:
	SBI	SDAPORT-1,SDAPIN
	RET

;------------------------------
i2c_restart:
	CBI	SCLPORT-1,SCLPIN
	CBI	SCLPORT-1,SCLPIN
	SBI	SDAPORT-1,SDAPIN
	RET

;------------------------------
i2c_write:
	LDI	R25,8
i2c_write_loop:
	SBI	SCLPORT-1,SCLPIN
	SBRC	R24,7
	CBI	SDAPORT-1,SDAPIN
	SBRS	R24,7
	SBI	SDAPORT-1,SDAPIN
	ROL	R24
	CBI	SCLPORT-1,SCLPIN
i2c_write_loop1:
	SBIS	SCLPORT-2,SCLPIN
	RJMP	i2c_write_loop1
	NOP
	DEC	R25
	BRNE	i2c_write_loop
	NOP
	SBI	SCLPORT-1,SCLPIN
	CBI	SDAPORT-1,SDAPIN
	CBI	SDAPORT-1,SDAPIN
	CBI	SDAPORT-1,SDAPIN
	CBI	SCLPORT-1,SCLPIN
	CLR	R24
	SBIS	SDAPORT-2,SDAPIN
	INC	R24
	CBI	SCLPORT-1,SCLPIN
	NOP
	SBI	SCLPORT-1,SCLPIN
	RET

;------------------------------
i2c_read:
	LDI	R25,8
	BST	R24,0
i2c_read_loop:
	SBI	SCLPORT-1,SCLPIN
	SBI	SCLPORT-1,SCLPIN
	SBI	SCLPORT-1,SCLPIN
	BLD	R24,0
	LSL	R24
	CBI	SCLPORT-1,SCLPIN
	SET
	SBIS	SDAPORT-2,SDAPIN
	CLT
	DEC	R25
	BRNE	i2c_read_loop
	BLD	R24,0
	SBI	SCLPORT-1,SCLPIN
	ROL	R25
	SBRS	R25,0
	SBI	SDAPORT-1,SDAPIN
	SBRC	R25,0
	CBI	SDAPORT-1,SDAPIN
	CBI	SCLPORT-1,SCLPIN
	CBI	SCLPORT-1,SCLPIN
	CBI	SCLPORT-1,SCLPIN
	CBI	SCLPORT-1,SCLPIN
	SBI	SCLPORT-1,SCLPIN
	CBI	SDAPORT-1,SDAPIN
	RET

;------------------------------
i2c_stop:
	SBI	SDAPORT-1,SDAPIN
	CBI	SCLPORT-1,SCLPIN
	CBI	SCLPORT-1,SCLPIN
	CBI	SDAPORT-1,SDAPIN
	RET

;------------------------------
Start:
	LDI	R16,Low(RAMEND)
	OUT	SPL,R16
	LDI	R16,High(RAMEND)
	OUT	SPH,R16
	CALL	i2c_init
Loop:
	CALL	i2c_start
	LDI	R24,$C0
	CALL	i2c_write
	LDI	R24,$07
	CALL	i2c_write
	LDI	R24,$FF
	CALL	i2c_write
	CALL	i2c_stop
	CALL	i2c_start
	LDI	R24,$80
	CALL	i2c_write
	LDI	R24,$03
	CALL	i2c_write
	LDI	R24,$11
	CALL	i2c_write
	CALL	i2c_stop
Loop1:
	CALL	i2c_start
	LDI	R24,$80
	CALL	i2c_write
	LDI	R24,$00
	CALL	i2c_write
	CALL	i2c_restart
	LDI	R24,$81
	CALL	i2c_write
	LDI	R24,$01
	CALL	i2c_read
	CALL	i2c_stop
	ANDI	R24,$01
	BRNE	Loop1
	CALL	i2c_start
	LDI	R24,$80
	CALL	i2c_write
	LDI	R24,$01
	CALL	i2c_write
	CALL	i2c_restart
	LDI	R24,$81
	CALL	i2c_write
	LDI	R24,$00
	CALL	i2c_read
	LDI	R24,$01
	CALL	i2c_read
	CALL	i2c_stop
	RJMP	Loop

 

Komandir
Offline
Зарегистрирован: 18.08.2018

Для C++:

#define SCLPORT PORTC
#define SCLPIN PORTC5
#define SDAPORT PORTC
#define SDAPIN PORTC4
void __attribute__ ((noinline)) i2c_init() {
  asm volatile(
    "CBI %0-1,%1\n\t"
    "CBI %2-1,%3\n\t"
    "CBI %2,%3\n\t"
    "CBI %0,%1\n\t"
    ::"I" (_SFR_IO_ADDR(SCLPORT)), "I" (SCLPIN), "I" (_SFR_IO_ADDR(SDAPORT)), "I" (SDAPIN) 
  );
}
void __attribute__ ((noinline)) i2c_start() {
  asm volatile(
    "SBI %0-1,%1\n\t"
    ::"I" (_SFR_IO_ADDR(SDAPORT)), "I" (SDAPIN)
  );
}
void __attribute__ ((noinline)) i2c_restart() {
  asm volatile(
    "CBI %0-1,%1\n\t"
    "CBI %0-1,%1\n\t"	//replacement for two NOP
//    "NOP\n\t"
//    "NOP\n\t"
    "SBI %2-1,%3\n\t"
    ::"I" (_SFR_IO_ADDR(SCLPORT)), "I" (SCLPIN), "I" (_SFR_IO_ADDR(SDAPORT)), "I" (SDAPIN)
  );
}
uint8_t __attribute__ ((noinline)) i2c_write(uint8_t data) {
  uint8_t result;
  uint8_t i=8;
  asm  volatile(
    "i2c_write_loop:"
    "SBI %1-1,%2\n\t"
    "SBRC %5,7\n\t"
    "CBI %3-1,%4\n\t"
    "SBRS %5,7\n\t"
    "SBI %3-1,%4\n\t"
    "ROL %5\n\t"
    "CBI %1-1,%2\n\t"
    "i2c_write_loop1:"
    "SBIS %1-2,%2\n\t"
    "RJMP i2c_write_loop1\n\t"
    "NOP\n\t"
    "DEC %6\n\t"
    "BRNE i2c_write_loop\n\t"
    "NOP\n\t"
    "SBI %1-1,%2\n\t"
    "CBI %3-1,%4\n\t"
    "CBI %3-1,%4\n\t"	//replacement for two NOP
    "CBI %3-1,%4\n\t"	//replacement for two NOP
//    "NOP\n\t"
//    "NOP\n\t"
//    "NOP\n\t"
//    "NOP\n\t"
    "CBI %1-1,%2\n\t"
    "CLR %0\n\t"
    "SBIS %3-2,%4\n\t"
    "INC %0\n\t"
    "CBI %1-1,%2\n\t"	//replacement for two NOP
//    "NOP\n\t"
//    "NOP\n\t"
    "NOP\n\t"
    "SBI %1-1,%2\n\t"
    : "=r" (result)
    : "I" (_SFR_IO_ADDR(SCLPORT)), "I" (SCLPIN), "I" (_SFR_IO_ADDR(SDAPORT)), "I" (SDAPIN), 
      "r" (data), "r" (i)
  );
  return result;
}
uint8_t __attribute__ ((noinline)) i2c_read(uint8_t last=false) {
  uint8_t result;
  uint8_t i=8;
  asm volatile(
    "BST %0,0\n\t"
    "i2c_read_loop:\n\t"
    "SBI %1-1,%2\n\t"
    "SBI %1-1,%2\n\t"	//replacement for two NOP
    "SBI %1-1,%2\n\t"	//replacement for two NOP
//    "NOP\n\t"
//    "NOP\n\t"
//    "NOP\n\t"
//    "NOP\n\t"
    "BLD %0,0\n\t"
    "LSL %0\n\t"
    "CBI %1-1,%2\n\t"
    "SET\n\t"
    "SBIS %3-2,%4\n\t"
    "CLT\n\t"
    "DEC %6\n\t"
    "BRNE i2c_read_loop\n\t"
    "BLD %0,0\n\t"
    "SBI %1-1,%2\n\t"
    "ROL %6\n\t"
    "SBRS %6,0\n\t"
    "SBI %3-1,%4\n\t"
    "SBRC %6,0\n\t"
    "CBI %3-1,%4\n\t"
    "CBI %1-1,%2\n\t"
    "CBI %1-1,%2\n\t"	//replacement for two NOP
    "CBI %1-1,%2\n\t"	//replacement for two NOP
    "CBI %1-1,%2\n\t"	//replacement for two NOP
//    "NOP\n\t"
//    "NOP\n\t"
//    "NOP\n\t"
//    "NOP\n\t"
//    "NOP\n\t"
//    "NOP\n\t"
    "SBI %1-1,%2\n\t"
    "CBI %3-1,%4\n\t"
    : "=r" (result)
    : "I" (_SFR_IO_ADDR(SCLPORT)), "I" (SCLPIN), "I" (_SFR_IO_ADDR(SDAPORT)), "I" (SDAPIN), 
      "r" (last), "r" (i)
  );
  return result;
}
void __attribute__ ((noinline)) i2c_stop() {
  asm volatile(
    "SBI %2-1,%3\n\t"
    "CBI %0-1,%1\n\t"
    "CBI %0-1,%1\n\t"	//replacement for two NOP
//    "NOP\n\t"
//    "NOP\n\t"
    "CBI %2-1,%3\n\t"
    ::"I" (_SFR_IO_ADDR(SCLPORT)), "I" (SCLPIN), "I" (_SFR_IO_ADDR(SDAPORT)), "I" (SDAPIN)
  );
}

void setup() {
  Serial.begin(9600);
  i2c_init();
}
void loop() {
uint8_t b,b1;
  i2c_start();
  i2c_write(0x40<<1);
  i2c_write(0x03);
  i2c_write(0x11);
  i2c_stop();
  do {
    i2c_start();
    i2c_write(0x40<<1);
    i2c_write(0x00);
    i2c_restart();
    i2c_write(0x40<<1 | 0x01);
    b=i2c_read(true);
    i2c_stop();
  } while (b & 0x01);
  i2c_start();
  i2c_write(0x40<<1);
  i2c_write(0x01);
  i2c_restart();
  i2c_write(0x40<<1 | 0x01);
  b=i2c_read(false);
  b1=i2c_read(true);
  i2c_stop();
  Serial.print(b, HEX);
  Serial.print(" ");
  Serial.println(b1, HEX);
  delay(1000);
  delay(100);
}
 

 

Komandir
Offline
Зарегистрирован: 18.08.2018

Помимо самих функций для интерфейса i2c - код содержит примеры, для схемы:

Komandir
Offline
Зарегистрирован: 18.08.2018

В железе тестировал на OLED 128x32 SSD1306. Код для него ещё короче, так как не нужны функции i2c_restart и i2c_read.

192 кадра в секунду !!!

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

1 000 000 / 1024 / 192 = 5,0862630208333333333333333333333

Т.е. Вы передаете байт за 5 тактов?

Можно привести исходник, который можно было бы "пощупать"?

 

Прошу прощения, не обратил внимания, что х32, а не х64, тогда 96 кадров для х64 - все сходится.

Но просьба насчет исходника остается.

Komandir
Offline
Зарегистрирован: 18.08.2018

Вот код для для SSD1306 128x32:

#define SCLPORT PORTC
#define SCLPIN PORTC5
#define SDAPORT PORTC
#define SDAPIN PORTC4
#include <avr/pgmspace.h>

void __attribute__ ((noinline)) i2c_init() {
  asm volatile(
    "CBI %0-1,%1\n\t"
    "CBI %2-1,%3\n\t"
    "CBI %2,%3\n\t"
    "CBI %0,%1\n\t"
    ::"I" (_SFR_IO_ADDR(SCLPORT)), "I" (SCLPIN), "I" (_SFR_IO_ADDR(SDAPORT)), "I" (SDAPIN) 
  );
}

void __attribute__ ((noinline)) i2c_start() {
  asm volatile(
    "SBI %0-1,%1\n\t"
    ::"I" (_SFR_IO_ADDR(SDAPORT)), "I" (SDAPIN)
  );
}

uint8_t __attribute__ ((noinline)) i2c_write(uint8_t data) {
  uint8_t result;
  uint8_t i=8;
  asm  volatile(
    "i2c_write_loop:"
    "SBI %1-1,%2\n\t"
    "SBRC %5,7\n\t"
    "CBI %3-1,%4\n\t"
    "SBRS %5,7\n\t"
    "SBI %3-1,%4\n\t"
    "ROL %5\n\t"
    "CBI %1-1,%2\n\t"
    "i2c_write_loop1:"
    "SBIS %1-2,%2\n\t"
    "RJMP i2c_write_loop1\n\t"
    "NOP\n\t"
    "DEC %6\n\t"
    "BRNE i2c_write_loop\n\t"
    "NOP\n\t"
    "SBI %1-1,%2\n\t"
    "CBI %3-1,%4\n\t"
    "CBI %3-1,%4\n\t"	//replacement for two NOP
    "CBI %3-1,%4\n\t"	//replacement for two NOP
//    "NOP\n\t"
//    "NOP\n\t"
//    "NOP\n\t"
//    "NOP\n\t"
    "CBI %1-1,%2\n\t"
    "CLR %0\n\t"
    "SBIS %3-2,%4\n\t"
    "INC %0\n\t"
    "CBI %1-1,%2\n\t"	//replacement for two NOP
//    "NOP\n\t"
//    "NOP\n\t"
    "NOP\n\t"
    "SBI %1-1,%2\n\t"
    : "=r" (result)
    : "I" (_SFR_IO_ADDR(SCLPORT)), "I" (SCLPIN), "I" (_SFR_IO_ADDR(SDAPORT)), "I" (SDAPIN), 
      "r" (data), "r" (i)
  );
  return result;
}

void __attribute__ ((noinline)) i2c_stop() {
  asm volatile(
    "SBI %2-1,%3\n\t"
    "CBI %0-1,%1\n\t"
    "CBI %0-1,%1\n\t"	//replacement for two NOP
//    "NOP\n\t"
//    "NOP\n\t"
    "CBI %2-1,%3\n\t"
    ::"I" (_SFR_IO_ADDR(SCLPORT)), "I" (SCLPIN), "I" (_SFR_IO_ADDR(SDAPORT)), "I" (SDAPIN)
  );
}

static const uint8_t PROGMEM init_bytes[]={0x3C<<1,0x00,0xAE,0xD5,0x80,0xA8,0x1F,0xD3,0x00,0x40,0x8D,0x14,0x20,0x00,0xA0,0xC0,
                                                   0xDA,0x02,0xD9,0xF1,0xDB,0x40,0x21,0x00,0x7f,0x22,0x00,0x03,0xA4,0xA6,0xAF};
static const uint8_t PROGMEM impreza[] = {
0xF8, 0xF8, 0x00, 0x00, 0xF8, 0xF8, 0x38, 0x70, 0xE0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0xC0, 0xE0, 0x70, 0x38, 0xF8, 0xF8, 0x00, 0x00, 0xF8, 0xF8, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x38, 0xF0, 0xE0, 0x00, 0x00, 0xF8, 0xF8,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x38, 0xF0,
0xE0, 0x00, 0x00, 0xE0, 0xF0, 0x38, 0x18, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x98, 0x98, 0xD8, 0xD8, 0x78, 0x78, 0x38, 0x38, 0x18, 0x18, 0x00, 0x00, 0xE0, 0xF0, 0x38,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x38, 0xF0, 0xE0,
0x1F, 0x1F, 0x00, 0x00, 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x0E, 0x1C, 0x0E, 0x07,
0x03, 0x01, 0x00, 0x00, 0x00, 0x1F, 0x1F, 0x00, 0x00, 0x1F, 0x1F, 0x00, 0x00, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x03, 0x01, 0x00, 0x00, 0x1F, 0x1F,
0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x0E, 0x1F, 0x1B,
0x11, 0x00, 0x00, 0x07, 0x0F, 0x1C, 0x18, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x00, 0x00, 0x18, 0x18, 0x1C, 0x1C, 0x1E, 0x1E, 0x1B, 0x1B,

0x19, 0x19, 0x19, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x1F, 0x1F, 0x00,
0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x1F, 0x1F};
void setup() {
  i2c_init();
  i2c_start();
  for(uint8_t i=0;i<sizeof(init_bytes);i++) i2c_write(pgm_read_byte(init_bytes+i));
  i2c_stop();
  i2c_start();
  i2c_write(0x3C<<1);
  i2c_write(0x40);
}
void loop() {
  for(uint8_t i=0;i<=127;i++) i2c_write(0x00);
  for(uint8_t i=0;i<=255;i++) i2c_write(pgm_read_byte(impreza+i));
  for(uint8_t i=0;i<=127;i++) i2c_write(0x00);
  while (1) {};
}
 

 

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Это софтверный I2C на стандартных хардверных ногах?

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Komandir пишет:

Для ASM:

.equ		SCLPORT=PORTC
.equ		SCLPIN=PORTC5
.equ		SDAPORT=PORTC
.equ		SDAPIN=PORTC

Снимаю шляпу. :-) 

Komandir
Offline
Зарегистрирован: 18.08.2018

Ноги можно прописать любые в самом начале ...

-NMi-
Offline
Зарегистрирован: 20.08.2018
1 .equ        SCLPORT=PORTC
2 .equ        SCLPIN=PORTC5
3 .equ        SDAPORT=PORTC

.equ        SDAPIN=PORTC

4

А как это работает???

 

 

Komandir
Offline
Зарегистрирован: 18.08.2018

Пропишите те порты и пины, где у Вас живет i2c девайс и компилируйте/заливайте/тестируйте ...

-NMi-
Offline
Зарегистрирован: 20.08.2018

Эти alias-ы реально переключают порт(ы) со входа на выход и наоборот???

Просто я не понимаю, как это работает.

Komandir
Offline
Зарегистрирован: 18.08.2018

Нет. Они используются дальше в командах - пример CBI SCLPORT-1,SCLPIN

Макроподстановка однако ...

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Нижнюю строчку поправь, а то галиматья получается

.equ        SDAPIN=PORTC4

Komandir
Offline
Зарегистрирован: 18.08.2018

ua6em пишет:

Нижнюю строчку поправь, а то галиматья получается

.equ        SDAPIN=PORTC4

У меня то вроде всё четко ...

-NMi-
Offline
Зарегистрирован: 20.08.2018

SBI - поставим бит в порту

CBI - сбросим (абнулим) бит в порту.

Это понятно, зачем ЧЕТЫРЕ алиаса?????????????

Komandir
Offline
Зарегистрирован: 18.08.2018

Две пары ПОРТ + ПИН

-NMi-
Offline
Зарегистрирован: 20.08.2018

Есть возможность выложить РАЗДЭЗ ассемблерного кода? Реально не понятно, как софт работает с портами.

Ну или скомпиль в объектник, я сам раздезю и гляну.

Komandir
Offline
Зарегистрирован: 18.08.2018

AVRASM ver. 2.1.42  ..\main.asm Fri Dec 04 20:24:30 2020

[builtin](2): Including file 'C:\Program Files (x86)\Labcenter Electronics\Proteus 8 Professional\Tools\AVRASM\appnotes\m328Pdef.inc'
                 
                 .equ		SCLPORT=PORTC
                 
                 ;***** Created: 2010-02-25 11:46 ******* Source: ATmega328P.xml **********
                 ;*************************************************************************
                 ;* A P P L I C A T I O N   N O T E   F O R   T H E   A V R   F A M I L Y
                 ;* 
                 ;* Number            : AVR000
                 ;* File Name         : "m328Pdef.inc"
                 ;* Title             : Register/Bit Definitions for the ATmega328P
                 ;* Date              : 2010-02-25
                 ;* Version           : 2.35
                 ;* Support E-mail    : avr@atmel.com
                 ;* Target MCU        : ATmega328P
                 ;* 
                 ;* DESCRIPTION
                 ;* When including this file in the assembly program file, all I/O register 
                 ;* names and I/O register bit names appearing in the data book can be used.
                 ;* In addition, the six registers forming the three data pointers X, Y and 
                 ;* Z have been assigned names XL - ZH. Highest RAM address for Internal 
                 ;* SRAM is also defined 
                 ;* 
                 ;* The Register names are represented by their hexadecimal address.
                 ;* 
                 ;* The Register Bit names are represented by their bit number (0-7).
                 ;* 
                 ;* Please observe the difference in using the bit names with instructions
                 ;* such as "sbr"/"cbr" (set/clear bit in register) and "sbrs"/"sbrc"
                 ;* (skip if bit in register set/cleared). The following example illustrates
                 ;* this:
                 ;* 
                 ;* in    r16,PORTB             ;read PORTB latch
                 ;* sbr   r16,(1<<PB6)+(1<<PB5) ;set PB6 and PB5 (use masks, not bit#)
                 ;* out   PORTB,r16             ;output to PORTB
                 ;* 
                 ;* in    r16,TIFR              ;read the Timer Interrupt Flag Register
                 ;* sbrc  r16,TOV0              ;test the overflow flag (use bit#)
                 ;* rjmp  TOV0_is_set           ;jump if set
                 ;* ...                         ;otherwise do something else
                 ;*************************************************************************
                 
                 #ifndef _M328PDEF_INC_
                 #define _M328PDEF_INC_
                 
                 
                 #pragma partinc 0
                 
                 ; ***** SPECIFY DEVICE ***************************************************
                 .device ATmega328P
                 #pragma AVRPART ADMIN PART_NAME ATmega328P
                 .equ	SIGNATURE_000	= 0x1e
                 .equ	SIGNATURE_001	= 0x95
                 .equ	SIGNATURE_002	= 0x0f
                 
                 #pragma AVRPART CORE CORE_VERSION V2E
                 
                 
                 ; ***** I/O REGISTER DEFINITIONS *****************************************
                 ; NOTE:
                 ; Definitions marked "MEMORY MAPPED"are extended I/O ports
                 ; and cannot be used with IN/OUT instructions
                 .equ	UDR0	= 0xc6	; MEMORY MAPPED
                 .equ	UBRR0L	= 0xc4	; MEMORY MAPPED
                 .equ	UBRR0H	= 0xc5	; MEMORY MAPPED
                 .equ	UCSR0C	= 0xc2	; MEMORY MAPPED
                 .equ	UCSR0B	= 0xc1	; MEMORY MAPPED
                 .equ	UCSR0A	= 0xc0	; MEMORY MAPPED
                 .equ	TWAMR	= 0xbd	; MEMORY MAPPED
                 .equ	TWCR	= 0xbc	; MEMORY MAPPED
                 .equ	TWDR	= 0xbb	; MEMORY MAPPED
                 .equ	TWAR	= 0xba	; MEMORY MAPPED
                 .equ	TWSR	= 0xb9	; MEMORY MAPPED
                 .equ	TWBR	= 0xb8	; MEMORY MAPPED
                 .equ	ASSR	= 0xb6	; MEMORY MAPPED
                 .equ	OCR2B	= 0xb4	; MEMORY MAPPED
                 .equ	OCR2A	= 0xb3	; MEMORY MAPPED
                 .equ	TCNT2	= 0xb2	; MEMORY MAPPED
                 .equ	TCCR2B	= 0xb1	; MEMORY MAPPED
                 .equ	TCCR2A	= 0xb0	; MEMORY MAPPED
                 .equ	OCR1BL	= 0x8a	; MEMORY MAPPED
                 .equ	OCR1BH	= 0x8b	; MEMORY MAPPED
                 .equ	OCR1AL	= 0x88	; MEMORY MAPPED
                 .equ	OCR1AH	= 0x89	; MEMORY MAPPED
                 .equ	ICR1L	= 0x86	; MEMORY MAPPED
                 .equ	ICR1H	= 0x87	; MEMORY MAPPED
                 .equ	TCNT1L	= 0x84	; MEMORY MAPPED
                 .equ	TCNT1H	= 0x85	; MEMORY MAPPED
                 .equ	TCCR1C	= 0x82	; MEMORY MAPPED
                 .equ	TCCR1B	= 0x81	; MEMORY MAPPED
                 .equ	TCCR1A	= 0x80	; MEMORY MAPPED
                 .equ	DIDR1	= 0x7f	; MEMORY MAPPED
                 .equ	DIDR0	= 0x7e	; MEMORY MAPPED
                 .equ	ADMUX	= 0x7c	; MEMORY MAPPED
                 .equ	ADCSRB	= 0x7b	; MEMORY MAPPED
                 .equ	ADCSRA	= 0x7a	; MEMORY MAPPED
                 .equ	ADCH	= 0x79	; MEMORY MAPPED
                 .equ	ADCL	= 0x78	; MEMORY MAPPED
                 .equ	TIMSK2	= 0x70	; MEMORY MAPPED
                 .equ	TIMSK1	= 0x6f	; MEMORY MAPPED
                 .equ	TIMSK0	= 0x6e	; MEMORY MAPPED
                 .equ	PCMSK1	= 0x6c	; MEMORY MAPPED
                 .equ	PCMSK2	= 0x6d	; MEMORY MAPPED
                 .equ	PCMSK0	= 0x6b	; MEMORY MAPPED
                 .equ	EICRA	= 0x69	; MEMORY MAPPED
                 .equ	PCICR	= 0x68	; MEMORY MAPPED
                 .equ	OSCCAL	= 0x66	; MEMORY MAPPED
                 .equ	PRR	= 0x64	; MEMORY MAPPED
                 .equ	CLKPR	= 0x61	; MEMORY MAPPED
                 .equ	WDTCSR	= 0x60	; MEMORY MAPPED
                 .equ	SREG	= 0x3f
                 .equ	SPL	= 0x3d
                 .equ	SPH	= 0x3e
                 .equ	SPMCSR	= 0x37
                 .equ	MCUCR	= 0x35
                 .equ	MCUSR	= 0x34
                 .equ	SMCR	= 0x33
                 .equ	ACSR	= 0x30
                 .equ	SPDR	= 0x2e
                 .equ	SPSR	= 0x2d
                 .equ	SPCR	= 0x2c
                 .equ	GPIOR2	= 0x2b
                 .equ	GPIOR1	= 0x2a
                 .equ	OCR0B	= 0x28
                 .equ	OCR0A	= 0x27
                 .equ	TCNT0	= 0x26
                 .equ	TCCR0B	= 0x25
                 .equ	TCCR0A	= 0x24
                 .equ	GTCCR	= 0x23
                 .equ	EEARH	= 0x22
                 .equ	EEARL	= 0x21
                 .equ	EEDR	= 0x20
                 .equ	EECR	= 0x1f
                 .equ	GPIOR0	= 0x1e
                 .equ	EIMSK	= 0x1d
                 .equ	EIFR	= 0x1c
                 .equ	PCIFR	= 0x1b
                 .equ	TIFR2	= 0x17
                 .equ	TIFR1	= 0x16
                 .equ	TIFR0	= 0x15
                 .equ	PORTD	= 0x0b
                 .equ	DDRD	= 0x0a
                 .equ	PIND	= 0x09
                 .equ	PORTC	= 0x08
                 .equ	DDRC	= 0x07
                 .equ	PINC	= 0x06
                 .equ	PORTB	= 0x05
                 .equ	DDRB	= 0x04
                 .equ	PINB	= 0x03
                 
                 
                 ; ***** BIT DEFINITIONS **************************************************
                 
                 ; ***** USART0 ***********************
                 ; UDR0 - USART I/O Data Register
                 .equ	UDR0_0	= 0	; USART I/O Data Register bit 0
                 .equ	UDR0_1	= 1	; USART I/O Data Register bit 1
                 .equ	UDR0_2	= 2	; USART I/O Data Register bit 2
                 .equ	UDR0_3	= 3	; USART I/O Data Register bit 3
                 .equ	UDR0_4	= 4	; USART I/O Data Register bit 4
                 .equ	UDR0_5	= 5	; USART I/O Data Register bit 5
                 .equ	UDR0_6	= 6	; USART I/O Data Register bit 6
                 .equ	UDR0_7	= 7	; USART I/O Data Register bit 7
                 
                 ; UCSR0A - USART Control and Status Register A
                 .equ	MPCM0	= 0	; Multi-processor Communication Mode
                 .equ	U2X0	= 1	; Double the USART transmission speed
                 .equ	UPE0	= 2	; Parity Error
                 .equ	DOR0	= 3	; Data overRun
                 .equ	FE0	= 4	; Framing Error
                 .equ	UDRE0	= 5	; USART Data Register Empty
                 .equ	TXC0	= 6	; USART Transmitt Complete
                 .equ	RXC0	= 7	; USART Receive Complete
                 
                 ; UCSR0B - USART Control and Status Register B
                 .equ	TXB80	= 0	; Transmit Data Bit 8
                 .equ	RXB80	= 1	; Receive Data Bit 8
                 .equ	UCSZ02	= 2	; Character Size
                 .equ	TXEN0	= 3	; Transmitter Enable
                 .equ	RXEN0	= 4	; Receiver Enable
                 .equ	UDRIE0	= 5	; USART Data register Empty Interrupt Enable
                 .equ	TXCIE0	= 6	; TX Complete Interrupt Enable
                 .equ	RXCIE0	= 7	; RX Complete Interrupt Enable
                 
                 ; UCSR0C - USART Control and Status Register C
                 .equ	UCPOL0	= 0	; Clock Polarity
                 .equ	UCSZ00	= 1	; Character Size
                 .equ	UCPHA0	= UCSZ00	; For compatibility
                 .equ	UCSZ01	= 2	; Character Size
                 .equ	UDORD0	= UCSZ01	; For compatibility
                 .equ	USBS0	= 3	; Stop Bit Select
                 .equ	UPM00	= 4	; Parity Mode Bit 0
                 .equ	UPM01	= 5	; Parity Mode Bit 1
                 .equ	UMSEL00	= 6	; USART Mode Select
                 .equ	UMSEL0	= UMSEL00	; For compatibility
                 .equ	UMSEL01	= 7	; USART Mode Select
                 .equ	UMSEL1	= UMSEL01	; For compatibility
                 
                 ; UBRR0H - USART Baud Rate Register High Byte
                 .equ	UBRR8	= 0	; USART Baud Rate Register bit 8
                 .equ	UBRR9	= 1	; USART Baud Rate Register bit 9
                 .equ	UBRR10	= 2	; USART Baud Rate Register bit 10
                 .equ	UBRR11	= 3	; USART Baud Rate Register bit 11
                 
                 ; UBRR0L - USART Baud Rate Register Low Byte
                 .equ	_UBRR0	= 0	; USART Baud Rate Register bit 0
                 .equ	_UBRR1	= 1	; USART Baud Rate Register bit 1
                 .equ	UBRR2	= 2	; USART Baud Rate Register bit 2
                 .equ	UBRR3	= 3	; USART Baud Rate Register bit 3
                 .equ	UBRR4	= 4	; USART Baud Rate Register bit 4
                 .equ	UBRR5	= 5	; USART Baud Rate Register bit 5
                 .equ	UBRR6	= 6	; USART Baud Rate Register bit 6
                 .equ	UBRR7	= 7	; USART Baud Rate Register bit 7
                 
                 
                 ; ***** TWI **************************
                 ; TWAMR - TWI (Slave) Address Mask Register
                 .equ	TWAM0	= 1	; 
                 .equ	TWAMR0	= TWAM0	; For compatibility
                 .equ	TWAM1	= 2	; 
                 .equ	TWAMR1	= TWAM1	; For compatibility
                 .equ	TWAM2	= 3	; 
                 .equ	TWAMR2	= TWAM2	; For compatibility
                 .equ	TWAM3	= 4	; 
                 .equ	TWAMR3	= TWAM3	; For compatibility
                 .equ	TWAM4	= 5	; 
                 .equ	TWAMR4	= TWAM4	; For compatibility
                 .equ	TWAM5	= 6	; 
                 .equ	TWAMR5	= TWAM5	; For compatibility
                 .equ	TWAM6	= 7	; 
                 .equ	TWAMR6	= TWAM6	; For compatibility
                 
                 ; TWBR - TWI Bit Rate register
                 .equ	TWBR0	= 0	; 
                 .equ	TWBR1	= 1	; 
                 .equ	TWBR2	= 2	; 
                 .equ	TWBR3	= 3	; 
                 .equ	TWBR4	= 4	; 
                 .equ	TWBR5	= 5	; 
                 .equ	TWBR6	= 6	; 
                 .equ	TWBR7	= 7	; 
                 
                 ; TWCR - TWI Control Register
                 .equ	TWIE	= 0	; TWI Interrupt Enable
                 .equ	TWEN	= 2	; TWI Enable Bit
                 .equ	TWWC	= 3	; TWI Write Collition Flag
                 .equ	TWSTO	= 4	; TWI Stop Condition Bit
                 .equ	TWSTA	= 5	; TWI Start Condition Bit
                 .equ	TWEA	= 6	; TWI Enable Acknowledge Bit
                 .equ	TWINT	= 7	; TWI Interrupt Flag
                 
                 ; TWSR - TWI Status Register
                 .equ	TWPS0	= 0	; TWI Prescaler
                 .equ	TWPS1	= 1	; TWI Prescaler
                 .equ	TWS3	= 3	; TWI Status
                 .equ	TWS4	= 4	; TWI Status
                 .equ	TWS5	= 5	; TWI Status
                 .equ	TWS6	= 6	; TWI Status
                 .equ	TWS7	= 7	; TWI Status
                 
                 ; TWDR - TWI Data register
                 .equ	TWD0	= 0	; TWI Data Register Bit 0
                 .equ	TWD1	= 1	; TWI Data Register Bit 1
                 .equ	TWD2	= 2	; TWI Data Register Bit 2
                 .equ	TWD3	= 3	; TWI Data Register Bit 3
                 .equ	TWD4	= 4	; TWI Data Register Bit 4
                 .equ	TWD5	= 5	; TWI Data Register Bit 5
                 .equ	TWD6	= 6	; TWI Data Register Bit 6
                 .equ	TWD7	= 7	; TWI Data Register Bit 7
                 
                 ; TWAR - TWI (Slave) Address register
                 .equ	TWGCE	= 0	; TWI General Call Recognition Enable Bit
                 .equ	TWA0	= 1	; TWI (Slave) Address register Bit 0
                 .equ	TWA1	= 2	; TWI (Slave) Address register Bit 1
                 .equ	TWA2	= 3	; TWI (Slave) Address register Bit 2
                 .equ	TWA3	= 4	; TWI (Slave) Address register Bit 3
                 .equ	TWA4	= 5	; TWI (Slave) Address register Bit 4
                 .equ	TWA5	= 6	; TWI (Slave) Address register Bit 5
                 .equ	TWA6	= 7	; TWI (Slave) Address register Bit 6
                 
                 
                 ; ***** TIMER_COUNTER_1 **************
                 ; TIMSK1 - Timer/Counter Interrupt Mask Register
                 .equ	TOIE1	= 0	; Timer/Counter1 Overflow Interrupt Enable
                 .equ	OCIE1A	= 1	; Timer/Counter1 Output CompareA Match Interrupt Enable
                 .equ	OCIE1B	= 2	; Timer/Counter1 Output CompareB Match Interrupt Enable
                 .equ	ICIE1	= 5	; Timer/Counter1 Input Capture Interrupt Enable
                 
                 ; TIFR1 - Timer/Counter Interrupt Flag register
                 .equ	TOV1	= 0	; Timer/Counter1 Overflow Flag
                 .equ	OCF1A	= 1	; Output Compare Flag 1A
                 .equ	OCF1B	= 2	; Output Compare Flag 1B
                 .equ	ICF1	= 5	; Input Capture Flag 1
                 
                 ; TCCR1A - Timer/Counter1 Control Register A
                 .equ	WGM10	= 0	; Waveform Generation Mode
                 .equ	WGM11	= 1	; Waveform Generation Mode
                 .equ	COM1B0	= 4	; Compare Output Mode 1B, bit 0
                 .equ	COM1B1	= 5	; Compare Output Mode 1B, bit 1
                 .equ	COM1A0	= 6	; Comparet Ouput Mode 1A, bit 0
                 .equ	COM1A1	= 7	; Compare Output Mode 1A, bit 1
                 
                 ; TCCR1B - Timer/Counter1 Control Register B
                 .equ	CS10	= 0	; Prescaler source of Timer/Counter 1
                 .equ	CS11	= 1	; Prescaler source of Timer/Counter 1
                 .equ	CS12	= 2	; Prescaler source of Timer/Counter 1
                 .equ	WGM12	= 3	; Waveform Generation Mode
                 .equ	WGM13	= 4	; Waveform Generation Mode
                 .equ	ICES1	= 6	; Input Capture 1 Edge Select
                 .equ	ICNC1	= 7	; Input Capture 1 Noise Canceler
                 
                 ; TCCR1C - Timer/Counter1 Control Register C
                 .equ	FOC1B	= 6	; 
                 .equ	FOC1A	= 7	; 
                 
                 ; GTCCR - General Timer/Counter Control Register
                 .equ	PSRSYNC	= 0	; Prescaler Reset Timer/Counter1 and Timer/Counter0
                 .equ	TSM	= 7	; Timer/Counter Synchronization Mode
                 
                 
                 ; ***** TIMER_COUNTER_2 **************
                 ; TIMSK2 - Timer/Counter Interrupt Mask register
                 .equ	TOIE2	= 0	; Timer/Counter2 Overflow Interrupt Enable
                 .equ	TOIE2A	= TOIE2	; For compatibility
                 .equ	OCIE2A	= 1	; Timer/Counter2 Output Compare Match A Interrupt Enable
                 .equ	OCIE2B	= 2	; Timer/Counter2 Output Compare Match B Interrupt Enable
                 
                 ; TIFR2 - Timer/Counter Interrupt Flag Register
                 .equ	TOV2	= 0	; Timer/Counter2 Overflow Flag
                 .equ	OCF2A	= 1	; Output Compare Flag 2A
                 .equ	OCF2B	= 2	; Output Compare Flag 2B
                 
                 ; TCCR2A - Timer/Counter2 Control Register A
                 .equ	WGM20	= 0	; Waveform Genration Mode
                 .equ	WGM21	= 1	; Waveform Genration Mode
                 .equ	COM2B0	= 4	; Compare Output Mode bit 0
                 .equ	COM2B1	= 5	; Compare Output Mode bit 1
                 .equ	COM2A0	= 6	; Compare Output Mode bit 1
                 .equ	COM2A1	= 7	; Compare Output Mode bit 1
                 
                 ; TCCR2B - Timer/Counter2 Control Register B
                 .equ	CS20	= 0	; Clock Select bit 0
                 .equ	CS21	= 1	; Clock Select bit 1
                 .equ	CS22	= 2	; Clock Select bit 2
                 .equ	WGM22	= 3	; Waveform Generation Mode
                 .equ	FOC2B	= 6	; Force Output Compare B
                 .equ	FOC2A	= 7	; Force Output Compare A
                 
                 ; TCNT2 - Timer/Counter2
                 .equ	TCNT2_0	= 0	; Timer/Counter 2 bit 0
                 .equ	TCNT2_1	= 1	; Timer/Counter 2 bit 1
                 .equ	TCNT2_2	= 2	; Timer/Counter 2 bit 2
                 .equ	TCNT2_3	= 3	; Timer/Counter 2 bit 3
                 .equ	TCNT2_4	= 4	; Timer/Counter 2 bit 4
                 .equ	TCNT2_5	= 5	; Timer/Counter 2 bit 5
                 .equ	TCNT2_6	= 6	; Timer/Counter 2 bit 6
                 .equ	TCNT2_7	= 7	; Timer/Counter 2 bit 7
                 
                 ; OCR2A - Timer/Counter2 Output Compare Register A
                 .equ	OCR2A_0	= 0	; Timer/Counter2 Output Compare Register Bit 0
                 .equ	OCR2A_1	= 1	; Timer/Counter2 Output Compare Register Bit 1
                 .equ	OCR2A_2	= 2	; Timer/Counter2 Output Compare Register Bit 2
                 .equ	OCR2A_3	= 3	; Timer/Counter2 Output Compare Register Bit 3
                 .equ	OCR2A_4	= 4	; Timer/Counter2 Output Compare Register Bit 4
                 .equ	OCR2A_5	= 5	; Timer/Counter2 Output Compare Register Bit 5
                 .equ	OCR2A_6	= 6	; Timer/Counter2 Output Compare Register Bit 6
                 .equ	OCR2A_7	= 7	; Timer/Counter2 Output Compare Register Bit 7
                 
                 ; OCR2B - Timer/Counter2 Output Compare Register B
                 .equ	OCR2B_0	= 0	; Timer/Counter2 Output Compare Register Bit 0
                 .equ	OCR2B_1	= 1	; Timer/Counter2 Output Compare Register Bit 1
                 .equ	OCR2B_2	= 2	; Timer/Counter2 Output Compare Register Bit 2
                 .equ	OCR2B_3	= 3	; Timer/Counter2 Output Compare Register Bit 3
                 .equ	OCR2B_4	= 4	; Timer/Counter2 Output Compare Register Bit 4
                 .equ	OCR2B_5	= 5	; Timer/Counter2 Output Compare Register Bit 5
                 .equ	OCR2B_6	= 6	; Timer/Counter2 Output Compare Register Bit 6
                 .equ	OCR2B_7	= 7	; Timer/Counter2 Output Compare Register Bit 7
                 
                 ; ASSR - Asynchronous Status Register
                 .equ	TCR2BUB	= 0	; Timer/Counter Control Register2 Update Busy
                 .equ	TCR2AUB	= 1	; Timer/Counter Control Register2 Update Busy
                 .equ	OCR2BUB	= 2	; Output Compare Register 2 Update Busy
                 .equ	OCR2AUB	= 3	; Output Compare Register2 Update Busy
                 .equ	TCN2UB	= 4	; Timer/Counter2 Update Busy
                 .equ	AS2	= 5	; Asynchronous Timer/Counter2
                 .equ	EXCLK	= 6	; Enable External Clock Input
                 
                 ; GTCCR - General Timer Counter Control register
                 .equ	PSRASY	= 1	; Prescaler Reset Timer/Counter2
                 .equ	PSR2	= PSRASY	; For compatibility
                 ;.equ	TSM	= 7	; Timer/Counter Synchronization Mode
                 
                 
                 ; ***** AD_CONVERTER *****************
                 ; ADMUX - The ADC multiplexer Selection Register
                 .equ	MUX0	= 0	; Analog Channel and Gain Selection Bits
                 .equ	MUX1	= 1	; Analog Channel and Gain Selection Bits
                 .equ	MUX2	= 2	; Analog Channel and Gain Selection Bits
                 .equ	MUX3	= 3	; Analog Channel and Gain Selection Bits
                 .equ	ADLAR	= 5	; Left Adjust Result
                 .equ	REFS0	= 6	; Reference Selection Bit 0
                 .equ	REFS1	= 7	; Reference Selection Bit 1
                 
                 ; ADCSRA - The ADC Control and Status register A
                 .equ	ADPS0	= 0	; ADC  Prescaler Select Bits
                 .equ	ADPS1	= 1	; ADC  Prescaler Select Bits
                 .equ	ADPS2	= 2	; ADC  Prescaler Select Bits
                 .equ	ADIE	= 3	; ADC Interrupt Enable
                 .equ	ADIF	= 4	; ADC Interrupt Flag
                 .equ	ADATE	= 5	; ADC  Auto Trigger Enable
                 .equ	ADSC	= 6	; ADC Start Conversion
                 .equ	ADEN	= 7	; ADC Enable
                 
                 ; ADCSRB - The ADC Control and Status register B
                 .equ	ADTS0	= 0	; ADC Auto Trigger Source bit 0
                 .equ	ADTS1	= 1	; ADC Auto Trigger Source bit 1
                 .equ	ADTS2	= 2	; ADC Auto Trigger Source bit 2
                 .equ	ACME	= 6	; 
                 
                 ; ADCH - ADC Data Register High Byte
                 .equ	ADCH0	= 0	; ADC Data Register High Byte Bit 0
                 .equ	ADCH1	= 1	; ADC Data Register High Byte Bit 1
                 .equ	ADCH2	= 2	; ADC Data Register High Byte Bit 2
                 .equ	ADCH3	= 3	; ADC Data Register High Byte Bit 3
                 .equ	ADCH4	= 4	; ADC Data Register High Byte Bit 4
                 .equ	ADCH5	= 5	; ADC Data Register High Byte Bit 5
                 .equ	ADCH6	= 6	; ADC Data Register High Byte Bit 6
                 .equ	ADCH7	= 7	; ADC Data Register High Byte Bit 7
                 
                 ; ADCL - ADC Data Register Low Byte
                 .equ	ADCL0	= 0	; ADC Data Register Low Byte Bit 0
                 .equ	ADCL1	= 1	; ADC Data Register Low Byte Bit 1
                 .equ	ADCL2	= 2	; ADC Data Register Low Byte Bit 2
                 .equ	ADCL3	= 3	; ADC Data Register Low Byte Bit 3
                 .equ	ADCL4	= 4	; ADC Data Register Low Byte Bit 4
                 .equ	ADCL5	= 5	; ADC Data Register Low Byte Bit 5
                 .equ	ADCL6	= 6	; ADC Data Register Low Byte Bit 6
                 .equ	ADCL7	= 7	; ADC Data Register Low Byte Bit 7
                 
                 ; DIDR0 - Digital Input Disable Register
                 .equ	ADC0D	= 0	; 
                 .equ	ADC1D	= 1	; 
                 .equ	ADC2D	= 2	; 
                 .equ	ADC3D	= 3	; 
                 .equ	ADC4D	= 4	; 
                 .equ	ADC5D	= 5	; 
                 
                 
                 ; ***** ANALOG_COMPARATOR ************
                 ; ACSR - Analog Comparator Control And Status Register
                 .equ	ACIS0	= 0	; Analog Comparator Interrupt Mode Select bit 0
                 .equ	ACIS1	= 1	; Analog Comparator Interrupt Mode Select bit 1
                 .equ	ACIC	= 2	; Analog Comparator Input Capture Enable
                 .equ	ACIE	= 3	; Analog Comparator Interrupt Enable
                 .equ	ACI	= 4	; Analog Comparator Interrupt Flag
                 .equ	ACO	= 5	; Analog Compare Output
                 .equ	ACBG	= 6	; Analog Comparator Bandgap Select
                 .equ	ACD	= 7	; Analog Comparator Disable
                 
                 ; DIDR1 - Digital Input Disable Register 1
                 .equ	AIN0D	= 0	; AIN0 Digital Input Disable
                 .equ	AIN1D	= 1	; AIN1 Digital Input Disable
                 
                 
                 ; ***** PORTB ************************
                 ; PORTB - Port B Data Register
                 .equ	PORTB0	= 0	; Port B Data Register bit 0
                 .equ	PB0	= 0	; For compatibility
                 .equ	PORTB1	= 1	; Port B Data Register bit 1
                 .equ	PB1	= 1	; For compatibility
                 .equ	PORTB2	= 2	; Port B Data Register bit 2
                 .equ	PB2	= 2	; For compatibility
                 .equ	PORTB3	= 3	; Port B Data Register bit 3
                 .equ	PB3	= 3	; For compatibility
                 .equ	PORTB4	= 4	; Port B Data Register bit 4
                 .equ	PB4	= 4	; For compatibility
                 .equ	PORTB5	= 5	; Port B Data Register bit 5
                 .equ	PB5	= 5	; For compatibility
                 .equ	PORTB6	= 6	; Port B Data Register bit 6
                 .equ	PB6	= 6	; For compatibility
                 .equ	PORTB7	= 7	; Port B Data Register bit 7
                 .equ	PB7	= 7	; For compatibility
                 
                 ; DDRB - Port B Data Direction Register
                 .equ	DDB0	= 0	; Port B Data Direction Register bit 0
                 .equ	DDB1	= 1	; Port B Data Direction Register bit 1
                 .equ	DDB2	= 2	; Port B Data Direction Register bit 2
                 .equ	DDB3	= 3	; Port B Data Direction Register bit 3
                 .equ	DDB4	= 4	; Port B Data Direction Register bit 4
                 .equ	DDB5	= 5	; Port B Data Direction Register bit 5
                 .equ	DDB6	= 6	; Port B Data Direction Register bit 6
                 .equ	DDB7	= 7	; Port B Data Direction Register bit 7
                 
                 ; PINB - Port B Input Pins
                 .equ	PINB0	= 0	; Port B Input Pins bit 0
                 .equ	PINB1	= 1	; Port B Input Pins bit 1
                 .equ	PINB2	= 2	; Port B Input Pins bit 2
                 .equ	PINB3	= 3	; Port B Input Pins bit 3
                 .equ	PINB4	= 4	; Port B Input Pins bit 4
                 .equ	PINB5	= 5	; Port B Input Pins bit 5
                 .equ	PINB6	= 6	; Port B Input Pins bit 6
                 .equ	PINB7	= 7	; Port B Input Pins bit 7
                 
                 
                 ; ***** PORTC ************************
                 ; PORTC - Port C Data Register
                 .equ	PORTC0	= 0	; Port C Data Register bit 0
                 .equ	PC0	= 0	; For compatibility
                 .equ	PORTC1	= 1	; Port C Data Register bit 1
                 .equ	PC1	= 1	; For compatibility
                 .equ	PORTC2	= 2	; Port C Data Register bit 2
                 .equ	PC2	= 2	; For compatibility
                 .equ	PORTC3	= 3	; Port C Data Register bit 3
                 .equ	PC3	= 3	; For compatibility
                 .equ	PORTC4	= 4	; Port C Data Register bit 4
                 .equ	PC4	= 4	; For compatibility
                 .equ	PORTC5	= 5	; Port C Data Register bit 5
                 .equ	PC5	= 5	; For compatibility
                 .equ	PORTC6	= 6	; Port C Data Register bit 6
                 .equ	PC6	= 6	; For compatibility
                 
                 ; DDRC - Port C Data Direction Register
                 .equ	DDC0	= 0	; Port C Data Direction Register bit 0
                 .equ	DDC1	= 1	; Port C Data Direction Register bit 1
                 .equ	DDC2	= 2	; Port C Data Direction Register bit 2
                 .equ	DDC3	= 3	; Port C Data Direction Register bit 3
                 .equ	DDC4	= 4	; Port C Data Direction Register bit 4
                 .equ	DDC5	= 5	; Port C Data Direction Register bit 5
                 .equ	DDC6	= 6	; Port C Data Direction Register bit 6
                 
                 ; PINC - Port C Input Pins
                 .equ	PINC0	= 0	; Port C Input Pins bit 0
                 .equ	PINC1	= 1	; Port C Input Pins bit 1
                 .equ	PINC2	= 2	; Port C Input Pins bit 2
                 .equ	PINC3	= 3	; Port C Input Pins bit 3
                 .equ	PINC4	= 4	; Port C Input Pins bit 4
                 .equ	PINC5	= 5	; Port C Input Pins bit 5
                 .equ	PINC6	= 6	; Port C Input Pins bit 6
                 
                 
                 ; ***** PORTD ************************
                 ; PORTD - Port D Data Register
                 .equ	PORTD0	= 0	; Port D Data Register bit 0
                 .equ	PD0	= 0	; For compatibility
                 .equ	PORTD1	= 1	; Port D Data Register bit 1
                 .equ	PD1	= 1	; For compatibility
                 .equ	PORTD2	= 2	; Port D Data Register bit 2
                 .equ	PD2	= 2	; For compatibility
                 .equ	PORTD3	= 3	; Port D Data Register bit 3
                 .equ	PD3	= 3	; For compatibility
                 .equ	PORTD4	= 4	; Port D Data Register bit 4
                 .equ	PD4	= 4	; For compatibility
                 .equ	PORTD5	= 5	; Port D Data Register bit 5
                 .equ	PD5	= 5	; For compatibility
                 .equ	PORTD6	= 6	; Port D Data Register bit 6
                 .equ	PD6	= 6	; For compatibility
                 .equ	PORTD7	= 7	; Port D Data Register bit 7
                 .equ	PD7	= 7	; For compatibility
                 
                 ; DDRD - Port D Data Direction Register
                 .equ	DDD0	= 0	; Port D Data Direction Register bit 0
                 .equ	DDD1	= 1	; Port D Data Direction Register bit 1
                 .equ	DDD2	= 2	; Port D Data Direction Register bit 2
                 .equ	DDD3	= 3	; Port D Data Direction Register bit 3
                 .equ	DDD4	= 4	; Port D Data Direction Register bit 4
                 .equ	DDD5	= 5	; Port D Data Direction Register bit 5
                 .equ	DDD6	= 6	; Port D Data Direction Register bit 6
                 .equ	DDD7	= 7	; Port D Data Direction Register bit 7
                 
                 ; PIND - Port D Input Pins
                 .equ	PIND0	= 0	; Port D Input Pins bit 0
                 .equ	PIND1	= 1	; Port D Input Pins bit 1
                 .equ	PIND2	= 2	; Port D Input Pins bit 2
                 .equ	PIND3	= 3	; Port D Input Pins bit 3
                 .equ	PIND4	= 4	; Port D Input Pins bit 4
                 .equ	PIND5	= 5	; Port D Input Pins bit 5
                 .equ	PIND6	= 6	; Port D Input Pins bit 6
                 .equ	PIND7	= 7	; Port D Input Pins bit 7
                 
                 
                 ; ***** TIMER_COUNTER_0 **************
                 ; TIMSK0 - Timer/Counter0 Interrupt Mask Register
                 .equ	TOIE0	= 0	; Timer/Counter0 Overflow Interrupt Enable
                 .equ	OCIE0A	= 1	; Timer/Counter0 Output Compare Match A Interrupt Enable
                 .equ	OCIE0B	= 2	; Timer/Counter0 Output Compare Match B Interrupt Enable
                 
                 ; TIFR0 - Timer/Counter0 Interrupt Flag register
                 .equ	TOV0	= 0	; Timer/Counter0 Overflow Flag
                 .equ	OCF0A	= 1	; Timer/Counter0 Output Compare Flag 0A
                 .equ	OCF0B	= 2	; Timer/Counter0 Output Compare Flag 0B
                 
                 ; TCCR0A - Timer/Counter  Control Register A
                 .equ	WGM00	= 0	; Waveform Generation Mode
                 .equ	WGM01	= 1	; Waveform Generation Mode
                 .equ	COM0B0	= 4	; Compare Output Mode, Fast PWm
                 .equ	COM0B1	= 5	; Compare Output Mode, Fast PWm
                 .equ	COM0A0	= 6	; Compare Output Mode, Phase Correct PWM Mode
                 .equ	COM0A1	= 7	; Compare Output Mode, Phase Correct PWM Mode
                 
                 ; TCCR0B - Timer/Counter Control Register B
                 .equ	CS00	= 0	; Clock Select
                 .equ	CS01	= 1	; Clock Select
                 .equ	CS02	= 2	; Clock Select
                 .equ	WGM02	= 3	; 
                 .equ	FOC0B	= 6	; Force Output Compare B
                 .equ	FOC0A	= 7	; Force Output Compare A
                 
                 ; TCNT0 - Timer/Counter0
                 .equ	TCNT0_0	= 0	; 
                 .equ	TCNT0_1	= 1	; 
                 .equ	TCNT0_2	= 2	; 
                 .equ	TCNT0_3	= 3	; 
                 .equ	TCNT0_4	= 4	; 
                 .equ	TCNT0_5	= 5	; 
                 .equ	TCNT0_6	= 6	; 
                 .equ	TCNT0_7	= 7	; 
                 
                 ; OCR0A - Timer/Counter0 Output Compare Register
                 .equ	OCR0A_0	= 0	; 
                 .equ	OCR0A_1	= 1	; 
                 .equ	OCR0A_2	= 2	; 
                 .equ	OCR0A_3	= 3	; 
                 .equ	OCR0A_4	= 4	; 
                 .equ	OCR0A_5	= 5	; 
                 .equ	OCR0A_6	= 6	; 
                 .equ	OCR0A_7	= 7	; 
                 
                 ; OCR0B - Timer/Counter0 Output Compare Register
                 .equ	OCR0B_0	= 0	; 
                 .equ	OCR0B_1	= 1	; 
                 .equ	OCR0B_2	= 2	; 
                 .equ	OCR0B_3	= 3	; 
                 .equ	OCR0B_4	= 4	; 
                 .equ	OCR0B_5	= 5	; 
                 .equ	OCR0B_6	= 6	; 
                 .equ	OCR0B_7	= 7	; 
                 
                 ; GTCCR - General Timer/Counter Control Register
                 ;.equ	PSRSYNC	= 0	; Prescaler Reset Timer/Counter1 and Timer/Counter0
                 .equ	PSR10	= PSRSYNC	; For compatibility
                 ;.equ	TSM	= 7	; Timer/Counter Synchronization Mode
                 
                 
                 ; ***** EXTERNAL_INTERRUPT ***********
                 ; EICRA - External Interrupt Control Register
                 .equ	ISC00	= 0	; External Interrupt Sense Control 0 Bit 0
                 .equ	ISC01	= 1	; External Interrupt Sense Control 0 Bit 1
                 .equ	ISC10	= 2	; External Interrupt Sense Control 1 Bit 0
                 .equ	ISC11	= 3	; External Interrupt Sense Control 1 Bit 1
                 
                 ; EIMSK - External Interrupt Mask Register
                 .equ	INT0	= 0	; External Interrupt Request 0 Enable
                 .equ	INT1	= 1	; External Interrupt Request 1 Enable
                 
                 ; EIFR - External Interrupt Flag Register
                 .equ	INTF0	= 0	; External Interrupt Flag 0
                 .equ	INTF1	= 1	; External Interrupt Flag 1
                 
                 ; PCICR - Pin Change Interrupt Control Register
                 .equ	PCIE0	= 0	; Pin Change Interrupt Enable 0
                 .equ	PCIE1	= 1	; Pin Change Interrupt Enable 1
                 .equ	PCIE2	= 2	; Pin Change Interrupt Enable 2
                 
                 ; PCMSK2 - Pin Change Mask Register 2
                 .equ	PCINT16	= 0	; Pin Change Enable Mask 16
                 .equ	PCINT17	= 1	; Pin Change Enable Mask 17
                 .equ	PCINT18	= 2	; Pin Change Enable Mask 18
                 .equ	PCINT19	= 3	; Pin Change Enable Mask 19
                 .equ	PCINT20	= 4	; Pin Change Enable Mask 20
                 .equ	PCINT21	= 5	; Pin Change Enable Mask 21
                 .equ	PCINT22	= 6	; Pin Change Enable Mask 22
                 .equ	PCINT23	= 7	; Pin Change Enable Mask 23
                 
                 ; PCMSK1 - Pin Change Mask Register 1
                 .equ	PCINT8	= 0	; Pin Change Enable Mask 8
                 .equ	PCINT9	= 1	; Pin Change Enable Mask 9
                 .equ	PCINT10	= 2	; Pin Change Enable Mask 10
                 .equ	PCINT11	= 3	; Pin Change Enable Mask 11
                 .equ	PCINT12	= 4	; Pin Change Enable Mask 12
                 .equ	PCINT13	= 5	; Pin Change Enable Mask 13
                 .equ	PCINT14	= 6	; Pin Change Enable Mask 14
                 
                 ; PCMSK0 - Pin Change Mask Register 0
                 .equ	PCINT0	= 0	; Pin Change Enable Mask 0
                 .equ	PCINT1	= 1	; Pin Change Enable Mask 1
                 .equ	PCINT2	= 2	; Pin Change Enable Mask 2
                 .equ	PCINT3	= 3	; Pin Change Enable Mask 3
                 .equ	PCINT4	= 4	; Pin Change Enable Mask 4
                 .equ	PCINT5	= 5	; Pin Change Enable Mask 5
                 .equ	PCINT6	= 6	; Pin Change Enable Mask 6
                 .equ	PCINT7	= 7	; Pin Change Enable Mask 7
                 
                 ; PCIFR - Pin Change Interrupt Flag Register
                 .equ	PCIF0	= 0	; Pin Change Interrupt Flag 0
                 .equ	PCIF1	= 1	; Pin Change Interrupt Flag 1
                 .equ	PCIF2	= 2	; Pin Change Interrupt Flag 2
                 
                 
                 ; ***** SPI **************************
                 ; SPDR - SPI Data Register
                 .equ	SPDR0	= 0	; SPI Data Register bit 0
                 .equ	SPDR1	= 1	; SPI Data Register bit 1
                 .equ	SPDR2	= 2	; SPI Data Register bit 2
                 .equ	SPDR3	= 3	; SPI Data Register bit 3
                 .equ	SPDR4	= 4	; SPI Data Register bit 4
                 .equ	SPDR5	= 5	; SPI Data Register bit 5
                 .equ	SPDR6	= 6	; SPI Data Register bit 6
                 .equ	SPDR7	= 7	; SPI Data Register bit 7
                 
                 ; SPSR - SPI Status Register
                 .equ	SPI2X	= 0	; Double SPI Speed Bit
                 .equ	WCOL	= 6	; Write Collision Flag
                 .equ	SPIF	= 7	; SPI Interrupt Flag
                 
                 ; SPCR - SPI Control Register
                 .equ	SPR0	= 0	; SPI Clock Rate Select 0
                 .equ	SPR1	= 1	; SPI Clock Rate Select 1
                 .equ	CPHA	= 2	; Clock Phase
                 .equ	CPOL	= 3	; Clock polarity
                 .equ	MSTR	= 4	; Master/Slave Select
                 .equ	DORD	= 5	; Data Order
                 .equ	SPE	= 6	; SPI Enable
                 .equ	SPIE	= 7	; SPI Interrupt Enable
                 
                 
                 ; ***** WATCHDOG *********************
                 ; WDTCSR - Watchdog Timer Control Register
                 .equ	WDP0	= 0	; Watch Dog Timer Prescaler bit 0
                 .equ	WDP1	= 1	; Watch Dog Timer Prescaler bit 1
                 .equ	WDP2	= 2	; Watch Dog Timer Prescaler bit 2
                 .equ	WDE	= 3	; Watch Dog Enable
                 .equ	WDCE	= 4	; Watchdog Change Enable
                 .equ	WDP3	= 5	; Watchdog Timer Prescaler Bit 3
                 .equ	WDIE	= 6	; Watchdog Timeout Interrupt Enable
                 .equ	WDIF	= 7	; Watchdog Timeout Interrupt Flag
                 
                 
                 ; ***** CPU **************************
                 ; SREG - Status Register
                 .equ	SREG_C	= 0	; Carry Flag
                 .equ	SREG_Z	= 1	; Zero Flag
                 .equ	SREG_N	= 2	; Negative Flag
                 .equ	SREG_V	= 3	; Two's Complement Overflow Flag
                 .equ	SREG_S	= 4	; Sign Bit
                 .equ	SREG_H	= 5	; Half Carry Flag
                 .equ	SREG_T	= 6	; Bit Copy Storage
                 .equ	SREG_I	= 7	; Global Interrupt Enable
                 
                 ; OSCCAL - Oscillator Calibration Value
                 .equ	CAL0	= 0	; Oscillator Calibration Value Bit0
                 .equ	CAL1	= 1	; Oscillator Calibration Value Bit1
                 .equ	CAL2	= 2	; Oscillator Calibration Value Bit2
                 .equ	CAL3	= 3	; Oscillator Calibration Value Bit3
                 .equ	CAL4	= 4	; Oscillator Calibration Value Bit4
                 .equ	CAL5	= 5	; Oscillator Calibration Value Bit5
                 .equ	CAL6	= 6	; Oscillator Calibration Value Bit6
                 .equ	CAL7	= 7	; Oscillator Calibration Value Bit7
                 
                 ; CLKPR - Clock Prescale Register
                 .equ	CLKPS0	= 0	; Clock Prescaler Select Bit 0
                 .equ	CLKPS1	= 1	; Clock Prescaler Select Bit 1
                 .equ	CLKPS2	= 2	; Clock Prescaler Select Bit 2
                 .equ	CLKPS3	= 3	; Clock Prescaler Select Bit 3
                 .equ	CLKPCE	= 7	; Clock Prescaler Change Enable
                 
                 ; SPMCSR - Store Program Memory Control and Status Register
                 .equ	SELFPRGEN	= 0	; Self Programming Enable
                 .equ	PGERS	= 1	; Page Erase
                 .equ	PGWRT	= 2	; Page Write
                 .equ	BLBSET	= 3	; Boot Lock Bit Set
                 .equ	RWWSRE	= 4	; Read-While-Write section read enable
                 .equ	RWWSB	= 6	; Read-While-Write Section Busy
                 .equ	SPMIE	= 7	; SPM Interrupt Enable
                 
                 ; MCUCR - MCU Control Register
                 .equ	IVCE	= 0	; 
                 .equ	IVSEL	= 1	; 
                 .equ	PUD	= 4	; 
                 .equ	BODSE	= 5	; BOD Sleep Enable
                 .equ	BODS	= 6	; BOD Sleep
                 
                 ; MCUSR - MCU Status Register
                 .equ	PORF	= 0	; Power-on reset flag
                 .equ	EXTRF	= 1	; External Reset Flag
                 .equ	EXTREF	= EXTRF	; For compatibility
                 .equ	BORF	= 2	; Brown-out Reset Flag
                 .equ	WDRF	= 3	; Watchdog Reset Flag
                 
                 ; SMCR - Sleep Mode Control Register
                 .equ	SE	= 0	; Sleep Enable
                 .equ	SM0	= 1	; Sleep Mode Select Bit 0
                 .equ	SM1	= 2	; Sleep Mode Select Bit 1
                 .equ	SM2	= 3	; Sleep Mode Select Bit 2
                 
                 ; GPIOR2 - General Purpose I/O Register 2
                 .equ	GPIOR20	= 0	; 
                 .equ	GPIOR21	= 1	; 
                 .equ	GPIOR22	= 2	; 
                 .equ	GPIOR23	= 3	; 
                 .equ	GPIOR24	= 4	; 
                 .equ	GPIOR25	= 5	; 
                 .equ	GPIOR26	= 6	; 
                 .equ	GPIOR27	= 7	; 
                 
                 ; GPIOR1 - General Purpose I/O Register 1
                 .equ	GPIOR10	= 0	; 
                 .equ	GPIOR11	= 1	; 
                 .equ	GPIOR12	= 2	; 
                 .equ	GPIOR13	= 3	; 
                 .equ	GPIOR14	= 4	; 
                 .equ	GPIOR15	= 5	; 
                 .equ	GPIOR16	= 6	; 
                 .equ	GPIOR17	= 7	; 
                 
                 ; GPIOR0 - General Purpose I/O Register 0
                 .equ	GPIOR00	= 0	; 
                 .equ	GPIOR01	= 1	; 
                 .equ	GPIOR02	= 2	; 
                 .equ	GPIOR03	= 3	; 
                 .equ	GPIOR04	= 4	; 
                 .equ	GPIOR05	= 5	; 
                 .equ	GPIOR06	= 6	; 
                 .equ	GPIOR07	= 7	; 
                 
                 ; PRR - Power Reduction Register
                 .equ	PRADC	= 0	; Power Reduction ADC
                 .equ	PRUSART0	= 1	; Power Reduction USART
                 .equ	PRSPI	= 2	; Power Reduction Serial Peripheral Interface
                 .equ	PRTIM1	= 3	; Power Reduction Timer/Counter1
                 .equ	PRTIM0	= 5	; Power Reduction Timer/Counter0
                 .equ	PRTIM2	= 6	; Power Reduction Timer/Counter2
                 .equ	PRTWI	= 7	; Power Reduction TWI
                 
                 
                 ; ***** EEPROM ***********************
                 ; EEARL - EEPROM Address Register Low Byte
                 .equ	EEAR0	= 0	; EEPROM Read/Write Access Bit 0
                 .equ	EEAR1	= 1	; EEPROM Read/Write Access Bit 1
                 .equ	EEAR2	= 2	; EEPROM Read/Write Access Bit 2
                 .equ	EEAR3	= 3	; EEPROM Read/Write Access Bit 3
                 .equ	EEAR4	= 4	; EEPROM Read/Write Access Bit 4
                 .equ	EEAR5	= 5	; EEPROM Read/Write Access Bit 5
                 .equ	EEAR6	= 6	; EEPROM Read/Write Access Bit 6
                 .equ	EEAR7	= 7	; EEPROM Read/Write Access Bit 7
                 
                 ; EEARH - EEPROM Address Register High Byte
                 .equ	EEAR8	= 0	; EEPROM Read/Write Access Bit 8
                 .equ	EEAR9	= 1	; EEPROM Read/Write Access Bit 9
                 
                 ; EEDR - EEPROM Data Register
                 .equ	EEDR0	= 0	; EEPROM Data Register bit 0
                 .equ	EEDR1	= 1	; EEPROM Data Register bit 1
                 .equ	EEDR2	= 2	; EEPROM Data Register bit 2
                 .equ	EEDR3	= 3	; EEPROM Data Register bit 3
                 .equ	EEDR4	= 4	; EEPROM Data Register bit 4
                 .equ	EEDR5	= 5	; EEPROM Data Register bit 5
                 .equ	EEDR6	= 6	; EEPROM Data Register bit 6
                 .equ	EEDR7	= 7	; EEPROM Data Register bit 7
                 
                 ; EECR - EEPROM Control Register
                 .equ	EERE	= 0	; EEPROM Read Enable
                 .equ	EEPE	= 1	; EEPROM Write Enable
                 .equ	EEMPE	= 2	; EEPROM Master Write Enable
                 .equ	EERIE	= 3	; EEPROM Ready Interrupt Enable
                 .equ	EEPM0	= 4	; EEPROM Programming Mode Bit 0
                 .equ	EEPM1	= 5	; EEPROM Programming Mode Bit 1
                 
                 
                 
                 ; ***** LOCKSBITS ********************************************************
                 .equ	LB1	= 0	; Lock bit
                 .equ	LB2	= 1	; Lock bit
                 .equ	BLB01	= 2	; Boot Lock bit
                 .equ	BLB02	= 3	; Boot Lock bit
                 .equ	BLB11	= 4	; Boot lock bit
                 .equ	BLB12	= 5	; Boot lock bit
                 
                 
                 ; ***** FUSES ************************************************************
                 ; LOW fuse bits
                 .equ	CKSEL0	= 0	; Select Clock Source
                 .equ	CKSEL1	= 1	; Select Clock Source
                 .equ	CKSEL2	= 2	; Select Clock Source
                 .equ	CKSEL3	= 3	; Select Clock Source
                 .equ	SUT0	= 4	; Select start-up time
                 .equ	SUT1	= 5	; Select start-up time
                 .equ	CKOUT	= 6	; Clock output
                 .equ	CKDIV8	= 7	; Divide clock by 8
                 
                 ; HIGH fuse bits
                 .equ	BOOTRST	= 0	; Select reset vector
                 .equ	BOOTSZ0	= 1	; Select boot size
                 .equ	BOOTSZ1	= 2	; Select boot size
                 .equ	EESAVE	= 3	; EEPROM memory is preserved through chip erase
                 .equ	WDTON	= 4	; Watchdog Timer Always On
                 .equ	SPIEN	= 5	; Enable Serial programming and Data Downloading
                 .equ	DWEN	= 6	; debugWIRE Enable
                 .equ	RSTDISBL	= 7	; External reset disable
                 
                 ; EXTENDED fuse bits
                 .equ	BODLEVEL0	= 0	; Brown-out Detector trigger level
                 .equ	BODLEVEL1	= 1	; Brown-out Detector trigger level
                 .equ	BODLEVEL2	= 2	; Brown-out Detector trigger level
                 
                 
                 
                 ; ***** CPU REGISTER DEFINITIONS *****************************************
                 .def	XH	= r27
                 .def	XL	= r26
                 .def	YH	= r29
                 .def	YL	= r28
                 .def	ZH	= r31
                 .def	ZL	= r30
                 
                 
                 
                 ; ***** DATA MEMORY DECLARATIONS *****************************************
                 .equ	FLASHEND	= 0x3fff	; Note: Word address
                 .equ	IOEND	= 0x00ff
                 .equ	SRAM_START	= 0x0100
                 .equ	SRAM_SIZE	= 2048
                 .equ	RAMEND	= 0x08ff
                 .equ	XRAMEND	= 0x0000
                 .equ	E2END	= 0x03ff
                 .equ	EEPROMEND	= 0x03ff
                 .equ	EEADRBITS	= 10
                 #pragma AVRPART MEMORY PROG_FLASH 32768
                 #pragma AVRPART MEMORY EEPROM 1024
                 #pragma AVRPART MEMORY INT_SRAM SIZE 2048
                 #pragma AVRPART MEMORY INT_SRAM START_ADDR 0x100
                 
                 
                 
                 ; ***** BOOTLOADER DECLARATIONS ******************************************
                 .equ	NRWW_START_ADDR	= 0x3800
                 .equ	NRWW_STOP_ADDR	= 0x3fff
                 .equ	RWW_START_ADDR	= 0x0
                 .equ	RWW_STOP_ADDR	= 0x37ff
                 .equ	PAGESIZE	= 64
                 .equ	FIRSTBOOTSTART	= 0x3f00
                 .equ	SECONDBOOTSTART	= 0x3e00
                 .equ	THIRDBOOTSTART	= 0x3c00
                 .equ	FOURTHBOOTSTART	= 0x3800
                 .equ	SMALLBOOTSTART	= FIRSTBOOTSTART
                 .equ	LARGEBOOTSTART	= FOURTHBOOTSTART
                 
                 
                 
                 ; ***** INTERRUPT VECTORS ************************************************
                 .equ	INT0addr	= 0x0002	; External Interrupt Request 0
                 .equ	INT1addr	= 0x0004	; External Interrupt Request 1
                 .equ	PCI0addr	= 0x0006	; Pin Change Interrupt Request 0
                 .equ	PCI1addr	= 0x0008	; Pin Change Interrupt Request 0
                 .equ	PCI2addr	= 0x000a	; Pin Change Interrupt Request 1
                 .equ	WDTaddr	= 0x000c	; Watchdog Time-out Interrupt
                 .equ	OC2Aaddr	= 0x000e	; Timer/Counter2 Compare Match A
                 .equ	OC2Baddr	= 0x0010	; Timer/Counter2 Compare Match A
                 .equ	OVF2addr	= 0x0012	; Timer/Counter2 Overflow
                 .equ	ICP1addr	= 0x0014	; Timer/Counter1 Capture Event
                 .equ	OC1Aaddr	= 0x0016	; Timer/Counter1 Compare Match A
                 .equ	OC1Baddr	= 0x0018	; Timer/Counter1 Compare Match B
                 .equ	OVF1addr	= 0x001a	; Timer/Counter1 Overflow
                 .equ	OC0Aaddr	= 0x001c	; TimerCounter0 Compare Match A
                 .equ	OC0Baddr	= 0x001e	; TimerCounter0 Compare Match B
                 .equ	OVF0addr	= 0x0020	; Timer/Couner0 Overflow
                 .equ	SPIaddr	= 0x0022	; SPI Serial Transfer Complete
                 .equ	URXCaddr	= 0x0024	; USART Rx Complete
                 .equ	UDREaddr	= 0x0026	; USART, Data Register Empty
                 .equ	UTXCaddr	= 0x0028	; USART Tx Complete
                 .equ	ADCCaddr	= 0x002a	; ADC Conversion Complete
                 .equ	ERDYaddr	= 0x002c	; EEPROM Ready
                 .equ	ACIaddr	= 0x002e	; Analog Comparator
                 .equ	TWIaddr	= 0x0030	; Two-wire Serial Interface
                 .equ	SPMRaddr	= 0x0032	; Store Program Memory Read
                 
                 .equ	INT_VECTORS_SIZE	= 52	; size in words
                 
                 #endif  /* _M328PDEF_INC_ */
                 
                 ; ***** END OF FILE ******************************************************
                 
                 .equ		SCLPIN=PORTC5
                 .equ		SDAPORT=PORTC
                 .equ		SDAPIN=PORTC4
                 
                 .CSEG
                 
                 .ORG		$0
000000 c078      	RJMP	Start
                 
                 .ORG		INT_VECTORS_SIZE
                 ;------------------------------
                 i2c_init:
000034 983d      	CBI	SCLPORT-1,SCLPIN
000035 983c      	CBI	SDAPORT-1,SDAPIN
000036 9844      	CBI	SDAPORT,SDAPIN
000037 9845      	CBI	SCLPORT,SCLPIN
000038 9508      	RET
                 
                 ;------------------------------
                 i2c_start:
000039 9a3c      	SBI	SDAPORT-1,SDAPIN
00003a 9508      	RET
                 
                 ;------------------------------
                 i2c_restart:
00003b 983d      	CBI	SCLPORT-1,SCLPIN
00003c 983d      	CBI	SCLPORT-1,SCLPIN
00003d 9a3c      	SBI	SDAPORT-1,SDAPIN
00003e 9508      	RET
                 
                 ;------------------------------
                 i2c_write:
00003f e098      	LDI	R25,8
                 i2c_write_loop:
000040 9a3d      	SBI	SCLPORT-1,SCLPIN
000041 fd87      	SBRC	R24,7
000042 983c      	CBI	SDAPORT-1,SDAPIN
000043 ff87      	SBRS	R24,7
000044 9a3c      	SBI	SDAPORT-1,SDAPIN
000045 1f88      	ROL	R24
000046 983d      	CBI	SCLPORT-1,SCLPIN
                 i2c_write_loop1:
000047 9b35      	SBIS	SCLPORT-2,SCLPIN
000048 cffe      	RJMP	i2c_write_loop1
000049 0000      	NOP
00004a 959a      	DEC	R25
00004b f7a1      	BRNE	i2c_write_loop
00004c 0000      	NOP
00004d 9a3d      	SBI	SCLPORT-1,SCLPIN
00004e 983c      	CBI	SDAPORT-1,SDAPIN
00004f 983c      	CBI	SDAPORT-1,SDAPIN
000050 983c      	CBI	SDAPORT-1,SDAPIN
000051 983d      	CBI	SCLPORT-1,SCLPIN
000052 2788      	CLR	R24
000053 9b34      	SBIS	SDAPORT-2,SDAPIN
000054 9583      	INC	R24
000055 983d      	CBI	SCLPORT-1,SCLPIN
000056 0000      	NOP
000057 9a3d      	SBI	SCLPORT-1,SCLPIN
000058 9508      	RET
                 
                 ;------------------------------
                 i2c_read:
000059 e098      	LDI	R25,8
00005a fb80      	BST	R24,0
                 i2c_read_loop:
00005b 9a3d      	SBI	SCLPORT-1,SCLPIN
00005c 9a3d      	SBI	SCLPORT-1,SCLPIN
00005d 9a3d      	SBI	SCLPORT-1,SCLPIN
00005e f980      	BLD	R24,0
00005f 0f88      	LSL	R24
000060 983d      	CBI	SCLPORT-1,SCLPIN
000061 9468      	SET
000062 9b34      	SBIS	SDAPORT-2,SDAPIN
000063 94e8      	CLT
000064 959a      	DEC	R25
000065 f7a9      	BRNE	i2c_read_loop
000066 f980      	BLD	R24,0
000067 9a3d      	SBI	SCLPORT-1,SCLPIN
000068 1f99      	ROL	R25
000069 ff90      	SBRS	R25,0
00006a 9a3c      	SBI	SDAPORT-1,SDAPIN
00006b fd90      	SBRC	R25,0
00006c 983c      	CBI	SDAPORT-1,SDAPIN
00006d 983d      	CBI	SCLPORT-1,SCLPIN
00006e 983d      	CBI	SCLPORT-1,SCLPIN
00006f 983d      	CBI	SCLPORT-1,SCLPIN
000070 983d      	CBI	SCLPORT-1,SCLPIN
000071 9a3d      	SBI	SCLPORT-1,SCLPIN
000072 983c      	CBI	SDAPORT-1,SDAPIN
000073 9508      	RET
                 
                 ;------------------------------
                 i2c_stop:
000074 9a3c      	SBI	SDAPORT-1,SDAPIN
000075 983d      	CBI	SCLPORT-1,SCLPIN
000076 983d      	CBI	SCLPORT-1,SCLPIN
000077 983c      	CBI	SDAPORT-1,SDAPIN
000078 9508      	RET
                 
                 ;------------------------------
                 Start:
000079 ef0f      	LDI	R16,Low(RAMEND)
00007a bf0d      	OUT	SPL,R16
00007b e008      	LDI	R16,High(RAMEND)
00007c bf0e      	OUT	SPH,R16
00007d 940e 0034 	CALL	i2c_init
                 Loop:
00007f 940e 0039 	CALL	i2c_start
000081 ec80      	LDI	R24,$C0
000082 940e 003f 	CALL	i2c_write
000084 e087      	LDI	R24,$07
000085 940e 003f 	CALL	i2c_write
000087 ef8f      	LDI	R24,$FF
000088 940e 003f 	CALL	i2c_write
00008a 940e 0074 	CALL	i2c_stop
00008c 940e 0039 	CALL	i2c_start
00008e e880      	LDI	R24,$80
00008f 940e 003f 	CALL	i2c_write
000091 e083      	LDI	R24,$03
000092 940e 003f 	CALL	i2c_write
000094 e181      	LDI	R24,$11
000095 940e 003f 	CALL	i2c_write
000097 940e 0074 	CALL	i2c_stop
                 Loop1:
000099 940e 0039 	CALL	i2c_start
00009b e880      	LDI	R24,$80
00009c 940e 003f 	CALL	i2c_write
00009e e080      	LDI	R24,$00
00009f 940e 003f 	CALL	i2c_write
0000a1 940e 003b 	CALL	i2c_restart
0000a3 e881      	LDI	R24,$81
0000a4 940e 003f 	CALL	i2c_write
0000a6 e081      	LDI	R24,$01
0000a7 940e 0059 	CALL	i2c_read
0000a9 940e 0074 	CALL	i2c_stop
0000ab 7081      	ANDI	R24,$01
0000ac f761      	BRNE	Loop1
0000ad 940e 0039 	CALL	i2c_start
0000af e880      	LDI	R24,$80
0000b0 940e 003f 	CALL	i2c_write
0000b2 e081      	LDI	R24,$01
0000b3 940e 003f 	CALL	i2c_write
0000b5 940e 003b 	CALL	i2c_restart
0000b7 e881      	LDI	R24,$81
0000b8 940e 003f 	CALL	i2c_write
0000ba e080      	LDI	R24,$00
0000bb 940e 0059 	CALL	i2c_read
0000bd e081      	LDI	R24,$01
0000be 940e 0059 	CALL	i2c_read
0000c0 940e 0074 	CALL	i2c_stop
0000c2 cfbc      	RJMP	Loop


RESOURCE USE INFORMATION
------------------------

Notice:
The register and instruction counts are symbol table hit counts,
and hence implicitly used resources are not counted, eg, the
'lpm' instruction without operands implicitly uses r0 and z,
none of which are counted.

x,y,z are separate entities in the symbol table and are
counted separately from r26..r31 here.

.dseg memory usage only counts static data declared with .byte

ATmega328P register use summary:
r0 :   0 r1 :   0 r2 :   0 r3 :   0 r4 :   0 r5 :   0 r6 :   0 r7 :   0 
r8 :   0 r9 :   0 r10:   0 r11:   0 r12:   0 r13:   0 r14:   0 r15:   0 
r16:   4 r17:   0 r18:   0 r19:   0 r20:   0 r21:   0 r22:   0 r23:   0 
r24:  25 r25:   7 r26:   0 r27:   0 r28:   0 r29:   0 r30:   0 r31:   0 
x  :   0 y  :   0 z  :   0 
Registers used: 3 out of 35 (8.6%)

ATmega328P instruction use summary:
.lds  :   0 .sts  :   0 adc   :   0 add   :   0 adiw  :   0 and   :   0 
andi  :   1 asr   :   0 bclr  :   0 bld   :   2 brbc  :   0 brbs  :   0 
brcc  :   0 brcs  :   0 break :   0 breq  :   0 brge  :   0 brhc  :   0 
brhs  :   0 brid  :   0 brie  :   0 brlo  :   0 brlt  :   0 brmi  :   0 
brne  :   3 brpl  :   0 brsh  :   0 brtc  :   0 brts  :   0 brvc  :   0 
brvs  :   0 bset  :   0 bst   :   1 call  :  26 cbi   :  23 cbr   :   0 
clc   :   0 clh   :   0 cli   :   0 cln   :   0 clr   :   1 cls   :   0 
clt   :   1 clv   :   0 clz   :   0 com   :   0 cp    :   0 cpc   :   0 
cpi   :   0 cpse  :   0 dec   :   2 eor   :   0 fmul  :   0 fmuls :   0 
fmulsu:   0 icall :   0 ijmp  :   0 in    :   0 inc   :   1 jmp   :   0 
ld    :   0 ldd   :   0 ldi   :  19 lds   :   0 lpm   :   0 lsl   :   1 
lsr   :   0 mov   :   0 movw  :   0 mul   :   0 muls  :   0 mulsu :   0 
neg   :   0 nop   :   3 or    :   0 ori   :   0 out   :   2 pop   :   0 
push  :   0 rcall :   0 ret   :   6 reti  :   0 rjmp  :   3 rol   :   2 
ror   :   0 sbc   :   0 sbci  :   0 sbi   :  13 sbic  :   0 sbis  :   3 
sbiw  :   0 sbr   :   0 sbrc  :   2 sbrs  :   2 sec   :   0 seh   :   0 
sei   :   0 sen   :   0 ser   :   0 ses   :   0 set   :   1 sev   :   0 
sez   :   0 sleep :   0 spm   :   0 st    :   0 std   :   0 sts   :   0 
sub   :   0 subi  :   0 swap  :   0 tst   :   0 wdr   :   0 
Instructions used: 22 out of 113 (19.5%)

ATmega328P memory use summary [bytes]:
Segment   Begin    End      Code   Data   Used    Size   Use%
---------------------------------------------------------------
[.cseg] 0x000000 0x000186    288      0    288   32768   0.9%
[.dseg] 0x000100 0x000100      0      0      0    2048   0.0%
[.eseg] 0x000000 0x000000      0      0      0    1024   0.0%

Assembly complete, 0 errors, 0 warnings

 

Komandir
Offline
Зарегистрирован: 18.08.2018

Это просто константы. Они прописаны в ...inc и заменяются реальными номерами портов и константами пинов для портов ...

-NMi-
Offline
Зарегистрирован: 20.08.2018

Надо деда просить, чтобы пояснил.

Komandir
Offline
Зарегистрирован: 18.08.2018

Вот тут видно:

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Зафаворитил :-)

Logik
Offline
Зарегистрирован: 05.08.2014

Komandir пишет:

В железе тестировал на OLED 128x32 SSD1306. Код для него ещё короче, так как не нужны функции i2c_restart и i2c_read.

192 кадра в секунду !!!

Опоздал ты с идеей на пяток лет. ))) Поищи, это ещё с Архатом и ещё кем-то тогда со всех сторон обгрызли идею. И юзаю так, даже прямо сейчас.  И нету там 1МГц. Говориш 192 ФПС. Считаем192*512*9=884КГц Девять тактов на байт - потому что АСК.. Все верно, дето так и у нас получалось.

АСМ там не нужен совсем. Пиши просто на Си, соберется считай так же.

Теперь о плохом.

Жаль что ТС так и не понял как работает I2C )))) Уровень 1 на SDA контроллер не выводит никогда. Нужно просто отпустить шину, а к 1 ее подтягивают резюки. Их там вообще 2, сказанное относится и к SCL по большому счету, но мультимастер  - экзотика.Отпустить шины -  это на ввод настроить.

АСК контролировать обязательно! Как только перейдеш от примера на ssd1306, на пример, к примеру на 24c512 - поймеш зачем. 

Но именно вот такую реализацию, без резюков подтяжки, без контроля АСК,  но на Си и с нормальной задачей пинов ( ну просто их номером)  я таки храню. Чтоб по быстряку ОЛЕД покинуть на любые ноги для отладки. Да и в проектах иногда подтяжки память влом ))) Пошарся по форуму, тут даже видео его работы лето валяется, там и осцилограф и ДПФ и диаграмки отрисовывает.

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Logik пишет:
Поищи, это ещё с Архатом и ещё кем-то тогда со всех сторон обгрызли идею.

Нарочно жопой крутишь? Это мой код софт И2С был, его и трахали по разному. До Миллиона довести нельзя. Но если всё увести в ассемблер, конечно не так, как тут, то может быть получится. Если родная softI2C  на arduino.cc очень грамотная. Которую можно ускорить, зная протокол (убрав проверки на "медленный слейв").

Logik
Offline
Зарегистрирован: 05.08.2014

Явился не прошенный, ещё и с претензией, не понятно на что. У меня моя реализация. А что у тебя там с Ахатом общее - сами решайте, главное не на людях ;)

Komandir
Offline
Зарегистрирован: 18.08.2018

Logik пишет:

Komandir пишет:

В железе тестировал на OLED 128x32 SSD1306. Код для него ещё короче, так как не нужны функции i2c_restart и i2c_read.

192 кадра в секунду !!!

Опоздал ты с идеей на пяток лет. ))) Поищи, это ещё с Архатом и ещё кем-то тогда со всех сторон обгрызли идею. И юзаю так, даже прямо сейчас.  И нету там 1МГц. Говориш 192 ФПС. Считаем192*512*9=884КГц Девять тактов на байт - потому что АСК.. Все верно, дето так и у нас получалось.

АСМ там не нужен совсем. Пиши просто на Си, соберется считай так же.

Теперь о плохом.

Жаль что ТС так и не понял как работает I2C )))) Уровень 1 на SDA контроллер не выводит никогда. Нужно просто отпустить шину, а к 1 ее подтягивают резюки. Их там вообще 2, сказанное относится и к SCL по большому счету, но мультимастер  - экзотика.Отпустить шины -  это на ввод настроить.

АСК контролировать обязательно! Как только перейдеш от примера на ssd1306, на пример, к примеру на 24c512 - поймеш зачем. 

Но именно вот такую реализацию, без резюков подтяжки, без контроля АСК,  но на Си и с нормальной задачей пинов ( ну просто их номером)  я таки храню. Чтоб по быстряку ОЛЕД покинуть на любые ноги для отладки. Да и в проектах иногда подтяжки память влом ))) Пошарся по форуму, тут даже видео его работы лето валяется, там и осцилограф и ДПФ и диаграмки отрисовывает.

Ну что тут сказать ...
Ты мальчик еще мал и глуп и не видал больших за...п !!!

Про скорость - скорость шины измеряется периодом следования сигналов на линии SCL !!!

Где ты тут нашел выставление 1 ? Тут ВЕЗДЕ подтяжка к нулю или отпускание !!! И на схеме R1 R2 для красоты что ли ???

Тут есть не только контроль ASK, но даже есть контроль удержания ведомым линии SCL в низком состоянии для паузы на обработку !!!

Разуй глаза ...

Logik
Offline
Зарегистрирован: 05.08.2014

Вау! К нам спец по за..там пожаловал!

Ну раздвигайся, принимай первую.  Если за 1 сек на SCL 884тысячи импульсов прошло, то какая частота на SCL?

Komandir
Offline
Зарегистрирован: 18.08.2018

9 тактов SCL за 9 микросекунд - это какая частота ?

Аппаратный i2c:
на 100 КГц выдает 9 тактов SCL за 90 микросекунд
на 400 КГц выдает 9 тактов SCL за 22,5 микросекунды
следовательно:
на 1000 КГц 9 тактов SCL должны генерироваться именно за 9 микросекунд !!!

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Logik пишет:

Явился не прошенный, ещё и с претензией, не понятно на что. У меня моя реализация. А что у тебя там с Ахатом общее - сами решайте, главное не на людях ;)


Спать уже ушел. С тилипона сложно... Логик! Шаббат шалом! Прочитай "Шма Исраэль" и ложись спать. Хорош тут лысого гонять на форумах. Не круто;)))

Logik
Offline
Зарегистрирован: 05.08.2014

///
9 тактов SCL за 9 микросекунд - это какая частота ?/p>

 

Такс, отвечаем вопросом на вопрос.... Ну ясно, спец по за..пам должен быть обрезаным.

Про 9 мкс на 9 тактов. Ты видно таки решил что тут самый обрезаный ))) И пропустил что любые 9 тактов за 9 мксек в течении сеанса обмена. А не некоторые, избранные. Вот если сделаеш так и продемонстрируеш опытным путём, по ФПС экрана, что хотя бы  в среднем 9мксек на 9 тактов - добро пожаловать. А пока наслаждайся за..пой. 

Повторяю вопрос. Какая частота шины при измеренных 192 фПС? В мои годы студентов, не отвечающих на такой вопрос отправляли применять сапоги и шинель. У замдекана спецом комплект хранился. Ты пишеш командир...из таких похоже.

Logik
Offline
Зарегистрирован: 05.08.2014

wdrakula пишет:
Logik пишет:

Явился не прошенный, ещё и с претензией, не понятно на что. У меня моя реализация. А что у тебя там с Ахатом общее - сами решайте, главное не на людях ;)

Спать уже ушел. С тилипона сложно... Логик! Шаббат шалом! Прочитай "Шма Исраэль" и ложись спать. Хорош тут лысого гонять на форумах. Не круто;)))

И тебе шалом, православный.

Та тут же лысый со знанием асма подвергался. Часто ль такое было!

Пс. Сам с планшета набирать замучался.

Komandir
Offline
Зарегистрирован: 18.08.2018

Если обратиться к первоисточнику:

Komandir
Offline
Зарегистрирован: 18.08.2018

Это генерирует мой код:

Komandir
Offline
Зарегистрирован: 18.08.2018

А тупых преподавателей везде хватает ! У нас в МЭИ был один похожий ... оценивал код на вес бумаги, на которой его распечатывали.

Logik это не ты в МЭИ преподавал нам ???

С частотой SCL ты жидко обделался !!!

 

Перейдём ко второму вопросу..

В какой строке я выставил "1" в порту для SCL или SDA, а не отпустил линию (перевел её в состояние входа) ?

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Komandir, разворошили :-)

Говорили ж мудрые англичане: "Let sleeping dogs lie" :-)

Komandir
Offline
Зарегистрирован: 18.08.2018

Вдогонку - аппаратная передача на 100 КГц:

Komandir
Offline
Зарегистрирован: 18.08.2018

и аппаратная передача на 400 КГц:

Komandir
Offline
Зарегистрирован: 18.08.2018

ЕвгенийП кто кого разбудил то ?

-NMi-
Offline
Зарегистрирован: 20.08.2018

Уровень 1 на SDA контроллер не выводит никогда. Нужно просто отпустить шину, а к 1 ее подтягивают резюки. Их там вообще 2, сказанное относится и к SCL по большому счету, но мультимастер  - экзотика.Отпустить шины -  это на ввод настроить.

Ligik всё уже объяснил выше.

В таком случае нам понадобятся две команды, одна из них CBI х,у для прижатия шины к земле, вторая DDRх,у для перевода пина на вход/выход для "отпускания" шины, т.е. выставления лог. 1 на ней.

 

Komandir
Offline
Зарегистрирован: 18.08.2018

-NMi- Ещё один знаток ассемблера AVR ? А как выглядит DDR x,y ? Раскройте мне глаза ?

Что па Вашему делают следующие команды, если SCLPORT=SDAPORT=PORTC=0x08 ?

CBI	SCLPORT-1,SCLPIN
CBI	SDAPORT-1,SDAPIN
CBI	SDAPORT,SDAPIN
CBI	SCLPORT,SCLPIN

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Komandir пишет:

-NMi- Ещё один знаток ассемблера AVR ? А как выглядит DDR x,y ? Раскройте мне глаза ?

Что па Вашему делают следующие команды, если SCLPORT=SDAPORT=PORTC=0x08 ?

CBI	SCLPORT-1,SCLPIN
CBI	SDAPORT-1,SDAPIN
CBI	SDAPORT,SDAPIN
CBI	SCLPORT,SCLPIN

смахивает на битву одного против трёх мушкетёров )))

Komandir
Offline
Зарегистрирован: 18.08.2018

ua6em воспитателя и детсадовцев ...

-NMi-
Offline
Зарегистрирован: 20.08.2018

Зачем так агрессировать? Просто мне не понятна одна вещь: для того, чтобы прижать пин к земле сколько нужно команд? Одна или две? Вот в чём вопрос..

Как по мне, нужно:

1 - сделать пин выходом

2 - сбросить бит в регистре пина, чтобы он вывел на пин "0"

И наоборот:

1 - сделать пин входом

2 - выставить бит пина в "1"

Или же просто манипулировать DDRх пинами без изменения битов регистра порта? Вот в чём вопрос...

Komandir
Offline
Зарегистрирован: 18.08.2018

CBI	SCLPORT-1,SCLPIN	// Вывод SCL - вход
CBI	SDAPORT-1,SDAPIN	// Вывод SDA - вход
CBI	SDAPORT,SDAPIN 		// Значение SDA=0. Дальше это значение не меняется НИ РАЗУ!!!
CBI	SCLPORT,SCLPIN		// Значение SCL=0. Дальше это значение не меняется НИ РАЗУ!!!
// Это инициализация линий. После этого
// Командой CBI SCLPORT-1,SCLPIN отпускается шина и получаем "1" от резистора подтяжки
// Командой SBI SCLPORT-1,SCLPIN притягиваем шину к записанному "0" и получаем "0"
// Командами SBIS / SBIC SCLPORT-2,SCLPIN можно проверить текущее состояние линии
// Всё это вытекает из того что SCLPORT=PORC, а SCLPORT-1=DDRC и SCLPORT-2=PINC.
// Это прописано в m328Pdef.inc
                 ...
                 .equ PORTD = 0x0b
                 .equ DDRD = 0x0a
                 .equ PIND = 0x09
                 .equ PORTC = 0x08
                 .equ DDRC = 0x07
                 .equ PINC = 0x06
                 .equ PORTB = 0x05
                 .equ DDRB = 0x04
                 .equ PINB = 0x03
                 ...
ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Komandir пишет:

ЕвгенийП кто кого разбудил то ?

Ваша тема разбудила застарелый срач, который тихо дремал себе до поры :-)

-NMi-
Offline
Зарегистрирован: 20.08.2018

Всё, вЪехал. Это просто для универсальности пользования сделано. Т.е. есть порт и есть пин в качестве констант или алиаса а дальше мы уже вычисляем те порты (регистры ввода-вывода), шо нужны нам.

))) с тилипона то не всё видно то... )))  вчерасЪ )))

Komandir
Offline
Зарегистрирован: 18.08.2018

ЕвгенийП Вот Вы лично как считаете ? Частота SCL определяет скорость работы сдвигового регистра при выводе одного байта, или же надо учесть кто и какой лопатой загружает эти байты в сдвиговый регистр.

Green
Offline
Зарегистрирован: 01.10.2015

Komandir, в i2c_read() всё красиво? Мне кажется на last никто не обращает внимания. 

Komandir
Offline
Зарегистрирован: 18.08.2018

Green В ассемблерном коде обратите внимание на стоки 148 и 150, в Сишном коде на строки 155 и 156.