🔌 PIC16F877A 📌 This page will help me with the final exam when solving the hardware question, specifically in writing the text file and starting to code. Brain Storming “ for text file and coding steps “ Ports and Pins We have 5 ports with 33 I/O pins. PORT A 1. Consists of 6 pins. 2. Defult set is Analog ( when reset / power on ) PORT B 1. Consists of 8 pins. 2. pins (RB0 , RB4-RB7) can generate an interrupt. PORT C 1. Consists of 8 pins. 2. PORT C gives access to timers and serial ports. PORT D 1. Consists of 8 pins. 2. Port D can be used as a slave port PORT E 1. Consists of 3 pins. 2. Defult set is Analog ( when reset / power on ) 3. Provide the control pins to make Port D used as a slave port. Port Function PIC16F877A 1 this picture to know the exact bits used for your chosen << operation mode >> Indirect access with arrays need to use a SFR called FSR and INDF is used to get the content of the address pointed by FSR. Indirect addressing is very convenient for manipulating data arrays located in GPR registers. In this case, it is necessary to initialize FSR register with a starting address of the array, and the rest of the data can be accessed by incrementing the FSR register. Memory Organization In PIC16F877A, there are 3 memories : Program memory, Data memory and EEPROM memory Program memory: PIC16F877A is divided to 4 banks, each bank contains SFRs, GFRs 2 The most important registers have addresses in all the four banks Bank 0 is the defult bank Ex: 0Bh address is reserved for INTCON register (bank 0) Bank 1 contains (TRISA, TRISB, TRISC, TRISD and TRISE) : used to define ( input or output for the ports ). Reset Vector = 0000h (the program will go here on reset) = 0004h (the program will go here on interrupt) Interrupt Vector SFRs “Special Function Registers” 1. STATUS register 2. OPTION_REG register 3. INTCON register 4. How to declare Timer 0 using INTCON, STATUS ? MOVLW MOVWF MOVLW MOVWF b'11011000' OPTION_REG b'10100000' INTCON ; ; TMR0 initialisation code ; Int clock, no prescale ; /* Enable the GIF "bit7", Enable TMR0 interrupt and TMR0 overflow bit "5" */ Instruction set Interrupt sources and their bits. PIC16F877A 3 FOR PWM https://www.instructables.com/Generating-50Hz-PWM-Using-PIC16F877A/ https://exploreembedded.com/wiki/PIC16F877A_PWM chromeextension://efaidnbmnnnibpcajpcglclefindmkaj/http://www.mwftr.com/book/PIC_CharlesKim_13.pdf https://circuitdigest.com/microcontroller-projects/pic-microcontroller-pic16f877a-pwm-tutorial https://forum.allaboutcircuits.com/threads/generating-a-sound-with-pic-assembly.90874/ http://www.mastincrosbie.com/mark/electronics/pic/fastflash.html https://www.microchip.com/forums/m161528.aspx https://www.microchip.com/forums/m164978.aspx https://pic-microcontroller.com/create-musical-tone-using-pic-code/ http://microcontrollerprojects00.blogspot.com/2012/06/generate-sound-and-melody-using-pic.html https://maker.pro/forums/threads/understanding-pwm-with-pic-assembly.269449/ https://openlabpro.com/guide/pwm-in-pic16f877a/ Exercise for writing the .txt file in the final “Explain the steps for KeyPad Project” 1. To implement a keypad, 7 pins from PIC16F877A are needed: 3 pins for columns and 4 pins for rows. PortD pins will be used, specifically (RD0-RD2) for columns and (RD4-RD7) for rows. 2. Rows will be used as output, columns will be used as inputs. 3. The 7 segment will be connected to PORTC, (RC1 -RC7) and they gonna be assign using TRISC as an output. 4. The idea here is to read the selected button using a combination of output and input bits (rows, columns). If the pair contents are both (0,0), then that means this is the selected button. 5. I will assume that all the rows and columns are initially high ( inputs), and the keystroke can be detected by setting each row to low (output) and check each column for a zero. when match print the number. 6. This works assuming number 2 is pressed, so that means the first row should be zero (RD4 = 0) and the second column must be 0 (RD1). This leads to a voltage difference and the current will PIC16F877A 4 flow to RD4. 7. To achieve this result, a variable called "key" will be declared. This key will count the number of tested keys when each key on the keypad is checked. So when a button is detected, the scan of the keypad is terminated with the current key number in the counter. 8. So the main loop in this project will contain the scanning subroutine and displaying subroutine. 9. the Scanning subroutine will have the following behavior: a. Clear the key counter ( After each time we read the button we have to clear it, to start detecing again) b. Set the carry Flag using STATUS register. ( will be used to restart the count of rows after we reach the last row ) c. Set the fist row to 0 d. and created a lable called newrow that GOTO row lable 10. Row lable will be used to check each colunm for the specified row, Pins RD0, RD1, RD2 will be tested if they are zero, if any match return from scanning and print the number, also here before testing the pin the keys varaiable should be incremented by 1. 11. in ROW lable if non of the columns are presed, then go to the next row, and this can be done using the Rotate left instruction ( RLF) and after that goto the scanning to check again the three colums. 12. The behavior of the scanning subroutain was desciribed as above, when there is a match the displaying subroutine wil excute. 13. The display subroutine has a defined lookup table that has the vlaues of the keypad ( 0,1,2 …. *, #) 14. this lookup table return a literal with the help of the key variable to choose the right value. 15. the chosen varaible will be displayed in portC where the 7 segment is connected. 16. the program keeps excuting in an infinte loop since we are not using an intturput. Exercise for writing the .txt file in the final “Explain the steps for VINTEST Project” 1. To implement an ADC test circuit, the LCD will be connected to port D, and a 4-bit mode will be implemented to reduce the number of bits used. 2. To do an AD converstion, the first step is to configure analog pins/ voltage reference and digital input output using ADCON1 3. Here the value of 00000011 was set to ADCON1 meaning that pins RA0, RA1, RA2 and RA5 are Analog inputs, RE 0-1 are digital and RA3 is voltage refference, aslo it means the A/D Result Format will be left justified. 4. Then the next step will be selecting A/D input channel using ADCON0, here the selected channal is 000 → RA0 PIC16F877A 5 5. Then select A/D conversion clock and enabling the A/D module using the ADCON0 → the value of ADCON0 is 01000001, that means: FOSC/8, and ADC mode is enabled. 6. After the configuration, a subroutine called getADC will be called in the main to start the A/D converstion and then the saved data will be convered to decimal and didplayed in the lcd using two functions ( subroutine) condec, putLCD. 7. The getADC will have the behavior as this: a. set the A/D conversion status bit to one ( to start the ADC) b. wait till finish convering then store in W register the value using register ADRESH and return. 8. The condec will have the behavior as this: a. this function (subroutine) get the result of ADC and save it in a register called ADbin to convert it to decimal using 3 registers ( hunds, tens, ones ) b. The main idea is, find the number of hundreds, tens and ones by subtracting 100, and incrementing huns register, and subtracting 10 and increment the tens, and the rest is the ones. This could be done by using the carray flag. c. lets take a senario: assume the ADC result is 241 and it’s saved in ADbin, to convert it, fitst find the number of huns by: i. inialize the 3 registers to zeros ii. set the carry flag to 1 iii. add 100 to the W register iv. subtract the W from ADbin v. add one to the huns vi. check if the carray flag is 0 vii. If it’s zero, then there is an additional loop count, so decrement the number of huns and add 100 to ADbin to restore the corret value. ( the carry will flip when the outpus is in negative ) viii. the steps from (i - vii) will be reapated to find the tens, put insted of adding 100, we add 10 here ix. after counting the huns and the tens, the reminder put it in the ones register. d. After finding the huns, tens and the ones, conver the output to ascii code by adding the 0x30 offset to huns, tens, and ones. e. the ascii step is because the LCD display only ascii code f. then display the output to the LCD using LCD function that are degined in "LCDIS.INC". 9. this is the behavior of the program, the used SFR are TRISD, ADCON1, ADCON0, & PORTD. Exercise for writing the .txt file in the final “Explain the steps for LED1H Project” the idea from this project is to create a two push buttons, one to light up the leds as 1, 2, 3, and the other is a reset button ( shut down all the leds) 1. To implement a LED circuit, the two buttons will be connected to portB, the step button will be conncted with the RB1, and the shutdown buttin will be connected to RB2. PIC16F877A 6 2. an 8 leds will be connected to port D (from RD0 -RD7) 3. PORTB will decleared as an input using TRISB, and portD will decleared as an output using TRISD. a. In this example timer0 is used as a hardware interrput, so registers INCON and OPT_REG will be used. b. bit 7 in INCON will be set to 1, to enable the global intrreupts, and bit 5, to enable TIMR0 inturrput. c. in this example the timer0 will have no prescaling and the Prescaler is assigned to the WDT, so bits(0-2) will be zero and bit 4 will be 1. d. the logic here to use timer0 intterput to read the button and print the output in the LEDS. e. a loop will be created to check if the reset button is clicked or not, if it’s clicked, clean portD, if it’s not ( the value on the pin is 1) so check step button , if pressed then reset the time , check for time out, if yes (bit 2 in INTCON is 1 ): i. check step button and wait until relased, then increment output at portB ii. if done repeate the main loop always. iii. reset the TMR0 interrupt flag to 0 to be able to read more interrrupts. if the time is not out yet ( bit 2 in INTCON is 0 ), wait ( means get stuck with the loop ) f. the behavior will repate itselfs. PIC16F877A 7