Jump to content
43oh

Noritake 800b 128x64 VFD Interface - Stellaris Launchpad


Recommended Posts

stellaris_launchpad_vfd_noritake_800b.jpg

 

stellaris_launchpad_vfd.JPG

 

I had a 128x64 Noritake VFD display at work, which is currently not being used. Did an extensive search for a driver until I found one by Henri Skippari. Code was ported from a a PIC16F877. Took a couple of hours for me to port and wire it up.

 

Below is the code which will need stellarisware.

/*
 * Noritake VFD 800B 128x64 Parallel Interface
 * Code courtesy : http://www.sourceboost.com/Products/C2C-plus/ExampleCode/noritake/noritake.c.html
 * Original author : Henri Skippari
 * Ported to Stellaris Launchpad : Gerard S, 12th August,  2013
 */

#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_gpio.h"
#include "driverlib/gpio.h"
#include "driverlib/pin_map.h"
#include "driverlib/sysctl.h"
#include "driverlib/systick.h"
#include "driverlib/gpio.h"
#include "driverlib/sysctl.h"
#include "utils/uartstdio.h"
#include "utils/ustdlib.h"

#define LAYER0_ON       1
#define LAYER0_OFF      0
#define LAYER1_ON       1
#define LAYER1_OFF      0
#define DISPLAY_ON      1
#define DISPLAY_OFF     0
#define REVERSE_ON      1
#define REVERSE_OFF     0
#define MODE_AND        0
#define MODE_EXOR       1
#define MODE_OR         2
#define VERTICAL_ON     1
#define VERTICAL_OFF    0
#define HORIZONTAL_ON   1
#define HORIZONTAL_OFF  0

#define D7              0x80
#define D6              0x40
#define D5              0x20
#define D4              0x10
#define D3              0x08
#define D2              0x04
#define D1              0x02
#define D0              0x01

#define	VFD_CONTROL_PERIPH	SYSCTL_PERIPH_GPIOA
#define VFD_CONTROL_BASE	GPIO_PORTA_BASE
#define VFD_WR		GPIO_PIN_2
#define VFD_CD		GPIO_PIN_3
#define VFD_RD		GPIO_PIN_4
#define VFD_CSS		GPIO_PIN_5

#define VFD_WR_HI HWREG(VFD_CONTROL_BASE + GPIO_O_DATA + (VFD_WR << 2)) = VFD_WR
#define VFD_WR_LO HWREG(VFD_CONTROL_BASE + GPIO_O_DATA + (VFD_WR << 2)) = 0

#define VFD_CD_HI HWREG(VFD_CONTROL_BASE + GPIO_O_DATA + (VFD_CD << 2)) = VFD_CD
#define VFD_CD_LO HWREG(VFD_CONTROL_BASE + GPIO_O_DATA + (VFD_CD << 2)) = 0

#define VFD_RD_HI HWREG(VFD_CONTROL_BASE + GPIO_O_DATA + (VFD_RD << 2)) = VFD_RD
#define VFD_RD_LO HWREG(VFD_CONTROL_BASE + GPIO_O_DATA + (VFD_RD << 2)) = 0

#define VFD_CSS_HI HWREG(VFD_CONTROL_BASE + GPIO_O_DATA + (VFD_CSS << 2)) = VFD_CSS
#define VFD_CSS_LO HWREG(VFD_CONTROL_BASE + GPIO_O_DATA + (VFD_CSS << 2)) = 0

#define	VFD_DATA_PERIPH	SYSCTL_PERIPH_GPIOB
#define VFD_DATA_BASE	GPIO_PORTB_BASE
#define VFD_DATA		GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | \
						GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7 |

