Further to my earlier post, i was looking for a way to drive my LCD in 8 bit mode, using pins that do not necessarily all come from one port. (I expect in due course I will switch to 4 bit mode but so I can get on with other elements of the project I decided to try a quick and dirty fix)
The code I had from the sample on the website, used an alias technique to assign the data to the pins. So I figure if the pins might be anyhow numbered why not just have a table and do this :-
if LCD_Alias=true then
LCD_Data = C else
for i=0 to 7
call PutPin(LCD_Pin(i),GetBit(C,i))
next i
so this code should in theory cope with either scenario depending on the setting of a variable.
If I define my pins like this:-
LCD_Pin(0)=A.0
LCD_Pin(1)=A.1
LCD_Pin(2)=A.2
LCD_Pin(3)=A.3
LCD_Pin(4)=A.4
LCD_Pin(5)=A.5
LCD_Pin(6)=A.6
LCD_Pin(7)=A.7
it seems to work, however if I use pin number instead of A.n etc i get a different result, the top line of the lcd is quite unreadable with nothing on line 2.
also, demonstrating that there is something i don't understand, if i use the working method to define the pins, then i swap 2 wires on the ZX24, and swap the corresponding pin designations i still get slightly garbled output on the lCD, when i was hoping if i swap 2 wires, and swap and the table entries in LCD_Pin the resuilt would still work.
i though aliasing was just a shorthand for referencing variables but there seems to be more going on than that would suggest.
thanks
There's something I don't understand
Re: There's something I don't understand
The table driven, bit-by-bit method should work using either the port.bit form or the physical pin number form. If it doesn't, then there is something going on that isn't quite right. If you can post or send me a complete project that exhibits the problem I'll take a look at it.FFMan wrote:i though aliasing was just a shorthand for referencing variables but there seems to be more going on than that would suggest.
You're using a ZX-24a, correct?
- Don Kinzer
yep and i realised just a few mins ago what was wrong - i had the pin designations running back to front, i though a0 was pin 13 when its pin 20, so the lcd was getting all sorts of nonsense.
and now when i swap the pins and the corresponding table entries about it works, so this means i can move the code to the 328n and use what ever pins i like
thanks don
(coding after a long day doing other stuff can lead to errors for me !)
and now when i swap the pins and the corresponding table entries about it works, so this means i can move the code to the 328n and use what ever pins i like
thanks don
(coding after a long day doing other stuff can lead to errors for me !)
You might consider several changes. The first is to use preprocessor conditionals to select the code to use (see the example below). Since you won't be changing the I/O assignment at run time there is no need to include code that will never be used. The example code that accompanies AN-220 uses this technique to support three different ways to connect to the LCD.FFMan wrote:this means i can move the code to the 328n and use what ever pins i like
Secondly, instead of using GetBit() to extract each data bit, simply shift the data value to the right and always use the least significant bit. This is more efficient in that it almost certainly executes faster and probably also results in smaller code size.
Lastly, put the mapping of data bits to I/O pins in a ProgMem array. Since these don't change at run time there is no need to keep them in RAM.
The example code below is incomplete but it illustrates the points made above. The code can be modified fairly easily for 4-bit data.
Code: Select all
' Uncomment the line below to use an entire port for the LCD data.
#define LCD_ALIAS
#if defined(LCD_ALIAS)
' the port used for the LCD data
Private LCD_Data as Byte Based Register.PortA.DataAddress
#else
' the mapping of LCD data bits to I/O pins
Private LCD_Pin_Data as ByteVectorData ({
A.0 ' LSB
A.1
A.2
A.3
A.4
A.5
A.6
A.7 ' MSB
})
#endif
Sub Main()
' LCD initialization code here
Call LCD_put_byte(&H55)
End Sub
Sub LCD_put_byte(ByVal data as Byte)
' output the data value
#if defined(LCD_ALIAS)
LCD_data = data
#else
Dim i as Byte
For i = 1 to 8
Call PutPin(LCD_Pin_Data(i), data And &H01)
data = data \ 2
Next i
#endif
' add code here to strobe the data into the LCD
End Sub
- Don Kinzer
thanks for the suggestions. In fact I had already made use of the compiler directives as it seemed sensible and the compiler throws up warnings about statements always being true etc
I shall move LCD_Pin to progmem, its only a few bytes but its the principal of efficiency that I like.
I like the bit shift technique, would SHL be even more efficient that a divide ?
Using the corrected code I got it working using various pins on the 328n
thanks
I shall move LCD_Pin to progmem, its only a few bytes but its the principal of efficiency that I like.
I like the bit shift technique, would SHL be even more efficient that a divide ?
Using the corrected code I got it working using various pins on the 328n
thanks
With optimization enabled, it doesn't matter because the ZBasic compiler recognizes that dividing by a power of 2 is the same as shifting right and generates code for shifting. The same idea applies to multiplying by a power of 2 and left shifting.FFMan wrote:I like the bit shift technique, would SHL be even more efficient that a divide ?
- Don Kinzer