Problem med LCD
Postat: 8 augusti 2005, 19:03:17
Mina "gamla" LCD rutiner för pic16 fungerar inte i pic18! Hur kommer det sig? Jag har tittat genom koden många många gånger. Ser ni något konstigt?
Kod: Markera allt
-----------------LCD.h------------------------------------
void LCD_data(char data, char mode); //Funktioner för LCD
void LCD_string(const char *string); //Funktioner för LCD
void lcd_dec_byte(int val, int digits); //Skriver int till LCD med given bas
void initlcd(void); //Initierar LCDn
void enable(void);
int num_to_char(int val); //Funktion för LCD, omvandlar från num (dec) till char för skrivning i LCD
#define lcd_rensa 0x01 //Rensa displayen
#define lcd_hem 0x02 //Markör till första raden första positionen
#define lcd_on 0x0C //Display på...
#define lcd_off 0x08 //..ja...undra...
#define lcd_rad1 0x80 //Första raden första positionen
#define lcd_rad2 0xC0
#define text 1
#define instr 0
-----------------LCD.c------------------------------------
#include <p18cxxx.h>
#include "LCD.h"
void initlcd(void)
{
delayMs(35);
LCD_data(0x02,instr);
LCD_data(0x02,instr);
LCD_data(0x02,instr);
LCD_data(0x00,instr);
LCD_data(0x0E,instr);
LCD_data(0x00,instr);
LCD_data(0x06,instr);
LCD_data(0x28,instr); //Två rader
}
void enable(void)
{
PORTBbits.RB6=1;
PORTBbits.RB6=0;
delayMs(4);
}
void LCD_data(char data, char mode) //4-bit data kommunikation med LCD:n
{
char nibble,j;
j=mode;
PORTBbits.RB5=j; //Register select - Välja register, data eller instruktion
nibble=data;
nibble=nibble>>3; //Skifta tre steg för att första nibblen ska hamna rätt...
nibble=(nibble&0x1E); //Nollställer allt utom den nibble vi vill skicka
PORTB = (PORTB&0xE1); //Nollställer databussarna
PORTB = (PORTB|nibble); //Odlar ihop nibblen och PORTB
enable(); //Uppdatera
nibble=data; //Samma fast den lägre nibblen
nibble=nibble<<1;
nibble=(nibble&0x1E);
PORTB = (PORTB&0xE1);
PORTB = (PORTB|nibble);
enable();
}
void LCD_string(const char *string)
{
char i=0;
while(string[i]!=0)
LCD_data(string[i++],text);
}
void lcd_dec_byte(int val, int digits) // displays byte in decimal as either 1, 2 or 3 digits
{
int d;
int ch;
if (digits == 3)
{
d=val/100;
ch=num_to_char(d);
LCD_data(ch,text);
}
if (digits >1) // take the two lowest digits
{
val=val%100;
d=val/10;
ch=num_to_char(d);
LCD_data(ch,text);
}
if (digits == 1) // take the least significant digit
{
val = val%100;
}
d=val % 10;
ch=num_to_char(d);
LCD_data(ch,text);
}
int num_to_char(int val) // converts val to hex character
{
int ch;
if (val < 10)
{
ch=val+'0';
}
else
{
val=val-10;
ch=val + 'A';
}
return(ch);
}
-----------------------main.c--------------------------------
...
void main(void)
{
ADCON1 |= 0x0F; // Default all pins to digital
TRISB= 0x00;
PORTB= 0x00;
PORTBbits.RB7=1;
initlcd();
delayMs(50);
LCD_data(lcd_rad1,instr);
LCD_string("xXx");
while(1);
}
..