// Fonts, first part
const unsigned char font5x7[]={
0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0xF2,0x00,0x00,
0x00,0xC0,0x00,0xC0,0x00,
0x28,0xFE,0x28,0xFE,0x28,
0x24,0x54,0xFE,0x54,0x48,
0xC4,0xC8,0x10,0x26,0x46,
0x6C,0x92,0x9A,0x64,0x0A,
0x00,0xA0,0xC0,0x00,0x00,
0x00,0x38,0x44,0x82,0x00,
0x00,0x82,0x44,0x38,0x00,
0x28,0x10,0x7C,0x10,0x28,

0x10,0x10,0x7C,0x10,0x10,
0x0A,0x0C,0x00,0x00,0x00,
0x10,0x10,0x10,0x10,0x10,
0x06,0x06,0x00,0x00,0x00,
0x04,0x08,0x10,0x20,0x40,
0x7C,0x8A,0x92,0xA2,0x7C,
0x00,0x42,0xFE,0x02,0x00,
0x42,0x86,0x8A,0x92,0x62,
0x84,0x82,0xA2,0xD2,0x8C,
0x18,0x28,0x48,0xFE,0x08,

0xE4,0xA2,0xA2,0xA2,0x9C,
0x3C,0x52,0x92,0x92,0x0C,
0x80,0x8E,0x90,0xA0,0xC0,
0x6C,0x92,0x92,0x92,0x6C,
0x60,0x92,0x92,0x94,0x78,
0x00,0x6C,0x6C,0x00,0x00,
0x00,0x6A,0x6C,0x00,0x00,
0x10,0x28,0x44,0x82,0x00,
0x28,0x28,0x28,0x28,0x28,
0x00,0x82,0x44,0x28,0x10,

0x40,0x80,0x8A,0x90,0x60,
0x4C,0x92,0x9E,0x82,0x7C,
0x3E,0x48,0x88,0x48,0x3E,
0xFE,0x92,0x92,0x92,0x6C,
0x7C,0x82,0x82,0x82,0x44,
0xFE,0x82,0x82,0x44,0x38,
0xFE,0x92,0x92,0x82,0x82,
0xFE,0x90,0x90,0x90,0x80,
0x7C,0x82,0x92,0x92,0x5C,
0xFE,0x10,0x10,0x10,0xFE,

0x00,0x82,0xFE,0x82,0x00,
0x04,0x02,0x82,0xFC,0x80,
0xFE,0x10,0x28,0x44,0x82,
0xFE,0x02,0x02,0x02,0x02,
0xFE,0x40,0x20,0x40,0xFE,
0xFE,0x20,0x10,0x08,0xFE,
0x7C,0x82,0x82,0x82,0x7C,
0xFE,0x90,0x90,0x90,0x60,
0x7C,0x82,0x8A,0x84,0x7A,
0xFE,0x90,0x98,0x94,0x62 // 50
};

// Fonts, second part
const unsigned char font5x7_2[]={
0x64,0x92,0x92,0x92,0x4C,
0x80,0x80,0xFE,0x80,0x80,
0xFC,0x02,0x02,0x02,0xFC,
0xF8,0x04,0x02,0x04,0xF8,
0xFC,0x02,0x0C,0x02,0xFC,
0xC6,0x28,0x10,0x28,0xC6,
0xE0,0x10,0x0E,0x10,0xE0,
0x86,0x8A,0x92,0xA2,0xC2,
0x00,0xFE,0x82,0x82,0x00,
0x40,0x20,0x10,0x08,0x04,

0x00,0x82,0x82,0xFE,0x00,
0x20,0x40,0x80,0x40,0x20,
0x02,0x02,0x02,0x02,0x02,
0x00,0x80,0x40,0x20,0x00,
0x04,0x2A,0x2A,0x2A,0x1E,
0xFE,0x12,0x12,0x12,0x0C,
0x1C,0x22,0x22,0x22,0x22,
0x0C,0x12,0x12,0x12,0xFE,
0x1C,0x2A,0x2A,0x2A,0x1A,
0x10,0x7E,0x90,0x40,0x00,
0x12,0x2A,0x2A,0x2A,0x3C,

0xFE,0x10,0x10,0x10,0x0E,
0x00,0x00,0x5E,0x00,0x00,
0x04,0x02,0x02,0xBC,0x00,
0xFE,0x08,0x14,0x22,0x00,
0x00,0x82,0xFE,0x02,0x00,
0x3E,0x20,0x18,0x20,0x3E,
0x3E,0x10,0x20,0x20,0x1E,
0x1C,0x22,0x22,0x22,0x1C,
0x3E,0x28,0x28,0x28,0x10,
0x10,0x28,0x28,0x28,0x3E,

0x3E,0x10,0x20,0x20,0x10,
0x12,0x2A,0x2A,0x2A,0x24,
0x20,0xFC,0x22,0x04,0x00,
0x3C,0x02,0x02,0x02,0x3C,
0x38,0x04,0x02,0x04,0x38,
0x3C,0x02,0x0C,0x02,0x3C,
0x22,0x14,0x08,0x14,0x22,
0x20,0x12,0x0C,0x10,0x20,
0x22,0x26,0x2A,0x32,0x22,
0x10,0x6C,0x82,0x82,0x00,

0x12,0x7E,0x92,0x82,0x42,
0x00,0x82,0x82,0x6C,0x10,
0x80,0x80,0x80,0x80,0x80,
0xFE,0xFE,0xFE,0xFE,0xFE}; // 44


