I used the code posted in this thread as well, and it had a serious flicker, so much so that some displays wouldn't sync, and none would sync without a video source. I combined the code from two earlier posts, removed most of it, and made some changes based on my understanding of the datasheet. the result is some rock-solid video that works with or without a source attached to Vin. Maybe it will help. Note it's set to NTSC; you'll have to make some adjustments if you're in a PAL part of the world.
Oh yeah, I ran the sketch that converts the character set so that ASCII is in the correct place before I used the following code.
-j
#define DATAOUT 11//MOSI
#define DATAIN 12//MISO
#define SPICLOCK 13//sck
#define MAX7456SELECT 10//ss
#define VSYNC 2// INT0
//MAX7456 opcodes
#define DMM_reg 0x04
#define DMAH_reg 0x05
#define DMAL_reg 0x06
#define DMDI_reg 0x07
#define VM0_reg 0x00
#define VM1_reg 0x01
// video mode register 0 bits
#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
// video mode register 1 bits
// duty cycle is on_off
#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
// blinking time
#define BLINK_TIME_0 0x00
#define BLINK_TIME_1 0x04
#define BLINK_TIME_2 0x08
#define BLINK_TIME_3 0x0C
// background mode brightness (percent)
#define BACKGROUND_BRIGHTNESS_0 0x00
#define BACKGROUND_BRIGHTNESS_7 0x01
#define BACKGROUND_BRIGHTNESS_14 0x02
#define BACKGROUND_BRIGHTNESS_21 0x03
#define BACKGROUND_BRIGHTNESS_28 0x04
#define BACKGROUND_BRIGHTNESS_35 0x05
#define BACKGROUND_BRIGHTNESS_42 0x06
#define BACKGROUND_BRIGHTNESS_49 0x07
#define BACKGROUND_MODE_GRAY 0x40
//MAX7456 commands
#define CLEAR_display 0x04
#define CLEAR_display_vert 0x06
#define END_string 0xff
// with NTSC
#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
// with NTSC
#define MAX_screen_size 390
#define MAX_screen_rows 13
//////////////////////////////////////////////////////////////
void setup()
{
byte spi_junk, eeprom_junk;
int x;
Serial.begin(9600);
Serial.flush();
pinMode(MAX7456SELECT,OUTPUT);
digitalWrite(MAX7456SELECT,HIGH); //disable device
pinMode(DATAOUT, OUTPUT);
pinMode(DATAIN, INPUT);
pinMode(SPICLOCK,OUTPUT);
pinMode(VSYNC, INPUT);
// SPCR = 01010000
//interrupt disabled,spi enabled,msb 1st,master,clk low when idle,
//sample on leading edge of clk,system clock/4 rate (4 meg)
SPCR = (1<<SPE)|(1<<MSTR);
spi_junk=SPSR;
spi_junk=SPDR;
delay(250);
// force soft reset on Max7456
digitalWrite(MAX7456SELECT,LOW);
spi_transfer(VM0_reg);
spi_transfer(MAX7456_reset);
digitalWrite(MAX7456SELECT,HIGH);
delay(500);
// set all rows to same charactor white level, 90%
digitalWrite(MAX7456SELECT,LOW);
for (x = 0; x < MAX_screen_rows; x++)
{
spi_transfer(x + 0x10);
spi_transfer(WHITE_level_90);
}
// make sure the Max7456 is enabled
spi_transfer(VM0_reg);
spi_transfer(VERTICAL_SYNC_NEXT_VSYNC|OSD_ENABLE);
digitalWrite(MAX7456SELECT,HIGH);
delay(100);
spi_transfer(VM1_reg);
spi_transfer(BLINK_DUTY_CYCLE_50_50|BLINK_TIME_3);
digitalWrite(MAX7456SELECT,HIGH);
Serial.println("OSD starting");
delay(100);
}
/////////////////////////////////////////////////////////////
void loop()
{
OSD_write_to_screen("Hello world", 3, 5, 0,0);
OSD_write_to_screen("Hello world", 5, 7, 0,1);
OSD_write_to_screen("Hello world", 7, 9, 1,0);
OSD_write_to_screen("Hello world", 9, 11, 1,1);
delay(5000);
spi_transfer(VM1_reg);
spi_transfer(BLINK_DUTY_CYCLE_75_25);
digitalWrite(MAX7456SELECT,HIGH);
delay(100);
OSD_write_to_screen("DUTY_CYCLE_75_25", 3, 5, 0,0);
OSD_write_to_screen("Hello world", 5, 7, 0,1);
OSD_write_to_screen("Hello world", 7, 9, 1,0);
OSD_write_to_screen("Hello world", 9, 11, 1,1);
delay(5000);
spi_transfer(VM1_reg);
spi_transfer(BLINK_DUTY_CYCLE_25_75);
digitalWrite(MAX7456SELECT,HIGH);
delay(100);
OSD_write_to_screen("DUTY_CYCLE_25_75", 3, 5, 0,0);
OSD_write_to_screen("Hello world", 5, 7, 0,1);
OSD_write_to_screen("Hello world", 7, 9, 1,0);
OSD_write_to_screen("Hello world", 9, 11, 1,1);
delay(5000);
spi_transfer(VM0_reg);
spi_transfer(VERTICAL_SYNC_NEXT_VSYNC|OSD_ENABLE|SYNC_MODE_INTERNAL);
digitalWrite(MAX7456SELECT,HIGH);
delay(100);
OSD_write_to_screen("internal sync ", 3, 5, 0,0);
OSD_write_to_screen("Hello world", 5, 7, 0,1);
OSD_write_to_screen("Hello world", 7, 9, 1,0);
OSD_write_to_screen("Hello world", 9, 11, 1,1);
delay(5000);
spi_transfer(VM0_reg);
spi_transfer(VERTICAL_SYNC_NEXT_VSYNC|OSD_ENABLE|SYNC_MODE_EXTERNAL);
digitalWrite(MAX7456SELECT,HIGH);
delay(100);
OSD_write_to_screen("external sync", 3, 5, 0,0);
OSD_write_to_screen("Hello world", 5, 7, 0,1);
OSD_write_to_screen("Hello world", 7, 9, 1,0);
OSD_write_to_screen("Hello world", 9, 11, 1,1);
delay(5000);
spi_transfer(VM0_reg);
spi_transfer(VERTICAL_SYNC_NEXT_VSYNC|OSD_ENABLE|SYNC_MODE_AUTO);
digitalWrite(MAX7456SELECT,HIGH);
delay(100);
OSD_write_to_screen("auto sync ", 3, 5, 0,0);
OSD_write_to_screen("Hello world", 5, 7, 0,1);
OSD_write_to_screen("Hello world", 7, 9, 1,0);
OSD_write_to_screen("Hello world", 9, 11, 1,1);
delay(5000);
}
//////////////////////////////////////////////////////////////
byte spi_transfer(volatile byte data)
{
SPDR = data; // Start the transmission
while (!(SPSR & (1<<SPIF))) // Wait the end of the transmission
{
};
return SPDR; // return the received byte
}
// ============================================================ WRITE TO SCREEN
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;
// convert x,y to line position
linepos = y*30+x;
// divide in to hi & lo byte
char_address_hi = linepos >> 8;
char_address_lo = linepos;
// clear the screen
//OSD_clear();
settings = B00000001;
// set blink bit
if (blink) {
settings |= (1 << 4); // forces nth bit of x to be 1. all other bits left alone.
//x &= ~(1 << n); // forces nth bit of x to be 0. all other bits left alone.
}
// set invert bit
if (invert){
settings |= (1 << 3); // forces nth bit of x to be 1. all other bits left alone.
}
digitalWrite(MAX7456SELECT,LOW);
spi_transfer(DMM_reg); //dmm
spi_transfer(settings);
spi_transfer(DMAH_reg); // set start address high
spi_transfer(char_address_hi);
spi_transfer(DMAL_reg); // set start address low
spi_transfer(char_address_lo);
while(s[local_count]!='\0') // write out full screen
{
screen_char = s[local_count];
spi_transfer(DMDI_reg);
spi_transfer(screen_char);
local_count++;
}
spi_transfer(DMDI_reg);
spi_transfer(END_string);
spi_transfer(DMM_reg); //dmm
spi_transfer(B00000000);
// spi_transfer(VM0_reg); // turn on screen next vertical
// spi_transfer(B01001100);
// digitalWrite(MAX7456SELECT,HIGH);
}