Arduino nano и MAX7456
- Войдите на сайт для отправки комментариев
Втр, 08/11/2016 - 11:37
Здравствуйте уважаемые жители и гости форума. Прошу помощи - разобратья в коде.
Я собираю связку Ардуино и OSD меню генератор MAX7456.
Вот код рабочий:
#define VSYNC 2 // INT0 #define DATAOUT 11//MOSI #define DATAIN 12//MISO #define SPICLOCK 13//sck #define MAX7456SELECT 10//ss #define DMM_reg 0x04 #define DMAH_reg 0x05 #define DMAL_reg 0x06 #define DMDI_reg 0x07 #define VM0_reg 0x00 #define VM1_reg 0x01 #define VIDEO_BUFFER_DISABLE 0x01 #define MAX7456_RESET 0x02 #define VERTICAL_SYNC_NEXT_VSYNC 0x04 #define OSD_ENABLE 0x08 #define SYNC_MODE_AUTO 0x00 #define SYNC_MODE_INTERNAL 0x30 #define SYNC_MODE_EXTERNAL 0x20 #define VIDEO_MODE_PAL 0x40 #define VIDEO_MODE_NTSC 0x00 #define BLINK_DUTY_CYCLE_50_50 0x00 #define BLINK_DUTY_CYCLE_33_66 0x01 #define BLINK_DUTY_CYCLE_25_75 0x02 #define BLINK_DUTY_CYCLE_75_25 0x03 #define BLINK_TIME_0 0x00 #define BLINK_TIME_1 0x04 #define BLINK_TIME_2 0x08 #define BLINK_TIME_3 0x0C #define BACKGROUND_BRIGHTNESS_0 0x00 #define BACKGROUND_BRIGHTNESS_7 0x10 #define BACKGROUND_BRIGHTNESS_14 0x20 #define BACKGROUND_BRIGHTNESS_21 0x30 #define BACKGROUND_BRIGHTNESS_28 0x40 #define BACKGROUND_BRIGHTNESS_35 0x50 #define BACKGROUND_BRIGHTNESS_42 0x60 #define BACKGROUND_BRIGHTNESS_49 0x70 #define BACKGROUND_MODE_GRAY 0x40 #define CLEAR_display 0x04 #define CLEAR_display_vert 0x06 #define END_string 0xff #define ENABLE_display 0x08 #define ENABLE_display_vert 0x0c #define MAX7456_reset 0x02 #define DISABLE_display 0x00 #define WHITE_level_80 0x03 #define WHITE_level_90 0x02 #define WHITE_level_100 0x01 #define WHITE_level_120 0x00 #define MAX_screen_size 390 #define MAX_screen_rows 16 byte spi_junk, eeprom_junk; int x; ////////////////////////////////////////////////////////////// void setup() { Serial.begin(115200); Serial.flush(); pinMode(MAX7456SELECT,OUTPUT); digitalWrite(MAX7456SELECT,HIGH); pinMode(DATAOUT, OUTPUT); pinMode(DATAIN, INPUT); pinMode(SPICLOCK,OUTPUT); pinMode(VSYNC, INPUT); SPCR = (1<<SPE)|(1<<MSTR); spi_junk=SPSR; spi_junk=SPDR; delay(250); digitalWrite(MAX7456SELECT,LOW); spi_transfer(VM0_reg); spi_transfer(MAX7456_reset); digitalWrite(MAX7456SELECT,HIGH); delay(500); digitalWrite(MAX7456SELECT,LOW); for (x = 0; x < MAX_screen_rows; x++) { spi_transfer(x + 0x10); spi_transfer(WHITE_level_90); } spi_transfer(VM0_reg); spi_transfer(VERTICAL_SYNC_NEXT_VSYNC|OSD_ENABLE|VIDEO_MODE_PAL); spi_transfer(VM1_reg); spi_transfer(BLINK_TIME_3); digitalWrite(MAX7456SELECT,HIGH); delay(100); } ///////////////////////////////////////////////////////////// void loop() { OSD_write_to_screen("http://compcar.ru", 2, 1, 0,1); OSD_write_to_screen("http://compcar.ru", 2, 2, 0,0); OSD_write_to_screen("Привет!!!", 11, 6, 1,1); OSD_write_to_screen("ПРИВЕТ!!!", 11, 7, 1,0); OSD_write_to_screen("http://compcar.ru", 13, 13, 0,1); OSD_write_to_screen("http://compcar.ru", 13, 14, 0,0); delay(5000); } ////////////////////////////////////////////////////////////// byte spi_transfer(volatile byte data) { SPDR = data; while (!(SPSR & (1<<SPIF))) { }; return SPDR; } // ============================================================ void OSD_write_to_screen(const char s[], byte x, byte y, byte blink, byte invert){ unsigned int linepos; byte local_count; byte settings, char_address_hi, char_address_lo; byte screen_char; local_count = 0; char_address_hi = 0; char_address_lo = 0; linepos = y*30+x; char_address_hi = linepos >> 8; char_address_lo = linepos; settings = B00000001; if (blink) { settings |= (1 << 4); } if (invert){ settings |= (1 << 3); } digitalWrite(MAX7456SELECT,LOW); spi_transfer(DMM_reg); spi_transfer(settings); spi_transfer(DMAH_reg); spi_transfer(char_address_hi); spi_transfer(DMAL_reg); spi_transfer(char_address_lo); while(s[local_count]!='\0') { screen_char = s[local_count]; if(screen_char != 208 && screen_char != 209) { spi_transfer(DMDI_reg); spi_transfer(screen_char); } local_count++; } spi_transfer(DMDI_reg); spi_transfer(END_string); spi_transfer(DMM_reg); spi_transfer(B00000000); digitalWrite(MAX7456SELECT,HIGH); }
Я, попробовал скопировать шапку:
#define DATAOUT 11//MOSI #define DATAIN 12//MISO #define SPICLOCK 13//sck #define MAX7456SELECT 10//ss #define VSYNC 0x02// INT0 #define DMM_reg 0x04 #define DMAH_reg 0x05 #define DMAL_reg 0x06 #define DMDI_reg 0x07 #define VM0_reg 0x00 #define VM1_reg 0x01 #define VIDEO_BUFFER_DISABLE 0x01 #define MAX7456_RESET 0x02 #define VERTICAL_SYNC_NEXT_VSYNC 0x04 #define OSD_ENABLE 0x08 #define SYNC_MODE_AUTO 0x00 #define SYNC_MODE_INTERNAL 0x30 #define SYNC_MODE_EXTERNAL 0x20 #define VIDEO_MODE_PAL 0x40 #define VIDEO_MODE_NTSC 0x00 #define BLINK_DUTY_CYCLE_50_50 0x00 #define BLINK_DUTY_CYCLE_33_66 0x01 #define BLINK_DUTY_CYCLE_25_75 0x02 #define BLINK_DUTY_CYCLE_75_25 0x03 #define BLINK_TIME_0 0x00 #define BLINK_TIME_1 0x04 #define BLINK_TIME_2 0x08 #define BLINK_TIME_3 0x0C #define BACKGROUND_BRIGHTNESS_0 0x00 #define BACKGROUND_BRIGHTNESS_7 0x10 #define BACKGROUND_BRIGHTNESS_14 0x20 #define BACKGROUND_BRIGHTNESS_21 0x30 #define BACKGROUND_BRIGHTNESS_28 0x40 #define BACKGROUND_BRIGHTNESS_35 0x50 #define BACKGROUND_BRIGHTNESS_42 0x60 #define BACKGROUND_BRIGHTNESS_49 0x70 #define BACKGROUND_MODE_GRAY 0x40 #define CLEAR_display 0x04 #define CLEAR_display_vert 0x06 #define END_string 0xff #define ENABLE_display 0x08 #define ENABLE_display_vert 0x0c #define MAX7456_reset 0x02 #define DISABLE_display 0x00 #define WHITE_level_80 0x03 #define WHITE_level_90 0x02 #define WHITE_level_100 0x01 #define WHITE_level_120 0x00 #define MAX_screen_size 390 #define MAX_screen_rows 16 byte spi_junk, eeprom_junk; int x; void setup() { Serial.begin(115200); Serial.flush(); pinMode(MAX7456SELECT,OUTPUT); digitalWrite(MAX7456SELECT,HIGH); pinMode(DATAOUT, OUTPUT); pinMode(DATAIN, INPUT); pinMode(SPICLOCK,OUTPUT); pinMode(VSYNC, INPUT); SPCR = (1<<SPE)|(1<<MSTR); spi_junk=SPSR; spi_junk=SPDR; delay(250); digitalWrite(MAX7456SELECT,LOW); spi_transfer(VM0_reg); spi_transfer(MAX7456_reset); digitalWrite(MAX7456SELECT,HIGH); delay(500); digitalWrite(MAX7456SELECT,LOW); for (x = 0; x < MAX_screen_rows; x++) { spi_transfer(x + 0x10); spi_transfer(WHITE_level_90); } spi_transfer(VM0_reg); spi_transfer(VERTICAL_SYNC_NEXT_VSYNC|OSD_ENABLE|VIDEO_MODE_PAL); spi_transfer(VM1_reg); spi_transfer(BLINK_TIME_3); digitalWrite(MAX7456SELECT,HIGH); delay(100); } void loop() { }
При проверке этой шапки выдает ошибку компилятор: spi_transfer() - не объявлена.
В первом коде - оригинальном, такой ошибки нет. Открываю все в одном и том же компиляторе, библиотек нет подключенных ни в первом ни во втором варианте. Почему так ведет себя компилятор?
И второй вопрос совсем дилетантский, уж простите новичка:
В шапке есть строки типа этих:
#define DMM_reg 0x04
это адреса байтов в MAX7456, а вот эти строки в коментариях на буржуйских форумах описаны, как команды:
#define VIDEO_BUFFER_DISABLE 0x01
define BACKGROUND_BRIGHTNESS_0 0x00
Не понимаю, как это работает? байты в первом случае описаны в даташите на MAX, а во втором что эти цифры (0x01,0x00) означают?
У Вас есть функция spi_transfer. Объявлена она в строке 119 исходного кода. А используется гораздо раньше (строки 85, 86, 93, 94 и т.д.)
Это само по себе плохо - это ошибка, которую за Вас исправляют некоторые версии IDE -не все), но сейчас не об этом.
Проблема в том, что когда Вы выбираете "шапку", Вы использование берёте, а определение выбрасываете.
байты в первом случае описаны в даташите на MAX, а во втором что эти цифры (0x01,0x00) означают?
Это команды, которые также описаны в даташите (числа описаны, а названия могут быть любыми)
У Вас есть функция spi_transfer. Объявлена она в строке 119 исходного кода. А используется гораздо раньше (строки 85, 86, 93, 94 и т.д.)
Это само по себе плохо - это ошибка, которую за Вас исправляют некоторые версии IDE -не все), но сейчас не об этом.
Проблема в том, что когда Вы выбираете "шапку", Вы использование берёте, а определение выбрасываете.
Уважаемый Евгений, то есть вот эта строка и объявляет функцию:
byte spi_transfer(volatile byte data) ?
Совсем запутался. Мы объявляем байт spi_transfer(volatile(переменный, не постоянный)data). Но тогда почему строка с командой: spi_transfer(VM1_reg) например, передает эти данные в MAX? По идее эти данные (define VM1_reg 0x01) присваиваются этому байту? Или я не правильно понимаю работу IDE?
байты в первом случае описаны в даташите на MAX, а во втором что эти цифры (0x01,0x00) означают?
Это команды, которые также описаны в даташите (числа описаны, а названия могут быть любыми)
Тогда получается, что строки:
означают:
начало записи SS - низкий уровень
байту spi_transfer присвоен адрес регистра VM0_reg - 0х00
байту spi_transfer присвоено значение MAX7456_reset - 0x02, что даст нам значение в двоичном виде 00000000 +10=00000010, а это как раз и есть софт сброс MAXа. Я правильно понял?
конец записи
пауза.
И тут еще один дилетантский вопрос - почему происходит отправка по SPI протоколу именно этого байта? Если не сложно просто ткните носом, как это работает, это надо читать даташит самой МЕГИ?
то есть вот эта строка и объявляет функцию:
byte spi_transfer(volatile byte data) ?
Разумеется.
Мы объявляем байт spi_transfer(volatile(переменный, не постоянный)data)
Что объявляете Вы я не знаю, а автор этой программы объявил функцию, которая возвращает значение типа byte.
По поводу "переменный, не постоянный" вышлядит как бред Не пользуйтесь переводчиком для конструкций языка программирования. Слова в языке программирования могут означать совсем не то, чо Вам даёт переводчик, лучше книжку по языку программирования почитайте.
Но тогда почему строка с командой: spi_transfer(VM1_reg) например, передает эти данные в MAX?
Эта строка вызывает функцию, а функция делает своё дело.
По идее эти данные (define VM1_reg 0x01) присваиваются этому байту?
Какому байту? Читайте и пока не прочитаете, не пытайтесь программировать.
Или я не правильно понимаю работу IDE?
ИДЕ тут вообще не при делах. Вы абсолютно не знаете языка программирования на котором пытаетесь писать. Берёте чужой код и пытаетесь методом тыка и гугл-перевода ключевых слов что-то понять. Это бесполезное занятие. Читайте и пока не прочитаете, не пытайтесь программировать.
Тогда получается, что строки:
означают:
начало записи SS - низкий уровень
байту spi_transfer присвоен адрес регистра VM0_reg - 0х00 (*)
байту spi_transfer присвоено значение MAX7456_reset - 0x02, что даст нам значение в двоичном виде 00000000 +10=00000010, а это как раз и есть софт сброс MAXа. (**)
Я правильно понял? (***)
почему происходит отправка по SPI протоколу именно этого байта? Если не сложно просто ткните носом, как это работает, это надо читать даташит самой МЕГИ?
Потому, что функция spi_transfer отправляет то что её передали параметром (см. её текст).
Мега с даташитом тут вообще не при делах. Вам просто надо прочитать какую-нибудь книгу по программированию на С. Вы не знаете ничего. Ссылку на книгу (одну из) я Вам давал.
Тогда получается, что строки:
означают:
начало записи SS - низкий уровень
байту spi_transfer присвоен адрес регистра VM0_reg - 0х00 (*)
байту spi_transfer присвоено значение MAX7456_reset - 0x02, что даст нам значение в двоичном виде 00000000 +10=00000010, а это как раз и есть софт сброс MAXа. (**)
Я правильно понял? (***)
почему происходит отправка по SPI протоколу именно этого байта? Если не сложно просто ткните носом, как это работает, это надо читать даташит самой МЕГИ?
Потому, что функция spi_transfer отправляет то что её передали параметром (см. её текст).
Мега с даташитом тут вообще не при делах. Вам просто надо прочитать какую-нибудь книгу по программированию на С. Вы не знаете ничего. Ссылку на книгу (одну из) я Вам давал.
Евгений, огромное вам спасибо. Часть стала понятна, другую вычитаю из книги. Вы мне очень помогли. А по поводу копирывания, так вы гляньте ради любопытства коды, предлагаемые для этой связки в нете, найдете три разных на русскоязычных форумах - уже и интернет закончится - тырят без разбора и копипастят, многие "авторы", даже не могут объяснить, как этот код работает, потому и обратился не к "авторам", а на этом форуме в надежде, что подскажут люди, знающие именно код. Вот вы и помогли, спасибо еще раз, пошел читать книгу!