Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить

Re: Вопросы по С/С++ (СИ)

Чт фев 27, 2020 10:52:52

сделаю наверно так-же, сдвиг аккумулятора влево, и проверка бита переноса. а там - либо пишу палку в SDA, либо не пишу. Почему - на асме это очень просто, и займет десяток байт и пару регистров.
возвращать бит - их есть у меня - флаг в ССП и бит-адресуемая память.

Re: Вопросы по С/С++ (СИ)

Чт фев 27, 2020 10:53:48

кстати... не i_тый, а (7-i)_тый :)
глупость, как минимум в том, что это трудно понять... а если весь код так написан... сопьёшься пока разберёшься...

Re: Вопросы по С/С++ (СИ)

Чт фев 27, 2020 10:57:23

Ivanoff-iv писал(а):не i_тый, а (7-i)_тый
с языка сняли :)
на асме особой проблемы нет, там двигать в перенос можно легко.

Re: Вопросы по С/С++ (СИ)

Чт фев 27, 2020 11:08:41

... а если весь код так написан... сопьёшься пока разберёшься...

Ну, там даже для меня понятно, мне надо в основном, это. А весь остальной код меня мало интересует.
Если интересно

Re: Вопросы по С/С++ (СИ)

Чт фев 27, 2020 11:13:50

Shuspano, а надо ли вам это "переносить"? Это ж софтовый I2C, одна из функций оного. Уж реализаций нормальных сразу на асме Soft I2C хватает вроде для AVR.
А вообще очень похоже на вот эту реализацию: http://extremeelectronics.co.in/avr-tut ... -avr-mcus/
Только там нормально байт данных просто на 1 влево в цикле каждый раз сдвигается и "выпуливаются" по старшему биту (& 0x80) данные, а не на i бит двигается каждый раз (что бред конечно).

Добавлено after 1 minute 39 seconds:
На всякий случай код аналогичной ф-ии из индусского примера:
Код:
uint8_t SoftI2CWriteByte(uint8_t data)
{
        uint8_t i;

        for(i=0;i<8;i++)
        {
                SOFT_I2C_SCL_LOW;
                Q_DEL;

                if(data & 0x80)
                    SOFT_I2C_SDA_HIGH;
                else
                    SOFT_I2C_SDA_LOW;

                H_DEL;

                SOFT_I2C_SCL_HIGH;
                H_DEL;

                while((SCLPIN & (1<<SCL))==0);

                data=data<<1;
        }

        //The 9th clock (ACK Phase)
        SOFT_I2C_SCL_LOW;
        Q_DEL;

        SOFT_I2C_SDA_HIGH;
        H_DEL;

        SOFT_I2C_SCL_HIGH;
        H_DEL;

        uint8_t ack=!(SDAPIN & (1<<SDA));

        SOFT_I2C_SCL_LOW;
        H_DEL;

        return ack;
}

Чуть лучше имхо будет )

Re: Вопросы по С/С++ (СИ)

Чт фев 27, 2020 11:16:25

Shuspano, а надо ли вам это "переносить"? Это ж софтовый I2C, одна из функций оного. Уж реализаций нормальных сразу на асме Soft I2C хватает вроде для AVR.
А вообще очень похоже на вот эту реализацию: http://extremeelectronics.co.in/avr-tut ... -avr-mcus/
Только там нормально байт данных просто на 1 влево в цикле каждый раз сдвигается и "выпуливаются" по старшему биту (& 0x80) данные, а не на i бит двигается каждый раз (что бред конечно).

Это не для AVR, это для 8051. У AVR аппаратный I2C есть. Софтовые реализации для 8051 непосредственно на астме - да, тоже есть, и я их уже попробовал. А этот пример пошел в протеусе, и есть надежда что получится лучше остальных
Последний раз редактировалось Shuspano Чт фев 27, 2020 11:21:20, всего редактировалось 1 раз.

Re: Вопросы по С/С++ (СИ)

Чт фев 27, 2020 11:18:34

еще лучше делать цикл по маске, которую и использовать для выделения бита. отдельная переменная-счетчик в этом случае не нужна, количество телодвижений минимально:
Код:
for(uint8_t mask=0x80; mask; mask >>=1){
  if (Data & mask) ...
}

Re: Вопросы по С/С++ (СИ)

Чт фев 27, 2020 11:25:46

Это не для AVR, это для 8051. У AVR аппаратный I2C есть.

