📄 lcd.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 + -