Arduino nano и MAX7456

onemamba
Offline
Зарегистрирован: 09.12.2015

Здравствуйте уважаемые жители и гости форума. Прошу помощи - разобратья в коде.

Я собираю связку Ардуино и 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() - не объявлена.

В первом коде - оригинальном, такой ошибки нет. Открываю все в одном и том же компиляторе, библиотек нет подключенных ни в первом ни во втором варианте. Почему так ведет себя компилятор?

onemamba
Offline
Зарегистрирован: 09.12.2015

И второй вопрос совсем дилетантский, уж простите новичка: 

В шапке есть строки типа этих: 

#define DMM_reg   0x04

это адреса байтов в MAX7456, а вот эти строки в коментариях на буржуйских форумах описаны, как команды:

#define VIDEO_BUFFER_DISABLE 0x01

define BACKGROUND_BRIGHTNESS_0 0x00

Не понимаю, как это работает? байты в первом случае описаны в даташите на MAX, а во втором что эти цифры (0x01,0x00) означают?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

У Вас есть функция spi_transfer. Объявлена она в строке 119 исходного кода. А используется гораздо раньше (строки 85, 86, 93, 94 и т.д.)

Это само по себе плохо - это ошибка, которую за Вас исправляют некоторые версии IDE -не все), но сейчас не об этом.

Проблема в том, что когда Вы выбираете "шапку", Вы использование берёте, а определение выбрасываете.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

onemamba пишет:

 байты в первом случае описаны в даташите на MAX, а во втором что эти цифры (0x01,0x00) означают?

Это команды, которые также описаны в даташите (числа описаны, а названия могут быть любыми)

onemamba
Offline
Зарегистрирован: 09.12.2015

ЕвгенийП пишет:

У Вас есть функция 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? 

onemamba
Offline
Зарегистрирован: 09.12.2015

ЕвгенийП пишет:

onemamba пишет:

 байты в первом случае описаны в даташите на MAX, а во втором что эти цифры (0x01,0x00) означают?

Это команды, которые также описаны в даташите (числа описаны, а названия могут быть любыми)

Тогда получается, что строки:

digitalWrite(MAX7456SELECT,LOW); 
  spi_transfer(VM0_reg); 
  spi_transfer(MAX7456_reset); 
  digitalWrite(MAX7456SELECT,HIGH); 
  delay(500); 

означают: 

начало записи SS - низкий уровень

байту spi_transfer присвоен адрес регистра VM0_reg - 0х00

байту spi_transfer присвоено значение MAX7456_reset - 0x02, что даст нам значение в двоичном виде 00000000 +10=00000010, а это как раз и есть софт сброс MAXа. Я правильно понял?

 конец записи

пауза.

 

И тут еще один дилетантский вопрос - почему происходит отправка по SPI протоколу именно этого байта? Если не сложно просто ткните носом, как это работает, это надо читать даташит самой МЕГИ?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

onemamba пишет:

то есть вот эта строка и объявляет функцию: 

byte spi_transfer(volatile byte data) ?

Разумеется.

onemamba пишет:

Мы объявляем байт spi_transfer(volatile(переменный, не постоянный)data)

Что объявляете Вы я не знаю, а автор этой программы объявил функцию, которая возвращает значение типа byte.

По поводу "переменный, не постоянный" вышлядит как бред Не пользуйтесь переводчиком для конструкций языка программирования. Слова в языке программирования могут означать совсем не то, чо Вам даёт переводчик, лучше книжку по языку программирования почитайте.

onemamba пишет:

 Но тогда почему строка с командой: spi_transfer(VM1_reg) например, передает эти данные в MAX? 

Эта строка вызывает функцию, а функция делает своё дело.

onemamba пишет:

По идее эти данные (define VM1_reg   0x01) присваиваются этому байту?

Какому байту? Читайте и пока не прочитаете, не пытайтесь программировать.

onemamba пишет:

Или я не правильно понимаю работу IDE? 

