I'm trying to control an HD44780 LCD with a 2560, but I'm a bit confused as to the pin arrangement. The instructions here http://arduino.cc/en/Tutorial/LiquidCrystal state which pins you should use, and the Arduino examples (such as Hello World) work flawlessly. However, since I am doing this in assembly, I need to know exactly which ATmega 2560 pin is connected to which IO pin on the board. If you go here http://arduino.cc/en/uploads/Main/arduino-mega2560-schematic.pdf you can see the schematic and which pin goes to what IO port. So I'm noticing that pins 2,3,4, and 5 go to PE4, PE5, PG5 (wtf?) and PE3(???). Is this arrangement correct? Because I thought (based on the instructions and examples I have found so far on how to make the LCD work in asm) that pins 2-5 were PE4-PE7 on the processor.
BTW... anyone know where I can find lots of asm examples for the 2560? I've only found a couple that are specific to that processor.
You can use any pins for the LCD, the interface is parallel, and will work with any DIO pins. Yes, the digital pins 2-5 on the mega map to PE 3,4,5 and PG 5, and you will want to use digital pins on the same bus, maybe PA 0-3 (mega digital pins 22,23,24,25). Just out of curiousity, why are you using assembly?
I'm using assembly because this is for a lab in my school and we aren't allowed to use higher level languages. Lemme show a bit of the code I have so far:
.INCLUDE "M2560DEF.INC"
.equ RS = portb6
.equ Enable = portb5
.equ BusyFlag = porte4
rjmp main
main:
rcall init
init:
rcall wait
sbi portb,6
ldi r16,0b0011_0000
out porte,r16
sbi portb,5 ;Set Enable
nop
cbi portb,5 ;Clear Enable
rcall wait
ldi r16,0b0011_0000
out porte,r16
sbi portb,5 ;Set Enable
nop
cbi portb,5 ;Clear Enable
rcall wait
ldi r16,0b0011_0000
out porte,r16
sbi portb,5 ;Set Enable
nop
cbi portb,5 ;Clear Enable
rcall wait
ldi r16,0b0010_0000 ;Start in 4-bit mode
out porte,r16
sbi portb,5 ;Set Enable
nop
cbi portb,5 ;Clear Enable
rcall LCD_busy
ldi r24,high(0b0010_0000) ;Set number of display lines and character font
ldi r25,low(0b0010_0000)
rcall sendcom
ldi r24,high(0b0000_1000) ;Display off
ldi r25,low(0b0000_1000)
rcall sendcom
ldi r24,high(0b0000_0001) ;Display clear
ldi r25,low(0b0000_0001)
rcall sendcom
ldi r24,high(0x06) ;Entry mode set
ldi r25,low(0x06)
rcall sendcom
ret
sendcom: ;Send Command - because we are using 4-bit mode, must send twice
out porte,r24 ;Send High
sbi portb,5 ;Set Enable
nop
cbi portb,5 ;Clear Enable
rcall LCD_busy
out porte,r25 ;Send Low
sbi portb,5 ;Set Enable
nop
cbi portb,5 ;Clear Enable
rcall LCD_busy
ret
LCD_busy:
cbi ddre,4 ;Set BF as input
check:
sbic pine,4
rjmp check
ret
wait:
ldi r17,8 ;Determines pause length, in this case 125ms
outer_loop:
ldi r24,low(3037)
ldi r25,high(3037)
delay_loop:
adiw r24,1
brne delay_loop
dec r17
brne outer_loop
ret
So I'm noticing that pins 2,3,4, and 5 go to PE4, PE5, PG5 (wtf?) and PE3(???). Is this arrangement correct?
Sounds right. Since the arduino environment "abstracts" pin numbers, they get a lot of flexibility is which pins are connected where. Perhaps this will help:
(It should be sortable on different columns, at least if you make your own copy of it...)
From that spreadsheet it looks like Ports A and C are nice and straightforward. Once you get your code working you should think about revising it so that any LCD pin can be connected to any microprocessor pin without changing anything except the equates.
you should think about revising it so that any LCD pin can be connected to any microprocessor pin
Why? It is extremely common in microcontroller designs to wire peripherals in ways that put all the pins associated with a peripheral on a single "port." It makes the code simpler and faster, and the HW design only slightly more complex. The Arduino abstraction of connecting 8+ pins to a device and changing the value one pin at a time is nearly unheard of. (it works mostly because many applications where arduino is used don't have many pins connected to a single device.)
Why? It is extremely common in microcontroller designs to wire peripherals in ways that put all the pins associated with a peripheral on a single "port."
That's fine if you have a microcontroller like the 2560 with lots of I/O pins. If you have a 328 then all of the I/O pins serve two or more functions. You may have to use miscellaneous pins from more than one port to avoid conflicts with other devices that must be on a specific pin (PWM, I2C, etc.).