⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lcd.c

📁 LCD source code
💻 C
字号:
#include <def21262.h>
#include <SRU.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <stdarg.h>

//Constants to indicate if the Register Select should be used
#define LCDNORS     0
#define LCDRS       1

//Constants to indicate if the Busy Flag should be clear before the operation is performed
#define WAITFORBF   1
#define NOWAITFORBF 0

//Subroutines contained in this file
void initLCD(void);
void microsec(int);
void nanosec(int);
void setupForLCD(int *);
void finishedWithLCD(int *);
int spreadData(int);
void writeToLCD(int,int,int);
int readFromLCD(int,int);
void lcdprint(char *);
void lcdshiftleft(int,int);
void lcdshiftright(int,int);
void lcdblink(int,int);
void ppInterruptVector(int);

//Global Variables
int  ppInterruptFlag=0;

//Parallel port interrupt subroutine
void ppInterruptVector(int sig_int)
{
    //Set the parallel port interrupt semaphore
     ppInterruptFlag = 1;
}

//Initialize the LCD as described in the HD44780 Datasheet
//Inputs passed - none
//Outputs returned - none
void initLCD()
{
     int readbyte,
         dummybyte,
         flagvalues;
     //Handle the parallel port interrupt using ppInterruptVector
     interrupt(SIG_PP, ppInterruptVector);

     //Set up DAI pin 15 as an output that is low
     SRU(LOW,DAI_PB15_I);
     SRU(HIGH,PBEN15_I);

     //Set up the DSP to access the LCD
     setupForLCD(&flagvalues);

     //Wait for 15 ms
     microsec(150);

     writeToLCD(LCDNORS,0x30,NOWAITFORBF);

     //Wait for 4.1 ms
     microsec( 41);

     writeToLCD(LCDNORS,0x30,NOWAITFORBF);

     //Wait for 100 us
     microsec(1);

     writeToLCD(LCDNORS,0x30,NOWAITFORBF);
     
     writeToLCD(LCDNORS,0x38,NOWAITFORBF);
     
     writeToLCD(LCDNORS,0x08,WAITFORBF);
     
     writeToLCD(LCDNORS,0x01,WAITFORBF);
     
     writeToLCD(LCDNORS,0x07,WAITFORBF);
     
     writeToLCD(LCDNORS,0x0C,WAITFORBF);
     
     finishedWithLCD(&flagvalues);

     return;
}

//Pause for a multiple of 100 us
//Inputs passed - duration in units of 100 us
//Outputs returned - none
void microsec(int duration)
{
     int i;

     for(i=0;i<duration;i++)
     {
          asm("lcntr=20000, do (pc,1) until lce; \
               nop;");
     }
     return;
}

//Pause for a multiple of 100 ns
//Inputs passed - duration in units of 100 ns
//Outputs returned - none
void nanosec(int duration)
{
     int i;

     for(i=0;i<duration;i++)
     {
          asm("lcntr=20, do (pc,1) until lce; \
               nop;");
     }
     return;
}

//Set up the DSP to access the LCD
//Inputs passed - Pointer to location to save the current value of the flags register
//Outputs returned - none
void setupForLCD(int * flagvalues)
{
     int dummy;

     asm("%0=flags;":"=d" (*flagvalues));

     asm("flags = 0xA8000000;");
     asm("flags = 0xA8000000;");

     REG(SYSCTL)|=PPFLGS;

     SRU(LOW,DAI_PB15_I);
     return;
}

//Restore the DSP to the state before accessing the LCD
//Inputs passed - Pointer to the location which contains the saved value of the flags register
//Outputs returned - none
void finishedWithLCD(int * flagvalues)
{
     int dummy;

     SRU(LOW,DAI_PB15_I);
     SRU(LOW,PBEN15_I);

     REG(SYSCTL)&=(0xFFFFFFFF-PPFLGS);

     asm("flags=%0;"::"d" (*flagvalues));
     asm("flags=%0;"::"d" (*flagvalues));

     return;
}

//Write to the LCD
//Inputs passed - RegisterSelect = Indicates the desired state of the RS pin
//                data = the byte of data to write to the lcd
//                bftest = wait for the busy flag to clear before writing
//Outputs returned - none
void writeToLCD(int RegisterSelect, int data, int bftest)
{
     const int Enable = 30,
               ReadWrite = 0;
     int busyflag=1;

     data=spreadData(data);

     if(bftest)
     {
          while(busyflag)
          {
               busyflag = readFromLCD(LCDNORS,NOWAITFORBF);
               busyflag = ((busyflag&0x80)>>7);
          }
     }

     asm("bit set flags 0xAAAA;");
     asm("bit clr flags 0x54005555;");

     asm("r0=flags; r0=r0 or %0; flags=r0;"::"d" (RegisterSelect<<26):"r0");
     asm("r0=flags; r0=r0 or %0; flags=r0;"::"d" (ReadWrite<<28):"r0");
     asm("r0=flags; r0=r0 or %0; flags=r0;"::"d" (data):"r0");
     nanosec(1);

     SRU(HIGH,DAI_PB15_I);
     nanosec(3);

     SRU(LOW,DAI_PB15_I);
     nanosec(1);

     return;
}

//Spread a byte of data to match the FLAGS register
//Inputs passed - data = byte of data to spread
//Outputs returned - the 2-byte equivalent of the input
int spreadData(int data)
{
     int  i,
          mask=0xff;

     for(i=7;i>0;i--)
     {
          mask = mask >> 1;
          data = (mask&data)|(((0xffffffff-mask)&data)<<1);
     }

     return data;
}

