** Эгоист **
Профи
(502)
2 месяца назад
Подключение I2C контроллеров
Общие подключения:
Подключите все контроллеры к шине I2C. Обычно SDA (данные) и SCL (тактовый сигнал) должны быть соединены, а также необходимо подтягивать линии к Vcc через резисторы (обычно 4.7 кОм).
Настройка адресов:
Каждый из ваших контроллеров должен иметь уникальный 7-битный адрес. Это можно сделать, например, следующим образом:
Первый Slave: 0x10
Второй Slave: 0x11
Третий Slave: 0x12
.include "m32def.inc" ; Подключаем определение для ATmega32
; Определение адресов Slave
.equ SLAVE1_ADDR = 0x10
.equ SLAVE2_ADDR = 0x11
.equ SLAVE3_ADDR = 0x12
; Регистры
.equ TWBR = 0xB8 ; Регистры TWI Bit Rate
.equ TWSR = 0xB9 ; Регистры TWI Status
.equ TWCR = 0xBC ; Регистры TWI Control
.equ TWDR = 0xBB ; Регистры TWI Data
; Установка частоты TWI
.equ TWI_FREQ = 100000 ; Частота 100kHz
; Инициализация TWI
init_twi:
ldi r16, 0x00 ; Установим предделитель
out TWSR, r16
ldi r16, (F_CPU / (2 * TWI_FREQ) - 8) ; Установим битрейт
out TWBR, r16
ret
; Отправка адреса Slave
send_slave_address:
; Отправка старта
ldi r16, (1 << TWSTA) | (1 << TWEN)
out TWCR, r16
; Ожидание завершения старта
wait_for_twint:
in r16, TWCR
sbrs r16, TWINT
rjmp wait_for_twint
; Отправка адреса
mov r16, SLAVE1_ADDR ; Здесь можно изменить на адрес второго или третьего Slave
out TWDR, r16
ldi r16, (1 << TWINT) | (1 << TWEN)
out TWCR, r16
; Ожидание завершения передачи
wait_for_twint2:
in r16, TWCR
sbrs r16, TWINT
rjmp wait_for_twint2
; Проверка ACK
in r16, TWSR
cpi r16, 0x18 ; Проверка на ACK
breq send_data ; Если ACK, переходим к передаче данных
; Если NACK, можно обработать ошибку
ret
; Отправка данных Slave
send_data:
; Здесь можно отправить данные
ldi r16, 0x01 ; Пример данных
out TWDR, r16
ldi r16, (1 << TWINT) | (1 << TWEN)
out TWCR, r16
; Ожидание завершения передачи данных
wait_for_twint3:
in r16, TWCR
sbrs r16, TWINT
rjmp wait_for_twint3
; Отправка стопа
ldi r16, (1 << TWSTO) | (1 << TWINT) | (1 << TWEN)
out TWCR, r16
ret
; Основная программа
.org 0x0000
rjmp main
main:
call init_twi ; Инициализация TWI
; Отправка данных к первым и вторым Slave
call send_slave_address
; Если необходимо, можно отправить к другому Slave
; Измените SLAVE1_ADDR на SLAVE2_ADDR или SLAVE3_ADDR в send_slave_address
rjmp main
Объяснение кода
Инициализация TWI: Устанавливается скорость передачи данных. Не забудьте подставить значение частоты F_CPU в определениях.
Отправка адреса Slave: После отправки адреса контроллер ждет ACK. Если NACK, код может обрабатывать эту ситуацию (например, можно попробовать повторить отправку или переключиться на следующий Slave).
Отправка данных: Данные передаются только если получен ACK.
Основной цикл: Вызовы функций для отправки данных к Slave находятся в бесконечном цикле.
Саша ЯровойПрофи (639)
2 месяца назад
; Если необходимо, можно отправить к другому Slave
; Измените SLAVE1_ADDR на SLAVE2_ADDR или SLAVE3_ADDR в send_slave_address
rjmp main
То есть нельзя несколько МК на одной шине?
Тогда использую маску TWAMR хоть частичну, хоть полную для разовой отправки Адреса обоим Slave, но они все равно реагируют только на полное указание адреса.
Даже не представляю как Программно заставить слушать пакеты после события $A0