A midrange PIC like the 16F688 uses PORT for output (and input) and TRIS for data direction so lcd_port must be PORTC, not TRISC. If you have gotten to a flashing cursor then you know that the basic databus, E etc is working. I would highly discourage changing direction again.#define lcd_port TRISC // NO
According to the datasheet for the 16F688: PORT is bi-directional, and the corresponding datadirection register is TRIS.
My IC do not have LAT, but TRIS.
Keep in mind that specifying XTAL_FREQ to the compiler has nothing to do with what the actual oscillator is running at, it only tells the compiler what you have set the oscillator to so that it knows how to compute delays. If the 300ms delay is problematic, comment it out for now.Do you think my delays look correct and that the _XTAL_FREQ is correct?
Leave the LCD out of circuit for now. Does the timing on the enable pin agree with your code?I have toggled the enable pin on/off every 10ms and it gives a nice square wave at 5V peak. However, when I plug the LCD in the square wave remains the same except the peak voltage is now 1.5V.
while(1)
{
LCD_ENout=1;
__delay_ms(10);
LCD_RSout=1; // power up delay for LCD
__delay_ms(10);
LCD_ENout=0;
//__delay_ms(10);
LCD_RSout=0; // power up delay for LCD
__delay_ms(10);
}
Change:
#pragma config CPUDIV = NOCLKDIV// CPU System Clock Selection Bit (NO CPU system divide)
_XTAL_FREQ = 4000000 // tell compiler we are running at 4MHz
//Add:
OSCCON = 0b00110100 // Internal oscillator = 4MHz (for now)
// PIC16F1459 Configuration Bit Settings
// 'C' source line config statements
#include <xc.h>
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
// CONFIG1
#pragma config FOSC = INTOSC // Oscillator Selection Bits (INTOSC oscillator: I/O function on CLKIN pin)
#pragma config WDTE = OFF // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = ON // Power-up Timer Enable (PWRT enabled)
#pragma config MCLRE = ON // MCLR Pin Function Select (MCLR/VPP pin function is MCLR)
#pragma config CP = OFF // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config BOREN = OFF // Brown-out Reset Enable (Brown-out Reset disabled)
#pragma config CLKOUTEN = OFF // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
#pragma config IESO = ON // Internal/External Switchover Mode (Internal/External Switchover Mode is enabled)
#pragma config FCMEN = ON // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled)
// CONFIG2
#pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off)
#pragma config CPUDIV = NOCLKDIV// CPU System Clock Selection Bit (NO CPU system divide)
#pragma config USBLSCLK = 48MHz // USB Low SPeed Clock Selection bit (System clock expects 48 MHz, FS/LS USB CLKENs divide-by is set to 8.)
#pragma config PLLMULT = 3x // PLL Multipler Selection Bit (3x Output Frequency Selected)
#pragma config PLLEN = ENABLED // PLL Enable Bit (3x or 4x PLL Enabled)
#pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset)
#pragma config BORV = LO // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LPBOR = OFF // Low-Power Brown Out Reset (Low-Power BOR is disabled)
#pragma config LVP = OFF // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming)
#define _XTAL_FREQ 4000000
//The pins used are same as explained earlier
#define lcd_port LATC // write to LAT, read from PORT
// RC7-4 is the LCD 4 bit databus
#define LCD_RSout LATC2 // moved from ICSP
#define LCD_ENout LATC3
// RC0,RC1 reserved for ICSP DEBUG
//======================= MAIN =====================================
void main ()
{
OSCCON = 0b00110100; // Internal oscillator = 4MHz (for now)
TRISC=0b00000000;
PORTC=0b00000000;
ANSELC=0b00000000;
TRISB=0b00000000;
PORTB=0b00000000;
ANSELB=0b00000000;
TRISA=0b00000000;
PORTA=0b00000000;
ANSELA=0b00000000;
while(1){
LCD_ENout=1;
__delay_ms(10); // 10ms ON
LCD_ENout=0;
__delay_ms(10);// 10ms OFF
}//while
}//main
// PIC16F1459 Configuration Bit Settings
// 'C' source line config statements
#include <xc.h>
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
// CONFIG1
#pragma config FOSC = INTOSC // Oscillator Selection Bits (INTOSC oscillator: I/O function on CLKIN pin)
#pragma config WDTE = OFF // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = ON // Power-up Timer Enable (PWRT enabled)
#pragma config MCLRE = ON // MCLR Pin Function Select (MCLR/VPP pin function is MCLR)
#pragma config CP = OFF // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config BOREN = OFF // Brown-out Reset Enable (Brown-out Reset disabled)
#pragma config CLKOUTEN = OFF // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
#pragma config IESO = ON // Internal/External Switchover Mode (Internal/External Switchover Mode is enabled)
#pragma config FCMEN = ON // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled)
// CONFIG2
#pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off)
#pragma config CPUDIV = NOCLKDIV// CPU System Clock Selection Bit (NO CPU system divide)
#pragma config USBLSCLK = 48MHz // USB Low SPeed Clock Selection bit (System clock expects 48 MHz, FS/LS USB CLKENs divide-by is set to 8.)
#pragma config PLLMULT = 3x // PLL Multipler Selection Bit (3x Output Frequency Selected)
#pragma config PLLEN = ENABLED // PLL Enable Bit (3x or 4x PLL Enabled)
#pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset)
#pragma config BORV = LO // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LPBOR = OFF // Low-Power Brown Out Reset (Low-Power BOR is disabled)
#pragma config LVP = OFF // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming)
#define _XTAL_FREQ 4000000 //31250
//The pins used are same as explained earlier
#define lcd_port LATC // write to LAT, read from PORT
// RC7-4 is the LCD 4 bit databus
#define LCD_RSout LATC2 // moved from ICSP
#define LCD_ENout LATC3
#define TRIGout LATB7 // RB7 is trigger out
// RC0,RC1 reserved for ICSP DEBUG
//======================= MAIN =====================================
void main ()
{
unsigned char i;
OSCCON = 0b00110100; // Internal oscillator = 4MHz (for now)
TRISC=0b00000000;
PORTC=0b00000000;
ANSELC=0b00000000;
TRISB=0b00000000;
PORTB=0b00000000;
ANSELB=0b00000000;
TRISA=0b00000000;
PORTA=0b00000000;
ANSELA=0b00000000;
while(1){
TRIGout = 1; // trigger the scope
TRIGout = 0;
for(i=0x80; i; ){ // rotate a bit through PORTC
LATC = i;
__delay_ms(10); // 10ms ON
i = i>>1;
}// for
}//while
}//main
// PIC16F1459 Configuration Bit Settings
// 'C' source line config statements
#include <xc.h>
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
// CONFIG1
#pragma config FOSC = INTOSC // Oscillator Selection Bits (INTOSC oscillator: I/O function on CLKIN pin)
#pragma config WDTE = OFF // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = ON // Power-up Timer Enable (PWRT enabled)
#pragma config MCLRE = ON // MCLR Pin Function Select (MCLR/VPP pin function is MCLR)
#pragma config CP = OFF // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config BOREN = OFF // Brown-out Reset Enable (Brown-out Reset disabled)
#pragma config CLKOUTEN = OFF // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
#pragma config IESO = ON // Internal/External Switchover Mode (Internal/External Switchover Mode is enabled)
#pragma config FCMEN = ON // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled)
// CONFIG2
#pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off)
#pragma config CPUDIV = NOCLKDIV// CPU System Clock Selection Bit (NO CPU system divide)
#pragma config USBLSCLK = 48MHz // USB Low SPeed Clock Selection bit (System clock expects 48 MHz, FS/LS USB CLKENs divide-by is set to 8.)
#pragma config PLLMULT = 3x // PLL Multipler Selection Bit (3x Output Frequency Selected)
#pragma config PLLEN = ENABLED // PLL Enable Bit (3x or 4x PLL Enabled)
#pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset)
#pragma config BORV = LO // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LPBOR = OFF // Low-Power Brown Out Reset (Low-Power BOR is disabled)
#pragma config LVP = OFF // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming)
#define _XTAL_FREQ 4000000 // 4MHz for now
//---------------------IO DEFINITIONS --------------------------
#define lcd_port LATC // write to LAT, read from PORT
// RC7-4 is the LCD 4 bit databus
#define LCD_RSout LATC2 // moved from ICSP
#define LCD_ENout LATC3
// RC0,RC1 reserved for ICSP DEBUG
//--------------------- STROBE LCD ---------------------------
// Pulses E line on LCD to write
int strobeLCD(void)
{
LCD_ENout = 1;
__delay_us(2); // Added a little here
LCD_ENout = 0;
}
//--------------------- WRITE 8 BIT DATA TO LCD -----------------
// Assumes LCD is ready and RS is set to correct value
// LCD data bus is RC4-RC7
// Enable cycle time is a side effect of execution time - faster clocks
// may require a specific delay.
void writeLCD(unsigned char dat)
{
lcd_port &= 0x0f; // get current port, clear upper bits
lcd_port |= (dat & 0xf0); // combine w/upper nibble, leave lower same
strobeLCD();
lcd_port &= 0x0f; // get current port, clear upper bits
lcd_port |= ((dat <<4) & (0xf0)); // combine w/lower nibble, leave lower port same
strobeLCD();
__delay_us(60); // wait for display to process
// This is sufficient for all but
// Clear display and Return - those need
// 1.52 ms
// We will revisit this...
}
//-------------------- WRITE LCD COMMAND --------------------
// Assumes E is low and display is NOT busy
void lcd_cmd (unsigned char cmd)
{
LCD_RSout = 0; // select command register
writeLCD(cmd);
}
//---------------------- WRITE LCD DATA --------------------------
void lcd_data (unsigned char dat)
{
LCD_RSout = 1; // select data register
writeLCD(dat);
}
//-------------------- RESET/CONFIGURE LCD -------------------------
// Delays are generous, trim when able
void lcd_reset()
{
lcd_port &= 0x0f; // clear upper bits of LCD port
lcd_port |= 0x30; // direct data to LCD DB7-4
LCD_RSout = 0;
strobeLCD(); // write 3h, wait 10ms
__delay_ms(10);
strobeLCD(); // write 3h, wait..
__delay_ms(10);
strobeLCD(); // write 3h
__delay_ms(10);
}
//------------------------ INIT AND CONFIGURE LCD ---------------------
void lcd_init ()
{
lcd_reset(); // LCD reset
lcd_cmd(0x28); // Funciton Set: 4-bit mode - 2 line - 5x7 font.
lcd_cmd(0x0F); // DisplayON, cursor ON, blink ON
lcd_cmd(0x06); // Automatic Increment - No Display shift.
lcd_cmd(0x80); // Address DDRAM with 0 offset 80h.
}
//======================= MAIN =====================================
void main ()
{
OSCCON = 0b00110100; // Internal oscillator = 4MHz (for now)
TRISC=0b00000000;
PORTC=0b00000000;
ANSELC=0b00000000;
TRISB=0b00000000;
PORTB=0b00000000;
ANSELB=0b00000000;
TRISA=0b00000000;
PORTA=0b00000000;
ANSELA=0b00000000;
__delay_ms(300); // power up delay for LCD
lcd_init();
//lcd_data('H'); // a flashing cursor will do for now
//lcd_data('E');
//lcd_data('L');
//lcd_data('L');
// lcd_data('O');
while(1); // wait forever
}//main
by Robert Keim
by Jake Hertz
by Duane Benson
by Duane Benson