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 отправляет то что её передали параметром (см. её текст).
Мега с даташитом тут вообще не при делах. Вам просто надо прочитать какую-нибудь книгу по программированию на С. Вы не знаете ничего. Ссылку на книгу (одну из) я Вам давал.
Евгений, огромное вам спасибо. Часть стала понятна, другую вычитаю из книги. Вы мне очень помогли. А по поводу копирывания, так вы гляньте ради любопытства коды, предлагаемые для этой связки в нете, найдете три разных на русскоязычных форумах - уже и интернет закончится - тырят без разбора и копипастят, многие "авторы", даже не могут объяснить, как этот код работает, потому и обратился не к "авторам", а на этом форуме в надежде, что подскажут люди, знающие именно код. Вот вы и помогли, спасибо еще раз, пошел читать книгу!