; LED Blink Example program, for use with the PJRC 8051 ; Development Circuit Board, Rev 4. ; ; http://www.pjrc.com/tech/8051/board4/blink_as31.html ;This line configures where the program will go into memory. ;2000 to 7FFF is RAM, which is the best place to download ;while testing your code. Memory from 8000 to F7FF is Flash ;ROM, which is non-volatile. You MUST ERASE the flash rom ;if the area you will use already has data in it. Unlike ;easily re-writable RAM, writing to flash rom can only change ;1's into 0's. To change the 0's back into 1's, you must ;erase the flash (which turns a section or all of it into ;0xFFs to all you to download again). .equ locat, 0x2000 ;Location for this program ;82C55 memory locations, Rev 4 .equ port_a, 0xF800 ;access port A .equ port_b, 0xF801 ;access port B .equ port_c, 0xF802 ;access port C .equ port_abc_pgm, 0xF803 ;configure in/out of all three ports .equ port_d, 0xF900 ;access port D .equ port_e, 0xF901 ;access port E .equ port_f, 0xF902 ;access port F .equ port_def_pgm, 0xF903 ;configure in/out of all three ports ; Useful routines in PAULMON2 that you can call. When you ; later want a stand-alone application, you can copy them ; from the PAULMON2 source code (or write you own if you like). .equ cout, 0x0030 ;print byte in acc to serial port .equ cin, 0x0032 ;get byte from serial port into acc .equ phex, 0x0034 ;print acc in hex (2 digits) .equ phex16, 0x0036 ;print dptr in hex (4 digits) .equ pstr, 0x0038 ;print a string @dptr .equ esc, 0x003E ;paulmon2's check for esc key .equ newline, 0x0048 ;print a newline (CR and LF) .equ pint8u, 0x004D ;print acc as unsigned int (0 to 255) .equ pint16u, 0x0053 ;print dptr as unsigned int (0 to 65535) ;Program Header. This is what PAULMON2 looks for to display the ;program in its memory usage and run menus. You would normally ;run this program with 'R', but you can also jump to 2040 (or .org locat .db 0xA5,0xE5,0xE0,0xA5 ;signiture bytes .db 35,255,0,0 ;id (35=prog) .db 0,0,0,0 ;prompt code vector .db 0,0,0,0 ;reserved .db 0,0,0,0 ;reserved .db 0,0,0,0 ;reserved .db 0,0,0,0 ;user defined .db 255,255,255,255 ;length and checksum (255=unused) .db "Blink LEDs",0 ;max 31 characters, plus the zero .org locat+64 ;executable code begins here ;Finally, the actual code.... much shorter than all these comments ;that try to explain how to set everything up! startup: mov dptr, #port_def_pgm mov a, #128 movx @dptr, a ;make all D-E-F port pins outputs begin: mov dptr, #table ;DPTR will keep track of which entry in ;the table we will do next loop: clr a movc a, @a+dptr ;get pattern to display acall update inc dptr lcall esc ;abort if the user presses ESC jc exit clr a movc a, @a+dptr ;get time to display this pattern jz begin ;restart when we hit the end of the table acall delay inc dptr sjmp loop ;keep doing the animation.... exit: ljmp 0 ;write the bit pattern in Acc to port E. We need to ;save DPTR (holding our position in the table) before ;using DPTR to access the 82C55 chip. update: push dph push dpl mov dptr, #port_e movx @dptr, a pop dpl pop dph ret ;delay for a number of ms (specified by acc) delay: mov r0, a dly2: mov r1, #230 dly3: nop nop nop ;6 NOPs + DJNZ is 4.34 us nop ;with the 22.1184 MHz crystal nop nop djnz r1, dly3 ;repeat 230 times for 1 ms djnz r0, dly2 ;repeat for specified # of ms ret ;The data table that is read by the MOVC instructions above. table: .db 01111111b, 90 .db 00111111b, 70 .db 00011111b, 50 .db 10001111b, 40 .db 11000111b, 40 .db 11100011b, 40 .db 11110001b, 40 .db 11111000b, 50 .db 11111100b, 70 .db 11111110b, 90 .db 11111100b, 70 .db 11111000b, 50 .db 11110001b, 40 .db 11100011b, 40 .db 11000111b, 40 .db 10001111b, 40 .db 00011111b, 50 .db 00111111b, 70 .db 255,0 ;zero marks end of table