возвращать бит - их есть у меня - флаг в ССП и бит-адресуемая память.
Вопросы по С/С++ (СИ)
- Сообщения: 270
- Зарегистрирован: Вс окт 20, 2019 13:03:56
сделаю наверно так-же, сдвиг аккумулятора влево, и проверка бита переноса. а там - либо пишу палку в SDA, либо не пишу. Почему - на асме это очень просто, и займет десяток байт и пару регистров.
возвращать бит - их есть у меня - флаг в ССП и бит-адресуемая память.
возвращать бит - их есть у меня - флаг в ССП и бит-адресуемая память.
- Реклама
кстати... не i_тый, а (7-i)_тый 
глупость, как минимум в том, что это трудно понять... а если весь код так написан... сопьёшься пока разберёшься...
глупость, как минимум в том, что это трудно понять... а если весь код так написан... сопьёшься пока разберёшься...
Для тех, кто не учил магию мир полон физики 
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
с языка снялиIvanoff-iv писал(а):не i_тый, а (7-i)_тый
на асме особой проблемы нет, там двигать в перенос можно легко.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Сообщения: 270
- Зарегистрирован: Вс окт 20, 2019 13:03:56
[uquote="Ivanoff-iv",url="/forum/viewtopic.php?p=3797743#p3797743"]... а если весь код так написан... сопьёшься пока разберёшься...[/uquote]
Ну, там даже для меня понятно, мне надо в основном, это. А весь остальной код меня мало интересует.
Если интересно
Ну, там даже для меня понятно, мне надо в основном, это. А весь остальной код меня мало интересует.
Если интересно
- Сообщения: 1978
- Зарегистрирован: Ср июл 17, 2013 13:55:57
Shuspano, а надо ли вам это "переносить"? Это ж софтовый I2C, одна из функций оного. Уж реализаций нормальных сразу на асме Soft I2C хватает вроде для AVR.
А вообще очень похоже на вот эту реализацию: http://extremeelectronics.co.in/avr-tut ... -avr-mcus/
Только там нормально байт данных просто на 1 влево в цикле каждый раз сдвигается и "выпуливаются" по старшему биту (& 0x80) данные, а не на i бит двигается каждый раз (что бред конечно).
Добавлено after 1 minute 39 seconds:
На всякий случай код аналогичной ф-ии из индусского примера:
Чуть лучше имхо будет )
А вообще очень похоже на вот эту реализацию: 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;
}- Реклама
- Сообщения: 270
- Зарегистрирован: Вс окт 20, 2019 13:03:56
[uquote="NStorm",url="/forum/viewtopic.php?p=3797756#p3797756"]Shuspano, а надо ли вам это "переносить"? Это ж софтовый I2C, одна из функций оного. Уж реализаций нормальных сразу на асме Soft I2C хватает вроде для AVR.
А вообще очень похоже на вот эту реализацию: http://extremeelectronics.co.in/avr-tut ... -avr-mcus/
Только там нормально байт данных просто на 1 влево в цикле каждый раз сдвигается и "выпуливаются" по старшему биту (& 0x80) данные, а не на i бит двигается каждый раз (что бред конечно).[/uquote]
Это не для AVR, это для 8051. У AVR аппаратный I2C есть. Софтовые реализации для 8051 непосредственно на астме - да, тоже есть, и я их уже попробовал. А [url="http://saeedsolutions.blogspot.com/2012 ... 7-rtc.html]этот[/url] пример пошел в протеусе, и есть надежда что получится лучше остальных
А вообще очень похоже на вот эту реализацию: http://extremeelectronics.co.in/avr-tut ... -avr-mcus/
Только там нормально байт данных просто на 1 влево в цикле каждый раз сдвигается и "выпуливаются" по старшему биту (& 0x80) данные, а не на i бит двигается каждый раз (что бред конечно).[/uquote]
Это не для AVR, это для 8051. У AVR аппаратный I2C есть. Софтовые реализации для 8051 непосредственно на астме - да, тоже есть, и я их уже попробовал. А [url="http://saeedsolutions.blogspot.com/2012 ... 7-rtc.html]этот[/url] пример пошел в протеусе, и есть надежда что получится лучше остальных
Последний раз редактировалось Shuspano Чт фев 27, 2020 11:21:20, всего редактировалось 1 раз.
еще лучше делать цикл по маске, которую и использовать для выделения бита. отдельная переменная-счетчик в этом случае не нужна, количество телодвижений минимально:
Код: Выделить всё
for(uint8_t mask=0x80; mask; mask >>=1){
if (Data & mask) ...
}если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Сообщения: 1978
- Зарегистрирован: Ср июл 17, 2013 13:55:57
[uquote="Shuspano",url="/forum/viewtopic.php?p=3797760#p3797760"]Это не для AVR, это для 8051. У AVR аппаратный I2C есть.[/uquote]
Не у всех AVR есть. Да и реализация выше в общем-то особо к платформе не привязана.
Не у всех AVR есть. Да и реализация выше в общем-то особо к платформе не привязана.
- Сообщения: 270
- Зарегистрирован: Вс окт 20, 2019 13:03:56
[uquote="NStorm",url="/forum/viewtopic.php?p=3797767#p3797767"]Не у всех AVR есть.[/uquote]
Ну в основном есть. Всегда можно распотрошить ардуину. 8051 с I2C можно пересчитать по пальцам одной руки, и часто они не от мира сего по устройству
А не поможете еще разок, объясните эту конструкцию?
Ну в основном есть. Всегда можно распотрошить ардуину. 8051 с I2C можно пересчитать по пальцам одной руки, и часто они не от мира сего по устройству
Да, действительно. Просто и понятно. Спасибо.Да и реализация выше в общем-то особо к платформе не привязана.
А не поможете еще разок, объясните эту конструкцию?
Код: Выделить всё
while((SCLPIN & (1<<SCL))==0);
if(SDAPIN &(1<<SDA))
data|=(0x80>>i);астма - это болезнь.Shuspano писал(а):на астме
а ассемблер сокращенно будет асм.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
бесконечное ожидание момента, когда бит SCL в регистре (?) SCLPIN станет равным 1.Shuspano писал(а):объясните эту конструкцию?
Код: Выделить всё
while((SCLPIN & (1<<SCL))==0);
Код: Выделить всё
if(SDAPIN &(1<<SDA))
data|=(0x80>>i);если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Сообщения: 768
- Зарегистрирован: Вс янв 19, 2014 00:55:09
съел на 6 байт побольше флеша, сравнительно с циклом, где маска не меняется.ARV писал(а):цикл по маске
Код: Выделить всё
// 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++;
}
Последний раз редактировалось MOHCTEP Пт фев 28, 2020 16:42:13, всего редактировалось 2 раза.
даже любопытно увидеть листинги вариантов 
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
MOHCTEP, Вы не те алгоритмы сравниваете. Что сдвиг маски, что сдвиг byte - это практически одно и тоже, видимо с неболшими нюансами
А вот тут (собственно от этой печки идет пляска), сдвиг Byte производится на i раз при каждой итерации цикла. Так как отсутствует инструкция сдвига на несколько бит, то скомпилится цикл в цикле и почем зря.
Добавлено after 7 minutes 26 seconds:
Возможно, основное отличие тут
между этим
и этим
В первом случае всегда проверяется старший бит в переменной, а во втором побитовое И между двумя переменными.
А вот тут (собственно от этой печки идет пляска), сдвиг Byte производится на i раз при каждой итерации цикла. Так как отсутствует инструкция сдвига на несколько бит, то скомпилится цикл в цикле и почем зря.
Добавлено after 7 minutes 26 seconds:
Возможно, основное отличие тут
между этим
Код: Выделить всё
byte & 0x80Код: Выделить всё
byte & mask- Сообщения: 768
- Зарегистрирован: Вс янв 19, 2014 00:55:09
ARV,
Z_h_e, да-да, я видел начало этой эпопеи. Там все объяснили, рассказали, вот канделябр только жалко - раритет все таки.
Понравился сам алгоритм от ARV. Простой, изящный, легко читается.
Спасибо за ответ. Теперь понятно, куда "лишние" байты делись.
Z_h_e, да-да, я видел начало этой эпопеи. Там все объяснили, рассказали, вот канделябр только жалко - раритет все таки.
Спасибо за ответ. Теперь понятно, куда "лишние" байты делись.
помогите понять как читает строчки атмега и сделать задержку...
есть код
атмега выполнила 1 стр. 2, 3, 4-7,4-7...( и так 12 раз) 8,9,10,11 затем 1,2 и т.д
правильно!?
добавим в код функцию millis();
как бы я хотел
атмега выполнила 1 стр. 2, 3, 4-7 8 стр. так как millis не равно нулю атмега выполняет 9,10,11,1,2 (прошло 75 мс) и millis равно нулю, амега выполнит 4-7,8 и вернется где прервала выполнение ко 2 стр.3,9,10,11,1,2 и т.д
на практике все не так и я чего то не понимаю...
https://www.radiokot.ru/forum/viewtopic ... 2#p3799892
есть код
Код: Выделить всё
1начало
2...
3...
4for (int q = 0; q < 12;q++ ) {
5 ...
6 ...
7 refreshAll(); } // вывод на экран
8...
9...
10...
11конецправильно!?
добавим в код функцию 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 и т.д
на практике все не так и я чего то не понимаю...
https://www.radiokot.ru/forum/viewtopic ... 2#p3799892
неправильноSerzh2000 писал(а): затем 1,2 и т.д
правильно!?
millis к паузе вообще отношения не имеет. Собственно, если бы Вы прочитали сами то, что процитировали по этому поводу, то тоже поняли бы это.Serzh2000 писал(а):8 millis() % 75==0; } //нужна здесь пауза 900мс/12=75мс
??? а как же контролер читаетнеправильно
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 }Спойлер
//----------------------------------------------------------------------- ВЫВОД ПОЛНЫХ ЧАСОВ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);
}
У Вас противоречивые хотелки - и паузу хотите, и чтобы не тормозило. В последовательно выполняющемся коде так не бывает.
Если не хотите тормозов, просто не используйте задержки вообще. Ни в виде отдельной delay() функции, ни в виде аналога на основе millis() - без разницы, каким способом контроллер будет висеть заказанное время в одном месте.
Если не хотите тормозов, просто не используйте задержки вообще. Ни в виде отдельной delay() функции, ни в виде аналога на основе millis() - без разницы, каким способом контроллер будет висеть заказанное время в одном месте.
совсем никак ? чтоб не висела , а выполняла другие действия как только придет время все бросила и выполнила отрисовку цифры, а потом с ного выполняла другие действия...висеть заказанное время в одном месте.