ИДЕ тут вообще не при делах. Вы абсолютно не знаете языка программирования на котором пытаетесь писать. Берёте чужой код и пытаетесь методом тыка и гугл-перевода ключевых слов что-то понять. Это бесполезное занятие. Читайте и пока не прочитаете, не пытайтесь программировать.

 

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

onemamba пишет:

Тогда получается, что строки:

digitalWrite(MAX7456SELECT,LOW); 
  spi_transfer(VM0_reg); 
  spi_transfer(MAX7456_reset); 
  digitalWrite(MAX7456SELECT,HIGH); 
  delay(500); 

означают: 

начало записи SS - низкий уровень

байту spi_transfer присвоен адрес регистра VM0_reg - 0х00 (*)

байту spi_transfer присвоено значение MAX7456_reset - 0x02, что даст нам значение в двоичном виде 00000000 +10=00000010, а это как раз и есть софт сброс MAXа.  (**)

Я правильно понял? (***)

(*) Нет там никакого байта. Вызывается функция spi_transfer и её передаётся параметр 0. Она (функция отправляет 0 в SPI
 
(**) Нет там никакого байта Вызывается функция spi_transfer и её передаётся параметр 2. Она (функция отправляет 2 в SPI. А уж что это означает для принимающей микросхему - это её дело.
 
(***) Как видите, нет.

onemamba пишет:

почему происходит отправка по SPI протоколу именно этого байта? Если не сложно просто ткните носом, как это работает, это надо читать даташит самой МЕГИ?

Потому, что функция spi_transfer  отправляет то что её передали параметром (см. её текст).

Мега с даташитом тут вообще не при делах. Вам просто надо прочитать какую-нибудь книгу по программированию на С. Вы не знаете ничего. Ссылку на книгу (одну из) я Вам давал.

 

 

onemamba
Offline
Зарегистрирован: 09.12.2015

ЕвгенийП пишет:

onemamba пишет:

Тогда получается, что строки:

digitalWrite(MAX7456SELECT,LOW); 
  spi_transfer(VM0_reg); 
  spi_transfer(MAX7456_reset); 
  digitalWrite(MAX7456SELECT,HIGH); 
  delay(500); 

означают: 

начало записи SS - низкий уровень

байту spi_transfer присвоен адрес регистра VM0_reg - 0х00 (*)

байту spi_transfer присвоено значение MAX7456_reset - 0x02, что даст нам значение в двоичном виде 00000000 +10=00000010, а это как раз и есть софт сброс MAXа.  (**)

Я правильно понял? (***)

(*) Нет там никакого байта. Вызывается функция spi_transfer и её передаётся параметр 0. Она (функция отправляет 0 в SPI
 
(**) Нет там никакого байта Вызывается функция spi_transfer и её передаётся параметр 2. Она (функция отправляет 2 в SPI. А уж что это означает для принимающей микросхему - это её дело.
 
(***) Как видите, нет.

onemamba пишет:

почему происходит отправка по SPI протоколу именно этого байта? Если не сложно просто ткните носом, как это работает, это надо читать даташит самой МЕГИ?

Потому, что функция spi_transfer  отправляет то что её передали параметром (см. её текст).

Мега с даташитом тут вообще не при делах. Вам просто надо прочитать какую-нибудь книгу по программированию на С. Вы не знаете ничего. Ссылку на книгу (одну из) я Вам давал.

 

 

Евгений, огромное вам спасибо. Часть стала понятна, другую вычитаю из книги. Вы мне очень помогли. А по поводу копирывания, так вы гляньте ради любопытства коды, предлагаемые для этой связки в нете, найдете три разных на русскоязычных форумах - уже и интернет закончится - тырят без разбора и копипастят, многие "авторы", даже не могут объяснить, как этот код работает, потому и обратился не к "авторам", а на этом форуме в надежде, что подскажут люди, знающие именно код. Вот вы и помогли, спасибо еще раз, пошел читать книгу!