Hello everyone, i want to ask a question...
i want to define a combined port register, for example i want to combine the first 4 ports from PORTA and the first 4 ports from PORTB and define it using #define...
do you know how to do that? any answer is appreciated, thx
[ASK] JOINING DIFFERENT PORT REGISTER AND DEFINE THEM
You will get better answers if you explain why you want to do this. THere are a few ways to do what you want.
Do you have an 8bit variable you want to display half on one port, the other on the other for example?
Jim
void write_port(uint8_t val) { PORTA = (PORTA & 0xF0) | (val & 0x0F); PORTB = (PORTB & 0xF0) | (val >> 4); }
or something like that perhaps?
void write_port(uint8_t val) { PORTA = (PORTA & 0xF0) | (val & 0x0F); PORTB = (PORTB & 0xF0) | (val >> 4); }or something like that perhaps?
yeah probably something like that...i want to use them in #define symbol
btw is it possible to use that function in a #define ?
i just want to know about how to join and use them in a #define
i just want to know about how to join and use them in a #define
I think what you are looking for is a MACRO maybe? I am probably wrong on that, but hey I might be right too...
JIm
Take look at this:
https://www.programiz.com/c-prog...
scroll down a little. I think thats what you are looking for
i want to use lcd library from pascal stang but looks like that library is only designed to use 1 port register, for example it just use only PORTC to define its I/O pins....i have to join 2 different port registers to use that lcd library anyway
i want to use lcd library from pascal stang
Link to the library would help. Like I said in post #2....more information up front gets better answers
JIm
probably you are right, at least i can join 2 different port registers to run my LCD using 8-bit mode and its pins are taken from 2 different port registers, for example PORTA.1...PORTA.4 and PORTB.1...PORTB.4
e0ne199 wrote:i want to use lcd library from pascal stangLink to the library would help. Like I said in post #2....more information up front gets better answers
JIm
// Enable one of the following interfaces to your LCD //#define LCD_MEMORY_INTERFACE #define LCD_PORT_INTERFACE // Enter the parameters for your chosen interface' // if you chose the LCD_PORT_INTERFACE: #ifdef LCD_PORT_INTERFACE #ifndef LCD_CTRL_PORT // port and pins you will use for control lines #define LCD_CTRL_PORT PORTC #define LCD_CTRL_DDR DDRC #define LCD_CTRL_RS 0 #define LCD_CTRL_RW 1 #define LCD_CTRL_E 2 #endif #ifndef LCD_DATA_POUT // port you will use for data lines #define LCD_DATA_POUT PORTC #define LCD_DATA_PIN PINC #define LCD_DATA_DDR DDRC // access mode you will use (default is 8bit unless 4bit is selected) // #define LCD_DATA_4BIT #endif #endif // if you chose the LCD_MEMORY_INTERFACE: #ifdef LCD_MEMORY_INTERFACE #ifndef LCD_CTRL_ADDR // CPU memory address of the LCD control register #define LCD_CTRL_ADDR 0x1000 #endif #ifndef LCD_DATA_ADDR // CPU memory address of the LCD data register #define LCD_DATA_ADDR 0x1001 #endif #endif // LCD display geometry // change these definitions to adapt settings #define LCD_LINES 4 // visible lines #define LCD_LINE_LENGTH 20 // line length (in characters) // cursor position to DDRAM mapping #define LCD_LINE0_DDRAMADDR 0x00 #define LCD_LINE1_DDRAMADDR 0x40 #define LCD_LINE2_DDRAMADDR 0x14 #define LCD_LINE3_DDRAMADDR 0x54 #endif
i want to configure LCD_DATA_POUT, LCD_DATA_PIN and LCD_DATA_DDR to use PORTC and PORTB for example, do you know how to do that?
I just took a look at Pascal stangs library. I would suggest you look at Peter Fleurys LCD library instead. It allows you to do EXACTLY what you want to do just by making a few modifications in a .h file
http://homepage.hispeed.ch/peter...
Halfway down " LCD library for HD44780 based LCD's "
Jim
Answer to post #9
You do not need to do anything in that code. Just change the PORTs for the control and the data, and then call out what pins on said ports are for. Just like Fleurys library
Jim
Edit: Spelling
Edit Edit:
I would look at Fleurys library. Seems a lot simpler than the one you are trying to work with.
I just took a look at Pascal stangs library. I would suggest you look at Peter Fleurys LCD library instead. It allows you to do EXACTLY what you want to do just by making a few modifications in a .h file
http://homepage.hispeed.ch/peter...
Halfway down " LCD library for HD44780 based LCD's "
Jim
it is a base library of avr-gcc, i would like to use that but it doesn't allow 8-bit I/O for the LCD
Answer to post #9
You do not need to do anything in that code. Just change the PORTs for the control and the data, and then call out what pins on said ports are for. Just like Fleurys library
Jim
Edit: Spelling
Edit Edit:
I would look at Fleurys library. Seems a lot simpler than the one you are trying to work with.
would you please give me an example for the code?
it is a base library of avr-gcc, i would like to use that but it doesn't allow 8-bit I/O for the LCD
Are you loooking to use 8bits for data and 4 bits for control? Why waste 12 bits of I/O when you can simply put it all on one port? You wil not notice any difference in speed
JIm
WHich AVR are you using?
JIm
WHich AVR are you using?
JIm
AVR atmega88pa, sorry for late post
I just looked at an example Studio project I did for another freak a while back. The Fleury Library does not allow you to split the data between ports as it only supports 4 bit data which is fine.
Do you really need to use all 8 bits for data?
On your Mega88 do you have one full port available? I can sip up this project and post it.
JIm
yeah probably something like that...i want to use them in #define symbol
btw is it possible to use that function in a #define ?
People tend to put too much reliance on the C pre-processor. If you program in a MISRA environment then you just aren't allowed to do it as MISRA considers macro "code" to be dangerous.
PS a macro version of what I wrote would presumably look something like:
#define WRITE_PORT( val) \ PORTA = (PORTA & 0xF0) | (val & 0x0F);\ PORTB = (PORTB & 0xF0) | (val >> 4);
but do NOT use this - use the C and make the function "static inline" perhaps even "static inline __attribute__((always_inline))"
I just looked at an example Studio project I did for another freak a while back. The Fleury Library does not allow you to split the data between ports as it only supports 4 bit data which is fine.
Do you really need to use all 8 bits for data?
On your Mega88 do you have one full port available? I can sip up this project and post it.
JIm
actually i usually use 4 bit data for LCD, but for now i really want to know how 8 bit data performs compared to 4 bit one..
and i also want to know how to combine and define different port registers if it is possible to do that
but for now i really want to know how 8 bit data performs compared to 4 bit one..
...but for now i really want to know how 8 bit data performs compared to 4 bit one..
That's an easy one; it's twice as fast.
However, unless you are aiming for unrealistic update rates, you will not notice any appreciable increase for 99.9% of applications.
[E2A]
Of course, in real life it's not twice as fast. If you look at the datasheet you will see that no write operation can be faster than 37us between consecutive commands. So speeding up your data transfer to the display is not really worth it.
That's an easy one; it's twice as fast.
Kind of a flippant answer, isn't it? As always one needs to tell how you are measuring, and what you are measuring. Is it really that straightforward with consecutive characters output on the same LCD line? Perhaps.
Is it close when there are positioning and other commands?
After we quell this tempest in a teapot, we'll find that the OP is using the "delay" method rather than the "ready" method.
Brian Fairchild wrote:That's an easy one; it's twice as fast.Kind of a flippant answer, isn't it?
It is. Which is why I added the bit about the 37us enforced gap between all write to CGRAM.
Let's assume a 16MHz AVR and a 2x16 display.
You issue a 'clear screen' command and then have to wait a minimum of 1.52ms. In that time your AVR will execute up to 24,320 instructions.
You write your first character to the display and then have to wait a minimum of 37us. In that time your AVR will execute up to another 592 instructions.
And repeat for all 32 characters. So to clear a display and write a full screen your processor could execute up to 24,320 + (32 x 592) = 43,264 instructions in the time it takes your display to deal with just 33 bytes of data.
Upon further reflection, this really is an interesting quest. If you use e.g. Fleury and place the 8 pins arbitrarily then there will be more code with every operation to do the placement. [Does that overlap with the wait/ready check so it is immaterial? What about on the first character of a string?]
I've done probably scores of production apps with that AVR family over the years that have character LCDs; all are driven in 4-bit mode. That family is hard to get a complete port -- port D is the only complete eight bits and that has the UART. I'll try to start the clear operation when needed and then come back later to get useful stuff done during the delay. My update rate is usually 2-4 times per second so a bit of extra time is virtually immaterial. It does indeed take a goodly amount of time to do a full repaint, especially on four-line displays. I keep a buffer of "dirty" lines, and do one line at a time and other important stuff between.
43,264 instructions
Surely the "issue" with 4/8 is purely about how many pins you are willing to sacrifice
I took the advice of another freak and simply use I2C backpacks on LCD's and the Davide Gironi library to drive them. MAkes for a very easy connection...power, data, clock.
JIm
For the Original Poster, there is a significant technical problem with the request. Lets lay it out...
1) AVR pins cannot be accessed in isolation. They are always part of a "port". It does not matter if the chip has one port or 10. Does not matter if Tiny or Mega or XMega.
2) Writing to a pin requires writing to a port. That is, each port takes its own write.
3) Thus, if you are trying to output parallel data, and that data is split across several ports, the data in each separate port would take a separate write.
4) If you are trying to get faster operation compared to use of a 4-bit data bus to an LCD, you would still have those separate port writes. So, it might net a LITTLE faster than two 4 bit nibble bus transfers, but not nearly as fast as the use of a full 8-bit wide dedicated port.
Then, there is the pragmatic issue of "Persistence Of Vision". You eyes cannot see changes that happen faster than 40ms or so. Your eyes "average it". That is why a rapidly flashing LED seems continuously ON, but dim. Thus, if you can write all of the changes needed for the LCD in less than 40ms, your eyes cannot tell if it was done in 1ms or 20ms.
Hope this helps in your design process.
Jim
AVR pins cannot be accessed in isolation. They are always part of a "port".
Sort of neutral on that thought, since we have cbi & sbi which can independently set any particular port bit. What is isolation? The pins are also all part of the AVR as well as ports.
Or maybe this is simply referring to the nomenclature, that they belong to a port group.
I was referring to the fact that you CANNOT say that I am going to construct a "virtual" port out of PA1 and PB3 and PC2 and PA5 and PD7 and .... , then write to it as a single port. In the example just given, you would need to write once to PORTA to do PA1 and PA5, once to PORTB to do PB3, once to PORTC to get PC2, once to PORTD to do PD7, and so forth.
Jim
sorry i have been busy with work lately..i have just come back here and i see more people are commenting here, thx for the response everyone
so the answer is it is kind of impossible to join different port register using #define to send data to LCD in 8-bit mode ?
anyway i am trying to do that using pascal stang's LCD library to test the LCD...
so the answer is it is kind of impossible to join different port register using #define to send data to LCD in 8-bit mode ?
The fact is that HD44780 use a strobe signal (it's called "E") to latch data at the input so you can build up all the bits individually if you like then when all 8 are present then you strobe E to latch what has been presented. So the fact that the individual bit setup may be staggered in this case does not really matter. As I already showed you could do:
#define WRITE_PORT( val) \ PORTA = (PORTA & 0xF0) | (val & 0x0F);\ PORTB = (PORTB & 0xF0) | (val >> 4);
In fact if all 8 bits in "val" were bits in different ports you could have this as complex as you like:
#define WRITE_PORT( val) \ PORTA = (PORTA & 0xFE) | (val & 0x01);\ PORTD = (PORTD & 0x7F) | (val & 02) << 6;\ PORTG = (PORTG & 0xEF) | (val & 04) << 2;\ PORTB = (PORTB & 0xFB) | (val & 08) >> 1;\ etc etc...
But I'd still argue than better than a define is:
static inline __attribute__((always_inline)) void write port(uint8_t val) { PORTA = (PORTA & 0xFE) | (val & 0x01); PORTD = (PORTD & 0x7F) | (val & 02) << 6; PORTG = (PORTG & 0xEF) | (val & 04) << 2; PORTB = (PORTB & 0xFB) | (val & 08) >> 1; etc etc }