Difference between revisions of "NU32v2: Nokia 5110 LCD"
NickMarchuk (talk | contribs) |
|||
(17 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
'''THIS PAGE REFERS TO A PRE-RELEASE VERSION OF THE NU32 PIC32 DEVELOPMENT BOARD. FOR INFORMATION, SAMPLE CODE, AND VIDEOS RELATED TO THE PRODUCTION VERSION (2016 AND LATER), AND TO THE CORRESPONDING BOOK "EMBEDDED COMPUTING AND MECHATRONICS WITH THE PIC32 MICROCONTROLLER," VISIT [[NU32|THE NU32 PAGE]].''' |
|||
'''Page Under Construction''' |
|||
'''NDM 1/10/2011''' |
|||
[[Image:nu32v2_nokia5110_example.jpg|thumb|300px|The Sparkfun Nokia 5110 controlled by the NU32v2.|center]] |
|||
The [http://www.sparkfun.com/products/10168 Nokia 5110 from Sparkfun] is a 84 x 48 pixel monochrome LCD and breakout board. It is controlled using SPI communication and several digital outputs. |
|||
== |
== Overview == |
||
An LCD is a convenient tool for communication data using text. The Nokia 5110 provides 6 rows of 12 characters of text, or can be used to draw in a 84 x 48 pixel space. The contrast is digitally controlled and 4 white LEDs behind the LCD provide a backlight. |
|||
The LCD requires five communication pins from a microcontroller: SPI CLK and SDO, and three digital outputs. The LCD is powered with 3.3V. |
|||
== Details == |
|||
/* |
|||
[[Media:nokia5110.pdf|Datasheet]] |
|||
Use the Sparkfun SPI LCD |
|||
Nick Marchuk |
|||
12/21/2010 |
|||
Example schematic when communicating with the NU32v2: |
|||
from http://www.arduino.cc/playground/Code/PCD8544 |
|||
* LCD 1-Vcc -----> NU32v2 3.3V |
|||
*/ |
|||
* LCD 2-GND -----> NU32v2 GND |
|||
* LCD 3-SCE -----> NU32v2 E2 |
|||
#include <stdlib.h> |
|||
* LCD 4-RST -----> NU32v2 E1 |
|||
#include <plib.h> |
|||
* LCD 5-D/C -----> NU32v2 E0 |
|||
* LCD 6-DNK(MOSI) -----> NU32v2 F8 (SDO3) |
|||
* LCD 7-SCLK -----> NU32v2 D15 (SCK3) |
|||
* LCD 8-LED -----> 330 ohm -----> 5V |
|||
** Note: hooking up 8-LED is only required if you want to use the backlight |
|||
== Library Functions == |
|||
// Configuration Bit settings |
|||
Code: [[Media:Nokia5110.h|Nokia5110.h]], [[Media:Nokia5110.c|Nokia5110.c]] |
|||
// SYSCLK = 80 MHz (8MHz Crystal/ FPLLIDIV * FPLLMUL / FPLLODIV) |
|||
// PBCLK = 80 MHz |
|||
// Primary Osc w/PLL (XT+,HS+,EC+PLL) |
|||
// WDT OFF |
|||
// Use Dbg Comm channel 2 |
|||
// Other options are don't care |
|||
#pragma config FPLLMUL = MUL_20, FPLLIDIV = DIV_2, FPLLODIV = DIV_1, FWDTEN = OFF |
|||
#pragma config POSCMOD = HS, FNOSC = PRIPLL, FPBDIV = DIV_1 |
|||
#pragma config ICESEL = ICS_PGx2 |
|||
Full example: [[Media:NU32v2_Nokia5110_example.zip|All example code]] |
|||
#define GetSystemClock() (80000000ul) |
|||
#define GetPeripheralClock() (GetSystemClock()/(1 << OSCCONbits.PBDIV)) |
|||
#define SYS_FREQ (80000000L) |
|||
Nokia5110.h sets up control pins on E0, E1 and E2. These may be changed if desired. The file also contains function prototypes, constants, and a 96 x 5 element lookup array of ASCII characters. |
|||
/** LED ************************************************************/ |
|||
#define mInitAllLEDs() LATG |= 0x3000; TRISG &= 0xCFFF; |
|||
#define mLED_1 LATGbits.LATG12 |
|||
#define mLED_2 LATGbits.LATG13 |
|||
Nokia5110.c contains the following functions: |
|||
#define mGetLED_1() mLED_1 |
|||
* LcdCharacter - used to write an individual ASCII character |
|||
#define mGetLED_2() mLED_2 |
|||
* LcdClear - clears the entire LCD |
|||
* LcdInitialize - Initializes SPI3 (can be changed if desired) and sends the startup commands to the LCD |
|||
** The second command sent (LCD Vop) sets the contrast of the LCD and can be altered for more or less contrast |
|||
* LcdString - writes a string of characters to the LCD |
|||
* LcdWrite - sends individual commands to the LCD |
|||
** Sending commands before the LCD is ready for them will make the LCD miss them, so 1000 Nop()s are called between commands |
|||
* gotoXY - places the cursor at an x pixel (0-84) and y character (0-5) |
|||
* setPixel - turns on a pixel at x (0-84) and y (0-48) |
|||
== Sample Code == |
|||
#define mLED_1_On() mLED_1 = 0; // low |
|||
#define mLED_2_On() mLED_2 = 0; // low |
|||
Initialize and clear the LCD: |
|||
#define mLED_1_Off() mLED_1 = 1; // high |
|||
<code><pre> |
|||
#define mLED_2_Off() mLED_2 = 1; // high |
|||
LcdInitialize(); |
|||
LcdClear(); |
|||
#define mLED_1_Toggle() mLED_1 = !mLED_1; |
|||
</pre></code> |
|||
#define mLED_2_Toggle() mLED_2 = !mLED_2; |
|||
Go to the leftmost side of the screen on the second line and write 'Hello' |
|||
<code><pre> |
|||
gotoXY(0,1); |
|||
LcdString("Hello"); |
|||
</pre></code> |
|||
Write the value of a variable: |
|||
#define mInitMotor() LATD |= 0x0000; TRISD &= 0xFFF9; |
|||
<code><pre> |
|||
#define mDir LATDbits.LATD1 |
|||
char str[5]; |
|||
#define mEn LATDbits.LATD2 |
|||
sprintf(str, "i=%d", i); |
|||
#define mDir_Low() mDir = 0; // low |
|||
LcdString(str); |
|||
#define mDirHigh() mDir = 1; // high |
|||
</pre></code> |
|||
#define mEn_Low() mEn = 0; // low |
|||
#define mEn_High() mEn = 1; // high |
|||
Turn on a pixel at (20,35): |
|||
<code><pre> |
|||
setPixel(20,35,1); |
|||
</pre></code> |
|||
== More Information == |
|||
// The desired rs232 BaudRate |
|||
The sample code in [[Media:NU32v2_Nokia5110_example.zip|All example code]] will create the image at the top of this page. Sending the NU32v2 an 'a' over serial will clear the LCD. |
|||
#define DESIRED_BAUDRATE (115200)//(1000000)//(115200) |
|||
// general functions |
|||
void init_serial(); |
|||
void WriteString(const char *string); |
|||
void PutCharacter(const char character); |
|||
// finger position variables |
|||
char RS232_Out_Buffer[32]; |
|||
// LCD variables |
|||
#define mInitLCDPins() LATE |= 0x0000; TRISE &= 0xFFF8; |
|||
#define mPIN_SCE LATEbits.LATE2 // LCD CS .... Pin 3 |
|||
#define mPIN_RESET LATEbits.LATE1 // LCD RST .... Pin 1 |
|||
#define mPIN_DC LATEbits.LATE0 // LCD Dat/Com. Pin 5 |
|||
#define mSCE_Low() mPIN_SCE = 0; // low |
|||
#define mSCE_High() mPIN_SCE = 1; // high |
|||
#define mRESET_Low() mPIN_RESET = 0; // low |
|||
#define mRESET_High() mPIN_RESET = 1; // high |
|||
#define mDC_Low() mPIN_DC = 0; // low |
|||
#define mDC_High() mPIN_DC = 1; // high |
|||
//#define PIN_SDIN 4 // LCD SPIDat . Pin 6 |
|||
//#define PIN_SCLK 3 // LCD SPIClk . Pin 4 |
|||
// LCD Gnd .... Pin 2 |
|||
// LCD Vcc .... Pin 8 |
|||
// LCD Vlcd ... Pin 7 |
|||
#define LCD_C 0 |
|||
#define LCD_D 1 |
|||
#define LCD_X 84 |
|||
#define LCD_Y 48 |
|||
//#define LCD_CMD 0 |
|||
// lcd functions |
|||
void LcdCharacter(char); |
|||
void LcdClear(void); |
|||
void LcdInitialise(void); |
|||
void LcdString(char *); //void LcdString(char *characters) |
|||
void LcdWrite(char, char); |
|||
void gotoXY(int, int); |
|||
void drawLine(void); |
|||
static const char ASCII[96][5] = { |
|||
{0x00, 0x00, 0x00, 0x00, 0x00} // 20 (space) |
|||
,{0x00, 0x00, 0x5f, 0x00, 0x00} // 21 ! |
|||
,{0x00, 0x07, 0x00, 0x07, 0x00} // 22 " |
|||
,{0x14, 0x7f, 0x14, 0x7f, 0x14} // 23 # |
|||
,{0x24, 0x2a, 0x7f, 0x2a, 0x12} // 24 $ |
|||
,{0x23, 0x13, 0x08, 0x64, 0x62} // 25 % |
|||
,{0x36, 0x49, 0x55, 0x22, 0x50} // 26 & |
|||
,{0x00, 0x05, 0x03, 0x00, 0x00} // 27 ' |
|||
,{0x00, 0x1c, 0x22, 0x41, 0x00} // 28 ( |
|||
,{0x00, 0x41, 0x22, 0x1c, 0x00} // 29 ) |
|||
,{0x14, 0x08, 0x3e, 0x08, 0x14} // 2a * |
|||
,{0x08, 0x08, 0x3e, 0x08, 0x08} // 2b + |
|||
,{0x00, 0x50, 0x30, 0x00, 0x00} // 2c , |
|||
,{0x08, 0x08, 0x08, 0x08, 0x08} // 2d - |
|||
,{0x00, 0x60, 0x60, 0x00, 0x00} // 2e . |
|||
,{0x20, 0x10, 0x08, 0x04, 0x02} // 2f / |
|||
,{0x3e, 0x51, 0x49, 0x45, 0x3e} // 30 0 |
|||
,{0x00, 0x42, 0x7f, 0x40, 0x00} // 31 1 |
|||
,{0x42, 0x61, 0x51, 0x49, 0x46} // 32 2 |
|||
,{0x21, 0x41, 0x45, 0x4b, 0x31} // 33 3 |
|||
,{0x18, 0x14, 0x12, 0x7f, 0x10} // 34 4 |
|||
,{0x27, 0x45, 0x45, 0x45, 0x39} // 35 5 |
|||
,{0x3c, 0x4a, 0x49, 0x49, 0x30} // 36 6 |
|||
,{0x01, 0x71, 0x09, 0x05, 0x03} // 37 7 |
|||
,{0x36, 0x49, 0x49, 0x49, 0x36} // 38 8 |
|||
,{0x06, 0x49, 0x49, 0x29, 0x1e} // 39 9 |
|||
,{0x00, 0x36, 0x36, 0x00, 0x00} // 3a : |
|||
,{0x00, 0x56, 0x36, 0x00, 0x00} // 3b ; |
|||
,{0x08, 0x14, 0x22, 0x41, 0x00} // 3c < |
|||
,{0x14, 0x14, 0x14, 0x14, 0x14} // 3d = |
|||
,{0x00, 0x41, 0x22, 0x14, 0x08} // 3e > |
|||
,{0x02, 0x01, 0x51, 0x09, 0x06} // 3f ? |
|||
,{0x32, 0x49, 0x79, 0x41, 0x3e} // 40 @ |
|||
,{0x7e, 0x11, 0x11, 0x11, 0x7e} // 41 A |
|||
,{0x7f, 0x49, 0x49, 0x49, 0x36} // 42 B |
|||
,{0x3e, 0x41, 0x41, 0x41, 0x22} // 43 C |
|||
,{0x7f, 0x41, 0x41, 0x22, 0x1c} // 44 D |
|||
,{0x7f, 0x49, 0x49, 0x49, 0x41} // 45 E |
|||
,{0x7f, 0x09, 0x09, 0x09, 0x01} // 46 F |
|||
,{0x3e, 0x41, 0x49, 0x49, 0x7a} // 47 G |
|||
,{0x7f, 0x08, 0x08, 0x08, 0x7f} // 48 H |
|||
,{0x00, 0x41, 0x7f, 0x41, 0x00} // 49 I |
|||
,{0x20, 0x40, 0x41, 0x3f, 0x01} // 4a J |
|||
,{0x7f, 0x08, 0x14, 0x22, 0x41} // 4b K |
|||
,{0x7f, 0x40, 0x40, 0x40, 0x40} // 4c L |
|||
,{0x7f, 0x02, 0x0c, 0x02, 0x7f} // 4d M |
|||
,{0x7f, 0x04, 0x08, 0x10, 0x7f} // 4e N |
|||
,{0x3e, 0x41, 0x41, 0x41, 0x3e} // 4f O |
|||
,{0x7f, 0x09, 0x09, 0x09, 0x06} // 50 P |
|||
,{0x3e, 0x41, 0x51, 0x21, 0x5e} // 51 Q |
|||
,{0x7f, 0x09, 0x19, 0x29, 0x46} // 52 R |
|||
,{0x46, 0x49, 0x49, 0x49, 0x31} // 53 S |
|||
,{0x01, 0x01, 0x7f, 0x01, 0x01} // 54 T |
|||
,{0x3f, 0x40, 0x40, 0x40, 0x3f} // 55 U |
|||
,{0x1f, 0x20, 0x40, 0x20, 0x1f} // 56 V |
|||
,{0x3f, 0x40, 0x38, 0x40, 0x3f} // 57 W |
|||
,{0x63, 0x14, 0x08, 0x14, 0x63} // 58 X |
|||
,{0x07, 0x08, 0x70, 0x08, 0x07} // 59 Y |
|||
,{0x61, 0x51, 0x49, 0x45, 0x43} // 5a Z |
|||
,{0x00, 0x7f, 0x41, 0x41, 0x00} // 5b [ |
|||
,{0x02, 0x04, 0x08, 0x10, 0x20} // 5c ¥ |
|||
,{0x00, 0x41, 0x41, 0x7f, 0x00} // 5d ] |
|||
,{0x04, 0x02, 0x01, 0x02, 0x04} // 5e ^ |
|||
,{0x40, 0x40, 0x40, 0x40, 0x40} // 5f _ |
|||
,{0x00, 0x01, 0x02, 0x04, 0x00} // 60 ` |
|||
,{0x20, 0x54, 0x54, 0x54, 0x78} // 61 a |
|||
,{0x7f, 0x48, 0x44, 0x44, 0x38} // 62 b |
|||
,{0x38, 0x44, 0x44, 0x44, 0x20} // 63 c |
|||
,{0x38, 0x44, 0x44, 0x48, 0x7f} // 64 d |
|||
,{0x38, 0x54, 0x54, 0x54, 0x18} // 65 e |
|||
,{0x08, 0x7e, 0x09, 0x01, 0x02} // 66 f |
|||
,{0x0c, 0x52, 0x52, 0x52, 0x3e} // 67 g |
|||
,{0x7f, 0x08, 0x04, 0x04, 0x78} // 68 h |
|||
,{0x00, 0x44, 0x7d, 0x40, 0x00} // 69 i |
|||
,{0x20, 0x40, 0x44, 0x3d, 0x00} // 6a j |
|||
,{0x7f, 0x10, 0x28, 0x44, 0x00} // 6b k |
|||
,{0x00, 0x41, 0x7f, 0x40, 0x00} // 6c l |
|||
,{0x7c, 0x04, 0x18, 0x04, 0x78} // 6d m |
|||
,{0x7c, 0x08, 0x04, 0x04, 0x78} // 6e n |
|||
,{0x38, 0x44, 0x44, 0x44, 0x38} // 6f o |
|||
,{0x7c, 0x14, 0x14, 0x14, 0x08} // 70 p |
|||
,{0x08, 0x14, 0x14, 0x18, 0x7c} // 71 q |
|||
,{0x7c, 0x08, 0x04, 0x04, 0x08} // 72 r |
|||
,{0x48, 0x54, 0x54, 0x54, 0x20} // 73 s |
|||
,{0x04, 0x3f, 0x44, 0x40, 0x20} // 74 t |
|||
,{0x3c, 0x40, 0x40, 0x20, 0x7c} // 75 u |
|||
,{0x1c, 0x20, 0x40, 0x20, 0x1c} // 76 v |
|||
,{0x3c, 0x40, 0x30, 0x40, 0x3c} // 77 w |
|||
,{0x44, 0x28, 0x10, 0x28, 0x44} // 78 x |
|||
,{0x0c, 0x50, 0x50, 0x50, 0x3c} // 79 y |
|||
,{0x44, 0x64, 0x54, 0x4c, 0x44} // 7a z |
|||
,{0x00, 0x08, 0x36, 0x41, 0x00} // 7b { |
|||
,{0x00, 0x00, 0x7f, 0x00, 0x00} // 7c | |
|||
,{0x00, 0x41, 0x36, 0x08, 0x00} // 7d } |
|||
,{0x10, 0x08, 0x08, 0x10, 0x08} // 7e ? |
|||
,{0x00, 0x06, 0x09, 0x09, 0x06} // 7f ? |
|||
}; // end char ASCII[96][5] |
|||
unsigned short int channel4; // conversion result as read from result buffer |
|||
unsigned short int channel5; // conversion result as read from result buffer |
|||
// main |
|||
int main(void) { |
|||
unsigned int pb_clock; |
|||
SYSTEMConfig(SYS_FREQ, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE); |
|||
// configure for multi-vectored mode |
|||
INTConfigureSystem(INT_SYSTEM_CONFIG_MULT_VECTOR); |
|||
// enable multi-vector interrupts |
|||
INTEnableSystemMultiVectoredInt(); |
|||
// initialize serial port and interrupt |
|||
init_serial(); |
|||
// initialize the leds |
|||
mInitAllLEDs(); |
|||
mLED_1_Off(); // low |
|||
mLED_2_On(); // low |
|||
LcdInitialise(); |
|||
LcdClear(); |
|||
// configure and enable the ADC |
|||
CloseADC10(); // ensure the ADC is off before setting the configuration |
|||
// define setup parameters for OpenADC10 |
|||
// Turn module on | output in integer | trigger mode auto | enable autosample |
|||
#define PARAM1 ADC_MODULE_ON | ADC_FORMAT_INTG | ADC_CLK_AUTO | ADC_AUTO_SAMPLING_ON |
|||
// define setup parameters for OpenADC10 |
|||
// ADC ref external | disable offset test | enable scan mode | perform 2 samples | use one buffer | use MUXA mode |
|||
// note: to read X number of pins you must set ADC_SAMPLES_PER_INT_X |
|||
#define PARAM2 ADC_VREF_AVDD_AVSS | ADC_OFFSET_CAL_DISABLE | ADC_SCAN_ON | ADC_SAMPLES_PER_INT_2 | ADC_ALT_BUF_OFF | ADC_ALT_INPUT_OFF |
|||
// define setup parameters for OpenADC10 |
|||
// use ADC internal clock | set sample time |
|||
#define PARAM3 ADC_CONV_CLK_INTERNAL_RC | ADC_SAMPLE_TIME_15 |
|||
// define setup parameters for OpenADC10 |
|||
// set AN4 and AN5 |
|||
#define PARAM4 ENABLE_AN4_ANA | ENABLE_AN5_ANA |
|||
// define setup parameters for OpenADC10 |
|||
// do not assign channels to scan |
|||
#define PARAM5 SKIP_SCAN_AN0 | SKIP_SCAN_AN1 | SKIP_SCAN_AN2 | SKIP_SCAN_AN3 | SKIP_SCAN_AN6 | SKIP_SCAN_AN7 | SKIP_SCAN_AN8 | SKIP_SCAN_AN9 | SKIP_SCAN_AN10 | SKIP_SCAN_AN11 | SKIP_SCAN_AN12 | SKIP_SCAN_AN13 | SKIP_SCAN_AN14 | SKIP_SCAN_AN15 |
|||
// use ground as neg ref for A |
|||
SetChanADC10( ADC_CH0_NEG_SAMPLEA_NVREF); // use ground as the negative reference |
|||
OpenADC10( PARAM1, PARAM2, PARAM3, PARAM4, PARAM5 ); // configure ADC using parameter define above |
|||
EnableADC10(); // Enable the ADC |
|||
while ( ! mAD1GetIntFlag() ) { } // wait for the first conversion to complete so there will be valid data in ADC result registers |
|||
int a,b; |
|||
char Str[15]; |
|||
// Draw a Box |
|||
//for(b=1000; b>0; b--){ |
|||
//drawLine(); |
|||
//for(a=0; a<=5 ; a++){ |
|||
gotoXY(0,1); |
|||
// Put text in Box |
|||
LcdString("1 Test1"); |
|||
gotoXY(0,0); |
|||
LcdString("012345678901"); |
|||
gotoXY(25,2); |
|||
LcdString("Test2"); |
|||
gotoXY(16,3); |
|||
LcdString("Test3"); |
|||
gotoXY(0,2); |
|||
LcdString("2"); |
|||
gotoXY(0,3); |
|||
LcdString("3"); |
|||
gotoXY(0,4); |
|||
LcdString("4"); |
|||
gotoXY(0,5); |
|||
LcdString("5"); |
|||
/* |
|||
gotoXY(24,3); |
|||
LcdCharacter('H'); |
|||
LcdCharacter('E'); |
|||
LcdCharacter('L'); |
|||
LcdCharacter('L'); |
|||
LcdCharacter('O'); |
|||
LcdCharacter(' '); |
|||
LcdCharacter('='); |
|||
// Draw + at this position |
|||
gotoXY(10,3); |
|||
LcdCharacter('='); |
|||
//delay(500); |
|||
gotoXY(24,3); |
|||
LcdCharacter('h'); |
|||
LcdCharacter('e'); |
|||
LcdCharacter('l'); |
|||
LcdCharacter('l'); |
|||
LcdCharacter('o'); |
|||
LcdCharacter(' '); |
|||
LcdCharacter('-'); |
|||
// Draw - at this position |
|||
gotoXY(10,3); |
|||
LcdCharacter('-'); |
|||
*/ |
|||
mLED_1_On(); |
|||
while(1) { |
|||
channel4 = ReadADC10(0); // read the result of channel 4 |
|||
sprintf(RS232_Out_Buffer,"a=%d",channel4); |
|||
gotoXY(25,4); |
|||
LcdString(RS232_Out_Buffer); |
|||
} |
|||
return 0; |
|||
} // end main |
|||
// init serial |
|||
void init_serial() { |
|||
int pbClk; |
|||
// Configure the system performance |
|||
pbClk = SYSTEMConfigPerformance(SYS_FREQ); |
|||
UARTConfigure(UART2A, UART_ENABLE_PINS_TX_RX_ONLY); |
|||
UARTSetFifoMode(UART2A, UART_INTERRUPT_ON_TX_DONE | UART_INTERRUPT_ON_RX_NOT_EMPTY); |
|||
UARTSetLineControl(UART2A, UART_DATA_SIZE_8_BITS | UART_PARITY_NONE | UART_STOP_BITS_1); |
|||
UARTSetDataRate(UART2A, GetPeripheralClock(), DESIRED_BAUDRATE); |
|||
UARTEnable(UART2A, UART_ENABLE_FLAGS(UART_PERIPHERAL | UART_RX | UART_TX)); |
|||
// Configure UART2A RX Interrupt |
|||
INTEnable(INT_U2ARX, INT_ENABLED); |
|||
INTSetVectorPriority(INT_UART_2A_VECTOR, INT_PRIORITY_LEVEL_2); |
|||
INTSetVectorSubPriority(INT_UART_2A_VECTOR, INT_SUB_PRIORITY_LEVEL_0); |
|||
} // end init serial |
|||
// write string |
|||
void WriteString(const char *string) { |
|||
while(*string != '\0') { |
|||
while(!UARTTransmitterIsReady(UART2A)); |
|||
UARTSendDataByte(UART2A, *string); |
|||
string++; |
|||
while(!UARTTransmissionHasCompleted(UART2A)); |
|||
} |
|||
} // end write string |
|||
// put character |
|||
void PutCharacter(const char character) { |
|||
while(!UARTTransmitterIsReady(UART2A)); |
|||
UARTSendDataByte(UART2A, character); |
|||
while(!UARTTransmissionHasCompleted(UART2A)); |
|||
} // end put character |
|||
// UART 2A interrupt handler, priority level 2 |
|||
void __ISR(_UART_2A_VECTOR, ipl2) IntUart2AHandler(void) { |
|||
// Is this an RX interrupt? |
|||
if(INTGetFlag(INT_SOURCE_UART_RX(UART2A))){ |
|||
// Clear the RX interrupt Flag |
|||
INTClearFlag(INT_SOURCE_UART_RX(UART2A)); |
|||
// Echo what we just received |
|||
//PutCharacter(UARTGetDataByte(UART2A)); |
|||
if(UARTGetDataByte(UART2A)=='a') { |
|||
// |
|||
} |
|||
} |
|||
// We don't care about TX interrupt |
|||
if(INTGetFlag(INT_SOURCE_UART_TX(UART2A))) { |
|||
INTClearFlag(INT_SOURCE_UART_TX(UART2A)); |
|||
} |
|||
} // end uart2 int |
|||
/////////////////////////////////////////////////////////////////////////////////////// |
|||
///////// LCD Functions ///////////////////////////////////////////////////////////// |
|||
/////////////////////////////////////////////////////////////////////////////////////// |
|||
void LcdCharacter(char character) |
|||
{ |
|||
LcdWrite(LCD_D, 0x00); |
|||
int index; |
|||
for (index = 0; index < 5; index++) |
|||
{ |
|||
LcdWrite(LCD_D, ASCII[character - 0x20][index]); |
|||
//LcdWrite(LCD_D, ASCII[character - 0x20 + index]); |
|||
} |
|||
LcdWrite(LCD_D, 0x00); |
|||
} |
|||
void LcdClear(void) |
|||
{ |
|||
int index; |
|||
for (index = 0; index < LCD_X * LCD_Y / 8; index++) |
|||
{ |
|||
LcdWrite(LCD_D, 0x00); |
|||
} |
|||
} |
|||
void LcdInitialise(void) |
|||
{ |
|||
//pinMode(PIN_SCE, OUTPUT); |
|||
//pinMode(PIN_RESET, OUTPUT); |
|||
//pinMode(PIN_DC, OUTPUT); |
|||
//pinMode(PIN_SDIN, OUTPUT); |
|||
//pinMode(PIN_SCLK, OUTPUT); |
|||
mInitLCDPins(); |
|||
SpiChnOpen(SPI_CHANNEL1A, SPI_OPEN_MSTEN|SPI_OPEN_MODE8|SPI_OPEN_ON, GetPeripheralClock()/100000); // will open SPI3 and set the bit rate to .1MHz |
|||
//digitalWrite(PIN_RESET, LOW); |
|||
// delay(1); |
|||
//digitalWrite(PIN_RESET, HIGH); |
|||
mRESET_Low(); |
|||
mRESET_High(); |
|||
mSCE_High(); |
|||
LcdWrite(LCD_C, 0x21 ); // LCD Extended Commands. |
|||
LcdWrite(LCD_C, 185 ); // Set LCD Vop (Contrast). //B1 |
|||
LcdWrite(LCD_C, 0x04 ); // Set Temp coefficent. //0x04 |
|||
LcdWrite(LCD_C, 0x14 ); // LCD bias mode 1:48. //0x13 |
|||
LcdWrite(LCD_C, 0x0C ); // LCD in normal mode. 0x0d for inverse |
|||
LcdWrite(LCD_C, 0x20); |
|||
LcdWrite(LCD_C, 0x0C); |
|||
} |
|||
void LcdString(char *characters) |
|||
{ |
|||
while (*characters) |
|||
{ |
|||
LcdCharacter(*characters++); |
|||
} |
|||
} |
|||
void LcdWrite(char dc, char data) |
|||
{ |
|||
//digitalWrite(PIN_DC, dc); |
|||
//digitalWrite(PIN_SCE, LOW); |
|||
if(dc) { |
|||
mDC_High(); |
|||
} |
|||
else { |
|||
mDC_Low(); |
|||
} |
|||
mSCE_Low(); |
|||
//shiftOut(PIN_SDIN, PIN_SCLK, MSBFIRST, data); |
|||
SpiChnPutC(SPI_CHANNEL1A, data); |
|||
int i; |
|||
for (i=0; i<10000; i++) { |
|||
Nop(); |
|||
} |
|||
//digitalWrite(PIN_SCE, HIGH); |
|||
mSCE_High(); |
|||
} |
|||
// gotoXY routine to position cursor |
|||
// x - range: 0 to 84 |
|||
// y - range: 0 to 5 |
|||
void gotoXY(int x, int y) |
|||
{ |
|||
LcdWrite( 0, 0x80 | x); // Column. |
|||
LcdWrite( 0, 0x40 | y); // Row. |
|||
} |
|||
void drawLine(void) |
|||
{ |
|||
unsigned char j; |
|||
for(j=0; j<84; j++) // top |
|||
{ |
|||
gotoXY (j,0); |
|||
LcdWrite (1,0x01); |
|||
} |
|||
for(j=0; j<84; j++) //Bottom |
|||
{ |
|||
gotoXY (j,5); |
|||
LcdWrite (1,0x80); |
|||
} |
|||
for(j=0; j<6; j++) // Right |
|||
{ |
|||
gotoXY (83,j); |
|||
LcdWrite (1,0xff); |
|||
} |
|||
for(j=0; j<6; j++) // Left |
|||
{ |
|||
gotoXY (0,j); |
|||
LcdWrite (1,0xff); |
|||
} |
|||
} |
Latest revision as of 05:28, 16 January 2016
THIS PAGE REFERS TO A PRE-RELEASE VERSION OF THE NU32 PIC32 DEVELOPMENT BOARD. FOR INFORMATION, SAMPLE CODE, AND VIDEOS RELATED TO THE PRODUCTION VERSION (2016 AND LATER), AND TO THE CORRESPONDING BOOK "EMBEDDED COMPUTING AND MECHATRONICS WITH THE PIC32 MICROCONTROLLER," VISIT THE NU32 PAGE.
The Nokia 5110 from Sparkfun is a 84 x 48 pixel monochrome LCD and breakout board. It is controlled using SPI communication and several digital outputs.
Overview
An LCD is a convenient tool for communication data using text. The Nokia 5110 provides 6 rows of 12 characters of text, or can be used to draw in a 84 x 48 pixel space. The contrast is digitally controlled and 4 white LEDs behind the LCD provide a backlight.
The LCD requires five communication pins from a microcontroller: SPI CLK and SDO, and three digital outputs. The LCD is powered with 3.3V.
Details
Example schematic when communicating with the NU32v2:
- LCD 1-Vcc -----> NU32v2 3.3V
- LCD 2-GND -----> NU32v2 GND
- LCD 3-SCE -----> NU32v2 E2
- LCD 4-RST -----> NU32v2 E1
- LCD 5-D/C -----> NU32v2 E0
- LCD 6-DNK(MOSI) -----> NU32v2 F8 (SDO3)
- LCD 7-SCLK -----> NU32v2 D15 (SCK3)
- LCD 8-LED -----> 330 ohm -----> 5V
- Note: hooking up 8-LED is only required if you want to use the backlight
Library Functions
Code: Nokia5110.h, Nokia5110.c
Full example: All example code
Nokia5110.h sets up control pins on E0, E1 and E2. These may be changed if desired. The file also contains function prototypes, constants, and a 96 x 5 element lookup array of ASCII characters.
Nokia5110.c contains the following functions:
- LcdCharacter - used to write an individual ASCII character
- LcdClear - clears the entire LCD
- LcdInitialize - Initializes SPI3 (can be changed if desired) and sends the startup commands to the LCD
- The second command sent (LCD Vop) sets the contrast of the LCD and can be altered for more or less contrast
- LcdString - writes a string of characters to the LCD
- LcdWrite - sends individual commands to the LCD
- Sending commands before the LCD is ready for them will make the LCD miss them, so 1000 Nop()s are called between commands
- gotoXY - places the cursor at an x pixel (0-84) and y character (0-5)
- setPixel - turns on a pixel at x (0-84) and y (0-48)
Sample Code
Initialize and clear the LCD:
LcdInitialize();
LcdClear();
Go to the leftmost side of the screen on the second line and write 'Hello'
gotoXY(0,1);
LcdString("Hello");
Write the value of a variable:
char str[5];
sprintf(str, "i=%d", i);
LcdString(str);
Turn on a pixel at (20,35):
setPixel(20,35,1);
More Information
The sample code in All example code will create the image at the top of this page. Sending the NU32v2 an 'a' over serial will clear the LCD.