EE2361 - Lab4a - RGB LED.pdf - EE 2361 Introduction to M...

This preview shows page 1 out of 19 pages.

Unformatted text preview: EE​ ​2361​ ​-​ ​Introduction​ ​to​ M ​ icrocontrollers Laboratory​ ​ ​#​ ​4a Bit​ ​Banging​ ​an​ ​RGB​ ​LED​ ​in​ ​Assembly Page​ ​1 EE​ ​2361​ ​-​ ​Lab​ ​#​ ​4a ECE​ ​ ​Department Background Serial​ ​communications​ ​protocols​ ​are​ ​a​ ​fundamental​ ​component​ ​of​ ​operating​ ​microcontrollers​ ​in today’s​ ​connected​ ​devices.​ ​ ​Serial​ ​communication​ ​allows​ ​for​ ​complex​ ​information​ ​to​ ​pass between​ ​devices​ ​over​ ​4,​ ​3,​ ​2​ ​or​ ​even​ ​just​ ​1​ ​wire.​ ​ ​Allowing​ ​everything​ ​from​ ​displays​ ​to​ ​sensors to​ ​function.​ ​ ​These​ ​protocols​ ​are​ ​so​ ​common​ ​and​ ​important,​ ​that​ ​they​ ​often​ ​have​ ​custom​ ​digital logic,​ ​referred​ ​to​ ​as​ ​peripherals​​ ​embedded​ ​on​ ​the​ ​MCU to​ ​improve​ ​efficiency.​ ​ ​In​ ​EE1301,​ ​we​ ​commonly​ ​used the​ ​“Serial”​ ​connection​ ​to​ ​output​ ​data​ ​to​ ​a​ ​computer over​ ​USB.​ ​ ​In​ ​later​ ​labs,​ ​we​ ​will​ ​learn​ ​how​ ​to​ ​use​ ​these optimized​ ​digital​ ​circuits​ ​to​ ​communicate​ ​over​ ​UART, I2C,​ ​or​ ​SPI. However​ ​on​ ​the​ ​cutting​ ​edge​ ​of​ ​development​ ​in​ ​custom systems,​ ​electrical​ ​engineers​ ​often​ ​need​ ​to​ ​develop software​ ​code​ ​to​ ​implement​ ​serial​ ​communication protocols​ ​from​ ​scratch. In​ ​our​ ​case​ ​the​ ​Individually​ ​Addressable​ ​RGB​ ​LED​ ​(iLED),​ ​introduced​ ​in​ ​EE1301,​ ​has​ ​no​ ​such dedicated​ ​digital​ ​support​ ​circuits.​ ​ ​In​ ​this​ ​lab,​ ​we​ ​will​ ​create​ ​our​ ​own​ ​implementation​ ​of​ ​a​ ​custom serial​ ​communication​ ​standard. Purpose In​ ​this​ ​lab​ ​you’ll​ ​familiarize​ ​yourself​ ​with​ ​the​ ​basic​ ​assembly​ ​instructions​ ​for​ ​changing​ ​the​ ​state​ ​of the​ ​GPIO​ ​pins​ ​on​ ​your​ ​PIC24​ ​microcontroller.​ ​ ​You’ll​ ​explore​ ​the​ ​timing​ ​implications​ ​of​ ​various instructions​ ​and​ ​their​ ​impact​ ​on​ ​the​ ​resulting​ ​output​ ​waveform.​ ​ ​You’ll​ ​combine​ ​these​ ​skills​ ​to change​ ​the​ ​color​ ​of​ ​an​ ​individually​ ​addressable​ ​RGB​ ​LED​ ​(iLED).​ ​ ​In​ ​the​ ​next​ ​lab,​ ​you’ll package​ ​up​ ​your​ ​assembly​ ​instructions​ ​into​ ​a​ ​C-library​ ​so​ ​that​ ​you​ ​can​ ​create​ ​sparkly​ ​light shows​ ​quickly​ ​and​ ​easily! Supplemental​ ​Resources PIC24FJ64GA004​ ​-​ ​Family​ ​Datasheet ● Section​ ​10.1​ ​Parallel​ ​I/O​ ​(PIO)​ ​Ports 16-bit​ ​MCU​ ​and​ ​DSC​ ​Programmer's​ ​Reference​ ​Manual ● REPEAT,​ ​CALL,​ ​and​ ​RETURN​ ​Functions iLED​ ​from​ ​Adafruit​ ​References: ● WS2812​ ​Datasheet ● Device​ ​Description​ ​-​ ​Individually​ ​Addressable​ ​LEDs​​ ​(from​ ​EE1301) ● EE1301​ ​-​ ​IoT​ ​Lab​ ​#2​ ​-​ ​Section​ ​Individually​ ​Addressable​ ​LEDs Required​ ​Components: Standard​ ​PIC24​ ​requirements​ ​(caps,​ ​pullup,​ ​debug​ ​header,​ ​etc.) Page​ ​2 EE​ ​2361​ ​-​ ​Lab​ ​#​ ​4a ECE​ ​Department iLED 100​ ​Ohm​ ​Resistor Standard​ ​LED​ ​or​ ​LED​ ​strip 220​ ​Ohm​ ​Resistor Pre-Lab Creating​ ​an​ ​assembly​ ​project​ ​in​ ​MPLAB​ ​X As​ ​discussed​ ​in​ ​Lab​ ​1,​ ​you​ ​will​ ​need​ ​to​ ​create​ ​a​ ​new​ ​project​ ​for​ ​this​ ​lab.​ ​Here​ ​is​ ​a​ ​brief​ ​outline​ ​of the​ ​steps: 1.) In​ ​MPLAB​ ​X,​ ​click​ ​on​ ​“File”​ ​→​ ​“New​ ​Project…” 2.) Select​ ​Microchip​ ​Embedded​ ​→​ ​Standalone​ ​Project 3.) Select​ ​16-bit​ ​MCU​ ​(PIC24)​ ​and​ ​PIC24FJ64GA002 4.) Leave​ ​the​ ​Debug​ ​Header​ ​set​ ​to​ ​“None” 5.) Select​ ​your​ ​Tool​ ​as​ ​“Simulator” 6.) Select​ ​your​ ​Compiler​ ​as​ ​“XC16” 7.) Finally,​ ​give​ ​your​ ​project​ ​a​ ​descriptive​​ ​name! (for​ ​example​ ​“x500_labX_vXXX”​ ​→​ ​ ​“orser_lab2_v001”) 8.) Click​ ​Finish Add​ ​boilerplate​ ​code​ ​for​ ​assembly​ ​language​ ​project The​ ​boilerplate​ ​code​ ​for​ ​an​ ​assembly-based​ ​project​ ​is​ ​slightly​ ​different​ ​than​ ​the​ ​C-based​ ​project we​ ​did​ ​in​ ​Lab​ ​2.​ ​ ​First,​ ​create​ ​a​ ​new​ ​assembly​ ​language​ ​file. 1.) In​ ​the​ ​“Projects”​ ​tab​ ​of​ ​MPLAB​ ​X,​ ​right-click​ ​on​ ​the​ ​“Source​ ​Files”​ ​directory​ ​and​ ​select “New”​ ​→​ ​“AssemblyFile.s”​ ​Careful!​ ​ ​There​ ​are​ ​three​ ​options​ ​that​ ​look​ ​similar. Page​ ​3 EE​ ​2361​ ​-​ ​Lab​ ​#​ ​4a ECE​ ​ ​Department Creating​ ​a​ ​new​ ​Assembly​ ​Language​ ​File​ ​in​ ​MPLAB​ ​X 2.) Give​ ​the​ ​file​ ​a​ ​name​ ​like,​ ​“orser_lab1_core_v001”,​ ​leave​ ​Project,​ ​folder,​ ​and​ ​Create​ ​File alone.​ ​ ​Make​ ​the​ ​name​ ​unique,​ ​as​ ​it​ ​gets​ ​confusing​ ​if​ ​there​ ​are​ ​three​ ​files​ ​open​ ​called “main.s” 3.) In​ ​some​ ​versions​ ​of​ ​MPLABX,​ ​this​ ​doesn’t​ ​add​ ​the​ ​new​ ​file​ ​to​ ​your​ ​project!​ ​ ​It​ ​just​ ​creates an​ ​empty​ ​file​ ​and​ ​opens​ ​the​ ​file​ ​for​ ​editing.​ ​ ​To​ ​add​ ​the​ ​file​ ​to​ ​your​ ​project:​ ​Right-click “Source​ ​Files”,​ ​select​ ​“Add​ ​Existing​ ​Item…”,​ ​click​ ​on​ ​your​ ​new​ ​file​ ​and​ ​click​ ​“Select”.​ ​ ​It should​ ​appear​ ​in​ ​your​ ​Project​ ​under​ ​the​ ​“Source​ ​Files”​ ​heading​ ​(or​ ​complain​ ​that​ ​the​ ​file is​ ​already​ ​part​ ​of​ ​the​ ​project,​ ​in​ ​which​ ​case​ ​no​ ​harm​ ​is​ ​done). Page​ ​4 EE​ ​2361​ ​-​ ​Lab​ ​#​ ​4a ECE​ ​ ​Department 4.) In​ ​the​ ​editor​ ​enter​ ​the​ ​following​ ​“boilerplate”​ ​text​ ​into​ ​your​ ​new​ ​source​ ​file: .equ​ ​__P24FJ64GA002,1​ ​ ​ ​ ​ ​ ​ ; ​ required​ ​"boiler-plate"​ ​(BP) .include​ ​"p24Fxxxx.inc"​ ​ ​ ​ ​ ; ​ BP #include​ ​"xc.inc"​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​;BP ;the​ ​next​ ​two​ ​lines​ ​set​ ​up​ ​the​ ​actual​ ​chip​ ​for​ ​operation​ ​-​ ​required config​ ​__CONFIG2,​ ​POSCMOD_EC​ ​&​ ​I2C1SEL_SEC​ ​&​ ​IOL1WAY_OFF​ ​&​ ​OSCIOFNC_ON​ ​& FCKSM_CSECME​ ​&​ ​FNOSC_FRCPLL​ ​&​ ​SOSCSEL_LPSOSC​ ​&​ ​WUTSEL_FST​ ​&​ ​IESO_OFF config​ ​__CONFIG1,​ ​WDTPS_PS1​ ​&​ ​FWPSA_PR32​ ​&​ ​WINDIS_OFF​ ​&​ ​FWDTEN_OFF​ ​&​ ​COE_ON​ ​& BKBUG_ON​ ​&​ ​GWRP_ON​ ​&​ ​GCP_ON​ ​&​ ​JTAGEN_OFF ​ ​ ​ ​ ​.bss​ ​ ​ counter: ​ ​ ​ ​ ​.space​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ stack: ​ ​ ​ ​ ​.space​ ​ ​ ​ ​ ​ ​;​ ​put​ ​the​ ​following​ ​labels​ ​in​ ​RAM ​2​ ​ ​ ​ ; ​ ​ a ​ ​ ​variable​ ​that​ ​takes​ ​two​ ​bytes​ ​(we​ ​won’t​ ​use ​ ​ ​ ​ ​ ; ​ ​ i ​ t​ ​for​ ​now,​ ​but​ ​put​ ​here​ ​to​ ​make​ ​this​ ​a​ ​generic ​ ​ ​ ​ ​ ; ​ ​ t ​ emplate​ ​to​ ​be​ ​used​ ​later). ​ ​32​ ​ ​;​ ​this​ ​will​ ​be​ ​our​ ​stack​ ​area,​ ​needed​ ​for​ ​func​ ​calls .text​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​;​ ​BP​ ​(put​ ​the​ ​following​ ​data​ ​in​ ​ROM(program​ ​memory)) ;because​ ​we​ ​are​ ​using​ ​the​ ​C​ c ​ ompiler​ ​to​ ​assemble​ ​our​ ​code,​ ​we​ ​need​ ​a​ ​"_main"​ ​label ;somewhere.​ ​(There's​ ​a​ ​link​ s ​ tep​ ​that​ ​looks​ ​for​ ​it.) .global​ ​_main​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ; ​ BP _main: ​ ​ ​ ​ b ​ clr​ ​ ​ ​ ​CLKDIV,#8​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​;BP ​ ​ ​ ​ n ​ op ​ ​ ​ ​ ; ​ ;​ ​---​ B ​ egin​ ​your​ p ​ rogram​ b ​ elow​ h ​ ere​ ​--- Code​ ​Example​ ​X:​ ​Boilerplate​ ​for​ ​ASM-only​ ​projects This​ ​boilerplate​ ​contains​ ​all​ ​the​ ​same​ ​functionality​ ​as​ ​our​ ​c-code​ ​boilerplate.​ ​ ​There​ ​are​ ​calls​ ​to supporting​ ​library​ ​definitions​ ​with​ ​.include()​ ​and​ ​#include​ ​statements.​ ​ ​You​ ​can​ ​see​ ​the​ ​flash configuration​ ​word​ ​declarations​ ​(__CONFIG1​ ​and​ ​__CONFIG2).​ ​And​ ​the​ ​Clock​ ​Divider​ ​setting of​ ​1:1​ ​for​ ​full​ ​16​ ​MIPS​ ​operation​ ​(bclr​ ​ ​ ​CLKDIV,#8). Turn​ ​on​ ​RA0 In​ ​this​ ​part​ ​of​ ​the​ ​lab​ ​we​ ​will​ ​prepare​ ​a​ ​simple​ ​assembly​ ​program​ ​that​ ​turns​ ​on​ ​the​ ​RA0​ ​pin.​ ​ ​This will​ ​demonstrate​ ​some​ ​basic​ ​structures​ ​of​ ​assembly​ ​code. 1.) Just​ ​like​ ​the​ ​C-program​ ​we​ ​need​ ​to​ ​add​ ​code​ ​that​ ​configures​ ​LATA,​ ​TRISA,​ ​and AD1PCFG​ ​registers.​ ​Remember,​ ​you​ ​can’t​ ​load​ ​an​ ​immediate​ ​directly​ ​into​ ​a​ ​general​ ​file register​ ​(generic​ ​memory​ ​location):​ ​you​ ​must​ ​first​ ​use​ ​a​ ​special​ ​function​ ​register​ ​as​ ​a middle-man. 2.) Just​ ​for​ ​the​ ​sake​ ​of​ ​clarity,​ ​let​ ​us​ ​go​ ​look​ ​at​ ​how​ ​the​ ​C-program​ ​compiles​ ​the​ ​first​ ​few lines​ ​of​ ​Lab​ ​1. a.) If​ ​you​ ​see​ ​the​ ​Lab1​ ​Project​ ​on​ ​the​ ​left​ ​pane,​ ​under​ ​“Projects”,​ ​Right-Click​ ​on​ ​the Lab1​ ​Project,​ ​and​ ​click​ ​“Set​ ​as​ ​Main”.​ ​Otherwise,​ ​just​ ​use​ ​File​ ​>​ ​Open​ ​Project​ ​to open​ ​it.​ ​You​ ​will​ ​later​ ​go​ ​back​ ​to ​your​ ​assembly​ ​project. Page​ ​5 EE​ ​2361​ ​-​ ​Lab​ ​#​ ​4a ECE​ ​ ​Department b.) Right-Click​ ​on​ ​Lab​ ​1​ ​project,​ ​click​ ​Properties,​ ​select​ ​Simulator​ ​as​ ​the​ ​target c.) Add​ ​a​ ​breakpoint​ ​on​ ​the​ ​line​ ​“AD1PCFG​ ​=​ ​0x9fff;” d.) Click​ ​Debug​ ​Main​ ​Project​ ​( this: ),​ ​if​ ​all​ ​goes​ ​well​ ​it​ ​should​ ​look​ ​something​ ​like Example​ ​of​ ​active​ ​breakpoint​ ​in​ ​Lab1 e.) Click​ ​on​ ​the​ ​menu​ ​item​ ​Window​ ​→​ ​Debugging​ ​→​ ​Disassembly,​ ​it​ ​should​ ​look something​ ​like​ ​this: Example​ ​of​ ​Disassembled​ ​Code You​ ​can​ ​see​ ​the​ ​C-code​ ​gets​ ​directly​ ​converted​ ​into​ ​two​ ​assembly​ ​instructions.​ ​ ​The​ ​first​ ​loads​ ​a register​ ​(w0)​ ​with​ ​an​ ​immediate​​ ​value​ ​(0x9FFF).​ ​ ​The​ ​second​ ​copies​ ​the​ ​contents​ ​of​ ​the​ ​register (w0)​ ​into​ ​the​ ​memory​ ​location​ ​of​ ​the​ ​register​ ​(AD1PCFG). Page​ ​6 EE​ ​2361​ ​-​ ​Lab​ ​#​ ​4a ECE​ ​ ​Department 3.) Now​ ​mimic​ ​this​ ​to​ ​set​ ​AD1PCFG,​ ​TRISA,​ ​and​ ​LATA​ ​to​ ​the​ ​following​ ​values: a.) Set​ ​AD1PCFG​ ​to​ ​0x9FFF​ ​//​ ​This​ ​sets​ ​all​ ​pins​ ​to​ d ​ igital​​ ​mode b.) Set​ ​TRISA​ ​to​ ​0b1111111111111110​ ​ ​//​ ​This​ ​sets​ ​the​ ​RA0​ ​pin​ ​to​ o ​ utput​​ ​mode​ ​and the​ ​rest​ ​of​ ​the​ ​PORTA​ ​pins​ ​to​ ​input​ ​(as​ ​a​ ​matter​ ​of​ ​fact,​ ​the​ ​chip​ ​that​ ​you​ ​work with​ ​has​ ​only​ ​5​ ​bits​ ​on​ ​PORT​ ​A,​ ​but​ ​the​ ​microcontroller​ ​doesn’t​ ​mind​ ​us​ ​setting all​ ​those​ ​16​ ​bits​ ​in​ ​TRISA.​ ​It​ ​will​ ​ignore​ ​bits​ ​5..15). c.) Set​ ​LATA​ ​to​ ​0x0001​ ​ ​//​ ​This​ ​sets​ ​RA0​ ​to​ ​output​ ​a​ ​logic​ h ​ igh ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​mov​ ​ ​mov​ ​ ​mov​ ​ ​mov​ ​ ​mov​ ​ ​mov​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​#0x9fff,w0 ​ ​w0,AD1PCFG​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​;​ ​Set​ ​all​ ​pins​ ​to​ ​digital​ ​mode ​ ​#0b1111111111111110,w0 ​ ​w0,TRISA​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​;​ ​set​ ​pin​ ​RA0​ ​to​ ​output ​ ​#0x0001,w0 ​ ​w0,LATA​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​;​ ​set​ ​pin​ ​RA0​ ​high 4.) It​ ​is​ ​“bad​ ​form”​ ​to​ ​let​ ​your​ ​program​ ​counter​ ​continue​ ​to​ ​execute​ ​past​ ​the​ ​end​ ​of​ ​your program.​ ​ ​Add​ ​a​ ​forever-do-nothing​ ​loop: ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​foreverLoop: ​ ​nop ​ ​bra​ ​ ​ ​ ​ ​foreverLoop ​ ​nop ​ ​.end​ ​ ​ ​ ​;​ ​this​ ​doesn’t​ a ​ ctually​ ​end​ ​anything.​ ​Does​ n ​ ot​ t ​ ranslate​ t ​ o​ ​assembly ​ ​ ​ ​ ​ ​ ​ ​ ​ ​;​ ​code.​ ​Just​ ​a​ w ​ ay​ ​to​ ​tell​ ​the​ ​compiler​ ​we​ a ​ re​ d ​ one​ ​with​ t ​ his​ ​file. Example​ ​of​ ​a​ ​forever-do-nothing​ ​loop NOTE:​ ​Don’t​ ​forget​ ​to​ ​set​ ​Lab​ ​2​ ​as​ ​your​ ​main​ ​project​ ​again!​ ​ ​This​ ​is​ ​a​ ​very​ ​common​ ​mistake while​ ​working​ ​in​ ​MPLAB​ ​X. 5.) Right​ ​click​ ​on​ ​Lab​ ​Project,​ ​click​ ​“Set​ ​as​ ​Main​ ​Project”,​ ​or,​ ​if​ ​you​ ​don’t​ ​see​ ​the​ ​project​ ​on the​ ​left,​ ​open​ ​it. 6.) Now​ ​compile​ ​your​ ​code,​ ​click​ ​ ,​ ​clean​ ​up​ ​any​ ​errors​ ​that​ ​result. 7.) Bring​ u ​ p​ ​your​ ​logic​ ​analyzer​ ​and​ ​add​ ​the​ ​signal​ ​RA0 8.) If​ ​you​ ​click​ ​( )​ ​to​ ​ ​simulate​ ​your​ ​code,​ ​your​ ​code​ ​runs​ ​forever​ ​because​ ​there​ ​are no​ ​breakpoints​ ​that​ ​stop​ ​the​ ​program.​ ​Try​ ​it! 9.) Click​ ​the​ ​Pause​ ​button​ ​( ).​ ​ ​It​ ​should​ ​look​ ​something​ ​like​ ​these​ ​screenshots: Page​ ​7 EE​ ​2361​ ​-​ ​Lab​ ​#​ ​4a ECE​ ​ ​Department Example​ ​of​ ​paused​ ​Simulation Example​ ​of​ ​RA0​ ​output​ ​on​ ​Logic​ ​Analyzer 10)​ ​Now​ ​press​ ​the​ ​“stop”​ ​button​ ​to​ ​stop​ ​simulating​ ​the​ ​program.​ ​Add​ ​a​ ​breakpoint​ ​on​ ​the​ ​line that​ ​says​ ​“mov​ ​ ​ ​ ​w0,LATA”.​ ​Press​ ​the​ ​Debug​ ​Project​ ​button​ ​( )​ ​again,​ ​and​ ​when​ ​the program​ ​stops​ ​at​ ​the​ ​breakpoint​ ​(make​ ​sure​ ​the​ ​“Logic​ ​Analyzer”​ ​window​ ​is​ ​up),​ ​press​ ​F8​ ​(Step Over​ ​ )​ ​a​ ​couple​ ​of​ ​times.​ ​You​ ​will​ ​notice​ ​that​ ​RA0​ ​makes​ ​a​ ​transition​ ​to​ ​1​ ​in​ ​the​ ​logic analyzer​ ​window. Page​ ​8 EE​ ​2361​ ​-​ ​Lab​ ​#​ ​4a ECE​ ​ ​Department Toggle​ ​RA0 In​ ​this​ ​section​ ​of​ ​the​ ​lab​ ​you​ ​will​ ​toggle​ ​RA0​ ​and​ ​learn​ ​to​ ​carefully​ ​control​ ​the​ ​duration​ ​of​ ​the high/low​ ​logic​ ​pulses. When​ ​properly​ ​configured​ ​our​ ​PIC24​ ​operates​ ​on​ ​a​ ​32​ ​MHz​ ​internal​ ​Clock,​ ​which​ ​results​ ​in​ ​a​ ​16 MIPS​ ​(million​ ​instructions​ ​per​ ​second).​ ​This​ ​is​ ​called​ ​Fcy=16MHz​ ​in​ ​the​ ​PIC​ ​manual.​ ​ ​This means​ ​most​ ​instructions​ ​take​ ​1/16MHz​ ​=​ ​62.5ns​ ​to​ ​execute.​ ​ ​We​ ​can​ ​use​ ​a​ ​combination​ ​of​ ​two programming​ ​methods​ ​to​ ​create​ ​blocking​ ​delays​ ​of​ ​precisely​ ​N​ ​times​ ​62.5ns. NOP​ ​Delay​ ​Method The​ ​most​ ​basic​ ​instruction​ ​for​ ​this​ ​purpose​ ​are​ ​“nop”.​ ​ ​Which​ ​does​ ​exactly​ ​what​ ​it​ ​says​ ​“No Operation”​ ​for​ ​62.5ns.​ ​ ​For​ ​example​ ​the​ ​following​ ​code​ ​produces​ ​the​ ​following​ ​output. Example​ ​of​ ​toggling​ ​RA0 Notice​ ​how​ ​the​ ​first​ ​pulse​ ​is​ ​narrower​ ​than​ ​the​ ​subsequent​ ​pulses?​ ​ ​The​ ​first​ ​rising​ ​edge​ ​on​ ​RA0 happened​ ​because​ ​of​ ​the​ ​“mov​ ​w0,​ ​LATA”,​ ​before​ ​the​ ​“foreverLoop”​ ​label.​ ​There​ ​were​ ​only​ ​two nop​ ​instructions​ ​between​ ​that​ ​instruction​ ​and​ ​the​ ​clr​ ​instruction,​ ​which​ ​results​ ​in​ ​a​ ​falling​ ​edge on​ ​RA0.​ ​However,​ ​when​ ​we​ ​are​ ​inside​ ​the​ ​loop,​ ​there​ ​are​ ​three​ ​instructions​ ​between​ ​the instruction​ ​causing​ ​a​ ​rising​ ​edge​ ​(inc​ ​LATA),​ ​and​ ​the​ ​falling​ ​edge​ ​(clr​ ​LATA).​ ​The​ ​branch instruction​ ​(bra​ ​foreverLoop)​ ​takes​ ​two​ ​instruction​ ​cycles,​ ​resulting​ ​in​ ​a​ ​total​ ​of​ ​5​ ​instruction cycles​ ​for​ ​the​ ​high​ ​part​ ​of​ ​the​ ​signal​ ​as​ ​opposed​ ​to​ ​only​ ​3​ ​during​ ​the​ ​low-time​ ​of​ ​the​ ​signal. Page​ ​9 EE​ ​2361​ ​-​ ​Lab​ ​#​ ​4a ECE​ ​ ​Department REPEAT​ ​Delay​ ​Method The​ ​second​ ​method​ ​is​ ​excellent​ ​for​ ​creating​ ​precise​ ​delays​ ​of​ ​longer​ ​duration.​ ​ ​The​ ​REPEAT instruction​ ​can​ ​be​ ​found​ ​in​ ​the​ ​16-bit​ ​PIC​ ​Programmers​ ​Reference​ ​Manual​ ​(page​ ​355​ ​as​ ​of​ ​the current​ ​printing.) Basically​ ​the​ ​REPEAT​ ​#N​ ​command​ ​repeats​ ​the​ ​next​ ​instruction​ ​N+1​ ​times,​ ​where​ ​N​ ​is​ ​the argument​ ​of​ ​REPEAT,​ ​a​ ​#l4lit​​ ​(a​ ​14-bit​ ​integer​ ​number​ ​between​ ​0​ ​and​ ​16383). Take​ ​a​ ​look​ ​at​ ​the​ ​following​ ​example​ ​code​ ​and​ ​simulation: Example​ ​use​ ​of​ ​REPEAT​ ​with​ ​comments REPEAT​ ​can​ ​create​ ​precise​ ​delays​ ​of​ ​between​ ​(3)*62.5ns​ ​=​ ​187.5ns​ ​and​ ​(16385)*62.5ns​ ​= 1,024,062.5​ ​ns​ ​(slightly​ ​more​ ​than​ ​1​ ​ms).​ ​ ​This​ ​makes​ ​it​ ​a​ ​fantastic​ ​tool​ ​for​ ​precise​ ​delays​ ​less than​ ​or​ ​equal​ ​to​ ​1ms.​ ​ ​The​ ​code​ ​is​ ​readable​ ​and​ ​takes​ ​a​ ​minimum​ ​of​ ​program​ ​memory​ ​space. There​ ​are​ ​several​ ​instructions​ ​that​ ​cannot​ ​follow​ ​a​ ​REPEAT​ ​(including​ ​the​ ​CALL​ ​instruction discussed​ ​in​ ​the​ ​next​ ​section)​ ​see​ ​the​ ​16-bit​ ​PIC​ ​Programmers​ ​Reference​ ​Manual​ ​for​ ​a complete​ ​list. Page​ ​10 EE​ ​2361​ ​-​ ​Lab​ ​#​ ​4a ECE​ ​ ​Department CALL​ ​and​ ​RETURN​ ​instructions Function​ ​calls​ ​(often​ ​referred​ ​to​ ​as​ ​subroutines​ ​in​ ​the​ ​PIC​ ​documentation)​ ​are​ ​executed​ ​in assembly​ ​via​ ​the​ ​CALL​ ​and​ ​RETURN​ ​instructions.​ ​ ​These​ ​instructions​ ​take​ ​several​ ​cycles​ ​each to​ ​store/retrieve​ ​important​ ​registers,​ ​update​ ​the​ ​program​ ​counter,​ ​and​ ​flush​ ​the​ ​instruction fetch+decode​ ​stage.​ ​ ​They​ ​are​ ​both​ ​defined​ ​in​ ​detail​ ​in​ ​the​ ​16-bit​ ​PIC​ ​Programmers​ ​Reference Manual.​ ​ ​We’ll​ ​briefly​ ​review​ ​them​ ​here,​ ​but​ ​if​ ​you​ ​need​ ​further​ ​information​ p ​ lease​​ ​read​ ​the manual​ ​before​ ​approaching​ ​your​ ​TA​ ​or​ ​instructor. The​ ​CALL​ ​instruction​ ​requires​ ​one​ ​argument,​ ​the​ ​address​ ​of​ ​the​ ​subroutine​ ​to​ ​be​ ​called​ ​(in​ ​our case​ ​actually​ ​a​ ​label.)​ ​CALL​ ​takes​ ​2​ ​cycles​ ​to​ ​execute.​ ​The​ ​RETURN​ ​instruction​ ​doesn’t​ ​require any​ ​arguments.​ ​RETURN​ ​takes​ ​3​ ​cycles.​ ​These​ ​extra​ ​cycles​ ​need​ ​to​ ​be​ ​accounted​ ​for​ ​when building​ ​precise​ ​timing​ ​code. In​ ​assembly,​ ​a​ ​function​ ​is​ ​simply​ ​a​ ​label​ ​with​ ​a​ ​RETURN​ ​instruction​ ​at​ ​the​ ​end. wait_10cycles: ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​repeat​ ​#3​ ​ ​ ​ ​ ​ ​nop​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​return​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​;​ ​;​ ​;​ ​;​ ​2​ ​cycles​ ​for​ ​function​ ​call ​ ​ ​cycle​ ​to​ ​load​ ​and​ ​prep 1 ​3+1​ ​cycles​ ​to​ ​execute​ ​NOP​ ​4​ ​times ​3​ ​cycles​ ​for​ ​the​ ​return Example​ ​of​ ​a​ ​function​ ​in​ ​assembly You​ ​call​ ​this​ ​function​ ​with​ ​the​ ​CALL​ ​instruction. ​ ​ ​ ​ ​foreverLoop: ​ ​ ​ ​ ​call​ ​ ​ ​ w ​ ait_10cycles​ ​ ​ ​ ​ ; ​ ​ 1 ​ 0​ ​cycles ​ ​ ​ ​ c ​ lr​ ​ ​ ​ ​ L ​ ATA​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ; ​ ​ s ​ et​ ​pin​ ​RA0​ ​low​ ​=​ ​1​ ​cycle ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​nop​ ​ ​ ​ ​ ​nop​ ​ ​ ​ ​ ​repeat​ ​ ​nop​ ​ ​ ​ ​ ​Inc​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​bra​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​#8​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​LATA​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​foreverLoop ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​;​ ​ ; ​;​ ​;​ ​;​ ​;​ ​2​ ​cycles​ ​to​ ​match​ ​BRA​ ​delay ​1​ ​cycle​ ​to​ ​load​ ​and​ ​prep ​8+1​ ​cycles​ ​to​ ​execute​ ​NOP​ ​9​ ​times ​set​ ​pin​ ​RA0​ ​high​ ​=​ ​1​ ​cycle ​Total​ ​=​ ​12​ ​cycles​ ​high,​ ​12​ ​cycles​ ​low Example​ ​of​ ​a​ ​function​ ​call​ ​in​ ​assembly In​ ​the​ ​pre-lab​ ​deliverables​ ​section​ ​below​ ​you​ ​will​ ​have​ ​to​ ​modify​ ​this​ ​above​ ​example​ ​to​ ​make the​ ​pulse​ ​generation​ ​its​ ​own​ ​function. HINT:​ ​It​ ​is​ ​possible​ ​to​ ​create​ ​wait​ ​functions​ ​for​ ​each​ ​pulse​ ​width​ ​(high​ ​and​ ​low).​ ​However,​ ​if​ ​you never​ ​reuse​ ​the​ ​function,​ ​it's​ ​a​ ​waste​ ​of​ ​time​ ​and​ ​energy​ ​to​ ​write​ ​it.​ ​ ​Instead,​ ​you​ ​should​ ​write the​ ​REPEAT/NOP​ ​instruction​ ​in-line. Page​ ​11 EE​ ​2361​ ​-​ ​Lab​ ​#​ ​4a ECE​ ​ ​Department Pre-Lab​ ​Deliverables For​ ​the​ ​Week​ ​1​ ​Pre-Lab,​ ​on​ ​your​ ​own,​ ​you​ ​need​ ​to​ ​create​ ​several​ ​pieces​ ​of​ ​complete​ ​assembly code.​ ​ ​These​ ​will​ ​be​ ​used​ ​in​ ​lab! 1.) Create​ ​an​ ​all​ ​assembly​ ​function​ ​and​ ​calling​ ​assembly​ ​program a.) The​ ​assembly​​ ​function​ ​should​ ​be​ ​of​ ​the​ ​form​ ​(pseudocode): void​ ​write_bit_stream(void)​ ​{} (NOTE:​ ​Remember​ ​your​ ​function​ ​should​ ​be​ ​in​ ​assembly​,​ ​where​ ​inputs​ ​and outputs​ ​are​ ​passed​ ​by​ ​either​ ​the​ ​“stack”​ ​or​ ​registers.​ ​ ​In​ ​this​ ​case​ ​there​ ​are neither.) b.) The​ ​function​ ​should​ ​generate​ ​a​ ​24-cycle​ ​high,​ ​32-cycle​ ​low​ ​pulse 2.) Place​ ​your​ ​function​ ​within​ ​your​ ​program​ ​within​ ​a​ ​forever​ ​loop​ ​ ​(HINT:​ ​you’ll​ ​have​ ​to​ ​add​ ​a couple​ ​NOPs​ ​to​ ​account​ ​for​ ​the​ ​forever​ ​loop​ ​BRA​ ​instruction​ ​and​ ​trim​ ​a​ ​couple​ ​cycles from​ ​the​ ​high/low​ ​delay​ ​in​ ​the​ ​function.)​ ​ ​The​ ​waveform​ ​is​ ​shown​ ​in​ ​the​ ​diagram​ ​below. Be​ ​prepared​ ​to​ ​demonstrate​ ​this​ ​program​ ​to​ ​your​ ​TA​ ​at​ ​the​ ​start​ ​of​ ​lab​ ​(ie.,​ ​hit​ ​simulate and​ ​view​ ​the​ ​logic​ ​analyzer.) Request​ ​Output​ ​Pulse​ ​Train​ ​Specification​ ​for​ ​Pre-Lab​ ​Week​ ​1 3.) Create​ ​four​ ​additional​ ​subroutines​ ​using​ ​REPEAT​ ​to​ ​provide​ e ​ xact​​ ​delays: ● Delay​ ​1us ● Delay​ ​10us ● Delay​ ​100us ● Delay​ ​1ms Pre-Lab​ ​Checklist ❏ ❏ ❏ ❏ Take​ ​pre-lab​ ​quiz​ ​on​ ​LATx,​ ​PORTx,​ ​ADxPCFG Complete​ ​the​ ​walk-through​ ​to​ ​create...
View Full Document

  • Left Quote Icon

    Student Picture

  • Left Quote Icon

    Student Picture

  • Left Quote Icon

    Student Picture