Language challange 1: LCD Control Panel
Ok, lets give this a try and see what comes of it. The challange for me is to write something that is clear and very tightly defines what must happen in language that is clear and very un-ambigous, without being written in any actual computer language. So I'm "makeing up" a language as I write code in it. It turned out to be more of a challange, but also more fun, than I thought it would be!
Hopefully, all the "code" will be self evident, but here are a few hints: Indents make all the difference. I've accetuated that with dashes. Double slashes start comments. It's sort of object oriented and each item after an object is passed to it as a message. So LED0 Off means that the LED0 object·(which was defined as a Pin) should assert zero. I didn't assign pin numbers so you can do that as you feel is appropo.
Some of this I wrote with specific language advantages / disadvantages in mind. For example, I give all the pin flips required to control an LCD, but I assume the language will "just do" the serial IO. That gives an advantage to SX/B and, I assume, some C's that have a well integrated library. But that is fair, since that is the point of higher level languages. Also, any good ASM coder already has serial code ready to go. Letting you arrange the pins may give ASM code an advantage. Also, that stupid debounce ISR is just begging for language based optimizations.
I debated putting in some higher math, but decided that this was enough to start and we should leave something for another time.
I've probably made mistakes, so I'd like to start by asking that everyone carefully look over the code and comment on anything that seems wrong. Now, there isn't any point in saying things like "you could optimize this part by aligning the pins" or "I wouldn't have written that in that way" because part of the goal here is to see how different languages manage things. What I'm looking for is factual errors like "you transposed a digit in the code to make an LCD panel do xyz" or like that.
Once we are fairly sure that the "code" makes sense and everybody agrees that it is clear, we can start to see what sort of code size it ends up being in your favorite language!
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
---
James Newton, Host of SXList.com
james at sxlist,com 1-619-652-0593 fax:1-208-279-8767
SX FAQ / Code / Tutorials / Documentation:
http://www.sxlist.com Pick faster!
Hopefully, all the "code" will be self evident, but here are a few hints: Indents make all the difference. I've accetuated that with dashes. Double slashes start comments. It's sort of object oriented and each item after an object is passed to it as a message. So LED0 Off means that the LED0 object·(which was defined as a Pin) should assert zero. I didn't assign pin numbers so you can do that as you feel is appropo.
Some of this I wrote with specific language advantages / disadvantages in mind. For example, I give all the pin flips required to control an LCD, but I assume the language will "just do" the serial IO. That gives an advantage to SX/B and, I assume, some C's that have a well integrated library. But that is fair, since that is the point of higher level languages. Also, any good ASM coder already has serial code ready to go. Letting you arrange the pins may give ASM code an advantage. Also, that stupid debounce ISR is just begging for language based optimizations.
I debated putting in some higher math, but decided that this was enough to start and we should leave something for another time.
I've probably made mistakes, so I'd like to start by asking that everyone carefully look over the code and comment on anything that seems wrong. Now, there isn't any point in saying things like "you could optimize this part by aligning the pins" or "I wouldn't have written that in that way" because part of the goal here is to see how different languages manage things. What I'm looking for is factual errors like "you transposed a digit in the code to make an LCD panel do xyz" or like that.
Once we are fairly sure that the "code" makes sense and everybody agrees that it is clear, we can start to see what sort of code size it ends up being in your favorite language!
// 2X16 44780 LCD / 4 Buttons / 4 LED Control Panel to Serial IO Controller Pins: - Pin LCD_E //LCD Enable Line - Pin LCD_RW //LCD Read/Write Line - Pin LCD_RS //LCD Data/Command Line - Byte LCD_DATA //LCD Data Port - Pin RX SerialOut //Serial In - Pin TX SerialIn //Serial Out - Pin B0 //Button 1 - Pin B1 //Button 2 - Pin B2 //Button 3 - Pin B3 //Button 4 - Pin LED0 //LED1 - Pin LED1 //LED2 - Pin LED3 //LED3 - Pin LED4 //LED4 Variables: - Byte temp //temporary storage. Will your compiler use W? - Byte B //prior state of the buttons Subroutines: - DelaymS (x) Pause execution for x milli seconds - Byte LCDGet //Get Data from LCD - - Local Byte temp - - LCD_DATA In - - LCD_RW High - - LCD_E High - - temp = LCD_DATA - - LCD_E Low - - LCD_RW Low - - LCD_DATA Out - - Return Temp - LCDBusy //Pause while LCD busy - - LCD_RS Low - - While LCDGet.7 - LCDPut (x) //Send Data to LCD - - LCD_RW Low - - LCD_E High - - LCD_DATA = x - - LCD_E Low - LCDPutCMD (x) //Send Command to LCD - - LCDBusy - - LCD_RS Low - - LCDPut x - LCDPutChr (x) //Send Character to LCD - - LCDBusy - - LCD_RS High - - LCDPut x - Byte LCDGetAddr //Get Address Counter Contents - - LCD_RS Low - - Return LCDGet AND 0x7F - LCDSetDDRAM (x) //Set the Display-Data-RAM address to X - - LCDPutCMD (x OR 0x80) - LCDSetCGRAM (x) //Set the Chararcter-Generator-RAM address - - LCDPutCMD ( (x AND 0x3F) OR 0x40 ) LCDDispMode (x) //Set Display Control x.0=cursor blink, x.1=cursor on, x.2=display on - LCDPutCMD ( (x AND 0x07) OR 0x08 ) LCDEntryMode (x) //Set Entry Control x.0=display shift, x.1=auto-increment - LCDPutCMD ( (x AND 0x03) OR 0x04 ) LCDInit //Initiallize LCD - LCD_E Low - LCD_RW Low - LCD_RS Low - LCD_DATA Out - DelaymS 15 - LCDPutCMD 0x38 //8 bit mode, 2 line - LCDDispMode 0 - LCDClear - LCDDispMode 4 - LCDEntryMode 2 ISR: - B0? - - NOT B.0? - - - SerialPut "A" - NOT B0? - - B.0? - - - SerialPut "a" - B.0 = B0 - B1? - - NOT B.1? - - - SerialPut "B" - NOT B1? - - B.1? - - - SerialPut "b" - B.1 = B1 - B2? - - NOT B.2? - - - SerialPut "C" - NOT B2? - - B.2? - - - SerialPut "c" - B.2 = B2 - B3? - - NOT B.3? - - - SerialPut "D" - NOT B3? - - B.3? - - - SerialPut "d" - B.3 = B3 Setup: - LCD_RS Out - LCD_RW Out - LCD_E Out - LCDInit - RX SerialInitIn 9600 N 8 1 - TX SerialInitOut 9600 N 8 1 - B0 In Pull //enable pullup resistors - B1 In Pull - B2 In Pull - B3 In Pull //assuming LED will be grounded on the other side. // High is On. Low is off. - LED0 Out High //Make one on by default - LED1 Out Low - LED3 Out Low - ISRInit 1000 //Hz Main: - SerialPut "OK" - While True - Temp = SerialGet - Select Temp - - Case 'a' //LED0 off - - - LED0 Low - - Case 'A' //LED0 on - - - LED0 High - - Case 'b' //LED1 off - - - LED1 Low - - Case 'B' //LED1 on - - - LED1 High - - Case 'c' //LED2 off - - - LED2 Low - - Case 'C' //LED2 on - - - LED2 High - - Case 'd' //LED3 off - - - LED3 Low - - Case 'D' //LED3 on - - - LED3 High - - Case 'R' //Reset - - - LCDInit - - Case 'E' //Erase - - - LCDPutCMD 0x01 - - Case 'H' //Home - - - LCDPutCMD 0x02 - - Case 'o' //Display off - - - LCDDispMode 0 - - Case 'O' //Display on, no cursor - - - LCDDispMode 4 - - Case '2' //Display on, standard cursor - - - LCDDispMode 6 - - Case '3' //Display on, blinking cursor - - - LCDDispMode 7 - - Case 'S' //Shift - - - LCDEntryMode 3 - - Case 'M' //Move - - - LCDEntryMode 2 - - Case 'L' //Shift Display Left - - - LCDPutCMD 0x18 - - Case 'R' //Shift Display Right - - - LCDPutCMD 0x1C - - Case '<' //Cursor Left - - - LCDPutCMD 0x10 - - Case '>' //Cursor Right - - - LCDPutCMD 0x14 - - Case '@' //Cursor Position - - - temp = SerialGet - '0' - - - temp = temp * 10 + (SerialGet - '0') - - - LCDSetDDRAM temp - - Case '"' //Start putting out text - - - temp = SerialGet // after the '"' - - - temp=='"'? // but two quotes - - - - LCDPutChr temp // puts out a quote chr - - - While temp NOT '"' //Until the next quote - - - - LCDPutChr temp // copy chrs to the LCD
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
---
James Newton, Host of SXList.com
james at sxlist,com 1-619-652-0593 fax:1-208-279-8767
SX FAQ / Code / Tutorials / Documentation:
http://www.sxlist.com Pick faster!
Comments
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
---
James Newton, Host of SXList.com
james at sxlist,com 1-619-652-0593 fax:1-208-279-8767
SX FAQ / Code / Tutorials / Documentation:
http://www.sxlist.com Pick faster!
A couple of points......
I would have preferred a functional description with timing parameters/constraints.
I presume the serial transmit and receive are asynchronous, so both should be able to run at the same time.
When you use the DELAY subroutine, I presume you do not want to halt operation, ie serial comms should continue.
Cheers,
Peter (pjv)
The timing diagrams for a 44780 are available all over, but one place is:
http://home.iae.nl/users/pouweha/lcd/lcd0.shtml#transfer
Yes, an interrupt could occur when the system is RX'ing a new command and if the ISR finds that a switch has been pressed or released, then it would want to TX a character. However, there is no reason why the serial system couldn't buffer those and send them when it is waiting for RX'd characters. So, I was ambiguous because I wanted to allow for what ever sort of serial setup the language wanted to use.
Delay can stop serial operation because it is only used between RX'd commands (when talking to the LCD) and it won't take long enough that an RX character is likely to be missed. It would be better if it didn't stop operations, and my expectation was that interrupts would continue to be processed during a delay loop. If the serial system is in the ISR (again, not specified because different languages do it differently) then there is no issue. I guess what is most important to say is that the delay must be that /or more/ and it is ok if it is a few cycles over.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
---
James Newton, Host of SXList.com
james at sxlist,com 1-619-652-0593 fax:1-208-279-8767
SX FAQ / Code / Tutorials / Documentation:
http://www.sxlist.com Pick faster!
If I got this right, I'll post my code and then if someone else decides too, their code needs to be more efficient than mine until we end up with the most effective code·and the fewest lines?
kinda like Sudoku, looks like it will be a great learning experience,I like it. I'm going to try this in SX/B first and then apply what I'm learning from Gunther's book next. I'm in SoCal, so I'll post in about a week, as soon as I recieve the LCD.
Note: Someone should post this in the BS, Javalin·& Propeller forums too. This could be a great challange in a busier forum
Thanks
Post Edited (Capt. Quirk) : 3/7/2007 5:29:33 PM GMT