/* Write data byte */
void VFD_WriteData(unsigned char data)
{
	VFD_CD_LO;
	VFD_WR_LO;
	VFD_RD_HI;
	VFD_CSS_LO;
	GPIOPinWrite( VFD_DATA_BASE, 0xFF, data);
    VFD_CD_LO;
    VFD_WR_HI;
    VFD_RD_HI;
    VFD_CSS_LO;
}

/* Write command byte */
void VFD_WriteCtrl(unsigned char command)
{
	VFD_CD_HI;
	VFD_WR_LO;
	VFD_RD_HI;
	VFD_CSS_LO;
	GPIOPinWrite( VFD_DATA_BASE, 0xFF, command);
    VFD_CD_HI;
    VFD_WR_HI;
    VFD_RD_HI;
   VFD_CSS_LO;
}

/*  Horizontal and vertical address auto increment on/off */
void VFD_AddressIncrementMode(unsigned char h, unsigned char v)
{
    unsigned char bit2=0, bit1=0;

    if(h==HORIZONTAL_ON) bit2 = 0x04;
    if(v==VERTICAL_ON) bit1 = 0x02;
    VFD_WriteCtrl(0x80+bit2+bit1);
}


void VFD_SetColumn(unsigned char column)
{
    VFD_WriteCtrl(0x64);
    VFD_WriteCtrl(column);
}

void VFD_SetRow(unsigned char row)
{
    VFD_WriteCtrl(0x60);
    VFD_WriteCtrl(row);
}


/* Display brightness 0-15 */
void VFD_SetBrightness(unsigned char brightness)
{
    if(brightness>15) brightness=15; // Check for too big values
    if(brightness<0) brightness=0; // Check for too small values
    VFD_WriteCtrl(0x40+(0x0F-brightness));
    // Delay for 100ms
    SysCtlDelay( (SysCtlClockGet()/(3*1000))*1 );
}

void VFD_ClearDisplay(void)
{
    VFD_WriteCtrl(0x5f);
    SysCtlDelay( (SysCtlClockGet()/(3*1000))*1 );
}

/* Set layers on/off + other display attributes */
void VFD_DisplaySetup(char layer0, char layer1, char gfx_on_off, char reverse, char mode)
{
    unsigned char l0=0, l1=0, gs=0, grv=0, and=0, exor=0;

    if(layer0==LAYER0_ON) l0 = D2;
    if(layer1==LAYER1_ON) l1 = D3;
    VFD_WriteCtrl(0x20+l0+l1);

    if(gfx_on_off==DISPLAY_ON) gs = D6;
    if(reverse==REVERSE_ON) grv = D4;
    if(mode==MODE_AND) and = D3;
    if(mode==MODE_EXOR) exor = D2;
    if(mode==MODE_OR) { }
    VFD_WriteCtrl(gs+grv+and+exor);
}

unsigned char swap(unsigned char x)
{
    unsigned char result=0,mask1=1,mask2=128;
    int b;

    for(b=0;b<8;b++)
    {
        if ((x&mask1)==mask1)
            result=result+mask2;
        mask1=mask1<<1;
        mask2=mask2>>1;
    }
    return(result);
}

void VFD_PrintChar(unsigned char chr)
{
    unsigned char data, i;

    VFD_AddressIncrementMode(HORIZONTAL_ON, VERTICAL_OFF); // Horizontal auto increment ON for font writing
    chr=chr-0x20; // Convert ascii code to Noritake code
    if(chr<51) // First font array
    {
        for(i=0;i<5;i++)
        {
            data = font5x7[chr*5+i];
            data = swap(data);
            VFD_WriteData(data);
        }
        VFD_WriteData(0);
    }
    else if(chr<96) // Second font array
    {
        chr = chr-51;

        for(i=0;i<5;i++)
        {
            data = font5x7_2[chr*5+i];
            data = swap(data);
            VFD_WriteData(data);
        }
        VFD_WriteData(0);
    }
}


