Здраствуйте, от вопросов с битами, перешел к практической реализации, в результате получил программу, котора работает всего на половину. Ведомый принимает адресс, ведущий, сигнализирует двойкой в порту Б, типа подтверждение принято и начинаю передачу данных. Но, данные почему-то не принимаются. В порт ведомого выдается значение принятого адресса. Где я ошибся. По графику на осциле, получается стартовый бит, адрессный пакет, в виде 1010101, бит 0 - типа запись, бит 0 - подтверждение - и все, дальше ни чего не происходит. Подскажите, что не так, вот примерные листинги программы на CODEVISION.
CODE
/*ведущий передатчик без ошибок*/
#include <mega16.h>
#include <delay.h>
int reg_stat, address, data; //все прерывания обзываются на самом верху, после дефайна не поймет
#define int_off (TWCR |= (1<<7));// выход из прерывания
#define int_on (TWCR |= (0<<7)); //вход в прерывания
/*разрешаем работу прерывания, сбрасываем флаг, формируем старт*/
#define start_bit (TWCR |= (1<<7)|(1<<5)|(0<<4)|(1<<2)|(1<<0));
#define start_slaw (TWCR |= (1<<7)|(1<<2)); //передача данных или адреса
#define stop_bit (TWCR |= (1<<7)|(1<<4)|(1<<2)); //стоп
/*инициируем, отключаем прерывания, причем записью 0, старты и стопы
разрешаем только работу модуля*/
#define twi_init (TWCR |= (0<<7)|(0<<6)|(0<<5)|(0<<4)|(0<<3)|(1<<2)|(0<<0))
master_transe()
{
twi_init ;
address = 0xAA;
data = 0x1;
start_bit;
/*twi_init ;
start_bit;
TWDR = 0x55;
start_slaw; //если убрать цикл, то он всегда будет передавать пакет, и постояно менять состояние порта,
//то есть заходитть в прерывание с каждым удачной передачей
/*twi_init ;
start_bit;
такой кусок программы уже работает и дает, импульс*/
}
interrupt [18] void twi_rasrul(void)
{
reg_stat = TWSR;
switch (reg_stat)
{
/*по этому коду был сформирован старт, передаем адресс, вышли
все удачно, срабатывает прерывание, переход*/
case 0x08: TWDR = address; PORTB =1; start_slaw; break;
/*по этому коду, удачно был передан адресс и получено подтверждение,
то есть ведомый удерживает низкий уровень, свободен*/
case 0x18: TWDR = data; #asm("nop"); start_slaw; PORTB = 2; break;
case 0x28: #asm("nop"); PORTB =4; stop_bit ; break;
}
}
void main() //так начинается тело в кодевизион
{
DDRB = 0xff;
DDRA = 0x00; // вход
PORTA = 0xff; //поддтягивающие
#asm("sei");// разрешаем глобальное прерывание
//разрешение прерывания
TWBR = 0xff;
/*TWSR = 0 с четвертого разряда начинается коды статуса. скорей всего относительно
их идет распределение разрядов. А первые три это степень в скорости
чем больше число, тем меньше скорость. пока не трогаю.
*/
while(1)
{
if (PINA.0 == 1)
{
master_transe();
delay_ms(1000000000000);
while (PINA.0 == 1); /*это чтобы не выходило из кнопки, пока не перекликну*/
}
}
}
CODE
/*ведомый приемник*/
#include <mega16.h>
#include <delay.h>
int reg_stat, address, data; //все прерывания обзываются на самом верху, после дефайна не поймет
#define init_off (TWCR |= (1<<7)|(1<<6));// выход из прерывания
#define init_on (TWCR |= (0<<7)); //вход в прерывания
#define start_bit (TWCR |= (1<<7)|(1<<5)|(1<<2));
/*устанавливаем флаг для сброса прерывания. сформировываем состояние старт
разрешаем рабобту модуля ТВИ*/
#define start_slaw (TWCR |= (1<<7)|(1<<2)|(1<<0)); //передача данных или адреса
#define stop_bit (TWCR |= (1<<7)|(1<<4)|(1<<2)); //стоп
#define receiver_init (TWCR |= (1<<7)|(1<<6)|(0<<4)|(1<<2)|(1<<0));
interrupt [18] void twi_rasrul(void)
{
reg_stat = TWSR;
switch (reg_stat)
{
case 0x60: #asm("nop"); #asm("nop"); #asm("nop"); PORTB = TWDR; break;
}
}
void main() //так начинается тело в кодевизион
{
DDRB = 0xFF;//выход
DDRA = 0x00; // вход
PORTA = 0xff; //поддтягивающие
#asm("sei");// разрешаем глобальное прерывание
//разрешение работы модуля, разрешение выдачи бита подтверждения
// разрешения прерывания
//TWBR = 0xff; значение этих битов в режиме ведомого безразличны
TWAR = 0xAA;//указание адреса устройства
receiver_init;
/*так как в адресном пакете он получит 0, то он автоматически перейдет в режим ведомого приемника*/
while(1);
}
От модератора. Используйте, пожалуйста, теги codebox для цитирования объемных исходных текстов!