Trying to run blinking 8051 code successfully
Quote from ivo on March 13, 2024, 4:17 pmHi, I am trying to get 8051 successfully running.
I opened Micro/mcs-51_blink/mcs-51_test.sim1 from examples. I have SDCC 4.4.0 (MINGW32) installed. I'm using v1.0.0 SimulIDE for now. In the editor I compile and upload this code:
#include <8051.h> #define Nop() __asm nop __endasm void delay_ms(unsigned int count) { unsigned int i, j; for (i = 0; i < count; i++) { // 0.001s / (12Mhz / 12T) = 1000 for (j = 0; j < 1000; j++) { Nop(); } } } int main(void) { while (1) { P1_0 = 0; delay_ms(200); P1_0 = 1; delay_ms(300); } }
But I can't get anything happening with P1_0 LED.
Hi, I am trying to get 8051 successfully running.
I opened Micro/mcs-51_blink/mcs-51_test.sim1 from examples. I have SDCC 4.4.0 (MINGW32) installed. I'm using v1.0.0 SimulIDE for now. In the editor I compile and upload this code:
#include <8051.h>
#define Nop() __asm nop __endasm
void delay_ms(unsigned int count) {
unsigned int i, j;
for (i = 0; i < count; i++) {
// 0.001s / (12Mhz / 12T) = 1000
for (j = 0; j < 1000; j++) {
Nop();
}
}
}
int main(void) {
while (1) {
P1_0 = 0;
delay_ms(200);
P1_0 = 1;
delay_ms(300);
}
}
But I can't get anything happening with P1_0 LED.
Quote from arcachofo on March 13, 2024, 4:37 pmHi.
Your code works correctly for me in SimulIDE 1.0.0.
Hi.
Your code works correctly for me in SimulIDE 1.0.0.
Quote from ivo on March 13, 2024, 5:32 pmOkay... true, you are right. I just repeated my own instructions and it did run!! However maybe I also found the deeper cause of my troubles.
I tried to modify the delay counts to something obviously different. I saved the file, then clicked Compile, then UpLoad, and started the simulation again. I can see that obviously nothing has changed. It uses the old counts. So this is probably what happened to me. I was trying different ports, different LEDs, etc, and probably the same old code with some bug was constantly being used instead of anything new I tried.
I could only get the new code to take effect by first deleting all files in the /build directory where simulide had put them, and then recompiling and uploading the new code worked to effect the new behaviour. I wonder if this is SDCC or simulide just refusing to recompile properly or something if there's existing artifacts? Having to delete everything inside the directory every time would be a bit of a pain... (I noticed if I delete the directory itself, I get an error! next time - failed to open output file)
Okay... true, you are right. I just repeated my own instructions and it did run!! However maybe I also found the deeper cause of my troubles.
I tried to modify the delay counts to something obviously different. I saved the file, then clicked Compile, then UpLoad, and started the simulation again. I can see that obviously nothing has changed. It uses the old counts. So this is probably what happened to me. I was trying different ports, different LEDs, etc, and probably the same old code with some bug was constantly being used instead of anything new I tried.
I could only get the new code to take effect by first deleting all files in the /build directory where simulide had put them, and then recompiling and uploading the new code worked to effect the new behaviour. I wonder if this is SDCC or simulide just refusing to recompile properly or something if there's existing artifacts? Having to delete everything inside the directory every time would be a bit of a pain... (I noticed if I delete the directory itself, I get an error! next time - failed to open output file)
Quote from ivo on March 13, 2024, 5:52 pmCuriously at least for this simulation I need a loop of
for (j = 0; j < 165; j++) { }
To get roughly a correct ms timing at least for this processor & compiler & simulator. I don't really have much idea where the number 165 should come from (apart from trial and error). I thought without the nop that SDCC might optimize the loop out of the assembly bit it seems not in this case. I still have some actual STC89C52's ( datasheet ) coming in the mail that I eventually want to test things out on. I'm guessing maybe using a timer might also be a lot more accurate.
Curiously at least for this simulation I need a loop of
for (j = 0; j < 165; j++) {
}
To get roughly a correct ms timing at least for this processor & compiler & simulator. I don't really have much idea where the number 165 should come from (apart from trial and error). I thought without the nop that SDCC might optimize the loop out of the assembly bit it seems not in this case. I still have some actual STC89C52's ( datasheet ) coming in the mail that I eventually want to test things out on. I'm guessing maybe using a timer might also be a lot more accurate.
Quote from arcachofo on March 13, 2024, 5:55 pmSeems that SDCC wont ovewrite a file if it already exist.
Not sure if there is an option to force it.If not, you can fix this by adding a step to delete the hex file in the compiler file:
data/codeeditor/compilers/compilers/sdcc.xml
For example in Linux:<compiler name="SDCC" type="sdcc" buildPath="build" > <step command="rm" arguments=" $buildPath$fileName.hex" /> <step command="sdcc" arguments=" -o$buildPath $filePath" /> </compiler>
Seems that SDCC wont ovewrite a file if it already exist.
Not sure if there is an option to force it.
If not, you can fix this by adding a step to delete the hex file in the compiler file:
data/codeeditor/compilers/compilers/sdcc.xml
For example in Linux:
<compiler name="SDCC" type="sdcc" buildPath="build" >
<step
command="rm"
arguments=" $buildPath$fileName.hex"
/>
<step
command="sdcc"
arguments=" -o$buildPath $filePath"
/>
</compiler>
Quote from arcachofo on March 13, 2024, 6:07 pmI don't really have much idea where the number 165 should come from (apart from trial and error).
You count asm instructions.
Look at the assembler and see what it really does and count cycles:;------------------------------------------------------------ ; 8051-blink.c:5: void delay_ms(unsigned int count) { ; ----------------------------------------- ; function delay_ms ; ----------------------------------------- _delay_ms: ar7 = 0x07 ar6 = 0x06 ar5 = 0x05 ar4 = 0x04 ar3 = 0x03 ar2 = 0x02 ar1 = 0x01 ar0 = 0x00 mov r6,dpl mov r7,dph ; 8051-blink.c:7: for (i = 0; i < count; i++) { mov r4,#0x00 mov r5,#0x00 00107$: clr c mov a,r4 subb a,r6 mov a,r5 subb a,r7 jnc 00109$ ; 8051-blink.c:9: for (j = 0; j < 1000; j++) { mov r2,#0xe8 mov r3,#0x03 00105$: ; 8051-blink.c:10: Nop(); nop mov a,r2 add a,#0xff mov r0,a mov a,r3 addc a,#0xff mov r1,a mov ar2,r0 mov ar3,r1 ; 8051-blink.c:9: for (j = 0; j < 1000; j++) { mov a,r0 orl a,r1 jnz 00105$ ; 8051-blink.c:7: for (i = 0; i < count; i++) { inc r4 cjne r4,#0x00,00107$ inc r5 sjmp 00107$ 00109$: ; 8051-blink.c:13: } ret
I'm guessing maybe using a timer might also be a lot more accurate.
For sure.
I don't really have much idea where the number 165 should come from (apart from trial and error).
You count asm instructions.
Look at the assembler and see what it really does and count cycles:
;------------------------------------------------------------
; 8051-blink.c:5: void delay_ms(unsigned int count) {
; -----------------------------------------
; function delay_ms
; -----------------------------------------
_delay_ms:
ar7 = 0x07
ar6 = 0x06
ar5 = 0x05
ar4 = 0x04
ar3 = 0x03
ar2 = 0x02
ar1 = 0x01
ar0 = 0x00
mov r6,dpl
mov r7,dph
; 8051-blink.c:7: for (i = 0; i < count; i++) {
mov r4,#0x00
mov r5,#0x00
00107$:
clr c
mov a,r4
subb a,r6
mov a,r5
subb a,r7
jnc 00109$
; 8051-blink.c:9: for (j = 0; j < 1000; j++) {
mov r2,#0xe8
mov r3,#0x03
00105$:
; 8051-blink.c:10: Nop();
nop
mov a,r2
add a,#0xff
mov r0,a
mov a,r3
addc a,#0xff
mov r1,a
mov ar2,r0
mov ar3,r1
; 8051-blink.c:9: for (j = 0; j < 1000; j++) {
mov a,r0
orl a,r1
jnz 00105$
; 8051-blink.c:7: for (i = 0; i < count; i++) {
inc r4
cjne r4,#0x00,00107$
inc r5
sjmp 00107$
00109$:
; 8051-blink.c:13: }
ret
I'm guessing maybe using a timer might also be a lot more accurate.
For sure.
Quote from ivo on March 13, 2024, 6:11 pmUnfortunately on Windows,
del
is normal command to delete files, but SIDE givesERROR: DEL
: Executable not found
: Check that Tool Path is correct
Yes, I checked both upper and lower case
Unfortunately on Windows, del
is normal command to delete files, but SIDE gives
ERROR: DEL
: Executable not found
: Check that Tool Path is correct
Yes, I checked both upper and lower case
Quote from arcachofo on March 13, 2024, 6:34 pmProbably there is not an executable named "del"
An option is to create an actual file that can be executed.
Maybe a batch?
Probably there is not an executable named "del"
An option is to create an actual file that can be executed.
Maybe a batch?
Quote from ivo on March 14, 2024, 5:22 amFor now, because I had msys64 installed through chocolatey, I could use
<step command="C:\tools\msys64\usr\bin\rm" arguments=" $buildPath$fileName.hex" />
and it worked. I seem to need a buffer in front of the LED. I'm not sure if that's the case for all signals sent out. Thanks for your help, cool software
For now, because I had msys64 installed through chocolatey, I could use
<step
command="C:\tools\msys64\usr\bin\rm"
arguments=" $buildPath$fileName.hex"
/>
and it worked. I seem to need a buffer in front of the LED. I'm not sure if that's the case for all signals sent out. Thanks for your help, cool software
Quote from arcachofo on March 14, 2024, 3:30 pmFor now, because I had msys64 installed through chocolatey, I could use
<step
command="C:\tools\msys64\usr\bin\rm" arguments=" $buildPath$fileName.hex" />and it worked.
Good idea...
I seem to need a buffer in front of the LED. I'm not sure if that's the case for all signals sent out.
Yes, as far as I know all Ports in 8051 are open collector. So they can sink current at Low state but not at High state.
I don't remember if there is some Port that is configurable.If you activate circuit animation you will see the type of input/output and state.
THose with "half arrows" are open collector, normal outputs have a "normal arrow", for example ALE or PSEN, and inputs have the arrow in the opposite direction, color represet state:
For now, because I had msys64 installed through chocolatey, I could use
<step
command="C:\tools\msys64\usr\bin\rm" arguments=" $buildPath$fileName.hex" />and it worked.
Good idea...
I seem to need a buffer in front of the LED. I'm not sure if that's the case for all signals sent out.
Yes, as far as I know all Ports in 8051 are open collector. So they can sink current at Low state but not at High state.
I don't remember if there is some Port that is configurable.
If you activate circuit animation you will see the type of input/output and state.
THose with "half arrows" are open collector, normal outputs have a "normal arrow", for example ALE or PSEN, and inputs have the arrow in the opposite direction, color represet state: