The purpose of the tutorial threads is to discuss the tutorial, not solve unrelated problems.
As such I'm going to lock this thread. If anyone has anything to add to the original article PM js, plons or clawson and ask us to temporarily unlock this.
Thanks for this LCD driver, it allowed me to get characters on the screen with next to zero nowledge of C 8)
I noticed that
LCD_WAIT_FOR_SCROLL_DONE();
Does not check if the text is long enough to scroll, and if it isnt, waits forever...
For the solar hotwater controller that I am building I need the numbers (and eventially will need the arrows). I was going to ask if you could do it for me, but I have come up with a brute force hack on your code, without really understanding it too well that gives the numbers 1-5 sequentially. i.e if 3 then you get 3,2,1. I'me sure theres a much nicer way of doing it. I havnt check the 3 as R200(?) is desoldered atm
diff /usr/src/AVR/include/LCD_Driver.c /usr/src/AVR/butterfly/LCD-test/LCD_Driver.c
29a30
> volatile uint8_t LCDNumbers = 5;
228,229c229,264
< if (Byte != LCD_SPACE_OR_INVALID_CHAR) // Null indicates invalid character or space
< SegData = pgm_read_word(&LCD_SegTable[Byte]);
---
> if (Byte != LCD_SPACE_OR_INVALID_CHAR) { // Null indicates invalid character or space
> /* To adds pecial characters to scrolling display we have thre cases
> * for 1-5:
> * 1 and 2, OR 0x4 to Digit 0 and 1 (2 and 3 on LCD) respectivly
> * 4 and 5, OR 0x2 to Digit 2 and 3 (4 and 5 on LCD) respectivly
> * 3, set LCDDR3=0x1, as I think this is not written to for normal CSS characters
> * Ime sure theres a better way (and there is for just 1 and 2...
> * But ime doing this with a long list of if statements...
> */
> if (LCDNumbers >= 5 && Digit == 3)
> SegData = pgm_read_word(&LCD_SegTable[Byte])|0x2;
> else if (LCDNumbers >= 4 && Digit == 2)
> SegData = pgm_read_word(&LCD_SegTable[Byte])|0x2;
> else if (LCDNumbers >= 2 && Digit == 1)
> SegData = pgm_read_word(&LCD_SegTable[Byte])|0x4;
> else if (LCDNumbers >= 1 && Digit == 0)
> SegData = pgm_read_word(&LCD_SegTable[Byte])|0x4;
> else
> SegData = pgm_read_word(&LCD_SegTable[Byte]);
> }
> else
> if (LCDNumbers >= 5 && Digit == 3)
> SegData = 0x2;
> else if (LCDNumbers >= 4 && Digit == 2)
> SegData = 0x2;
> else if (LCDNumbers >= 2 && Digit == 1)
> SegData = 0x4;
> else if (LCDNumbers >= 1 && Digit == 0)
> SegData = 0x4;
> else
> SegData = 0x0 ;
>
> if (LCDNumbers >= 3 && Digit == 0)
> LCDDR3 = 0x1;
> else
> LCDDR3 = 0x0;
253a289,300
> UpdateDisplay = true;
> }
>
> /*
> NAME: | LCD_ShowNumbers
> PURPOSE: | Routine to sequentially turn on the LCD's numbers
> ARGUMENTS: | Highest number, 0 for none
> RETURNS: | None
> */
> void LCD_ShowNumbers( uint8_t LNumbers)
> {
> LNumbers = LCDNumbers;
the LCD_ShowNumbers() thing doesn't work, but setting the value LCDNumbers seems to, again due to my complete ignorance of C.
If you could improve on this and perhaps do it in a way that allowed for more general orring of bits to LCDDR* then I could try and fill in the rest to get arrows working. I can see myself doing it with another heap of if statements, which doesnt feel very eloquent.
I guess its more general to call LCD_Numbers() and have just this number appear, and as such LCD_Arrows() and have the corresponding arrow appear.
and... theres always one more thing... I would like to use portD, which means making sure that there is no way that anything gets put on segments 5,6,and 7 (All special segments except 9 are ok tho). How can I be sure of this by modifying your driver?
Hi there!
I've got a Butterfly, and I'm trying since fife weeks to write something on the display...
I'm new on AVR but I know the C-Language well. I've tried to make a new Project with AVRStudio 5 and copied the code from Dean (first comment) I've made a headerfile for the LDC_Driver.h but nothing works... :(
The only thing I can do, is to put the programm which was on it at first.
I'm becoming desperate of trying...
Can somebody help, even when it's a old thread??
Posted by abcminiuser: Sun. Sep 30, 2012 - 05:45 PM
1
2
3
4
5
Total votes: 0
Quote:
Well, it is an AVR Butterly board.
This is a joke right? It's a LCD driver for the Butterfly board, which has the ATMEGA169 on it. Therefore, if you have a Butterfly board with said MEGA169 on it there's a fairly good chance it will be compatible.
- Dean :twisted:
Make Atmel Studio better with my free extensions. Open source and feedback welcome!
1) 0xF is exactly the same as 0x000F (or any number of leading 0s in fact) but I think the author is making the point that it's masking the bottom 4 from the full 16 bits.
2) a & 1 test is usually an even/odd test. Even numbers are 0 when & 1 while odd numbers return 1 which is interpreted as "true" in a conditional test.
3) the line is taking the bottom 4 bits of what is already in the location pointed to then putting MaskedSegData into the upper 4 bits.
Here BuffPtr is defined which corresponds to LCD registers starting with LCDDR0. Next would be LCDDR5, then LCDDR10, and then LCDDR15 (according to COM0, COM1, COM2, and COM3). This is clear for me. But again - what Digit >> 1 means here?
Then,
uint16_t SegData = 0x0000;
Here SegData is declared with initial value.
Then,
if (Byte != LCD_SPACE_OR_INVALID_CHAR)
SegData = pgm_read_word(&LCD_SegTable[Byte]);
Here it's checking if Byte is not invalid character and if it is not, then avr function pgm_read_word() is parsing LCD_SegTable[] array for the Byte value and then store it to the SegData variable.
For example, let's take number 0 to be shown on my segment LCD which in my case in array LCD_SegTable[] is defined as 0x3132
Then,
for (uint8_t BNib = 0; BNib < 4; BNib++) {
Here it is looping through nibbles (4 bits). I think this is because AVR Butterfly LCD has 16 bits for the digit. But in my case I have 8 bits, so I thought I need to loop only through two nibbles? I tried to change here BNib < 2, but then wrong segments are lit.
Then,
uint8_t MaskedSegData = (SegData & 0x0000F);
Here MaskedSegData is defined and it takes SegData value which was read from LCD_SegTable[] array (in this example it is 0x3132) and then it is AND-ed with bottom 4 bits. Right?
If I convert 0x3132 from hex to bin, i get
0000 0000 0011 0001 0011 0010
AND-ed with 1111 it is then
0000 0000 0011 0001 0011 0010 right? The same!
Why it is AND-ed in the first place? You wrote that it is checking for even/odd numbers. Why it is needed here?
This I cannot understand at all. It's AND-ing Digit with 1 (if the last bit is 1?) and if true, then BuffPtr is AND-ed with bottom 4 bits and then OR-ed... what that means? It's definitely related to LCDDRx, but I can't get the point.
So if AND-ing Digit with 1 is false (the last bit is 0?), then BuffPtr is AND-ed with top 4 bits and then again OR-ed... what that means?
And finally,
BuffPtr += 5;
SegData >>= 4;
BuffPtr now is incremented by 5 (this probably is related to those LCDDR0, LCDDR5, LCDDR10 and so on, or LCDDR1, LCDDR6, LCDDR11 and so on). This probably is needed because next for loop iteration will be on the next register. Right?
And SegData? This I don't understand at all. What SegData = SegData >> 4 means in the first place? I know that shifting to the right is basically dividing, but I'm not sure if it's that case here.
As you already seem to be getting lost with some basic C code.
I would suggest setting a side the code you have at the moment and take your time to get to grips with the C operators.
All your questions seem to be coming from not understanding what the specific operators do and in what order they are executed.
Also you have to have a good look at the datasheet.
My first guess it that the pointer BuffPtr is initialized to point to the start of the RAM area in the chip that holds the actual display data. so what segments on the display are off or on
All that is done is to update the state of certain pixels that need to be updated to display the correct character on the display itself
All the programmer has done is instead of putting some calculations on separate lines they have combined them on a single line to make the code better readable ( in their eyes... )
As you already seem to be getting lost with some basic C code. I would suggest setting a side the code you have at the moment and take your time to get to grips with the C operators.
+10
Exactly what I was going to say. You can't really hope to use a code like this until you understand it and to understand it you need a grasp of some of the basic concepts in C like shifting and masking.
Works very well! Thanks for posting it.
- Log in or register to post comments
Tophi,
i wanna ask about how to add LCD_UpdateRequired function to dean's code..
thanks..
- Log in or register to post comments
Tophttps://www.avrfreaks.net/index.p...
The purpose of the tutorial threads is to discuss the tutorial, not solve unrelated problems.
Smiley
- Log in or register to post comments
Topoh.. okay, i'm sorry... :D
- Log in or register to post comments
TopAs such I'm going to lock this thread. If anyone has anything to add to the original article PM js, plons or clawson and ask us to temporarily unlock this.
Moderator
- Log in or register to post comments
TopIt would just be something simple like:
Added to the driver code.
- Dean :twisted:
Make Atmel Studio better with my free extensions. Open source and feedback welcome!
- Log in or register to post comments
TopThanks for this LCD driver, it allowed me to get characters on the screen with next to zero nowledge of C 8)
I noticed that
Does not check if the text is long enough to scroll, and if it isnt, waits forever...
For the solar hotwater controller that I am building I need the numbers (and eventially will need the arrows). I was going to ask if you could do it for me, but I have come up with a brute force hack on your code, without really understanding it too well that gives the numbers 1-5 sequentially. i.e if 3 then you get 3,2,1. I'me sure theres a much nicer way of doing it. I havnt check the 3 as R200(?) is desoldered atm
the LCD_ShowNumbers() thing doesn't work, but setting the value LCDNumbers seems to, again due to my complete ignorance of C.
If you could improve on this and perhaps do it in a way that allowed for more general orring of bits to LCDDR* then I could try and fill in the rest to get arrows working. I can see myself doing it with another heap of if statements, which doesnt feel very eloquent.) and have just this number appear, and as such LCD_Arrows() and have the corresponding arrow appear.
I guess its more general to call LCD_Numbers(
and... theres always one more thing... I would like to use portD, which means making sure that there is no way that anything gets put on segments 5,6,and 7 (All special segments except 9 are ok tho). How can I be sure of this by modifying your driver?
TIA
- Log in or register to post comments
TopHi there!
I've got a Butterfly, and I'm trying since fife weeks to write something on the display...
I'm new on AVR but I know the C-Language well. I've tried to make a new Project with AVRStudio 5 and copied the code from Dean (first comment) I've made a headerfile for the LDC_Driver.h but nothing works... :(
The only thing I can do, is to put the programm which was on it at first.
I'm becoming desperate of trying...
Can somebody help, even when it's a old thread??
THX in advence
- Log in or register to post comments
TopWill this code work with my Atmega169?
Thanks
- Log in or register to post comments
TopDepends if it's attached to an LCD with the same segment layout as the Atmel Butterfly or not.
However even if the segment layout is different the general technique should be adaptable.
- Log in or register to post comments
TopWell, it is an AVR Butterly board.
Please let me know what you mean by "LCd with the same segment layout as the Atmel Butteryfly or not."
Thanks
- Log in or register to post comments
TopThis is a joke right? It's a LCD driver for the Butterfly board, which has the ATMEGA169 on it. Therefore, if you have a Butterfly board with said MEGA169 on it there's a fairly good chance it will be compatible.
- Dean :twisted:
Make Atmel Studio better with my free extensions. Open source and feedback welcome!
- Log in or register to post comments
TopThanks buddy....it helped me a lot!
Success is optional, choose wisely!
- Log in or register to post comments
TopThank you Dean for posting the LCD driver - it worked for me perfectly the first time.
- Log in or register to post comments
TopHello,
Sorry for bringing back this old thread. My main question is more about C/C++ programming.
Original AVR Butterfly LCD has 16 bits for one digit, but my LCD has 8 bits.
Original LCD_WriteChar method:
If I change this line:
to this line:
I can "move cursor" to the second digit fine, but it doesn't move to the third digit.
So my main questions are about this particular LCD_WriteChar method from C/C++ perspective:
1) what means SegData & 0x0000F in this line? Why 0x0000F instead of 0x0F?
2) what means Digit & 0x01 in this line?
3) what means this line?
Regards,
Furieux
- Log in or register to post comments
TopAre you really talking about a segment LCD driven by a 169 or a 329?
- Log in or register to post comments
TopHi Clawson,
Yes, sorry, I’m actually talking about 329.
- Log in or register to post comments
Top1) 0xF is exactly the same as 0x000F (or any number of leading 0s in fact) but I think the author is making the point that it's masking the bottom 4 from the full 16 bits.
2) a & 1 test is usually an even/odd test. Even numbers are 0 when & 1 while odd numbers return 1 which is interpreted as "true" in a conditional test.
3) the line is taking the bottom 4 bits of what is already in the location pointed to then putting MaskedSegData into the upper 4 bits.
- Log in or register to post comments
TopOk, could you please help me to analyze this function deeper?
Here BuffPtr is defined which corresponds to LCD registers starting with LCDDR0. Next would be LCDDR5, then LCDDR10, and then LCDDR15 (according to COM0, COM1, COM2, and COM3). This is clear for me. But again - what Digit >> 1 means here?
Then,
Here SegData is declared with initial value.
Then,
Here it's checking if Byte is not invalid character and if it is not, then avr function pgm_read_word() is parsing LCD_SegTable[] array for the Byte value and then store it to the SegData variable.
For example, let's take number 0 to be shown on my segment LCD which in my case in array LCD_SegTable[] is defined as 0x3132
Then,
Here it is looping through nibbles (4 bits). I think this is because AVR Butterfly LCD has 16 bits for the digit. But in my case I have 8 bits, so I thought I need to loop only through two nibbles? I tried to change here BNib < 2, but then wrong segments are lit.
Then,
Here MaskedSegData is defined and it takes SegData value which was read from LCD_SegTable[] array (in this example it is 0x3132) and then it is AND-ed with bottom 4 bits. Right?
If I convert 0x3132 from hex to bin, i get
0000 0000 0011 0001 0011 0010
AND-ed with 1111 it is then
0000 0000 0011 0001 0011 0010 right? The same!
Why it is AND-ed in the first place? You wrote that it is checking for even/odd numbers. Why it is needed here?
Then,
This I cannot understand at all. It's AND-ing Digit with 1 (if the last bit is 1?) and if true, then BuffPtr is AND-ed with bottom 4 bits and then OR-ed... what that means? It's definitely related to LCDDRx, but I can't get the point.
Then,
So if AND-ing Digit with 1 is false (the last bit is 0?), then BuffPtr is AND-ed with top 4 bits and then again OR-ed... what that means?
And finally,
BuffPtr now is incremented by 5 (this probably is related to those LCDDR0, LCDDR5, LCDDR10 and so on, or LCDDR1, LCDDR6, LCDDR11 and so on). This probably is needed because next for loop iteration will be on the next register. Right?
And SegData? This I don't understand at all. What SegData = SegData >> 4 means in the first place? I know that shifting to the right is basically dividing, but I'm not sure if it's that case here.
- Log in or register to post comments
TopAs you already seem to be getting lost with some basic C code.
I would suggest setting a side the code you have at the moment and take your time to get to grips with the C operators.
All your questions seem to be coming from not understanding what the specific operators do and in what order they are executed.
Also you have to have a good look at the datasheet.
My first guess it that the pointer BuffPtr is initialized to point to the start of the RAM area in the chip that holds the actual display data. so what segments on the display are off or on
All that is done is to update the state of certain pixels that need to be updated to display the correct character on the display itself
All the programmer has done is instead of putting some calculations on separate lines they have combined them on a single line to make the code better readable ( in their eyes... )
- Log in or register to post comments
TopExactly what I was going to say. You can't really hope to use a code like this until you understand it and to understand it you need a grasp of some of the basic concepts in C like shifting and masking.
- Log in or register to post comments
TopOk, I got it.
Until that my only option will be to just leave unconnected those two pins (unneeded 8 bits) and use the same code...
Anyway, thanks for the help!
- Log in or register to post comments
TopPages