PDA

Επιστροφή στο Forum : STK-500 σύνδεση με LCD...αρχάριος



markos374
04-11-06, 16:36
Πρόσφατα αγόρασα το STK500 απο τη Micrelec και κατάφερα να ελέγξω με PWM ,με ένα LM317 ένα μοτεράκι απο ένα τηλεκατευθηνόμενο!Εχθές πήγα και πήρα μια LCD 2x16 αλλά δε έχω ιδέα πως να τη συνδέσω με κάποια πόρτα του 8515 μου.Είναι το μοντέλο P-S2B16CT-E1 και έχει 16 εισόδους απο πάνω και άλλες 2 στα πλάγια.Δεδομένου οτι δεν έχω κάποιο manual έχω μπερδευτεί...Πρέπει να μεσολαβήσει κάτι σαν πολυπλέκτης ή απλά υπάρχει μια στάνταρ συνδεσμολογία που πρέπει να κάνω???Και αν ποιά είναι αυτή???

gsmaster
04-11-06, 17:29
Κατέβασε και διάβασε αυτό τον οδηγό για lcd χαρακτήρων (http://www.hlektronika.gr/pafiledb/pafiledb.php?action=file&id=33)

markos374
04-11-06, 18:56
Το κατέβασα ωστόσο θα μου πάρει κάποια ώρα να το μελετήσω...Φαίνεται όμως να αναφέρεται σε assembly προγραμματισμό και αναφέρεται σε PIC.Αν εγώ προγραμματίζω avr με codevision αλλάζει κάτι στη συνδεσμολογία?Και κάτι άλλο.Έχω 16 εισόδους και όχι 14 μάλλον γιατί έχει backlight το LCD μου...Α!Και να διορθώσω μια μπούρδα που είπα πριν το L293 χρησιμοποίησα όχι to LM317...

gsmaster
04-11-06, 23:40
Ναι και μένα κάτι δεν μου πήγε καλά με το LM317...

Στη συνδεσμολογια δεν αλλάζει κάτι, ο κώδικας θα είναι ο ανάλογος για την γλώσσα που χρησιμοποιείς.

Διάβασε το datasheet και θα καταλάβεις πως οδηγείς την οθόνη.

pet
28-11-06, 14:27
οι lcd με 16 ποδάρια είναι με back light συγκεκριμένα είναι

15 V+
16 V-

ο τρόπος που την δουλεύω εγώ είναι το 16 στην γή και το 15 στο όγδοο (πιν7) ποδάρι
της πορτας του avr (τα άλλα πιν της ίδιας πόρτας απο πιν0 εώς πιν6 οδηγούν την οθόνη
σε 4 μπιτ mode)

με logic high στο 15 (pin7) θα ανάψει το back light.

ο πιο βολικός τρόπος είναι μέσω της A αν δεν χρησημοποιείς το build in adc μιας και οι άλλες πόρτες έχουν χρήσιμες λειτουργίες
ίσως και η PC σε βολέψει (σε κάποιον μC που έχει βέβεια).

Για να την λειτουργήσεις πρέπει να προσέξεις κάποια πράγματα εκτός απο τις βασικές εντολές (HOME, CLR, SHIFTS κλπ):
τους χρονισμούς στο init

Ανακεφαλαίωση:

Διαβάσεις το συνημένο που λέει τα πάντα και είναι uC independent.
Έχει τους χρονισμούς, τις εντολές για οθόνες μίας και δύο γραμμών καθώς
και 4 και 8 μπιτ mode

Συνιστώμενo wiring (avr-gcc)




// avr config definitions
#define LCD_PORT PORTA
#define LCD_PORTIN PINA
#define LCD_DDR DDRA
// 4 bit mode, data cables
#define LCD_D4 PORT0
#define LCD_D5 PORT1
#define LCD_D6 PORT2
#define LCD_D7 PORT3
// mcu control cables
#define LCD_RW PORT4
#define LCD_E PORT5
#define LCD_RS PORT6
// power on/off cable
#define LCD_PW PORT7



προσοχή στο αρχείο main.c , είναι γραμμένο για κάθε κρύσταλλο
εκτός απο την lcd_pulse_e() που ίσως χρειαστεί να κρατήσεις τον παλμό
σηκωτέο λίγο παραπάνω σε περισσότερα MHz



// pulse the enable r/w pin
static inline void lcd_pulse_e(void)
{
LCD_PORT |= 1 << LCD_E;

// with greater clock a small delay
// maybe be needed
// ie&#58; __asm__ volatile &#40; "nop"&#41;;
LCD_PORT &= ~&#40;1 << LCD_E&#41;;
&#125;


και φυσικά όλα προυποθέτουν ότι η οθόνη σου είναι hd44780 συμβατή


main.c (avr-gcc main program)


// frequency of ext crystal in Hz
// set the low fuse, low nibble as recommended for F_CPU
// using a programmer
#define F_CPU 4000000UL

#include <ctype>
#include <stdint>
#include <stdio>
#include <avr>
#include <avr>
#include <util>
#include <stdbool>

// avr config definitions
#define LCD_PORT PORTA
#define LCD_PORTIN PINA
#define LCD_DDR DDRA
// 4 bit mode, data cables
#define LCD_D4 PORT0
#define LCD_D5 PORT1
#define LCD_D6 PORT2
#define LCD_D7 PORT3
// mcu control cables
#define LCD_RW PORT4
#define LCD_E PORT5
#define LCD_RS PORT6
// power on/off cable
#define LCD_PW PORT7

// mask for data bits 0x0f
#define LCD_DATABITS &#40;&#40;1 << LCD_D4&#41; | &#40;1 << LCD_D5&#41; | &#40;1 << LCD_D6&#41; | &#40;1 << LCD_D7&#41;&#41;
// mask of the busy flag, used as cable LCD_D7
#define LCD_BUSYFLAG 0x80

// used as functions
#define lcd_outcmd&#40;n&#41; lcd_outbyte&#40;&#40;n&#41;, 0&#41;
#define lcd_outdata&#40;n&#41; lcd_outbyte&#40;&#40;n&#41;, 1&#41;
#define lcd_incmd&#40;&#41; lcd_inbyte&#40;0&#41;
#define lcd_indata&#40;&#41; lcd_inbyte&#40;1&#41;

// definitions for lcd instructions
#define LCD_CLR 0x01
#define LCD_HOME 0x02
#define LCD_ENTMODE 0x04
#define LCD_DISPCTL 0x0C
#define LCD_FNSET 0x28

// pulse the enable r/w pin
static inline void lcd_pulse_e&#40;void&#41;
&#123;
LCD_PORT |= 1 << LCD_E;
// delay for 500 ns
//__asm__ volatile&#40;"nop"&#41;;
//__asm__ volatile&#40;"nop"&#41;;
LCD_PORT &= ~&#40;1 << LCD_E&#41;;
&#125;

static void lcd_outnibble&#40;uint8_t n, uint8_t rs&#41;
&#123;
// set in write mode
LCD_PORT &= ~&#40;1 << LCD_RW&#41;;
// enable or disable register select
if &#40;rs&#41;
LCD_PORT |= 1 << LCD_RS;
else
LCD_PORT &= ~&#40;1 <<LCD_RS>>4, rs&#41;;
// out low nibble
lcd_outnibble&#40;b & 0x0f, rs&#41;;
&#125;

static uint8_t lcd_innibble&#40;uint8_t rs&#41;
&#123;
// set RW of lcd_port high, this is read
LCD_PORT |= 1 << LCD_RW;
// set lcd_ddr high nibble as is, low nibble to zeros
// this is input for port0 to port3
LCD_DDR &= ~LCD_DATABITS;
// enable or disable register select
if &#40;rs&#41;
LCD_PORT |= 1 << LCD_RS;
else
LCD_PORT &= ~&#40;1 << LCD_RS&#41;;
// pulse_e so data transfer can start
lcd_pulse_e&#40;&#41;;

// whatever is high and it with databits
uint8_t x = LCD_PORTIN & LCD_DATABITS;
// high the databits in data direction register
// configure them again as output
LCD_DDR |= LCD_DATABITS;
// low the rw bit in lcd_port
// this brings the system in write mode
LCD_PORT &= ~&#40;1 << LCD_RW&#41;;
// erase high nibble of x
return x & LCD_DATABITS;
&#125;

uint8_t lcd_inbyte&#40;uint8_t rs&#41;
&#123;
uint8_t x;
// read nibble and shift to the high part of x
x = lcd_innibble&#40;rs&#41; << 4;
// read nibble and leave it as is
x |= lcd_innibble&#40;rs&#41;;
return x;
&#125;

void lcd_wait_ready&#40;void&#41;
&#123;
// busy wait for the compination of RS = 0 &#40;instuction&#41; and RW = 1 &#40;read&#41;
while &#40;lcd_incmd&#40;&#41; & LCD_BUSYFLAG&#41;
;
&#125;


int main&#40;void&#41;
&#123;
// set data direction reg as output
LCD_DDR = &#40;1 << LCD_RS&#41; | &#40;1 << LCD_RW&#41; | &#40;1 << LCD_E&#41; | LCD_DATABITS;
// clean the port
// LCD_PORT = 0xf0 & LCD_DATABITS;

// delay for 15 ms with 4.5V power
_delay_ms&#40;15&#41;;

// the low nibble of this must be 0011
lcd_outnibble&#40;0x03, 0&#41;;
// delay for 4.1 ms
_delay_ms&#40;4.1&#41;;

lcd_outnibble&#40;0x03, 0&#41;;
// delay for 100 us
_delay_us&#40;100&#41;;

// interface to be four bit long
lcd_outnibble&#40;0x02, 0&#41;;
lcd_wait_ready&#40;&#41;;

// lines=2
lcd_outbyte&#40;0x28, 0&#41;;
lcd_wait_ready&#40;&#41;;

// display on , cursor off
lcd_outbyte&#40;0x0c, 0&#41;;
lcd_wait_ready&#40;&#41;;

// display clear
lcd_outbyte&#40;0x01, 0&#41;;
lcd_wait_ready&#40;&#41;;

// entry mode set
lcd_outbyte&#40;0x03, 0&#41;;
lcd_wait_ready&#40;&#41;;


lcd_outbyte&#40;'w', 1&#41;;
lcd_wait_ready&#40;&#41;;

lcd_outbyte&#40;'o', 1&#41;;
lcd_wait_ready&#40;&#41;;

lcd_outbyte&#40;'r', 1&#41;;
lcd_wait_ready&#40;&#41;;

lcd_outbyte&#40;'k', 1&#41;;
lcd_wait_ready&#40;&#41;;

lcd_outbyte&#40;'s', 1&#41;;
lcd_wait_ready&#40;&#41;;

lcd_outbyte&#40;'?', 1&#41;;
lcd_wait_ready&#40;&#41;;


return 0;
&#125;


makefile for main.c


PRG= main
OBJ = main.o
TARGET = atmega16
OPTIONS = -g -Wall -Os

CC = avr-gcc
CFLAGS = $&#40;OPTIONS&#41; -mmcu=$&#40;TARGET&#41;
LDFLAGS = -Wl,-Map,$&#40;PRG&#41;.map
OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump

# avrdude
AD_PART = m16
AD_PORT = /dev/ttyS0
AD_BOARD = stk500v2
AD_CONFIG = -p $&#40;AD_PART&#41; -P $&#40;AD_PORT&#41; -c $&#40;AD_BOARD&#41;

AD_LOFUSE = 0xEE
AD_HIFUSE = 0xD9

all&#58; $&#40;PRG&#41;.elf lst text

$&#40;PRG&#41;.elf&#58; $&#40;OBJ&#41;
$&#40;CC&#41; $&#40;CFLAGS&#41; $&#40;LDFLAGS&#41; -o $@ $^

lst&#58; $&#40;PRG&#41;.lst

%.lst&#58; %.elf
$&#40;OBJDUMP&#41; -h -S $< > $@

text&#58; hex bin srec

hex&#58; $&#40;PRG&#41;.hex
bin&#58; $&#40;PRG&#41;.bin
srec&#58; $&#40;PRG&#41;.srec

%.hex&#58; %.elf
$&#40;OBJCOPY&#41; -j .text -j .data -O ihex $< $@

%.srec&#58; %.elf
$&#40;OBJCOPY&#41; -j .text -j .data -O srec $< $@

%.bin&#58; %.elf
$&#40;OBJCOPY&#41; -j .text -j .data -O binary $< $@

eeprom&#58; ehex ebin esrec

ehex&#58; $&#40;PRG&#41;_eeprom.hex
ebin&#58; $&#40;PRG&#41;_eeprom.bin
esrec&#58; $&#40;PRG&#41;_eeprom.srec

%_eeprom.hex&#58; %.elf
$&#40;OBJCOPY&#41; -j .eeprom --change-section-lma .eeprom=0 -O ihex $< $@

%_eeprom.srec&#58; %.elf
$&#40;OBJCOPY&#41; -j .eeprom --change-section-lma .eeprom=0 -O srec $< $@

%_eeprom.bin&#58; %.elf
$&#40;OBJCOPY&#41; -j .eeprom --change-section-lma .eeprom=0 -O binary $< $@

clean&#58;
rm -rf *.o $&#40;PRG&#41;.elf *.lst *.map *.bin *.hex *.srec *.tmp

program&#58;
avrdude $&#40;AD_CONFIG&#41; -U flash&#58;w&#58;$&#40;PRG&#41;.hex

program_fuses&#58;
avrdude $&#40;AD_CONFIG&#41; -u -U lfuse&#58;w&#58;$&#40;AD_LOFUSE&#41;&#58;m
avrdude $&#40;AD_CONFIG&#41; -u -U hfuse&#58;w&#58;$&#40;AD_HIFUSE&#41;&#58;m



main.avr (tavrasm program)


.include "m16def.inc"

.equ LCD_PIN = PINA
.equ LCD_PORT = PORTA
.equ LCD_PORT0 = PORTA0
.equ LCD_PORT1 = PORTA1
.equ LCD_PORT2 = PORTA2
.equ LCD_PORT3 = PORTA3
.equ LCD_PORT4 = PORTA4
.equ LCD_PORT5 = PORTA5
.equ LCD_PORT6 = PORTA6
.equ LCD_PORT7 = PORTA7
.equ LCD_DDR = DDRA

.equ LCD_RW = LCD_PORT4
.equ LCD_RS = LCD_PORT6
.equ LCD_E = LCD_PORT5

.equ LCD_CLEAR = 0b00000001 ; clear display
.equ LCD_HOME = 0b00000010 ; return home
.equ LCD_CURSOR = 0b00000110 ; set Cursor
.equ LCD_ON = 0b00001110 ; LCD on
.equ LCD_SET = 0b00101100 ; 8 bits, 2 lines, 5x7dots
.equ LCD_4BIT = 0b00000010 ; 4 bit mode
.equ LCD_WIRING = 0b11100000

.def char = R0
.def buffer = R16
.def counter = R17
.def temp = R18

.def wait0 = R21
.def wait1 = R22

.def delay0 = R23
.def delay1 = R24

.CSEG
.ORG 0x00

rjmp init

_delayproc&#58;
ldi wait1, 50

_delayproc_0&#58;
dec wait0
brne _delayproc_0
dec wait1
brne _delayproc_0
ret

LCD_inst&#58;
cbi LCD_PORT, LCD_RS
rjmp LCD_write

LCD_data&#58;
sbi LCD_PORT, LCD_RS

LCD_write&#58;
in temp, LCD_PORT
push buffer
swap buffer

andi buffer, 0x0f
or buffer, temp
out LCD_PORT, buffer
sbi LCD_PORT, LCD_E

rcall _delayproc
cbi LCD_PORT, LCD_E

pop buffer
andi buffer, 0x0f
or buffer, temp
out LCD_PORT, buffer
sbi LCD_PORT, LCD_E
rcall _delayproc

cbi LCD_PORT, LCD_E
clr temp
out LCD_PORT, temp
ret

LCD_init&#58;
rcall _delayproc

ldi buffer, 0x30
rcall LCD_inst

rcall _delayproc

ldi buffer, LCD_4BIT
out LCD_PORT, buffer

sbi LCD_PORT, LCD_E
rcall _delayproc
cbi LCD_PORT, LCD_E

ldi buffer, 0x28
rcall LCD_inst

ldi buffer, LCD_ON
rcall LCD_inst

ldi buffer, LCD_CLEAR
rcall LCD_inst

ldi buffer, LCD_HOME
rcall LCD_inst

ret

init&#58;
ldi temp, $FF
out spl, temp

ser temp
out LCD_DDR, temp ; LCD_PORT output

main&#58;
rcall LCD_init
ldi ZL, LOW&#40;tabel*2&#41;
ldi ZH, HIGH&#40;tabel*2&#41;

tloop&#58;
lpm
mov temp, char
cpi temp, '#'
breq tloop1

mov buffer, char ; Jump if send buffer empty
rcall LCD_data

inc ZL ; next character
brne tloop ; next character

tloop1&#58;
ldi temp, LCD_WIRING
out LCD_DDR, temp

ldi temp, 0b00011111
out LCD_PORT, temp

_main&#58;

ldi delay0, 0x0
ldi delay1, 0x0

_delay&#58;
dec delay0
brne _delay
dec delay1
brne _delay

rjmp _main

tabel&#58;

.DB "Welcome to Hlektronika.gr#"


makefile for main.avr


UMCU = atmega16
PORT = /dev/ttyS0
UISP = uisp
BOARD = stk500

DEFS = /opt/avr/share/defs

SRC = main.avr
HEX = main.hex

all&#58; hex

hex&#58;
tavrasm -I $&#40;DEFS&#41; $&#40;SRC&#41;

clean&#58;
rm -rf $&#40;HEX&#41;


program &#58;
$&#40;UISP&#41; -dprog=$&#40;BOARD&#41; -dserial=$&#40;PORT&#41; -dpart=$&#40;UMCU&#41; --erase
$&#40;UISP&#41; -dprog=$&#40;BOARD&#41; -dserial=$&#40;PORT&#41; -dpart=$&#40;UMCU&#41; --upload if=$&#40;HEX&#41; -v=2
# $&#40;UISP&#41; -dprog=$&#40;BOARD&#41; -dserial=$&#40;PORT&#41; -dpart=$&#40;UMCU&#41; --wr_fuse_l=0xee

erase &#58;
$&#40;UISP&#41; -dprog=$&#40;BOARD&#41; -dserial=$&#40;PORT&#41; -dpart=$&#40;UMCU&#41; --erase




Το manual για τις HD44780 το έβαλα στην σελίδα μου επειδή είναι χρήσιμο και επειδή το πισί μ
δεν είναι ανοιχτό πάντα βάλτε το αρχείο στα downloads

http://pet.homeunix.org/HD44780.pdf

gsmaster
28-11-06, 16:55
Υπόψην κυκλοφορούν οθόνες μάρκας cct, οι οποίες έχουν τα πιν 15 και 16 ανεστραμμένα.
Με κάποια μικρή τροποποίηση, στις αντιστάσεις 0Ω που έχουν απο πίσω, και αν κοπεί και κανας χαλκοδιάδρομος μπορούμε να τις φέρουμε στα κανονικά τους.

pet, το datasheet που έβαλες είναι μεν χρήσιμο, αλλά υπάρχει παντού στο ιντερνετ. Δεν λέω έχει τα πάντα, αλλά ο οδηγός που έδωσα παραπάνω αναφέρει τα ίδια, πιο περιεκτικά.

pet
28-11-06, 17:30
ok κανένα πρόβλημα

εγώ θυμάμαι το έψαχνα και δεν το έβρισκα γιαυτό

kopla
28-11-06, 21:45
Πρόσφατα αγόρασα το STK500 απο τη Micrelec

Υπάρχει κανένα site γι αυτό ??

pet
28-11-06, 22:37
micrelec, site απο ελλάδα, στο google

kopla
28-11-06, 22:52
Οκ, το σιτε το βρήκα αλλά δεν βλέπω results όταν ψάχνω για STK

pet
28-11-06, 23:24
για θα τους κάνεις ένα interrupt, το TELEPHONE_vect
:lol: