Работа с TM1639
- Войдите на сайт для отправки комментариев
Пт, 01/01/2021 - 17:17
Добрый день.
Пробую писать скетч для работы с TM1639 (библиотеки под него нет), но что-то не получается.
int dataPin = 8; //Передача данных
int clockPin = 9; //Синхронизация передачи данных
int strobePin = 10; //Chip select,выбор микросхемы, разрешение/запрет записи данных
byte info[] = {B00001111, B00001111, B00000000, B00000000, //индикатор1 горит, 2 не горит
B00001111, B00001111, B00000000, B00000000,
B00001111, B00001111, B00000000, B00000000,
B00001111, B00001111, B00000000, B00000000,
}; //Значения для 8 сегментов, загораются через один
/************
Байт передачи D7 D6 D5 D4 D3 D2 D1 D0
первый 0 0 0 0 D C B A
второй 0 0 0 0 H G F E
************/
void setup() {
pinMode(dataPin, OUTPUT); //Настроим пины как выходы
pinMode(clockPin, OUTPUT);
pinMode(strobePin, OUTPUT);
digitalWrite(strobePin, HIGH); //Запретим запись в TM1639
delay(1); //Время на запуск TM1639 после подачи питания
digitalWrite(strobePin, LOW); //Первый полученый байт - инструкция
/******************
Команда B7 B6 B5 B4 B3 B2 B1 B0
Команда передачи, приема данных 0 1 0 0 0 0 0 0
Команда управления работы дисплея 1 0 0 0 0 0 0 0
Команда указания адреса загружаемых данных для отображения 1 1 0 0 0 0 0 0
******************/
send(B01000000); //Начать прием данных
send(B11000000); //Адрес первого индикатора
send(info[0]);
send(B11000001); //Адрес первого индикатора
send(info[1]);
digitalWrite(strobePin, HIGH);
}
void loop() {
}
void send(byte data) //Функция передачи данных
{
for (int i = 0; i < 8; i++) { //Переберем биты отправляемого байта
digitalWrite(clockPin, LOW); //Установим синхр. вывод в 0
digitalWrite(dataPin, data & 1 ? HIGH : LOW); //В зависимости от значения бита выставим 0/1 на выводе Data
data >>= 1; //Выберем следующий бит
digitalWrite(clockPin, HIGH); //TM1639 считывает данные по фронту сигнала синхр. вывода
delay(1);
}
}
После загрузки индикаторы не горят
Ссылка на сайт с примером
И даташит
На сайте с примером вроде есть библиотеки. Да и без библиотек они нормально работают. Перед отправкой данных, должна быть инициализация и настройка регистров. 1639 похожа на 1650. Посмотрите здесь http://arduino.ru/forum/programmirovanie/kontroller-led-i-klaviatury-fd650v-kak-im-upravlyat#comment-232263 может там более понятно как с ним работать. И сюда загляните https://github.com/maxint-rd/TM16xx
Нет, не помогло, видимо я не понимаю чего-то фундаментального.
Можно на примере моего кода, что там не хватает? Перечитал даташит, вроде все делаю правильно:
1. Отправляю команду на запись данных в регистр
2. Отправляю адрес сегмента
3. Отправляю что там и как должно гореть
Нет, не помогло, видимо я не понимаю чего-то фундаментального.
Можно на примере моего кода, что там не хватает? Перечитал даташит, вроде все делаю правильно:
1. Отправляю команду на запись данных в регистр
2. Отправляю адрес сегмента
3. Отправляю что там и как должно гореть
Сначала нужно инициализировать. Указать яркость, режим работы включен или выключен и что-то еще должно быть. Во всяком случае в 1650 так. Без этого он не включится.
Работает, пока только на вывод сообщений из массива info[]
Может кому поможет
int dataPin = 8; //Передача данных int clockPin = 9; //Синхронизация передачи данных int strobePin = 10; //Chip select,выбор микросхемы, разрешение/запрет записи данных byte info[] = {B10000001, B10000001, B10000001, B10000001, //данные для вывода B10000001, B10000001, B10000001, B11111111, }; void setup() { pinMode(dataPin, OUTPUT); //Настроим пины как выходы pinMode(clockPin, OUTPUT); pinMode(strobePin, OUTPUT); digitalWrite(strobePin, HIGH); //Запретим запись в TM1639 digitalWrite(clockPin, HIGH); //Уровень яркости 2/16 delay(1); //Время на запуск TM1639 после подачи питания //////////////////////////////////////// инициализация sendCommand(0x40); //Аналогично B01000000 - Запись данных для отображения sendCommand(B10000001); //////////////////////////////////////// //////////////////////////////////////// очистка буфера микросхемы digitalWrite(strobePin, LOW); send(0x00); //Команда из нулей (первое число после strobePin в 0 - воспринмается как команда) for (int i = 0; i < 16; i++) { //Перебираем 16 байт что бы обнулить состояние всех 8 сегментов send(0x00); //Отправляем 16 байт, т.к. 1 сегмент управляется 2 полубайтами } digitalWrite(strobePin, HIGH); //////////////////////////////////////// //////////////////////////////////////// выведем что-нибудь на экран draw(); } void loop() { } void sendCommand(byte cmd) //Функция передачи команды { digitalWrite(strobePin, LOW); //Разрешим запись выбрав микросхему send(cmd); //Данные для передачи в микросхему digitalWrite(strobePin, HIGH); //Запретим запись } void send(byte data) //Функция передачи данных { for (int i = 0; i < 8; i++) { //Переберем биты отправляемого байта digitalWrite(clockPin, LOW); //Установим синхр. вывод в 0 digitalWrite(dataPin, data & 1 ? HIGH : LOW); //В зависимости от значения бита выставим 0/1 на выводе Data data >>= 1; //Выберем следующий бит digitalWrite(clockPin, HIGH); //TM1639 считывает данные по фронту сигнала синхр. вывода delay(1); } } void draw() { //Функция вывода данных for (int i = 0; i < 8; i++) { int pos = B11000000; //Команда указания адреса загружаемых данных для отображения int data; //Вспомогательная переменная 1 int data2; //Вспомогательная переменная 2 for (int a = 0; a < 4; a++) { //Переберем первые 4 значащих байта bitWrite(data, a, bitRead(info[a], i)); //и запишем их в первую вспомогательную переменную } for (int a = 4; a < 8; a++) { bitWrite(data2, a - 4, bitRead(info[a], i)); //а вторые во вторую переменную } sendData((pos + i * 2), data); //отправим первый полубайт данных по первому адресу сегмента sendData((pos + i * 2 + 1), data2); //отправим второй полубай по второму адресу сегмента } sendCommand(0x40); //Аналогично B01000000 - Запись данных для отображения sendCommand(B10001000); //Команда "Включить дисплей" } void sendData(byte address, byte data) //Передадим данные по адресу { // sendCommand(0x42); //ЗАЧЕМ??? digitalWrite(strobePin, LOW); send(0x00 | address); //Побитовое "или", по сути задаем адрес сегмента send(data); //Передаем данные для конкретного адреса digitalWrite(strobePin, HIGH); }Что бы темы не плодить... Пытаюсь прочесть состояние нажатия кнопок, но что-то не читается...
Что я делаю не так?
Чтение идет в цикле void loop()
int dataPin = 8; //Передача данных int clockPin = 9; //Синхронизация передачи данных int strobePin = 10; //Chip select,выбор микросхемы, разрешение/запрет записи данных byte info[] = {B11111111, B11111111, B11111111, B11111111, //данные для вывода B11111111, B11111111, B11111111, B11111111, }; void setup() { Serial.begin(9600); pinMode(dataPin, OUTPUT); //Настроим пины как выходы pinMode(clockPin, OUTPUT); pinMode(strobePin, OUTPUT); digitalWrite(strobePin, HIGH); //Запретим запись в TM1639 digitalWrite(clockPin, HIGH); //Тактовый пин в 1 delay(1); //Время на запуск TM1639 после подачи питания //////////////////////////////////////// инициализация sendCommand(0x40); //Аналогично B01000000 - Запись данных для отображения sendCommand(B10000001); //Яркость дисплея 2/16 //////////////////////////////////////// //////////////////////////////////////// очистка буфера микросхемы digitalWrite(strobePin, LOW); send(0x00); //Команда из нулей (первое число после strobePin в 0 - воспринмается как команда) for (int i = 0; i < 16; i++) { //Перебираем 16 байт что бы обнулить состояние всех 8 сегментов send(0x00); //Отправляем 16 байт, т.к. 1 сегмент управляется 2 полубайтами } digitalWrite(strobePin, HIGH); //////////////////////////////////////// //////////////////////////////////////// выведем что-нибудь на экран draw(); } void loop() { delay(500); pinMode(dataPin, INPUT); digitalWrite(clockPin, LOW); digitalWrite(strobePin, LOW); Serial.println(); sendCommand(0x42); //Команда на запрос состояния кнопок for (int i = 0; i < 16; i++) { //Перебираем 16 байт digitalWrite(clockPin, HIGH); Serial.print(digitalRead(dataPin)); Serial.print(" "); digitalWrite(clockPin, LOW); } digitalWrite(strobePin, HIGH); pinMode(dataPin, OUTPUT); } void sendCommand(byte cmd) //Функция передачи команды { digitalWrite(strobePin, LOW); //Разрешим запись выбрав микросхему send(cmd); //Данные для передачи в микросхему digitalWrite(strobePin, HIGH); //Запретим запись } void send(byte data) //Функция передачи данных { for (int i = 0; i < 8; i++) { //Переберем биты отправляемого байта digitalWrite(clockPin, LOW); //Установим синхр. вывод в 0 digitalWrite(dataPin, data & 1 ? HIGH : LOW); //В зависимости от значения бита выставим 0/1 на выводе Data data >>= 1; //Выберем следующий бит digitalWrite(clockPin, HIGH); //TM1639 считывает данные по фронту сигнала синхр. вывода delay(1); } } void draw() { //Функция вывода данных for (int i = 0; i < 8; i++) { int pos = B11000000; //Команда указания адреса загружаемых данных для отображения int data; //Вспомогательная переменная 1 int data2; //Вспомогательная переменная 2 for (int a = 0; a < 4; a++) { //Переберем первые 4 значащих байта bitWrite(data, a, bitRead(info[a], i)); //и запишем их в первую вспомогательную переменную } for (int a = 4; a < 8; a++) { bitWrite(data2, a - 4, bitRead(info[a], i)); //а вторые во вторую переменную } sendData((pos + i * 2), data); //отправим первый полубайт данных по первому адресу сегмента sendData((pos + i * 2 + 1), data2); //отправим второй полубай по второму адресу сегмента } sendCommand(0x40); //Аналогично B01000000 - Запись данных для отображения sendCommand(B10001000); //Команда "Включить дисплей" } void sendData(byte address, byte data) //Передадим данные по адресу { // sendCommand(0x42); //ЗАЧЕМ??? digitalWrite(strobePin, LOW); send(0x00 | address); //Побитовое "или", по сути задаем адрес сегмента send(data); //Передаем данные для конкретного адреса digitalWrite(strobePin, HIGH); }Выдержка из даташита, вроде все верно, отправил команду 0х42 на считывание, считал 2 байта даных
Немного поправил функцию loop, остальное без изменений, но все так же не работает, в мониторе порта только 0
void loop() { delay(500); digitalWrite(clockPin, LOW); Serial.println(); digitalWrite(strobePin, LOW); send(0x42); //Команда на запрос состояния кнопок delay(1); pinMode(dataPin, INPUT); delay(1); for (int i = 0; i < 8; i++) { //Перебираем 8 байт digitalWrite(clockPin, HIGH); delay(1); Serial.print(digitalRead(dataPin)); Serial.print(" "); digitalWrite(clockPin, LOW); } delay(1); for (int p = 0; p < 8; p++) { //Перебираем 8 байт digitalWrite(clockPin, HIGH); delay(1); Serial.print(digitalRead(dataPin)); Serial.print(" "); digitalWrite(clockPin, LOW); } pinMode(dataPin, OUTPUT); digitalWrite(strobePin, HIGH); }Вопрос снят, все работает.
Может кому пригодится
https://github.com/MaximAivazov/Arduino-TM1639.git