Irinka
25.Декабрь.2023 14:03:45
1
Код программы
#define DATA_PIN 10 // пин данных
#define LATCH_PIN 11 // пин защелки
#define CLOCK_PIN 12 // пин тактов синхронизации
void setup() {
pinMode(DATA_PIN, INPUT);
pinMode(CLOCK_PIN, OUTPUT);
pinMode(LATCH_PIN, OUTPUT);
digitalWrite(LATCH_PIN, HIGH);
Serial.begin(9600);
}
byte readByte() {
byte byteR = 0;
digitalWrite(LATCH_PIN, LOW);
digitalWrite(LATCH_PIN, HIGH);
for (int i = 7; i >= 0; i--) {
if (digitalRead(DATA_PIN)) bitSet(byteR, i);
digitalWrite(CLOCK_PIN, HIGH);
digitalWrite(CLOCK_PIN, LOW);
}
return byteR;
}
void loop() {
Serial.println(in_165_shift(), BIN);
Serial.println(readByte(), BIN);
delay(1000);
}
byte in_165_shift() {
digitalWrite(LATCH_PIN, LOW);
digitalWrite(LATCH_PIN, HIGH);
return shiftIn(DATA_PIN, CLOCK_PIN, LSBFIRST );
}
В каких-то примерах используются три пина ардуино, в каких-то четыре.
Функция byte readByte() читает - 10000001
Функция byte in_165_shift() читает- 1000000
Как правильно?
Установите на вход “несимметричное” значение, например 193,
чтобы убедиться в правильности чтения, младший бит должен первым быть
2 лайка
@Irinka , я не большой специалист в этой микросхеме, но думаю, что заводить пин 15 на землю - очень плохая идея. Он нужен, чтобы не было ложных сдвигов.
У меня отлично работает вот такой
скетч
static constexpr uint8_t pinINH = 4;
static constexpr uint8_t pinCLK = 5;
static constexpr uint8_t pinSHLD = 6;
static constexpr uint8_t pinSO = 7;
inline void clkHIGH(void) { digitalWrite(pinCLK, HIGH); }
inline void shldLOW(void) { digitalWrite(pinSHLD, LOW); }
inline void shldHIGH(void) { digitalWrite(pinSHLD, HIGH); }
inline void inhLOW(void) { digitalWrite(pinINH, LOW); }
inline void inhHIGH(void) { digitalWrite(pinINH, HIGH); }
inline void shldTICK(void) { shldLOW(); shldHIGH(); }
uint8_t readData(void) {
shldTICK();
clkHIGH();
inhLOW();
const uint8_t result = shiftIn(pinSO, pinCLK, MSBFIRST);
inhHIGH();
return result;
}
void setup(void) {
pinMode(pinINH, OUTPUT);
inhHIGH();
pinMode(pinCLK, OUTPUT);
pinMode(pinSHLD, OUTPUT);
shldHIGH();
pinMode(pinSO, INPUT);
Serial.begin(9600);
Serial.println("Let's go on!");
}
void loop(void) {
static uint8_t oldValue = 0;
const uint8_t value = readData();
if (value != oldValue) {
Serial.print((value < 16) ? "0x0" : "0x");
Serial.println(value, HEX);
oldValue = value;
}
}
При вот такой
схеме
Всё показывает, при включении/выключении того или иного тумблера адекватно новое значение выводит.
А если убрать всю работу с INH и притянуть его к земле - тут же начинает лишний бит читать, попробуйте.
1 лайк
Irinka
25.Декабрь.2023 19:15:37
4
Спасибо. Всё таки 4 пина)
В теме Класс для чтения резисторной клавиатуры Вы сказали что:
constexpr
Указание компилятору, что все вычисления, которые там написаны, он должен выполнить сам, а в код вставить только готовый результат.
static constexpr uint8_t pinINH = 4;
А здесь же мы ничего не считаем, заранее знаем номер пина.
И почему static constexpr ?
а зачем в 15 строке, клок в HIGH выставляется?
что-то мне подсказывает если при inh=0 инвертировать такты то лишний бит пропадет
upd, был не прав - посмотрел на дш без очков, в очках все по-другому
На всякий случай , всё же проверьте, Ваша функция
readByte(), возможно, будет работать и на 3-х пинах, в Proteus глянул, всё норм. Микросхемы , чтобы проверить в железе - увы , нет
P.S. Если что, я ещё более
лишь Proteus и datasheet)))
te238s
26.Декабрь.2023 02:09:17
8
А не приладить ли сюда SPI? Так-то как раз его задача. Хоть аппаратный, хоть программный.
От SPI есть одно неприятное отличие: отсутствие CS.
Главная разница между:
#define A 11
// и
constexpr uint8_t А = 11;
в том, что во втором случае явно указан тип данных, а в первом - нет. это может сыграть свою роль, например, при вызове перегруженной функции. Да и просто, мне комфортнее, когда я знаю все типы
ХЗ. Но если этого не делать, то самый младший бит всегда ноль, попробуйте. Там в ДШ есть загадочная ремарка, которую я не понимаю:
Вполне возможно. Если будете пробовать, скажите, пожалуйста.
Так по сути shiftIn
и есть SPI
, а если честный SPI
присобачивать, то там придётся акромя MISO
, ещё и MOSI
задействовать, ему же надо что-то слать, чтобы ответ получить. Он же тоже сдвиговый регистр.
andriano:
отсутствие CS.
INH за него.
te238s
28.Декабрь.2023 08:04:49
11
Да ну бросьте. Ну будет он выдавать в “воздух” и что с того. SPI же не всегда двунаправленный нужен.
te238s:
и что с того
Да, ничего, просто пин на ровном месте занят. Если это ничему не мешает, то почему бы и нет?
Irinka
28.Декабрь.2023 20:25:34
13
А почему static,а не const?
constexpr
уже предполагает const
. Можно ещё и const
приписать, ошибкой не будет, но это “масляное масло”. А static
для глобальной переменной означает, что “не видно из других файлов ”. В данном случае это без разницы, но тут привычка работает: “нужно, чтобы было видно? нет? пиши static
”
4 лайка
Irinka
29.Декабрь.2023 18:48:25
15
Спасибо. С Наступающим новым годом)
Сейчас проверила
#include "setting_pins.h"
void setup() {
Serial.begin(9600);
}
void loop() {
Serial.println(num);
}
setting_pins.h"
static constexpr uint8_t num = 3;
Монитор порта печатает 3
Я что-то не так поняла про другие файлы?)
Полагаю, что имелись в виду “другие compilation unit”. Header-файл включаемый, при компиляции он образует единое целое с .cpp/.ino
А вот ежели взять a.cpp и b.cpp, в первый поместить static global variable, то из второго его низачто не увидеть.
2 лайка
BOOM
30.Декабрь.2023 12:32:29
18
@Irinka , пора заготовки к салатам делать.
Моя всегда так делает (и сегодня тоже).
Завтра только из холодильника достать и «замесить» нужно будет
Лайхаки от старпёров (Хотя лично я ещё очень молод в душе, а супруга моя - никогда и не старела!).
1 лайк