Осваиваю С. AtmelStudio 7 . Пишу тестовую программу для I2C Slave.
Код: Выделить всё
Файл Main.c
------------------------------------------------------------------------
int main(void)
{
Sb_Start() ; // Инициализация. Там же запускается Sb_I2c_Init()
while (1)
{
// Пустой цикл
}
}
------------------------------------------------------------------------
Файл I2Cs.c
------------------------------------------------------------------------
void Sb_I2c_Init(void){
... Тут инициализация TWI в режиме SLAVE
}
ISR(TWI_vect){ // Прерывание модуля TWI
unsigned char I2c_uC_status = 0 ; // статус регистра TWSR
I2c_uC_status = TWSR & 0xF8 ; // отбрасываем 3 лишних байта [ -, TWSP1,TWSP2 ]
switch (I2c_uC_status){
// .... код
case 0x80: //** адресованы, был принят байт данных и послан ACK ------
Mr_I2C_SL_On_A ; // Макрос. Настраивает TWCR : Будет принят байт + ACK
Mr_SetBit_0(PORTC, Led2) ; // Макрос. Записывает 0 в бит "Led2" в регистре "PORTC" = Зажигает светодиод
break;
//...... код
}
Mr_SetBit_1(TWCR, TWINT) ; // <- 1 : Сброс флага прерывания (записать 1)
}
------------------------------------------------------------------------
Испытываю в железе. Отправляю посылку по I2C. МК принимает. Светодиод зажигается. Всё ОК.
Обрабатывать принятый байт буду в MAIN. Поэтому вместо включения светодиода в прерывании ставлю флаг, который проверяется в главном цикле и при выставленном флаге включается светодиод.
Код: Выделить всё
Файл Main.c
------------------------------------------------------------------------
int main(void)
{
Sb_Start() ; // Инициализация. Там же запускается Sb_I2c_Init()
while (1)
{
if (0 != (I2c_uC_Flags1 & (1<<I2c_Fe_Mess_Byte_New))) { // ФЛАГ = принят байт ?
Mr_SetBit_0(I2c_uC_Flags1, I2c_Fe_Mess_Byte_New) ; // Макрос. Сброс флага
Mr_SetBit_0(PORTC, Led2) ; // Макрос. Записывает 0 в бит "Led2" в регистре "PORTC" = Зажигает светодиод
}
}
}
------------------------------------------------------------------------
Файл I2Cs.c
------------------------------------------------------------------------
void Sb_I2c_Init(void){
... Тут инициализация TWI в режиме SLAVE
}
ISR(TWI_vect){ // Прерывание модуля TWI
unsigned char I2c_uC_status = 0 ; // статус регистра TWSR
I2c_uC_status = TWSR & 0xF8 ; // отбрасываем 3 лишних байта [ -, TWSP1,TWSP2 ]
switch (I2c_uC_status){
// .... код
case 0x80: //** адресованы, был принят байт данных и послан ACK ------
Mr_I2C_SL_On_A ; // Макрос. Настраивает TWCR : Будет принят байт + ACK
Mr_SetBit_1(I2c_uC_Flags1, I2c_Fe_Mess_Byte_New) ; Макрос. УСТАНОВКА ФЛАГА. Записывает 1 в бит "I2c_Fe_Mess_Byte_New" в регистре "I2c_uC_Flags1"
break;
//...... код
}
Mr_SetBit_1(TWCR, TWINT) ; // <- 1 : Сброс флага прерывания (записать 1)
}
------------------------------------------------------------------------
Собственно проблема в том, что так НЕ работает, светодиод не включается. Почему !?
Простейшая задача Поставить флаг в прерывании. А в главном цикле зажечь светодиод, если флаг установлен.