Har nu försökt att få det att fungera i en PIC16F628A med en 16 x 1 LCD.
LCD´n visar endast 8 fyrkantiga rutor direkt när den ansluts till spänning.
Det som skiljer är att jag använder de 4 höga bitarna RB4-RB7 som databitar i stället för RD0-RD4 i originalprogrammet.
Jag använder RA1 till RS och RA0 till E. RW är kopplad låg på kortet.
Har missat något men hittar inte vad.
En annan sak som jag har problem med är att det inte går att sätta breakpoint på vissa ställen. Jag får meddelandet: one or more breakpoints could not be resolved.
Ex. på rad som inte går att sätta breakpoint på:
Kod: Markera allt
void
lcd_putch(char c)
{
LCD_RS = 1; // write characters
lcd_write( c );
}
Kod: Markera allt
/*
* LCD interface to PIC16F877A
* Uses routines from delay.c
* This code will interface to a standard LCD controller
* like the Hitachi HD44780. It uses it in 4 bit mode, with
* the hardware connected as follows :
*
* PORTD bits 0-3 are connected to the LCD data bits 4-7 (high nibble)
* PORTB bit 4 is connected to the LCD RS input (register select)
* PORTB bit 6 is connected to the LCD R/W bit (READ WRITE)
* PORTB bit 7 is connected to the LCD E bit (ENABLE)
* To use these routines, set up the port I/O (TRISB, TRISD) then
* call lcd_init(), then other routines as required.
*
*/
#ifndef _XTAL_FREQ
// Unless specified elsewhere, 4MHz system frequency is assumed
#define _XTAL_FREQ 4000000
#endif
#include <htc.h>
#include "lcd.h"
#define LCD_RS RB4
#define LCD_RW RB6
#define LCD_EN RB7
#define LCD_DATA PORTD
#define LCD_STROBE() ((LCD_EN = 1),(LCD_EN=0))
//Teckentabell med 8 byte för varje tecken. totalt 4 tecken å,Å,;Ä,Ö med adress 0x40 till 0x5f
unsigned char char_table[32]={0x04,0x0e,0x11,0x11,0x1f,0x11,0x11,0x00,0x11,0x0e,0x11,0x11,0x1f,0x11,0x11,0x00,0x11,0x0e,0x11,0x11,0x11,0x11,0x0e,0x00,0x04,0x00,0x0e,0x01,0x0f,0x11,0x0f,0x00};
/* write a byte to the LCD in 4 bit mode */
void
lcd_write(unsigned char c)
{
if (c == 'Å') c = 0x00; // Å
if (c == 'Ä') c = 0x01; // Ä
if (c == 'Ö') c = 0x02; // Ö
if (c == 'å') c = 0x03; // å
if (c == 'ä') c = 0xe1; // ä
if (c == 'ö') c = 0xef; // ö
__delay_us(40);
LCD_DATA = ( ( c >> 4 ) & 0x0F );
LCD_STROBE();
LCD_DATA = ( c & 0x0F );
LCD_STROBE();
}
/*
* Clear and home the LCD
*/
void
lcd_clear(void)
{
LCD_RS = 0;
lcd_write(0x1);
__delay_ms(2);
}
void
lcd_right(void)
{
LCD_RS = 0;
lcd_write(0x14);
__delay_ms(2);
}
void
lcd_left(void)
{
LCD_RS = 0;
lcd_write(0x10);
__delay_ms(2);
}
void
lcd_cur_off(void)
{
LCD_RS = 0;
lcd_write(0xC);
__delay_ms(2);
}
/* write a string of chars to the LCD */
void
lcd_puts(const char * s)
{
LCD_RS = 1; // write characters
while(*s)
lcd_write(*s++);
}
/* write one character to the LCD */
void
lcd_putch(char c)
{
LCD_RS = 1; // write characters
lcd_write( c );
}
/*
* Go to the specified position
*/
void
lcd_goto(unsigned char pos)
{
LCD_RS = 0;
lcd_write(0x80+pos);
}
/* initialise the LCD - put into 4 bit mode */
void
lcd_init()
{
char init_value;
//ADCON1 = 0x06; // Disable analog pins on PORTA
init_value = 0x3;
TRISB=0;
//ANSELH = 0b00000000; //(FÖR 16F997)
TRISD=0;
LCD_RS = 0;
LCD_EN = 0;
LCD_RW = 0;
__delay_ms(50); // wait 15mSec after power applied,
LCD_DATA = init_value;
LCD_STROBE();
__delay_ms(5);
LCD_STROBE();
__delay_us(200);
LCD_STROBE();
__delay_us(200);
LCD_DATA = 2; // Four bit mode
LCD_STROBE();
lcd_write(0x28); // Set interface length
lcd_write(0xF); // Display On, Cursor On, Cursor Blink
lcd_clear(); // Clear screen
lcd_write(0x6); // Set entry Mode
// ladda ner svenska tecken
int i=0;
for(i = 0; i < 32; i++){
LCD_RS = 0;
lcd_write(0x40+i); //CG-RAM-adress
__delay_us(50);
LCD_RS = 1;
lcd_write(char_table[i]); //CG-RAM-data
__delay_us(50);
}
}
Kod: Markera allt
/*
* LCD interface to PIC16F628A
* like the Hitachi HD44780. It uses it in 4 bit mode, with
* the hardware connected as follows :
*
* PORTB bits 4-7 are connected to the LCD data bits 4-7 (high nibble)
* PORTA bit 1 is connected to the LCD RS input (register select)
* LCD R/W bit is connected to ground
* PORTA bit 0 is connected to the LCD E bit (ENABLE)
*/
unsigned int var_c =0;
#ifndef _XTAL_FREQ
// Unless specified elsewhere, 4MHz system frequency is assumed
#define _XTAL_FREQ 4000000
#endif
#include <htc.h>
#include "lcd.h"
#define LCD_RS RA1
//#define LCD_RW RB6
#define LCD_EN RA0
#define LCD_DATA PORTB
#define LCD_STROBE() ((LCD_EN = 1),(LCD_EN=0))
/* write a byte to the LCD in 4 bit mode */
void
lcd_write(unsigned char c){
__delay_us(40);
var_c = c; //****** användes för kontroll vid debugg ********
//LCD_DATA = ( ( c >> 4 ) & 0b11110000 ); // gamla prog. där port B0-B3 anv till data
LCD_DATA = ( c & 0b11110000 );
LCD_STROBE();
LCD_DATA = ( ( c << 4 ) & 0b11110000 );
//LCD_DATA = ( c & 0x0F ); // gamla prog. där port B0-B3 anv till data
LCD_STROBE();
}
/*
* Clear and home the LCD
*/
void
lcd_clear(void)
{
LCD_RS = 0;
lcd_write(0x1);
__delay_ms(2);
}
void
lcd_right(void)
{
LCD_RS = 0;
lcd_write(0x14);
__delay_ms(2);
}
void
lcd_left(void)
{
LCD_RS = 0;
lcd_write(0x10);
__delay_ms(2);
}
void
lcd_cur_off(void)
{
LCD_RS = 0;
lcd_write(0xC);
__delay_ms(2);
}
/* write a string of chars to the LCD */
void
lcd_puts(const char * s)
{
LCD_RS = 1; // write characters
while(*s)
lcd_write(*s++);
}
/* write one character to the LCD */
void
lcd_putch(char c)
{
LCD_RS = 1; // write characters
lcd_write( c );
}
/*
* Go to the specified position
*/
void
lcd_goto(unsigned char pos)
{
LCD_RS = 0;
lcd_write(0x80+pos);
}
/* initialise the LCD - put into 4 bit mode */
void
lcd_init()
{
char init_value;
//ADCON1 = 0x06; // Disable analog pins on PORTA
TRISB = 0b00000000;
CMCON = 0b00000111; //Comparators Off
TRISA = 0b00000000;
LCD_RS = 0;
LCD_EN = 0;
//LCD_RW = 0;// ****** satt till jord *******
init_value = 0x30; // ****** 2 lägsta bitarna i höga nibbles
__delay_ms(50); // wait 15mSec after power applied,
LCD_DATA = init_value;
LCD_STROBE();
__delay_ms(5);
LCD_STROBE();
__delay_us(200);
LCD_STROBE();
__delay_us(200);
LCD_DATA = 0x20; // Four bit mode
LCD_STROBE();
lcd_write(0x28); // Set interface length
lcd_write(0xF); // Display On, Cursor On, Cursor Blink
lcd_clear(); // Clear screen
lcd_write(0x6); // Set entry Mode
}
Kod: Markera allt
//* LCD mainroutine Ver 1.0
//* LCD interface to PIC16F628A
//*lcd.c Ver 1.0 is included
//*lcd.h is included
#include <htc.h>
#include "lcd.h"
#define _XTAL_FREQ 4000000
#define DelayS(T){unsigned char i;for (i=0; i<T*10; i++)__delay_ms(100);}
#define LED_1 RA2
void main()
{
lcd_init();
lcd_goto(0); // select first line
lcd_puts("Hello World");
for(;;){
LED_1 = 1;// kontroll att PICén funkar. blinkar en led 1 gång /sek.
DelayS(1);
LED_1 = 0;
DelayS(1);
}
}