Не у всех AVR есть. Да и реализация выше в общем-то особо к платформе не привязана.

Re: Вопросы по С/С++ (СИ)

Чт фев 27, 2020 11:39:23

Не у всех AVR есть.

Ну в основном есть. Всегда можно распотрошить ардуину. 8051 с I2C можно пересчитать по пальцам одной руки, и часто они не от мира сего по устройству
Да и реализация выше в общем-то особо к платформе не привязана.

Да, действительно. Просто и понятно. Спасибо.

А не поможете еще разок, объясните эту конструкцию?
Код:
      while((SCLPIN & (1<<SCL))==0);
      
      if(SDAPIN &(1<<SDA))
         data|=(0x80>>i);

Re: Вопросы по С/С++ (СИ)

Чт фев 27, 2020 13:24:59

Shuspano писал(а):на астме
астма - это болезнь.
а ассемблер сокращенно будет асм.

Re: Вопросы по С/С++ (СИ)

Чт фев 27, 2020 13:29:22

Shuspano писал(а):объясните эту конструкцию?
    
Код:
 while((SCLPIN & (1<<SCL))==0);
бесконечное ожидание момента, когда бит SCL в регистре (?) SCLPIN станет равным 1.
Код:
if(SDAPIN &(1<<SDA))
         data|=(0x80>>i);
если бит SDA в регистре SDAPIN установлен, то установить i-й слева (повбывал бы!) бит в переменной data

Re: Вопросы по С/С++ (СИ)

Пт фев 28, 2020 16:15:04

ARV писал(а):цикл по маске
съел на 6 байт побольше флеша, сравнительно с циклом, где маска не меняется.
Код:
//    uint8_t bit = 8;
//    while(bit--){
//       draw_pixel(x, y, byte & 0x80, width);
//       byte <<= 1;
//       y++;
//    }
// + 6 bytes FLASH
   for (uint8_t mask = 0x80; mask; mask >>=1)   {
      draw_pixel(x, y, byte & mask, width);
      y++;
   }
А жаль. Вариант ARV выглядит эстетичнее.
Последний раз редактировалось MOHCTEP Пт фев 28, 2020 16:42:13, всего редактировалось 2 раз(а).

Re: Вопросы по С/С++ (СИ)

Пт фев 28, 2020 16:20:10

даже любопытно увидеть листинги вариантов :)

Re: Вопросы по С/С++ (СИ)

Пт фев 28, 2020 16:32:39

MOHCTEP, Вы не те алгоритмы сравниваете. Что сдвиг маски, что сдвиг byte - это практически одно и тоже, видимо с неболшими нюансами

А вот тут (собственно от этой печки идет пляска), сдвиг Byte производится на i раз при каждой итерации цикла. Так как отсутствует инструкция сдвига на несколько бит, то скомпилится цикл в цикле и почем зря.

Добавлено after 7 minutes 26 seconds:
Возможно, основное отличие тут
между этим
Код:
byte & 0x80

и этим
Код:
byte & mask

В первом случае всегда проверяется старший бит в переменной, а во втором побитовое И между двумя переменными.

Re: Вопросы по С/С++ (СИ)

Пт фев 28, 2020 17:12:36

ARV, :beer:
Z_h_e, да-да, я видел начало этой эпопеи. Там все объяснили, рассказали, вот канделябр только жалко - раритет все таки. :)) Понравился сам алгоритм от ARV. Простой, изящный, легко читается.
Спасибо за ответ. Теперь понятно, куда "лишние" байты делись.

Re: Вопросы по С/С++ (СИ)

Сб мар 14, 2020 16:16:12

помогите понять как читает строчки атмега и сделать задержку...

есть код
Код:
1начало
2...
3...
4for (int q = 0; q < 12;q++ ) {
5  ...
6  ...
7 refreshAll(); }    // вывод на экран
8...
9...
10...
11конец


атмега выполнила 1 стр. 2, 3, 4-7,4-7...( и так 12 раз) 8,9,10,11 затем 1,2 и т.д

правильно!?

добавим в код функцию millis();
Спойлерmillis() – Возвращает количество миллисекунд, прошедших с запуска. Возвращает unsigned long, от 1 до 4 294 967 295 миллисекунд (~50 суток), имеет разрешение 1 миллисекунда, после переполнения сбрасывается в 0. Работает на системном таймере Timer 0


