PDA

View Full Version : Emag Board



nippinout
05-29-2003, 07:13 PM
Has AGD changed the emag board from surface mounting to socketing the microcontroller?

Could I get a little more information about the display driver?

Is the display driver an off the shelf component? Is it built into the display?

BajaBoy
05-29-2003, 07:57 PM
ooh, ide like to know too.


p.s. our threds have the same name lol

yagrmiestr
05-31-2003, 01:20 AM
Sorry guys I've been busy otherwise I would have responded sooner. Here's a little explanation of how I programmed the LED display.

Each character on the display is 5 bytes of data. There are 8 characters on the display (40 bytes total). For each character I store the 5 bytes of data in the eeprom inside the AT90S2313 microcontroller. The micro has 128 bytes of memory. This would give you space for 25 complete characters (128/5 = 25.6). So the 5 bytes of character one are located in eeprom byte 1, 2, 3, 4, and 5 (don't use location 0 because it could glitch per datasheet comment). I store the starting location of each charater inside my code. So for for character one I would load a "1" into the disp() array and for character two I would load a "6".

Then when I want to write to the display I load the 8 byte "disp(8)" array with the starting location for each of the 8 characters. Then I call the following routine and pass it the "disp(8)" array and it reads all the data for each character from the eeprom and then writes it out to the full display. When the data gets written out it actual goes out one BIT at a time. So one character is 5 bytes X 8 bits = 40 bits. Then one display is 8 characters X 40 bits = 320 bits total. Hence in my code there is a loop for each character loop, each byte of a character, and each bits of a character byte.

I will follow up with some code....

yagrmiestr
05-31-2003, 01:34 AM
'Write LED Display Routine
Sub Writemenu(byval Disp(8) As Byte)
Portb.4 = 0 'Selects to write to Data registers of LED display
Countb = 1
For Countb = 1 To 8 'Loop for each of the 8 characters
Addr = Disp(countb) 'Grab Start address for current byte
Startadd = Addr 'Set start address
Stopadd = Addr + 4 'One character ends 4 bytes later, so 5 in total
For Addr = Startadd To Stopadd 'Read each of the 5 bytes for each character
Readeeprom Col , Addr 'Read data from eeprom
Waitms 1
Portd.6 = 0 'Enable the LED display serial port
Waitus 15
Call Writecolumn(col) 'Write one of the 5 bytes of a character
Waitus 15
Portd.6 = 1 'Finish write sequence
Waitus 5
Portb.3 = 1 'Reset Serial Data
Portb.2 = 0 'Reset Serial Clock
Next Addr
Next Countb
End Sub

'Write Column Routine
Sub Writecolumn(byval Col As Byte)
Countc = 7
For Countc = 7 To 0 Step -1 'Loop for 8 bits of a character data (does this 5 times per character)
Portb.2 = 0 'Toggle serial clock low
Portb.3 = Col.countc 'Data pin set to current bit of character data
Waitus 3
Portb.2 = 1 'Toggle clock high and LED reads data in
Waitus 15
Next Countc
End Sub

Edit: One clarification. The 5 bytes for each character are actually 5 columns of LEDs. So the "Col" variable is one column, or one data byte, of a character.

yagrmiestr
05-31-2003, 01:41 AM
This routine will blank the display with one byte instead of writing 8 blank characters (40 bytes) of data. I use it after I fire the solenoid to clear the display quickly.

'Blank Display
Blankdisp:
'Control Word 0
Portb.4 = 1
Waitms 1
Portd.6 = 0
Waitus 15
Call Writecolumn(&B00001111)
Waitus 15
Portd.6 = 1
Waitus 5
Portb.3 = 1
Portb.2 = 0
Portb.4 = 0
Return


This routine will enable the display after you have blanked it or initialize it for the first time when you power everything up.

'Enable / Initialize LED Display
Initdisp:
'Control Word 0
Portb.4 = 1
Waitms 1
Portd.6 = 0
Waitus 15
Call Writecolumn(&B01001111)
Waitus 15
Portd.6 = 1
Portb.3 = 1
Portb.2 = 0
' Control Word 1
Waitms 1
Portd.6 = 0
Waitus 15
Call Writecolumn(&B10000000)
Waitus 15
Portd.6 = 1
Portb.3 = 1
Portb.2 = 0
Portb.4 = 0
Return

Edit: Spelling

yagrmiestr
05-31-2003, 01:43 AM
That should give you guys something to think about. :D I will start a post later with some "responsible" code (i.e. no full auto or low solenoid dwell times) when I find some more time.

yagrmiestr
05-31-2003, 01:53 AM
One more comment. ;) If you look at the code I reset the serial communication (PD.6, PB.2 & PB.3) after each byte. I don't believe you have to do this for each byte, but instead could write all 40 bytes in succession. However the code works and we are only talking about a saving maybe few hundred miliseconds so I never bothered optimizing it further. Just make sure you don't call anything but the blank display routine in the middle of your firing routine as it will throw off all your timing. If you have access to an oscilloscope like me, hook your board up to an oscilloscope and fine-tune your firing sequences after you have written your code. ;)

