Had to walk away from it for a bit, but think I finally converted your tutorial to a pic 16f648a because that's what I have to work with. Tomorrow I will try it out on the breadboard. Pulled my hair out on the stack under run error. Then on the PC memory wrap. Your videos on LED matrix's and 7 segment displays will also be very helpful when the time comes. Thanks again
Awesome!!!! FINALLY I find someone who speaks my language. I have been wracking my brains trying to figure code compiling out. Thank You so much for explaining what the commands are doing as you do them. MPLAB and the PIC datasheets are pretty technical. Im off to check out more of your videos. Thanks again
I am working with a pic 18f46k22 using assembly. I would love to see a video working with indirect addressing. And not just using the example that the datasheet shows clearing a set of registers. I would like to to see it from start to finish with an application please. I hope you can do this for us, I have really enjoyed your videos and found them really helpful.
Stack over and under runs can drive one crazy, and finding the problem can be an adventure in itself, especially when you have thousands of lines of code.... A good habit to get into is to always use the "banksel f" instruction before referencing a register, especially if you are letting the compiler decide where the program's variables will be located in RAM.
That depends on what language you're using and what microcontroller. Some of the commands you have there aren't available in Microchip's assembly and are leaning more towards C. But in theory, you're code looks sound.
If you don't already know a programming language, trying to learn off the web can be a very challenging experience. You are also facing the fact that different platforms have programming differences. The best advice I can give you is to purchase a programming book for beginners on the programming language you want to learn.
Make sure the code is DECFSZ LED_LOOP,F If the F isn't there then compiler will assume you mean the working register (w) and store the resulting math there instead of back in F, thereby causing an endless loop.
Trying to make my first led blink. But I'm using a 16F84A, Pic Basic Pro Demo version and the K150 programmer. I used code on p 126 of book, Picbasic Projects by Dogan Ibrahim. The code compiled successfully, and I programmed the 16F84A. Transferred the chip to the breadboard and powered on. Nothing happened. I rechecked programming, wiring and fuses, and disabled the WDT. Still nothing. There is 1.57 V on the pin driving the led, not 5V. Any suggestions? I can provide info on circuit.
I can certainly add this to my to do list, though if you have a specific question regarding using the FSR and INDF registers just let me know, I'll do my best to answer your question.
nice thats detailed but what about this one, wrote it yesterday and dont know if its good because my program is not working atm: variable equ 0x20 do ; decrementing portc and incrementing variable decf PORTC decf PORTC incf variable ; putting 0x16 to w-reg to compare with variable to see if variable is greater than w-reg movlw 0x16 cpfsgt variable goto do goto out is this ok or do i have something wrong?
First of all, thanks so much for these tutorials. This is perfect, and although I have a PIC12F675, the datasheet shows the different register names and there's no problem there. Second: I didn't get the external power supply part... I assume then that the PIC is not able to draw enough current to feed all the 8 LED's then? How did you wire them? I'm new to PIC's and I definitely dont want to burn anything. I'm more of an Arduino guy... yet. Thanks again, David.
Thank you, Actually, it's the programmer that can't supply enough current to drive a whole lot. Adding in external power to the breadboard relieves that demand on the programmer. Every PIC is different in what it can and can't do. Most can supply 100ma on a port, so driving 8 LEDs is very possible as long as you keep the current under that 100ma. However, it's always best to check the datasheet of the PIC you're using to be sure what it's electrical limits are.
Originally I was trying to decfsz PORTC directly, and after messing with the code for about an hour, countless google searches, I came across this video where you break that same command into several commands (INCF, MOVF, and then MOWF PORTA). Doing it this way fixed my probem. Why doesn't decfsz PORTC seem to work? I've seen code examples that have incf PORTx, but my experience suggests that they are mistaken. I've tried googling this but its kind of a hard situation to look up.
Hello Andrew, It really depends on the MCU you're using, not all of them support all the assembly commands, hence why I used INCF, MOVF, and MOVWF. Look at the datasheet and make sure the command is supported and also that it will do what you want it to do. Also, don't write to PORTC directly, write to LATC. If the MCU is running fast enough, it's possible to read a port before the previously written data has fully registered. So you can write a 1 and if you read back the port right after, it's possible to read the previous data that was there, such as a 0. Two things prevent this, using a NOP to give voltages time to settle or writing to LATx (which is why it's there). Hope this helps.
David, An excellent tutorial and very well presented! I have one comment and one question: I downloaded the source code and assembled it successfully. 1. at the start of the program the statement: #include is commented out but at the end of the program it appears again and is not commented out. 2. in the .err file, for the statements CRLF ANSEL and MOVWF TRISTA I get the message: "Register in operand not in Bank0". Nonetheless it assembles successfully. Is the appearance of these messages normal or is there something one can do to eliminate them as well? thanks, larry
Hello Larry, First, I've been coding in C for the past year and half and it's has been a long time since I've coded anything in assembly, so my memory is bit fuzzy on some details. 1) There might be a more pressing reason, but I think it's just control placement of the code during the compile. 2) It's not really an error, more of a warning that's there to remind you to make sure you've selected the correct bank that the register appears in. I do believe there is a compiler directive you can add to your code that will suppress that particular warning. However, I prefer to see the warning as it is intended as useful information.
There's not much to something like this. You just need to check the IO bit the switch is tied to and then turn on / off the LED. The code would look something like this: BTFSS PORTA,0 ;is switch pressed? BSF PORTA,1 ;yes - so turn on LED. BTFSC PORTA,0 ;is switched released? BCF PORTA,1 ;yes - so turn off LED. Use a pull-up resistor to set PORTA,0 high with switch tied to PORTA,0 and ground. When switch is pressed, it will pull that input low and turn off the LED.
Hello Dave, I have a project board with 6 seven segments display designed for a pic16f877. I tried to find any a program to multiplex the 6 or lesser 7 seg-displays, but nothing will work. The reason that no programs will work is because the 7 seg-segment are common anode. Can you please do a video or give me an idea on how to multiplex common anode the 7seg-displays? The 6 transistors to turn On the 6 ; 7seg_ displays (turn them High to 5 volts ) are connected to port A, and the 7seg_Display LED’s are connected to port D. Thanks in advance.
C or Assembly? Sounds like you're circuit is setup correctly with the transistors driving the Anode of the display to +5V. To turn on a segment you just need to bring the bit on PORT D low (effectively making it ground). steps: 1) Turn off all transistors (make sure display is off) 2) Update data on PORTD to reflect new digit to display. 3) Turn on first transistor 4) Wait long enough for the human eye to register the data. (refresh rate). 5) Turn of first transistor repeat steps 2 - 5 for each digit. Also, make sure the port on that MCU can handle the current you're trying to sink into it. Otherwise the port will shut down to protect the MCU. You can adjust the current draw by adjusting the resistor values you are using on the display.
Assembly language. About the Board, you are correct; that is the way the board is set up. Today, thanks to your suggestion I was able to turn On the 7seg_Displays. However I can not make the 7seg_Display show different characters or number. ( multiplexing) Even with a delay all 6 -7seg-Display segments are all On. Thank you for the quick response.
@@mega2034 How do you have your memory setup to keep track of each digits' current value? For example: use a SRAM memory location to keep track of what digit 1 displays, another memory location for digit 2, ect... Setup some labels to point to SRAM in the PIC memory. For example (hex values are example only, you'll have to assign them to un-allocated SRAM addresses.): #define display_1 0x00 #define display_2 0x01 #define display_3 0x02 #define display_4 0x03 #define display_5 0x04 ect... As you move from digit to digit you can reference the stored data to display the correct value using the method listed in my previous message. To change displayed data you just need change the value in the memory location referenced by display_x.
do you know how to control or block usb ports using emulator 8086?can i have the copy of the code? or do you have any code of emu8086 that implementing pc interfacing
Hello John, If you can forward a copy of the circuit and the program to me, I'm sure I can help you. Without that information, I'll just be guessing at what the problem is. David
+garcia pedro I recommend using a timer in the MCU. Configure the timer to increment every 10ms, then all you have to do is change the LED when the timer reaches a certain value. Don't forget to reset the timer after you change the LED.
In assembly, something like this: Off the top of my head, so could be buggy. BANKSEL COUNT ;NOT NEEDED IF COUNT IS GLOBAL. CLRF COUNT BANKSEL PORTC CLRF PORTC PORTC_INCREMENT BANKSEL PORTC INCF PORTC,F ; Increment PORTC by 1. INCF PORTC,F ; Increment PORTC by 1. BANKSEL COUNT ; Select bank COUNT register is in. INCF COUNT,F ; Increment COUNT by 1. MOVLW 0X10 SUBWF COUNT,W BTFSS STATUS,C ; Count = 16? GOTO PORTC_INCREMENT ; No, loop around and do it again. ...
Hi David, You're a legend sir. In the video, I heard you mentioning that you would do a tutorial where you would 'add the code to define ASCII Characters' in another video. It'd nice if you could post that video, sir. Thank you again.
Kerdiang Miabok Lots of good info on in the Keyboard videos and the "Real Time Clock Calander", both of these use ASCII code to send data to the computer for display. As for doing that in the Dot Matrix project, I never have gotten back to the project. Though, I'm thining about designing up a PC board for a DOT matrix display so everyone could follow along easily.
Dear David Thank you very much for your tutoring. I am an absolute beginer I have tried to compile yor file Lab.001.asm for my PIc16f876a without success. Here is the code LIST p=16F876a ; list directive to define processor #INCLUDE ; processor specific variable definitions ; TODO INSERT CONFIG CODE HERE USING CONFIG BITS GENERATOR ; CONFIG ; __config 0xFFFB __CONFIG _FOSC_EXTRC & _WDTE_OFF & _PWRTE_OFF & _BOREN_ON & _LVP_ON & _CPD_OFF & _WRT_OFF & _CP_OFF ; '__CONFIG' directive is used to embed configuration word within .asm file. ; The lables following the directive are located in the respective .inc file. ; See data sheet for additional information on configuration word settings. ; Note that the _DEBUG_ON is changed by selecting a debugger or programmer. ; There isn't much advantage to setting it in the code. ; UDATA declares a section of uninitialized data VARIABLES UDATA ; VARIABLES is the name of the section of memory myvar1 RES 1 ; uninitialized data, placed by linker in GPR's. myvar2 RES 1 LED_VAR UDATA_SHR LED_LOOP RES 1 LED_LOOP2 RES 1 LED_COUNT RES 1 FX_TEMP RES 1 GLOBAL FX_TEMP ;#INCLUDE ;------------------------------------------------------------------------------ ; EEPROM INITIALIZATION ; ; The 16F882 has 128 bytes of non-volatile EEPROM, starting at address 0x2100 ; ;------------------------------------------------------------------------------ ORG 0x2100 DE 0x00, 0x01, 0x02, 0x03 ;------------------------------------------------------------------------------ ; RESET VECTOR ;------------------------------------------------------------------------------ RES_VECT CODE 0x0000 ; processor reset vector GOTO START ; go to beginning of program ;------------------------------------------------------------------------------ ; TODO ADD INTERRUPTS HERE IF USED ;------------------------------------------------------------------------------ ; CONFIGURATION CODE ;------------------------------------------------------------------------------ ;START ORG 0X05 MAIN_PROG CODE ; let linker place main program START BANKSEL PORTA CLRF PORTA BANKSEL ANSEL CLRF ANSEL BANKSEL TRISA MOVLW 0X00 MOVWF TRISA MOVLW 0X01 MOVWF LED_COUNT BANKSEL STATUS BCF STATUS,C ;------------------------------------------------------------------------------ ; MAIN CODE ;------------------------------------------------------------------------------ MAIN BANKSEL PORTA RRF LED_COUNT,F MOVF LED_COUNT,W MOVWF PORTA CALL LED_PAUSE GOTO MAIN LED_PAUSE MOVLW 0XFF MOVWF LED_LOOP2 LED_PAUSE2 CLRF LED_LOOP DECFSZ LED_LOOP,F GOTO $-1 DECFSZ LED_LOOP2,F GOTO LED_PAUSE2 RETURN ;#include GOTO $ ; loop forever END and here the errors Warning[205] C:\USERS\JCASE\MPLABXPROJECTS\MAGIDAVID_AL_101.X\MAGIDAVID_LAB_001.ASM 50 : Found directive in column 1. (GLOBAL) Error[113] C:\USERS\JCASE\MPLABXPROJECTS\MAGIDAVID_AL_101.X\MAGIDAVID_LAB_001.ASM 85 : Symbol not previously defined (ANSEL) Error[113] C:\USERS\JCASE\MPLABXPROJECTS\MAGIDAVID_AL_101.X\MAGIDAVID_LAB_001.ASM 86 : Symbol not previously defined (ANSEL) My E mail is jcaser1948@yahoo.es
Not sure about the first error, but maybe this line? ";START ORG 0X05", should the ";" be there? Try ANSELA in place of the ANSEL. Different MCUs handle the ANSEL registers differently, you can look in the datasheet to find out what label names to use for each register, Microchip is pretty good about using the same name in the datasheet in the compiler.
I have tried another approach. First I took your Surcecode and tried to compile it "as it is"It failed because file was not there. I commented t5his file out. Still did not compile with the error Warning[205] C:\USERS\JCASE\MPLABXPROJECTS\MAGIDAVID_AL_101.X\MAGIDAVID_LAB_001.ASM 26 : Found directive in column 1. (__CONFIG). I commented the configutations bits out, and then your source code compiled. with no errors. I substituted the processor for the PIC16F876a (Nothing else changed) and I get the following errors Warning[205] C:\USERS\JCASE\MPLABXPROJECTS\MAGIDAVID_AL_101.X\MAGIDAVID_LAB_001.ASM 47 : Found directive in column 1. (GLOBAL) Error[113] C:\USERS\JCASE\MPLABXPROJECTS\MAGIDAVID_AL_101.X\MAGIDAVID_LAB_001.ASM 77 : Symbol not previously defined (ANSEL) Error[113] C:\USERS\JCASE\MPLABXPROJECTS\MAGIDAVID_AL_101.X\MAGIDAVID_LAB_001.ASM 78 : Symbol not previously defined (ANSEL). So I am now more confused as bevor.Does it mean I have to change every programm to fit every single of the Microchip chips?.Could your recommend me a book where a systematic approach to the assebler language is implemented? Thanks
There's a template directory with MPLABX C:\Program Files (x86)\Microchip\MPLABX\v3.26\mpasmx\templates which has a template file for all the MCUs that Microchip makes. Find the one for the PIC16F876 and start with that file, it will contain the correct __config directives. Next, fine the proper include file for the PIC16F876 and copy it over to your project folder. The INC file has the proper labels for the resources inside the PIC16F876, so you'll want to include this in your project file. If your MCU doesn't have analog capability then it won't use the ANSEL register. In this case, you can remove the ANSEL command from the code. If the PIC16F876 does have analog control then look up the analog section in the datasheet and see if PORTA is analog capable, if it is then you'll need to configure the ANSELA register for digital.
Thanks for your tip. I have builded a sort of "frankenstein" between your code and the template. Now it compiles. I post it here in case some bloody beguinner leik me can use it. list p=16f876A ; list directive to define processor #include ; processor specific variable definitions __CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _RC_OSC & _WRT_OFF & _LVP_ON & _CPD_OFF ; '__CONFIG' directive is used to embed configuration data within .asm file. ; The lables following the directive are located in the respective .inc file. ; See respective data sheet for additional information on configuration word. ;***** VARIABLE DEFINITIONS w_temp EQU 0x7D ; variable used for context saving status_temp EQU 0x7E ; variable used for context saving pclath_temp EQU 0x7F ; variable used for context saving ; UDATA declares a section of uninitialized data VARIABLES UDATA ; VARIABLES is the name of the section of memory myvar1 RES 1 ; uninitialized data, placed by linker in GPR's. myvar2 RES 1 LED_VAR UDATA_SHR LED_LOOP RES 1 LED_LOOP2 RES 1 LED_COUNT RES 1 FX_TEMP RES 1 GLOBAL FX_TEMP ;********************************************************************** ORG 0x000 ; processor reset vector nop ; nop required for icd goto MAIN ; go to beginning of program ORG 0x004 ; interrupt vector location movwf w_temp ; save off current W register contents movf STATUS,w ; move status register into W register movwf status_temp ; save off contents of STATUS register movf PCLATH,w ; move pclath register into w register movwf pclath_temp ; save off contents of PCLATH register movf pclath_temp,w ; retrieve copy of PCLATH register movwf PCLATH ; restore pre-isr PCLATH register contents movf status_temp,w ; retrieve copy of STATUS register movwf STATUS ; restore pre-isr STATUS register contents swapf w_temp,f swapf w_temp,w ; restore pre-isr W register contents retfie ; return from interrupt MAIN BANKSEL PORTA RRF LED_COUNT,F MOVF LED_COUNT,W MOVWF PORTA CALL LED_PAUSE GOTO MAIN LED_PAUSE MOVLW 0XFF MOVWF LED_LOOP2 LED_PAUSE2 CLRF LED_LOOP DECFSZ LED_LOOP,F GOTO $-1 DECFSZ LED_LOOP2,F GOTO LED_PAUSE2 RETURN END ; directive 'end of program'
Hello David and thank you for your wonderful work. You said that we can ask questions and that's what I'm going to do. Based on your video from above I tried to program an 16f690 and I encounter the following problem (th-cam.com/video/G-qzoRoL-9I/w-d-xo.html) .Thank you for your time.
Had to walk away from it for a bit, but think I finally converted your tutorial to a pic 16f648a because that's what I have to work with. Tomorrow I will try it out on the breadboard. Pulled my hair out on the stack under run error. Then on the PC memory wrap. Your videos on LED matrix's and 7 segment displays will also be very helpful when the time comes. Thanks again
Awesome!!!! FINALLY I find someone who speaks my language. I have been wracking my brains trying to figure code compiling out. Thank You so much for explaining what the commands are doing as you do them. MPLAB and the PIC datasheets are pretty technical. Im off to check out more of your videos. Thanks again
I am working with a pic 18f46k22 using assembly. I would love to see a video working with indirect addressing. And not just using the example that the datasheet shows clearing a set of registers. I would like to to see it from start to finish with an application please. I hope you can do this for us, I have really enjoyed your videos and found them really helpful.
this is by far the best pic tutorial on the web!
Stack over and under runs can drive one crazy, and finding the problem can be an adventure in itself, especially when you have thousands of lines of code.... A good habit to get into is to always use the "banksel f" instruction before referencing a register, especially if you are letting the compiler decide where the program's variables will be located in RAM.
That depends on what language you're using and what microcontroller. Some of the commands you have there aren't available in Microchip's assembly and are leaning more towards C. But in theory, you're code looks sound.
If you don't already know a programming language, trying to learn off the web can be a very challenging experience. You are also facing the fact that different platforms have programming differences. The best advice I can give you is to purchase a programming book for beginners on the programming language you want to learn.
I would be grateful if you could explain the very basic of writing a program to turn a LED on while the switch is pressed.
@David13241 You're welcome, and I'm glad you found the video useful.
Make sure the code is DECFSZ LED_LOOP,F
If the F isn't there then compiler will assume you mean the working register (w) and store the resulting math there instead of back in F, thereby causing an endless loop.
Trying to make my first led blink. But I'm using a 16F84A, Pic Basic Pro Demo version and the K150 programmer. I used code on p 126 of book, Picbasic Projects by Dogan Ibrahim. The code compiled successfully, and I programmed the 16F84A. Transferred the chip to the breadboard and powered on. Nothing happened. I rechecked programming, wiring and fuses, and disabled the WDT. Still nothing. There is 1.57 V on the pin driving the led, not 5V. Any suggestions? I can provide info on circuit.
"Thank You", thank you very much. I look forward to your tutoring...
+Inquire98 You're most welcome, and thank you. :)
I can certainly add this to my to do list, though if you have a specific question regarding using the FSR and INDF registers just let me know, I'll do my best to answer your question.
nice thats detailed but what about this one, wrote it yesterday and dont know if its good because my program is not working atm:
variable equ 0x20
do
; decrementing portc and incrementing variable
decf PORTC
decf PORTC
incf variable
; putting 0x16 to w-reg to compare with variable to see if variable is greater than w-reg
movlw 0x16
cpfsgt variable
goto do
goto out
is this ok or do i have something wrong?
First of all, thanks so much for these tutorials. This is perfect, and although I have a PIC12F675, the datasheet shows the different register names and there's no problem there.
Second: I didn't get the external power supply part... I assume then that the PIC is not able to draw enough current to feed all the 8 LED's then? How did you wire them? I'm new to PIC's and I definitely dont want to burn anything. I'm more of an Arduino guy... yet. Thanks again, David.
Thank you,
Actually, it's the programmer that can't supply enough current to drive a whole lot. Adding in external power to the breadboard relieves that demand on the programmer.
Every PIC is different in what it can and can't do. Most can supply 100ma on a port, so driving 8 LEDs is very possible as long as you keep the current under that 100ma. However, it's always best to check the datasheet of the PIC you're using to be sure what it's electrical limits are.
Originally I was trying to decfsz PORTC directly, and after messing with the code for about an hour, countless google searches, I came across this video where you break that same command into several commands (INCF, MOVF, and then MOWF PORTA). Doing it this way fixed my probem.
Why doesn't decfsz PORTC seem to work? I've seen code examples that have incf PORTx, but my experience suggests that they are mistaken. I've tried googling this but its kind of a hard situation to look up.
Hello Andrew,
It really depends on the MCU you're using, not all of them support all the assembly commands, hence why I used INCF, MOVF, and MOVWF. Look at the datasheet and make sure the command is supported and also that it will do what you want it to do.
Also, don't write to PORTC directly, write to LATC. If the MCU is running fast enough, it's possible to read a port before the previously written data has fully registered. So you can write a 1 and if you read back the port right after, it's possible to read the previous data that was there, such as a 0. Two things prevent this, using a NOP to give voltages time to settle or writing to LATx (which is why it's there).
Hope this helps.
can someone tell me how i can write a do while program like, decrease portc with 2 and increase x by 1 while x < 16.
David,
An excellent tutorial and very well presented!
I have one comment and one question: I downloaded the source code and assembled it successfully.
1. at the start of the program the statement: #include is commented out but at the end of the program it appears again and is not commented out.
2. in the .err file, for the statements CRLF ANSEL and MOVWF TRISTA
I get the message: "Register in operand not in Bank0". Nonetheless it assembles successfully.
Is the appearance of these messages normal or is there something one can do to eliminate them as well?
thanks,
larry
Hello Larry,
First, I've been coding in C for the past year and half and it's has been a long time since I've coded anything in assembly, so my memory is bit fuzzy on some details.
1) There might be a more pressing reason, but I think it's just control placement of the code during the compile.
2) It's not really an error, more of a warning that's there to remind you to make sure you've selected the correct bank that the register appears in. I do believe there is a compiler directive you can add to your code that will suppress that particular warning. However, I prefer to see the warning as it is intended as useful information.
There's not much to something like this. You just need to check the IO bit the switch is tied to and then turn on / off the LED. The code would look something like this:
BTFSS PORTA,0 ;is switch pressed?
BSF PORTA,1 ;yes - so turn on LED.
BTFSC PORTA,0 ;is switched released?
BCF PORTA,1 ;yes - so turn off LED.
Use a pull-up resistor to set PORTA,0 high with switch tied to PORTA,0 and ground. When switch is pressed, it will pull that input low and turn off the LED.
Hello Dave,
I have a project board with 6 seven segments display designed for a pic16f877.
I tried to find any a program to multiplex the 6 or lesser 7 seg-displays, but nothing will work. The reason that no programs will work is because the 7 seg-segment are common anode. Can you please do a video or give me an idea on how to multiplex common anode the 7seg-displays? The 6 transistors to turn On the 6 ; 7seg_ displays (turn them High to 5 volts ) are connected to port A, and the 7seg_Display LED’s are connected to port D. Thanks in advance.
C or Assembly?
Sounds like you're circuit is setup correctly with the transistors driving the Anode of the display to +5V. To turn on a segment you just need to bring the bit on PORT D low (effectively making it ground).
steps:
1) Turn off all transistors (make sure display is off)
2) Update data on PORTD to reflect new digit to display.
3) Turn on first transistor
4) Wait long enough for the human eye to register the data. (refresh rate).
5) Turn of first transistor
repeat steps 2 - 5 for each digit.
Also, make sure the port on that MCU can handle the current you're trying to sink into it. Otherwise the port will shut down to protect the MCU. You can adjust the current draw by adjusting the resistor values you are using on the display.
Assembly language. About the Board, you are correct; that is the way the board is set up. Today, thanks to your suggestion I was able to turn On the 7seg_Displays. However I can not make the 7seg_Display show different characters or number. ( multiplexing) Even with a delay all 6 -7seg-Display segments are all On. Thank you for the quick response.
@@mega2034 How do you have your memory setup to keep track of each digits' current value?
For example: use a SRAM memory location to keep track of what digit 1 displays, another memory location for digit 2, ect...
Setup some labels to point to SRAM in the PIC memory. For example (hex values are example only, you'll have to assign them to un-allocated SRAM addresses.):
#define display_1 0x00
#define display_2 0x01
#define display_3 0x02
#define display_4 0x03
#define display_5 0x04
ect...
As you move from digit to digit you can reference the stored data to display the correct value using the method listed in my previous message.
To change displayed data you just need change the value in the memory location referenced by display_x.
هلا و الله ..............
جزاك الله خير .......
Finally......... I got the idea, I hope to improve my project very well
do you know how to control or block usb ports using emulator 8086?can i have the copy of the code? or do you have any code of emu8086 that implementing pc interfacing
Sorry, I'm not familiar with emu8086.
Hello John,
If you can forward a copy of the circuit and the program to me, I'm sure I can help you. Without that information, I'll just be guessing at what the problem is.
David
tanks for all ; plz how to control time of blinking ; if i want 1 second or half or maybe 1 min ????
+garcia pedro I recommend using a timer in the MCU. Configure the timer to increment every 10ms, then all you have to do is change the LED when the timer reaches a certain value. Don't forget to reset the timer after you change the LED.
I wish you makes another video to explain that
why do you need 2 loops for pause, why isn't 1 loop DECFSZ working?
because 1 loop is not enough pause time (blink too fast)?
Exactly, the second loop is allowing more time.
What is the original path to the templates?
You can find the link for the code in the description of the video, you'll need to click the "show more" button to see the links.
Sir which software use to programing
MPLAB X which is free from Microchip.com
How nice, all my CRs were removed, which makes reading that code hard.
im learning asm for a pic18f458
Thank you very much for the video.
you're welcome and thank you.
Thanks!
In assembly, something like this: Off the top of my head, so could be buggy.
BANKSEL COUNT ;NOT NEEDED IF COUNT IS GLOBAL.
CLRF COUNT
BANKSEL PORTC
CLRF PORTC
PORTC_INCREMENT
BANKSEL PORTC
INCF PORTC,F ; Increment PORTC by 1.
INCF PORTC,F ; Increment PORTC by 1.
BANKSEL COUNT ; Select bank COUNT register is in.
INCF COUNT,F ; Increment COUNT by 1.
MOVLW 0X10
SUBWF COUNT,W
BTFSS STATUS,C ; Count = 16?
GOTO PORTC_INCREMENT ; No, loop around and do it again.
...
FIRST THANKS FOR THE TUTORIAL. SECOND WHERE IS PART 2 SIR?
Hello,
They aren't exactly labeled as part 1, part 2, ect... But there are a lot of videos on Assembly programming in my channel.
Hi David, You're a legend sir. In the video, I heard you mentioning that you would do a tutorial where you would 'add the code to define ASCII Characters' in another video. It'd nice if you could post that video, sir. Thank you again.
Kerdiang Miabok
Lots of good info on in the Keyboard videos and the "Real Time Clock Calander", both of these use ASCII code to send data to the computer for display. As for doing that in the Dot Matrix project, I never have gotten back to the project. Though, I'm thining about designing up a PC board for a DOT matrix display so everyone could follow along easily.
David, that would be awesome. You make em assembly look very simple in your videos. Do more of em please. Regards, Kerdiang.
Dear David
Thank you very much for your tutoring. I am an absolute beginer
I have tried to compile yor file Lab.001.asm for my PIc16f876a without success.
Here is the code
LIST p=16F876a ; list directive to define processor
#INCLUDE ; processor specific variable definitions
; TODO INSERT CONFIG CODE HERE USING CONFIG BITS GENERATOR
; CONFIG
; __config 0xFFFB
__CONFIG _FOSC_EXTRC & _WDTE_OFF & _PWRTE_OFF & _BOREN_ON & _LVP_ON & _CPD_OFF & _WRT_OFF & _CP_OFF
; '__CONFIG' directive is used to embed configuration word within .asm file.
; The lables following the directive are located in the respective .inc file.
; See data sheet for additional information on configuration word settings.
; Note that the _DEBUG_ON is changed by selecting a debugger or programmer.
; There isn't much advantage to setting it in the code.
; UDATA declares a section of uninitialized data
VARIABLES UDATA ; VARIABLES is the name of the section of memory
myvar1 RES 1 ; uninitialized data, placed by linker in GPR's.
myvar2 RES 1
LED_VAR UDATA_SHR
LED_LOOP RES 1
LED_LOOP2 RES 1
LED_COUNT RES 1
FX_TEMP RES 1
GLOBAL FX_TEMP
;#INCLUDE
;------------------------------------------------------------------------------
; EEPROM INITIALIZATION
;
; The 16F882 has 128 bytes of non-volatile EEPROM, starting at address 0x2100
;
;------------------------------------------------------------------------------
ORG 0x2100
DE 0x00, 0x01, 0x02, 0x03
;------------------------------------------------------------------------------
; RESET VECTOR
;------------------------------------------------------------------------------
RES_VECT CODE 0x0000 ; processor reset vector
GOTO START ; go to beginning of program
;------------------------------------------------------------------------------
; TODO ADD INTERRUPTS HERE IF USED
;------------------------------------------------------------------------------
; CONFIGURATION CODE
;------------------------------------------------------------------------------
;START ORG 0X05
MAIN_PROG CODE ; let linker place main program
START
BANKSEL PORTA
CLRF PORTA
BANKSEL ANSEL
CLRF ANSEL
BANKSEL TRISA
MOVLW 0X00
MOVWF TRISA
MOVLW 0X01
MOVWF LED_COUNT
BANKSEL STATUS
BCF STATUS,C
;------------------------------------------------------------------------------
; MAIN CODE
;------------------------------------------------------------------------------
MAIN
BANKSEL PORTA
RRF LED_COUNT,F
MOVF LED_COUNT,W
MOVWF PORTA
CALL LED_PAUSE
GOTO MAIN
LED_PAUSE
MOVLW 0XFF
MOVWF LED_LOOP2
LED_PAUSE2
CLRF LED_LOOP
DECFSZ LED_LOOP,F
GOTO $-1
DECFSZ LED_LOOP2,F
GOTO LED_PAUSE2
RETURN
;#include
GOTO $ ; loop forever
END
and here the errors
Warning[205] C:\USERS\JCASE\MPLABXPROJECTS\MAGIDAVID_AL_101.X\MAGIDAVID_LAB_001.ASM 50 : Found directive in column 1. (GLOBAL)
Error[113] C:\USERS\JCASE\MPLABXPROJECTS\MAGIDAVID_AL_101.X\MAGIDAVID_LAB_001.ASM 85 : Symbol not previously defined (ANSEL)
Error[113] C:\USERS\JCASE\MPLABXPROJECTS\MAGIDAVID_AL_101.X\MAGIDAVID_LAB_001.ASM 86 : Symbol not previously defined (ANSEL)
My E mail is jcaser1948@yahoo.es
Not sure about the first error, but maybe this line? ";START ORG 0X05", should the ";" be there?
Try ANSELA in place of the ANSEL. Different MCUs handle the ANSEL registers differently, you can look in the datasheet to find out what label names to use for each register, Microchip is pretty good about using the same name in the datasheet in the compiler.
I have tried another approach.
First I took your Surcecode and tried to compile it "as it is"It failed because file was not there. I commented t5his file out. Still did not compile with the error
Warning[205] C:\USERS\JCASE\MPLABXPROJECTS\MAGIDAVID_AL_101.X\MAGIDAVID_LAB_001.ASM 26 : Found directive in column 1. (__CONFIG).
I commented the configutations bits out, and then your source code compiled. with no errors.
I substituted the processor for the PIC16F876a (Nothing else changed) and I get the following errors
Warning[205] C:\USERS\JCASE\MPLABXPROJECTS\MAGIDAVID_AL_101.X\MAGIDAVID_LAB_001.ASM 47 : Found directive in column 1. (GLOBAL)
Error[113] C:\USERS\JCASE\MPLABXPROJECTS\MAGIDAVID_AL_101.X\MAGIDAVID_LAB_001.ASM 77 : Symbol not previously defined (ANSEL)
Error[113] C:\USERS\JCASE\MPLABXPROJECTS\MAGIDAVID_AL_101.X\MAGIDAVID_LAB_001.ASM 78 : Symbol not previously defined (ANSEL).
So I am now more confused as bevor.Does it mean I have to change every programm to fit every single of the Microchip chips?.Could your recommend me a book where a systematic approach to the assebler language is implemented?
Thanks
There's a template directory with MPLABX C:\Program Files (x86)\Microchip\MPLABX\v3.26\mpasmx\templates which has a template file for all the MCUs that Microchip makes. Find the one for the PIC16F876 and start with that file, it will contain the correct __config directives.
Next, fine the proper include file for the PIC16F876 and copy it over to your project folder. The INC file has the proper labels for the resources inside the PIC16F876, so you'll want to include this in your project file.
If your MCU doesn't have analog capability then it won't use the ANSEL register. In this case, you can remove the ANSEL command from the code. If the PIC16F876 does have analog control then look up the analog section in the datasheet and see if PORTA is analog capable, if it is then you'll need to configure the ANSELA register for digital.
Thanks for your tip.
I have builded a sort of "frankenstein" between your code and the template. Now it compiles.
I post it here in case some bloody beguinner leik me can use it.
list p=16f876A ; list directive to define processor
#include ; processor specific variable definitions
__CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _RC_OSC & _WRT_OFF & _LVP_ON & _CPD_OFF
; '__CONFIG' directive is used to embed configuration data within .asm file.
; The lables following the directive are located in the respective .inc file.
; See respective data sheet for additional information on configuration word.
;***** VARIABLE DEFINITIONS
w_temp EQU 0x7D ; variable used for context saving
status_temp EQU 0x7E ; variable used for context saving
pclath_temp EQU 0x7F ; variable used for context saving
; UDATA declares a section of uninitialized data
VARIABLES UDATA ; VARIABLES is the name of the section of memory
myvar1 RES 1 ; uninitialized data, placed by linker in GPR's.
myvar2 RES 1
LED_VAR UDATA_SHR
LED_LOOP RES 1
LED_LOOP2 RES 1
LED_COUNT RES 1
FX_TEMP RES 1
GLOBAL FX_TEMP
;**********************************************************************
ORG 0x000 ; processor reset vector
nop ; nop required for icd
goto MAIN ; go to beginning of program
ORG 0x004 ; interrupt vector location
movwf w_temp ; save off current W register contents
movf STATUS,w ; move status register into W register
movwf status_temp ; save off contents of STATUS register
movf PCLATH,w ; move pclath register into w register
movwf pclath_temp ; save off contents of PCLATH register
movf pclath_temp,w ; retrieve copy of PCLATH register
movwf PCLATH ; restore pre-isr PCLATH register contents
movf status_temp,w ; retrieve copy of STATUS register
movwf STATUS ; restore pre-isr STATUS register contents
swapf w_temp,f
swapf w_temp,w ; restore pre-isr W register contents
retfie ; return from interrupt
MAIN
BANKSEL PORTA
RRF LED_COUNT,F
MOVF LED_COUNT,W
MOVWF PORTA
CALL LED_PAUSE
GOTO MAIN
LED_PAUSE
MOVLW 0XFF
MOVWF LED_LOOP2
LED_PAUSE2
CLRF LED_LOOP
DECFSZ LED_LOOP,F
GOTO $-1
DECFSZ LED_LOOP2,F
GOTO LED_PAUSE2
RETURN
END ; directive 'end of program'
Hello David and thank you for your wonderful work. You said that we can ask questions and that's what I'm going to do. Based on your video from above I tried to program an 16f690 and I encounter the following problem (th-cam.com/video/G-qzoRoL-9I/w-d-xo.html) .Thank you for your time.
goen
did you have to to play music? I find your video very informative but the music is just unbearable
MUSIC IS GOOD