Например TDA7294

Форум РадиоКот • Просмотр темы - Работа с TWI на Atmega
Форум РадиоКот
Здесь можно немножко помяукать :)

Текущее время: Пт сен 26, 2025 14:31:24

Часовой пояс: UTC + 3 часа


ПРЯМО СЕЙЧАС:



Начать новую тему Ответить на тему  [ 1 сообщение ] 
Автор Сообщение
Не в сети
 Заголовок сообщения: Работа с TWI на Atmega
СообщениеДобавлено: Вт авг 13, 2024 15:22:27 
Родился

Зарегистрирован: Вт авг 13, 2024 15:00:14
Сообщений: 1
Рейтинг сообщения: 0
Написал простенькую программку, которая перебирает все возможные адреса TWI устройств на шине, если находит, выплёвывает адрес в COM. Сижу уже несколько дней и не понимаю в чем может быть проблема. Стартовый бит отправляется без проблем (я вижу сообщение "START bit transmitted"). Проблема начинается когда мы заходим в функцию write_byte(...). Там почему-то после записи регистров TWDR и TWCR не устанавливается флаг TWINT, и соответственно он зацикливается в while и спамит мне "Wait sending adress byte". Проверил, TWDR и TWCR записываются корректно. Пробовал выставлять задержки (хотя они тут не нужны), тоже ничего. Вообщем много что перепробовал. Дебажил всё в ардуино, потому что проще.

Код:
#include <Arduino.h>

//Set your needed setttings here

long int CPU_freq = 16000000;    //Processor frequency of the microcontroller
long int FreqI2C = 200000;       //Frequency of SCL line "Hz" (The frequency of operation of your connected device)
uint16_t twps_reg = 0x00;                 //TWI prescaler bits
                                      //(TWPS = 0x00: freq SCL [30;10^3]KHz)
                                      //(TWPS = 0x01: freq SCL [8;10^3]KHz)
                                      //(TWPS = 0x02: freq SCL [2;10^3]KHz)
                                      //(TWPS = 0x03: freq SCL [0.5;10^3]KHz)

//Global Variables
volatile uint8_t TWSR_state;
bool write = 0;
bool read = 1;
volatile uint8_t addres_device;

//All functions
//Initialization of bus I2C
void init_TWI(){
  int Prescaler;                              //TWI Prescaler Bits (see Datasheet)
    switch(twps_reg){
        case 0x00: Prescaler = 1; break;
        case 0x01: Prescaler = 4; break;
        case 0x02: Prescaler = 16; break;
        case 0x03: Prescaler = 64; break;
        default: Serial.println("Check if the register twps_reg is correct");
        Prescaler = 1;                        //default
    }
  TWBR = (CPU_freq/FreqI2C - 8)/Prescaler;    //TWI Bit Rate Register
  TWSR = twps_reg;
  digitalWrite(SDA, 1);                       //Transfer the SCL and SDA lines to an internal pull-up resistor
  digitalWrite(SCL, 1);
}

//Sending start bit
bool transfer_start_bit(){   
  TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN)|(1<<TWIE);                                  //TWI Control Register
  while (!(TWCR & (1<<TWINT))) Serial.println("Wait sending START bit");   //Waiting for the TWINT bit to be set
    if ((TWSR_state == 0x08) || (TWSR_state == 0x10)) return 1;
  return 0;
}

//Sending SLA+W and data byte
bool write_byte(uint8_t byte, bool R_W){
  TWDR = (byte << 1) + R_W;                                                     //TWI Data Register                                               
  TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWIE);
  while (!(TWCR & (1<<TWINT))) Serial.println("Wait sending address byte");   //Waiting for the TWINT bit to be set
  if ((TWSR_state == 0x18) || (TWSR_state == 0x28)) return 1;
  return 0;
}

//Sending STOP bit
void bus_stop(){
  TWCR = (1<<TWEN)|(1<<TWINT)|(1<<TWSTO);
}


//Finding the adress of slave
uint8_t searching_I2C_device(){                                         //We are going through all possible addresses
  for (uint8_t adress = 0x00; adress < 0xFF; adress++){
  if (transfer_start_bit() == 1){
    if (write_byte(adress, write) == 1) return adress;
  }
  bus_stop();
  }
  return 0;
}

//Timer1_delay
void time1_delay(int delay){                                       //Delay is specified in the number of processor cycles
  TCCR1A = 0x00;
  TCNT1 = 0x0000;
  TCCR1B = (1<<WGM12)|(0<<CS12)|(1<<CS10)|(0<<CS11);
  OCR1A = delay;
  TIMSK1 = (1<<OCIE1A);
  while(TIMSK1 & (1<<OCIE1A)){}
}

//Read status of TWSR register
ISR (TWI_vect){
switch(TWSR & 0xF8){
  case 0x00: TWSR_state = 0x00;                                         //Bus error due to an illegal START or STOP condition
              Serial.println("Bus error due START or STOP condition");
              break;
              //bus_stop();
  case 0x08: TWSR_state = 0x08;                                         //A START condition has been tranmitted
              Serial.println("START bit transmitted");
              break;
  case 0x10: TWSR_state = 0x10;                                         //A repeated START condition has been transmitted
              Serial.println("Reapeated START bit transmitted");
              break;
  case 0x18: TWSR_state = 0x18;                                         //SLA+W has been transmitted and ACK has been recieved
              Serial.println("SLA+W transmitted and ACK bit received");
              break;
  case 0x20: TWSR_state = 0x20;                                         //SLA+W has been transmitted and NOT ACK has been recieved
              Serial.println("SLA+W transmitted and NOT ACK bit received");
              break;
              //bus_stop();
  case 0x28: TWSR_state = 0x28;                                         //Data byte has been transmitted and ACK has been recieved
              Serial.println("Data byte transmitted and ACK bit recieved");
              break;
  case 0x30: TWSR_state = 0x30;                                         //Data byte has been transmitted and NOT ACK has been recieved
              Serial.println("Data byte transmitted and NOT ACK bit recieved");
              break;
              bus_stop();
  case 0xF8: TWSR_state = 0xF8;                                         //No relevant state information available; TWINT = '0'
              Serial.println("No relevant state information");
              break;
  default: TWSR_state = 0xFF;                                           //Nothing of the above
  Serial.println("Undefined state 0xFF");
  break;
  }
  TWCR = 0x00;
}

//Turn off the Timer1
ISR(TIMER1_COMPA_vect){
  cli();
  TIMSK1 = (0<<OCIE1A);
  asm volatile ("nop");
  sei();
}

//Setup initial parameters
void setup() {
  sei();
  Serial.begin(9600);
  Serial.println("Start finding the adress of VEML6040");
  init_TWI();
}

void loop() {
  addres_device = searching_I2C_device();
  if(addres_device != 0){
  Serial.print("Address of slave is 0x");
  Serial.println(searching_I2C_device(), HEX);
  }
  else Serial.println("Address of device is not found");
  bus_stop();
}


Вложения:
TWI.txt [6.31 KiB]
Скачиваний: 71
Вернуться наверх
 
Показать сообщения за:  Сортировать по:  Вернуться наверх
Начать новую тему Ответить на тему  [ 1 сообщение ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: Ljubitel и гости: 62


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB
Extended by Karma MOD © 2007—2012 m157y
Extended by Topic Tags MOD © 2012 m157y