Код:
1начало
2...
3...
4for (int q = 0; q < 12;q++ ) {
5  ...
6  ...
7 refreshAll();     // вывод на экран
8 millis() % 75==0; } //нужна здесь пауза 900мс/12=75мс
9...
10...
11конец



как бы я хотел

атмега выполнила 1 стр. 2, 3, 4-7 8 стр. так как millis не равно нулю атмега выполняет 9,10,11,1,2 (прошло 75 мс) и millis равно нулю, амега выполнит 4-7,8 и вернется где прервала выполнение ко 2 стр.3,9,10,11,1,2 и т.д


на практике все не так и я чего то не понимаю... :dont_know:
https://www.radiokot.ru/forum/viewtopic ... 2#p3799892

Re: Вопросы по С/С++ (СИ)

Сб мар 14, 2020 18:03:10

Serzh2000 писал(а): затем 1,2 и т.д

правильно!?
неправильно
Serzh2000 писал(а):8 millis() % 75==0; } //нужна здесь пауза 900мс/12=75мс
millis к паузе вообще отношения не имеет. Собственно, если бы Вы прочитали сами то, что процитировали по этому поводу, то тоже поняли бы это.

Re: Вопросы по С/С++ (СИ)

Сб мар 14, 2020 18:45:51

неправильно


??? а как же контролер читает

millis к паузе вообще отношения не имеет.


Код:
1начало
2...
3...
4for (int q = 0; q < 12;q++ ) {
5  ...
6  ...
7 refreshAll();     // вывод на экран
8 my_millis(10);  } //нужна здесь пауза
9...
10...
11конец
12 void my_millis(uint32_t us) {
13 uint32_t tmr = millis();
14  while (millis() - tmr < us);
15 }


вот так пауза есть, но она как и функция delay(); все тормозит
Спойлер//---------- ВЫВОД ПОЛНЫХ ЧАСОВ
void showClockMed(){ //

clrAll(); // очищает экран полностью (смотрим вкладку "max7219.h")


int flag = millis() % 1000; // счетчик будет считать до тысячи и все заново
if ( flag > 500) { setCol(10, 0x24);} // если флаг больше 500, рисуем точки



// выводим цифры, которые не изменились
if (s0 == lasts0){showDigit(s0, 28, dig3x7s);}
if (s1 == lasts1){showDigit(s1, 24, dig3x7s);}
if (m0 == lastm0){showDigit(m0, 17, dig4x8);}
if (m1 == lastm1){showDigit(m1, 12, dig4x8);}
if (h0 == lasth0){showDigit(h0, 5, dig4x8);}
if ((h1>0)&&(h1 == lasth1)){showDigit(h1, 0, dig4x8);}



for (int q = 0; q < 12; q++ ) { // а теперь цикл по изменившимся цифрам

if (s0 != lasts0){showDigit( s0 * 12 + q, 28, dig3x7q);}
if (s1 != lasts1){showDigit( s1 * 12 + q, 24, dig3x7q);}
if (m0 != lastm0){showDigit( m0 * 12 + q, 17, dig4x8q);}
if (m1 != lastm1){showDigit( m1 * 12 + q, 12, dig4x8q);}
if (h0 != lasth0){showDigit( h0 * 12 + q, 5, dig4x8q);}
if ((h1>0)&&(h1 != lasth1)){showDigit( h1 * 12 + q, 0, dig4x8q);}




refreshAll(); // обновляем экран после каждой строки
my_millis(25); // задержка для плавного вывода цифр
}
lasth1 = h1; lasth0 = h0; lastm1 = m1; lastm0 = m0; lasts1 = s1; lasts0 = s0; // для того чтобы знать изменилась цифра или нет

}
//----------


void my_millis(uint32_t us) {
uint32_t tmr = millis();
while (millis() - tmr < us);
}

Re: Вопросы по С/С++ (СИ)

Сб мар 14, 2020 19:02:28

У Вас противоречивые хотелки - и паузу хотите, и чтобы не тормозило. В последовательно выполняющемся коде так не бывает.

Если не хотите тормозов, просто не используйте задержки вообще. Ни в виде отдельной delay() функции, ни в виде аналога на основе millis() - без разницы, каким способом контроллер будет висеть заказанное время в одном месте.

Re: Вопросы по С/С++ (СИ)

Сб мар 14, 2020 19:26:39

висеть заказанное время в одном месте.

совсем никак ? чтоб не висела , а выполняла другие действия как только придет время все бросила и выполнила отрисовку цифры, а потом с ного выполняла другие действия...
Ответить