void VFD_Init( void )
{
    unsigned char i;

	SysCtlPeripheralEnable(VFD_CONTROL_PERIPH);
	GPIOPinTypeGPIOOutput(VFD_CONTROL_BASE, VFD_WR	|	\
											VFD_CD	|	\
											VFD_RD |	\
											VFD_CSS);

	SysCtlPeripheralEnable(VFD_DATA_PERIPH);
	GPIOPinTypeGPIOOutput(VFD_DATA_BASE, 0xFF);


    for(i=0;i<8;i++)
    {
        // address area set
        VFD_WriteCtrl(0x62);
        VFD_WriteCtrl(i);
        VFD_WriteData(0xff);
    }

    VFD_AddressIncrementMode(HORIZONTAL_ON, VERTICAL_OFF); // Default to horizontal address increment ON
    VFD_SetColumn(0); // Set address pointer to (0,0)
    VFD_SetRow(0); // Set address pointer to (0,0)
    VFD_SetBrightness(0); // Set brightness to lowest possible

    VFD_DisplaySetup(LAYER0_OFF, LAYER1_OFF, DISPLAY_OFF, REVERSE_OFF, MODE_AND); // Set everything OFF
    VFD_ClearDisplay();
}

/* Draw vertical bar. Used in the sample.*/
void DrawVertBar(unsigned char height, unsigned char pos)
{
    unsigned char i;

    VFD_AddressIncrementMode(HORIZONTAL_OFF, VERTICAL_ON); // Vertical bars are drawn so vertical auto increment is enabled
    VFD_SetColumn(pos);
    VFD_SetRow(7-height);

    for(i=7-height;i<8;i++)
    {
        VFD_WriteData(254); // Draw vertical byte with one bit off: oxxxxxxx
        // Address pointer is incremented vertically after every byte written
    }
}

int main(void) {
	
    int i, j, c;

	// Setup the processor clock at 80Mhz.
	SysCtlClockSet(	SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL |	\
					SYSCTL_OSC_MAIN   | SYSCTL_XTAL_16MHZ);

	// Enable UART0 @115200bps N81.
	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
	GPIOPinConfigure(GPIO_PA0_U0RX);
	GPIOPinConfigure(GPIO_PA1_U0TX);
	GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
	UARTStdioInit(0);

	//Clear the terminal
	UARTprintf("\033[2J");
    UARTprintf("\n\nNoritake VFD 800b test\n");
    UARTprintf("-----------------------------------\n");



    // Arrays to store height and current direction for moving bars
    unsigned char value[16]; // Height of bar, 0 to 8
    unsigned char dir[16]; // 1=up, 0=down

    // Initialize values for bars
    for(i=0;i<8;i++)
    {
        value[i]=i; // 8 bars with values from 0 to 7
        dir[i]=1; // Going up
        value[8+i]=(8-i); // 8 bars with values from 8 to 1
        dir[8+i]=0; // Going down
    }


    VFD_Init();
    VFD_DisplaySetup(LAYER0_ON, LAYER1_ON, DISPLAY_ON, REVERSE_OFF, MODE_OR);
    VFD_SetBrightness(15); // Set brightness to maximum

    // Write all available fonts to display
    // Change row after 20 characters
    c=32;
    for(i=0;i<5;i++)
    {
        VFD_SetColumn(0);
        VFD_SetRow(8+i); // Start from the beginning of second layer
        for(j=0;j<20;j++)
        {
            VFD_PrintChar(c++);
        }
    }

    SysCtlDelay( (SysCtlClockGet()/(3*1000))*1000 );

    while( 1 )
    {
        // Draw some moving bars on the display
        for(i=0;i<16;i++)
        {
            for(j=0;j<8;j++)
            {
                DrawVertBar(value[i], i*8);
            }
            if(value[i]>=8) dir[i]=0;
            else if(value[i]<=0) dir[i]=1;

            if(dir[i]==0) value[i]=value[i]-1;
            else if(dir[i]==1) value[i]=value[i]+1;
        }
        SysCtlDelay( (SysCtlClockGet()/(3*1000))*50 );
        VFD_ClearDisplay();
    }

    return 0;
}

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...