yagrmiestr
05-31-2003, 01:54 AM
lol, am I a post whore now? :p

mh53eplt
05-31-2003, 10:40 PM
categorically speaking--- YES :D :D :D

BajaBoy
06-01-2003, 04:19 PM
Originally posted by mh53eplt
categorically speaking--- YES :D :D :D

nooo lol, this is all helpful info.. if only i knew what he is talking about

314159
06-01-2003, 07:21 PM
here is some pic asm code subroutines, kinda dirty, but just copying and pasting some routines i wrote.

ClearDisplay bsf PORTB,DisplayClock
bcf PORTB,DisplayRegisterSelect ;select dot register
bcf PORTB,DisplayChipEnable ;set low to enter data
bcf PORTB,DisplayClock
bcf PORTB,DisplayDataIn ;this routine loads a couple more blank
movlw d'2' ; pixles than necessary, but it is not a
movwf OuterCount ; problem
movlw d'160'
movwf InnerCount
bsf PORTB,DisplayClock
bcf PORTB,DisplayClock
decf InnerCount,f
btfss STATUS,Z
goto $ - 4
decf OuterCount,f
btfss STATUS,Z
goto $ - 9
bsf PORTB,DisplayClock
bsf PORTB,DisplayChipEnable
bcf PORTB,DisplayClock
return

LoadCollumW movwf TempVar
movlw d'8'
movwf InnerCount
btfsc TempVar,7
bsf PORTB,DisplayDataIn
btfss TempVar,7
bcf PORTB,DisplayDataIn
bsf PORTB,DisplayClock
bcf PORTB,DisplayClock
rlf TempVar,f
decf InnerCount,f
btfss STATUS,Z
goto $ - 9
return

LoadCollumWLast movwf TempVar
movlw d'7'
movwf InnerCount
btfsc TempVar,7
bsf PORTB,DisplayDataIn
btfss TempVar,7
bcf PORTB,DisplayDataIn
bsf PORTB,DisplayClock
bcf PORTB,DisplayClock
rlf TempVar,f
decf InnerCount,f
btfss STATUS,Z
goto $ - 9

btfsc TempVar,7
bsf PORTB,DisplayDataIn
btfss TempVar,7
bcf PORTB,DisplayDataIn

bsf PORTB,DisplayClock
return

LoadDisplaySettings bsf PORTB,DisplayClock ;prep to write to setup reg
bsf PORTB,DisplayRegisterSelect
bcf PORTB,DisplayChipEnable
bcf PORTB,DisplayClock


movlw b'01101111' ;write to setup reg msb first d4 clear for 31% bright, set for 100%
call LoadCollumWLast ;so that msb is written first (lsb of num loaded into w)

bsf PORTB,DisplayChipEnable ;latch data
bcf PORTB,DisplayClock

bsf PORTB,DisplayClock ;prep to write to setpu reg
bcf PORTB,DisplayChipEnable
bcf PORTB,DisplayClock

movlw b'10000001' ;write to setup reg msb first
call LoadCollumWLast ;so that msb is written first (lsb of num loaded into w)

bsf PORTB,DisplayChipEnable ;latch data
bcf PORTB,DisplayClock
return


and here is a routine to display the char "A" (need to move char info to a table sometime to optimise for size)

LoadCharUA movlw 0x7E
call LoadCollumW
movlw 0x09
call LoadCollumW
movlw 0x09
call LoadCollumW
movlw 0x09
call LoadCollumW
movlw 0x7E
call LoadCollumWLast
return

agd uses an atmel processor, the atmel processor has a lot of similar routines to the pic, so porting should not be too hard if u wanted to convert this to atmel code.