//Read from the LCD
//Inputs passed - RegisterSelect = Indicates the desired state of the RS pin
//                bftest = wait for the busy flag to clear before writing
//Outputs returned - the byte of data read from the LCD
int readFromLCD(int RegisterSelect, int bftest)
{
     const int Enable = 30,
               ReadWrite = 1;

     int data,
         busyflag = 1;

     if(bftest)
     {
          while(busyflag)
          {
               busyflag = readFromLCD(LCDNORS,NOWAITFORBF);
               busyflag = ((busyflag&0x80)>>7);
          }
     }

     asm("bit clr flags 0x5400AAAA;");

     asm("r0=flags; r0=r0 or %0; flags=r0;"::"d" (RegisterSelect<<26):"r0");
     asm("r0=flags; r0=r0 or %0; flags=r0;"::"d" (ReadWrite<<28):"r0");
     nanosec(1);

     SRU(HIGH,DAI_PB15_I);
     nanosec(3);

     asm("r0=flags; r1=0x5555; %0=r0 and r1;":"=d" (data)::"r0","r1");
     SRU(LOW,DAI_PB15_I);
     nanosec(1);

     data = despreadData(data);

     return data;
}

//Unspread a byte of data to match the FLAGS register
//Inputs passed - data = byte of data to unspread
//Outputs returned - the 2-byte equivalent of the input
int despreadData(int data)
{
     int  i,
          newdata=0,
          mask=1;

     for(i=0;i<8;i++)
     {
          newdata |= (mask&data);
          mask <<= 1;
          data >>= 1;
     }

     return newdata;
}

//Print a string to the LCD
//Inputs passed - the string to be printed.
//Outputs returned - none
void lcdprint(char * display)
{
     int i,flagvalues;

     //Set up the DSP to access the LCD
     setupForLCD(&flagvalues);

     //Set up the interface
     writeToLCD(LCDNORS,0x3C,WAITFORBF);
     //Turn on the display with no cursor
     writeToLCD(LCDNORS,0x0C,WAITFORBF);
     //Set the mode to increment the address by one and shift to the right
     writeToLCD(LCDNORS,0x06,WAITFORBF);

     //If the string is too long for the display memory, say so
     if(strlen(display)>40)
     {
          lcdprint("String too long");
          return;
     }

     //Clear the display
     writeToLCD(LCDNORS,0x01,WAITFORBF);

     //Return the cursor to home
     writeToLCD(LCDNORS,0x02,WAITFORBF);

     //For when the string is less than 8 characters
     if(strlen(display)<=8)
     {
          for(i=0;i<strlen(display);i++)
          {
               writeToLCD(LCDRS,display[i],WAITFORBF);
          }

          //Shift the cursor to the last 8 chars
          writeToLCD(LCDNORS,0xE0,WAITFORBF);

          //Write the last 8 chars
          for(i=0;i<strlen(display);i++)
          {
               writeToLCD(LCDRS,display[i],WAITFORBF);
          }          
     }

     //For all other cases
     else
     {
               //Write first 8 chars
          for(i=0;i<strlen(display);i++)
          {
               writeToLCD(LCDRS,display[i],WAITFORBF);
          }

          //Shift the cursor to the last 8 chars
          writeToLCD(LCDNORS,0xC0,WAITFORBF);

          //Write the last 8 chars
          for(i=0;i<(strlen(display)-8);i++)
          {
               writeToLCD(LCDRS,display[(i+8)],WAITFORBF);
          }

          //Shift the cursor to the last 8 chars
          writeToLCD(LCDNORS,0xE0,WAITFORBF);

          //Write the last 8 chars
          for(i=0;i<8;i++)
          {
               writeToLCD(LCDRS,display[i],WAITFORBF);
          }
     }
     
     finishedWithLCD(&flagvalues);
     return;
}

//Shift the contents of the LCD to the left
//Inputs passed - number of times to repeat the shift
//              - interval between the shifts
//Outputs returned - none
void lcdshiftleft(int number,int interval)
{
     int i,flagvalues;

     //Set up the DSP to access the LCD
     setupForLCD(&flagvalues);

     for(i=0;i<number;i++)
     {
          microsec(interval);
          //Write the shift left command
          writeToLCD(LCDNORS,0x18,WAITFORBF);
     }


     finishedWithLCD(&flagvalues);
     return;
}

//Shift the contents of the LCD to the right
//Inputs passed - number of times to repeat the shift
//              - interval between the shifts
//Outputs returned - none
void lcdshiftright(int number,int interval)
{
     int i,flagvalues;

     setupForLCD(&flagvalues);

     for(i=0;i<number;i++)
     {
          microsec(interval);
          //Write the shift right command
          writeToLCD(LCDNORS,0x1C,WAITFORBF);
     }

     finishedWithLCD(&flagvalues);
     return;
}

//Blink the contents of the LCD
//Inputs passed - number of times to blink
//              - Duration that the LCD is on/off
//Outputs returned - none
void lcdblink(int number,int interval)
{
     int i,flagvalues;

     setupForLCD(&flagvalues);
     for(i=0;i<number;i++)
     {
          microsec(interval);
          //Turn the display off
          writeToLCD(LCDNORS,0x08,WAITFORBF);
          microsec(interval);
          //Turn the display on
          writeToLCD(LCDNORS,0x0C,WAITFORBF);
     }
     finishedWithLCD(&flagvalues);
     return;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -