📄 main.cpp
字号:
/* main.cpp
*
* Sample program for controlling Nokia-type graphic LCD.
*
* Revisions:
* 08-21-06 changes in globals section
* 07-13-06 included in LCDSample project
*
* Written by Cathy Saxton
* robotics@idleloop.com
*/
#include <stdio.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include "main.h"
/*
* Globals
*
* If you change wiring, be sure to change this section as well!
*/
#define regA &DDRA, &PORTA, &PINA
#define regB &DDRB, &PORTB, &PINB
#define regC &DDRC, &PORTC, &PINC
#define regD &DDRD, &PORTD, &PIND
TIMER g_timer;
/* optional pushbutton on PB3 */
IN g_btnSel (regB, 3, fTrue); // button (with pull-up R)
/* LCD control lines */
OUT g_outE (regC, 0, 1); // start high (signal = !ChipSelect)
OUT g_outReset (regA, 7, 1); // start high (signal = !Reset)
/* data is sent using SPI; the following (three) definitions should be set
based on the pin assignments listed in the AVR datasheet*/
OUT g_outMOSI (regB, 5, 0); // goes to LCD's SDATA
OUT g_outSCK (regB, 7, 0); // goes to LCD's SCLK
/* note that in order for SPI to function properly (in SPI Master mode),
!SS must be set as an output (high or low), or as an input pulled high
(AVR default is input without pull-up, so we need something here) */
OUT g_outSS (regB, 4, 0);
LCD g_lcd(&g_outE, &g_outMOSI, &g_outSCK, &g_outReset,
&g_font5x9, clrYellow, clrDkBlue);
/*
* Main Program
*
* The code will automatically cycle through sample graphics screens;
* it will stop cycling if g_btnSel is pressed, and then will only advance
* when button is pressed (i.e. that turns off timed cycling).
*/
static const uint msWait = 5000; // time to show each screen (in milliseconds)
void ShowGraphics();
void ShowText();
void ShowBitmaps();
void ShowColors();
void VolumeExperiment(uchar ratioFirst, uchar ratioLast,
uchar volFirst, uchar volLast, uchar volStep, ulong ms);
/* the list of "Show" functions to cycle through */
typedef void (*PFN_SHOW)(void);
static const PFN_SHOW s_apfn[] =
{
ShowGraphics,
ShowText,
ShowBitmaps,
ShowColors,
};
static const uint cpfn = DIM(s_apfn);
int main()
{
ulong ms;
uint ipfn;
bool fAuto;
#if 0 // change this to "#if 1" to run experiment to determine best volume
/* the voltage used for the backlight will affect what values you need
to use to set the "volume" for the LCD; see header comment for
VolumeExperiment for details on experimenting to find a good value
for your system */
while (1)
VolumeExperiment(0, 7, 0, 63, 8, 250);
#endif
g_lcd.SetVolume(1, 14);
ipfn = 0;
fAuto = fTrue;
while (1)
{
(s_apfn[ipfn])();
if (++ipfn >= cpfn)
ipfn = 0;
if (fAuto)
{
/* wait for msWait before show next screen */
ms = g_timer.MsCur();
while (!g_timer.FElapsed(ms, msWait))
{
if (g_btnSel.FPressed())
{
/* cancel auto cycle; wait for button presses */
fAuto = fFalse;
goto LWaitButton;
}
}
}
else
{
LWaitButton:
while (!g_btnSel.FPressed())
;
}
}
return 0;
}
void ShowGraphics()
{
g_lcd.FillRect(0, 0, dxLCDScreen, dyLCDScreen, clrBlack);
g_lcd.DrawHLine(0, clrMagenta);
g_lcd.DrawHLine(129, clrRed);
g_lcd.DrawVLine(0, clrGreen);
g_lcd.DrawVLine(129, clrBlue);
g_lcd.FillRect(10, 10, 5, 5, clrMedBlue);
g_lcd.FrameRect(40, 20, 10, 10, clrMedRed);
g_lcd.FrameCircle(90, 30, 20, clrTeal);
g_lcd.ColorPixel(90, 30, clrDkTeal);
g_lcd.FillCircle(105, 85, 15, clrWhite);
#define xC 45
#define yC 80
#define d1 15
#define d2 37
g_lcd.DrawLine(xC, yC, xC+d1, yC+d2, clrGreen);
g_lcd.DrawLine(xC, yC, xC-d1, yC+d2, clrCyan);
g_lcd.DrawLine(xC, yC, xC-d1, yC-d2, clrWhite);
g_lcd.DrawLine(xC, yC, xC+d1, yC-d2, clrRed);
g_lcd.DrawLine(xC, yC, xC+d2, yC+d1, clrYellow);
g_lcd.DrawLine(xC, yC, xC-d2, yC+d1, clrBlue);
g_lcd.DrawLine(xC, yC, xC-d2, yC-d1, clrMagenta);
g_lcd.DrawLine(xC, yC, xC+d2, yC-d1, clrOrange);
}
void ShowText()
{
g_lcd.FillRect(0, 0, dxLCDScreen, dyLCDScreen, clrYellow);
g_lcd.FillCircle(100, 30, 20, clrWhite);
g_lcd.SetBackClr(clrTransparent);
#ifdef FONT_3x5
g_lcd.SetFont(&g_font3x5);
#endif
g_lcd.SetForeClr(clrMedBlue);
g_lcd.Print("The quick brown fox jumped", 1);
g_lcd.Print("over the lazy dogs! 0123456789", 0);
#ifdef FONT_5x9_MONO
g_lcd.SetFont(&g_font5x9Mono);
#endif
g_lcd.SetForeClr(clrMedGreen);
g_lcd.Print("The quick brown fox", 0);
g_lcd.Print("jumped over the lazy", 0);
g_lcd.Print("dogs!", 0);
g_lcd.SetFont(&g_font5x9);
g_lcd.SetForeClr(clrPurple);
g_lcd.Print("The quick brown fox", 6);
g_lcd.Print("jumped over the lazy", 0);
g_lcd.Print("dogs!", 0);
g_lcd.SetForeClr(clrMedRed);
g_lcd.SetBackClr(clrWhite);
g_lcd.Print("0123456789 +-*/ a<b;", 0);
g_lcd.Print("~!@#$%^&* ( ) [ ] { }", 0);
g_lcd.SetBackClr(clrBlack);
g_lcd.Print("no padding", 0, fFalse);
g_lcd.SetPos(5, 0); // move to the position 5 on this line
g_lcd.WriteCh('x');
g_lcd.WriteCh('y');
}
void ShowBitmaps()
{
g_lcd.FillRect(0, 0, dxLCDScreen, dyLCDScreen, clrBlack);
#ifdef BITMAP_FRACTAL
g_lcd.ShowBitmap(g_abFractal, 80, 75);
#endif
#ifdef BITMAP_GIRAFFE
g_lcd.ShowBitmap(g_abGiraffe, 10, 10);
#endif
}
void ShowColors()
{
uint i;
uchar aclr[] =
{
clrLtRed, clrLtOrange, clrLtYellow, clrLyGreen, clrLtCyan, clrLtBlue, clrLtMagenta, clrBlack,
clrRed, clrOrange, clrYellow, clrGreen, clrCyan, clrBlue, clrMagenta, clrWhite,
clrMedRed, clrBlack, clrBrown, clrMedGreen, clrTeal, clrMedBlue, clrPurple, clrBlack,
clrDkRed, clrBlack, clrBlack, clrDkGreen, clrDkTeal, clrDkBlue,
};
static const uint cclr = DIM(aclr);
g_lcd.FillRect(0, 0, dxLCDScreen, dyLCDScreen, clrBlack);
/* defined colors */
for (i = 0; i < cclr; ++i)
g_lcd.FillRect(1 + (i % 8) * 16, 1 + (i / 8) * 16, 16, 16, aclr[i]);
/* color bars */
for (i = 1; i < 8; ++i)
{
g_lcd.FillRect(1 + i * 16, 1 + 5 * 16, 16, 16, i << 5); // red
g_lcd.FillRect(1 + i * 16, 1 + 6 * 16, 16, 16, i << 2); // green
if (i < 4)
g_lcd.FillRect(1 + i * 16, 1 + 7 * 16, 16, 16, i); // blue
}
}
/* the voltage used for the backlight will affect what values you need
to use to set the "volume" for the LCD; call VolumeExperiment with different
parameters to experiment and find a good range for your system; example:
1. Do a coarse scan through the entire range to find a ratio that looks good:
VolumeExperiment(0, 7, 0, 63, 8, 250);
(this will take ~16 seconds to cycle)
2. Set the first two parameters to that ratio (e.g. 3 in this code), then
scan its full range looking for values to consider more carefully:
VolumeExperiment(3, 3, 0, 63, 2, 500);
(this will take ~16 seconds to cycle)
3. Set the second pair of parameters to the new, smaller range, then scan it
slowly to find your favorite volume value:
VolumeExperiment(3, 3, 18, 40, 1, 2000);
4. At the beginning of main(), add a call to g_lcd.SetVolume using the
ratio and volume values you've chosen.
*/
void VolumeExperiment(uchar ratioFirst, uchar ratioLast,
uchar volFirst, uchar volLast, uchar volStep, ulong ms)
{
uchar ratio, vol;
char szBuf[16];
ShowColors();
g_lcd.SetBackClr(clrWhite);
g_lcd.SetForeClr(clrBlack);
for (ratio = ratioFirst; ratio <= ratioLast; ++ratio)
{
for (vol = volFirst; vol <= volLast; vol += volStep)
{
g_lcd.SetVolume(ratio, vol);
snprintf(szBuf, sizeof(szBuf), " ratio = %2d", ratio);
g_lcd.Print(szBuf, 6);
snprintf(szBuf, sizeof(szBuf), " volume = %2d", vol);
g_lcd.Print(szBuf, 7);
g_timer.WaitMs(ms);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -