Avr-gcc, указатели при работе с avr и переферией

Обсуждаем контроллеры компании Atmel.
Ответить
Catdawr
Первый раз сказал Мяу!
Сообщения: 34
Зарегистрирован: Вс авг 21, 2016 19:53:33

Avr-gcc, указатели при работе с avr и переферией

Сообщение Catdawr »

Atmel_Studio 7, "Си",Proteus 8, Atmega 8, ds3231... вроде ничего не забыл

Добрый вечер, Коты и Киски. Скажите пжалста, есть какие то ... ограничения в использовании Си-шных указателей в авр-ах?
Я почему спрашиваю-то. Хотел я забашить 1у функцию для TWI, чтобы править всеми !!! в ней было все, что нужно для работы с аппаратами, управляемыми этим протоколом(пока она только под ds3231, но это только пока), хотябы режим мастер-слайв. Но, что б грузить/выгружать данные сразу массивами. Что б их доставить в функцию, понятно, использую указатель. Имя устройства и адрес ячейки летит из простых констант(и долетают они корректно). Однако, дальше он делает бяку. Когда в цикле впрягаются в TWDR, по очереди, данные из массива- по дебагеру I2C в протеусе, вижу на месте первого отправленного байта непонятное число, а все остальные данные как бы сдвигаются на +1, в нумерации массива. Даже когда я пытался начать отправлять не с 0-го а, предположим, с 3-го - летит это самое число, а потом уже 3ий байт и последующие ( оно почти всегда одинаковое, меняется в зависимости от положения в коде, адрес массива, наверное. Однако, непонятно как оно туда попадает, непонятно :dont_know: )
вставлю пока проблемный огрызок кода:

Код: Выделить всё

 - это из main.c , данные набиты от балды
	int confclc[] = {0x04,0x12,0x06};
	_write_m(DS3231,B_W,0x0E,2,confclc);

Код: Выделить всё

 - это из хедера
void _write_m (int slaveAddr, int wrFLAG, uint8_t addPACK, int num_pack, int *wPACK)
{

int g=0;

		//-------- START
	    TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
	    while(!(TWCR & (1<<TWINT))); // ожидания освобождения шины
	    if((TWSR & 0xF8) != TW_START);

		//------- SEND ADDRESS
	    uint8_t sendaddr = slaveAddr +wrFLAG ;
	    TWDR = sendaddr;
	    TWCR =(1<<TWINT|1<<TWEN);
	    while(!(TWCR & (1<<TWINT)));
	    //  if ((TWSR & 0xF8) != TW_MT_SLA_ACK);

		//------- SEND ADDRESS BYTE

	    TWDR = addPACK;
		TWCR =(1<<TWINT|1<<TWEN);
		while(!(TWCR & (1<<TWINT)));

	    TWDR = wPACK;
		TWCR =(1<<TWINT|1<<TWEN);
		while(!(TWCR & (1<<TWINT)));

		switch (wrFLAG) // 

		//------- WRITE/READ
		{
			case 0b00000000 :   //  запись в устройство
            for (g=0;g<num_pack;g++)       //0 < 1 -- цикл идет
            {
				TWDR= wPACK[g];
				TWCR =(1<<TWINT|1<<TWEN);
				while(!(TWCR & (1<<TWINT)));
				if ((TWSR & 0xF8) != TW_MT_DATA_ACK);
            }
			break;

			case 0b00000001 :
			while (g<num_pack) // нет ничего пока, да и сфинкс с ним

			break;
		}
		//------ STOP
	    TWCR =(1<<TWINT)|(1<<TWSTO)|(1<<TWEN);
... Если, мне сразу не скажут в каком месте у меня руки кривые не от туда растут. То скину код целиком, в конце концов, найти то все равно хотелось бы. Спасибо
Реклама
Аватара пользователя
Z_h_e
Собутыльник Кота
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Re: Avr-gcc, указатели при работе с avr и переферией

Сообщение Z_h_e »

Catdawr писал(а):Когда в цикле впрягаются в TWDR, по очереди, данные из массива- по дебагеру I2C в протеусе, вижу на месте первого отправленного байта непонятное число,
Этот регистр двойной. В него кладутся данные для отправки и из него читаются полученные данные. Не знаю как с I2С, но с SPI (там тоже двойной регистр) Протеус в отладке значение регистра данных адекватно не отображает, хотя сама программа работает правильно.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Реклама
viiv
Грызет канифоль
Сообщения: 289
Зарегистрирован: Чт ноя 06, 2014 13:09:06

Re: Avr-gcc, указатели при работе с avr и переферией

Сообщение viiv »

Код: Выделить всё

TWDR = wPACK;
Это зачем? Вот это и есть бяка (отправляешь младшие 8 бит адреса массива confclc).

ЗЫ.
I)

Код: Выделить всё

 switch (wrFLAG) //

      //------- WRITE/READ
      {
         case 0b00000000 :   //  запись в устройство
...
         break;

         case 0b00000001 :
...
         break;
      }
Зачем? Так же понятнее (ну и более правильное имя переменной wrFlag - это rdFlag (в ней истина, когда операция чтения))

Код: Выделить всё

if (wrFLAG) {
...
} else {
...
}
II) Зачем slaveAddr, wrFLAG num_pack и *wPACK двухбайтовые?
III) В чем смысл?

Код: Выделить всё

 if ((TWSR & 0xF8) != TW_MT_DATA_ACK);
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Avr-gcc, указатели при работе с avr и переферией

Сообщение ARV »

я бы все-таки оформил код в виде отельных функций: более врехнего уровня для отправки/приема данных по адресу устройства, и более низкого уровня - для выставления адреса устройства, выдачи/ приема байта и т.п. имеющийся код и читать и понимать сложно, и где-то там вполне могут быть спрятавшиеся ошибки...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Реклама
Эиком - электронные компоненты и радиодетали
Catdawr
Первый раз сказал Мяу!
Сообщения: 34
Зарегистрирован: Вс авг 21, 2016 19:53:33

Re: Avr-gcc, указатели при работе с avr и переферией

Сообщение Catdawr »

и правда. в этом беда -

Код: Выделить всё

      TWDR = wPACK;
      TWCR =(1<<TWINT|1<<TWEN);
      while(!(TWCR & (1<<TWINT))); 
Как обычно, косяк на ровном месте. Спасибо большое отозвавшимся
Реклама
Ответить

Вернуться в «AVR»