Está en la página 1de 17

Guadepickit3

Elcontadordeprograma Estetiene21bitsdeanchuraysedivideentresde8bits,PCL,PCH,PCUsiendoPCHY PCUlosregistrosalosquenosepuedeescribirdirectamentenitampocosonvisiblesanoserque serealicemediantealgunainstruccindelecturaoescriturasobreelregistroPCL.Deestaformase actualizalosregistrossuperioresdelPC.Tambinesmodificablesiunainstruccindesaltoode subrutinaseejecuta,permitindoselaescrituradirectamentepordichasinstruccionesperoeldato nosertransferidodesdeelPCHyPCUalcontadorderegistro. Anteunreset,el PCsecargaconelvalor0,porloqueesteapuntaaladireccin0dela memoriadeprograma,ysegnlainstruccinescrita(normalmenteun"goto")asactuar. Hayquedecirquelasinstruccionesnosepuedenejecutarenbytesimpares,yaqueel PC solovasaltandodedosendosyaquesubitdemenospeso,tienesiemprepuestoa0porloquesolo sonpareslaslineasalasquesalta. PROGRAMANDOCONC ElcompiladorCparapicdeMPLABimplementalasiguienteregla: 1. Lasinstruccionessealmacenanenlaseccindenominadacode. 2. LosdatossonalmacenadosenromdataconjuntamenteconROM MPLAB C COMPILER puede generar dos modelos de memoria, corto y largo. En el modelocortoseusaunpunterode16bits,mientrasqueelmodelolargoseusaunode24bits(PC). MEMORIA DEDATOS La memoria de datos es llamada file register o memoria de registros. Una vez que encendemoselpic,losdatoscontenidosendichosregistros,sonaleatorios.Losregistrosseagrupan enordende256bytesloscualespuedenserseleccionadosenbancosaccesiblesporlos4bitsde mayorpesodelregistrodedirecciones BSR ( Bank Select Register ).Lasreasespecialesenel banco0yenel15sondirectamenteaccesiblesysondenominadasACCESSRAMyesaqudonde estnlosregistrosespeciales(FSR)comosonporejemplo,losregistrosparaprogramarunpuerto deI/O,bitsdealgnregistrodeestado.... #pragmavarlocateledicealcompiladordndesealmacenanlasvariables. Las variables noinicializadassonalmacenadasenmemoriamedianteudata,yelcompilador realizar lo necesario para almacenar y distribuir los datos correctos, as como su tipo para optimizarlamemoriaalmximo,unavezqueloinicialiceelcompiladorpasarlosdatosdela memoriadeprogramaaladedatosparacomprobarsucorrectaortografaytiposdedatospara luegooptimizarelprograma. REGISTROSESPECIALESSFR Estos registros especiales son( PC,status,pila, EEDATA,,,,)sirvenpara programar los perifricosylosdemsregistroscomoSTATUSoPCyelcompiladordeCpuedeaccederaello porsunombreypuedemodificarlosyleerloscomosifuesenvariables.SelocalizanelelBanco15 delamemoriadedatos.

EJERCICIOSPRACTICOSSOBREC EJERCICIO1 ConectarelPICKIT3alpuertousbdelpcydespusconectarnoslaplacaalconectorICSP. VamosacrearunproyectodecompilacinenCconelcompiladorCdeMPLAB. Elproyectoconsisteenencenderunledindefinidamenteconectadoaunapuerta,yveremos comoserealizantodoslospasosparasucompilacin.Paracrearunproyectovamosarealizarlo medianteelasistente,porloqueaccedemosaProject>ProjectWizard...ynossaleunaventanade bienvenida,porloquepulsamosNEXT. 1. SeleccionamosuncomponentequeenestecasoserPIC18F45K20ypulamosenNext. 2. SeleccionamosellenguajedeprogramacinMicrochipC18ToolsuiteypulsamosNext. 3. Crear un nuevo proyecto. Busca C.\Lessosn\PICKIT 3 Debug Express Lessons\01 Hello LED ynombraelproyecto Lessson1 LED yloguardamoscon SAVE entoncesledamosa NEXTparacontinuar. 4. Podemosaadirarchivosyfuentesquetengamosescritosalproyecto(evidentementeantes debenestarcreadosennuestrodiscoduro).Alaizquierdaseleccionamoselarchivo 01 HELLOLED.cyloaadimos.PulsamosNextparacontinuar. 5. EstaultimaventanaverificaremostodosnuestrosdatosypincharemosenFinish. Paraverelproyectoquehemoscreado,vamosa View>Projectyveremosnuestroreade trabajoelarchivollamado Lesson1LED.mcw(enelttulodelaventana)yelarchivoproyecto Lesson1LED.mcp. Para completar el proyecto tenemos que aadir Linker Script y el header del microcontroladoralproyecto.ElLinkerScriptsenecesitaparaconstruirelproyecto.Esunarchivo decomandosparaelcompiladorysedefinenlasopcionesquedescribeelmapadememoriadel microcontroladoryexisten4linkers: 18f45k20.lkr Linkerbsicoenmodonoextendido 18f45k20_e.lkr Linkerparacompilarenmodoextendido. 18F45k20i.lkr LinkerqueseusaconDebbuger(previeneelcdigodeaplicaciones ejecutarpequeasreasdememoriareservadaaldebugger.). 18f45k20i_e.lkr Linkerparaeldebbugerenmodoextendido. ParaaadirellinkeralproyectohacemosProject>Addfilestoproject...ydentrodelacaja deseleccindeFilesoftypes seleccionamos LinkerScritp(*.lkr)queestnenC\MCC18\hy abrimosel p18f45k20.h.Unanotaimportante,simodificamoselarchivoseleccionadoennuestro proyecto,tambinsemodificareloriginalyportantoesonolodeseamos,porloqueharemoslo siguiente, File>Save AS.... para salvar una copia en el nuevo proyecto, es decir, el archivo p18f45k20.h lo copiaremos en el presente proyecto y as no lo modificaremos. Por ltimo File>SaveWorkspace.Debequedarnosalgoas:

Elprograma:

/**CONFIGURATIONBITS******************************/ #pragmaconfigFOSC=INTIO67 #pragmaconfigWDTEN=OFF,LVP=OFF /**INCLUDES**************************************************/ #include"p18f45K20.h" /**DECLARATIONS*******************************************/ voidmain(void) { TRISD=0b01111111; LATDbits.LATD7=1; while(1); }

//PORTDbit7tooutput(0);bits6:0areinputs(1) //SetLATregisterbit7toturnonLED

Veamoscomofuncionaesto,,,, #pragmaconfigSirveparaconfigurarlosregistros,queenestecasosonFOSCYWDTENYLVP #include Paraincluirlosheaderdeloschipsusados TRISD EsunavariablequeaccedealsfrconelmismonombreTRISDqueestincluidaen elincludeanterior.Enconcretoestaponea0o1losbitsdelapuertaDsiendo0las queseusancomosaliday1losqueseusancomoentrada.Astenemoselcdigo 0b01111111porloqueponeaRD7COMOSALIDAYELRESTOCOMO ENTRADA(RD6RD0).El0besunanotacinparaelcompiladorqueleindica queeldatoexpresadoesbinario,sifuesehexadecimalseria0x.....

LATDBITS.LATD7LATDBITStambinestdefinidoenelp18f45k20.hypermiteelaccesoalos bitsindividualesdelregistroLATDelcualenestainstruccinseponea1lasalida D7atravsdeLATD7(latch7). CONSTRUYENDOYPROGRAMANDOELPROYECTO SeleccionamosProject>BuildAll.Elarchivogeneradoesunhexquesegrabarenelpic. Cuando termine aparece el mensaje Build sucess, si ha ocurrido algn error, del tipo p18f45k20.hnoseapodidoencontrar,esdebidoaqueMPLABCfueinstaladosinaadir Add headerfilepathtoMCC_INCLUDEenviromnetvariableoption durantelainstalacinporloque habrquereinstalarMPLABCdenuevo. Ahora vamos a elegir el pickitt 3 como programador yendo a Programmer > Select Programmer>4pickitt3.loqueharqueaparezcaunanuevapestaaenlapartedelaventanade informacin,mostrandoelestadodedichoprogramadorytodoslosmensajesqueseproduzcan.El programadorserinicializadoystedebeinformardequehaencontradolaplacaDEMOalaque estenganchadoymostrarelmicrocontroladorqueposee,queenestecasoesnuestropic18f45k20.

ventananuestropic18f45k20. Pasamosahoraameterelprogramaenelpic18f45k20yendoa Programmer>Program y .listo,yaestaprogramado.Sisehacometidoalgnerrorenlaprogramacinconsultarlaayuda delpickit3 Help>Topics... ybajo Programmer seleccionamos pickit3 yOK.Enlapestaade contenidosseleccionamosTroubleshootingparamsinformacin. PROYECTO2LEDPARPADEANTE. Aquseexponeunproyectoconlametade: AbrirunreadetrabajodeproyectoseleccionadodesdeFile>openWorkspaces Configuracin de bits de propsito especial, modos de operacin y habilitar caractersticasdelmicrocontrolador. Retardos,libreras..... Enestepunto,yahemosprogramadonuestropic18f45k20ytodavanosehacerradoel proyecto,peronosotrosvamosaabrirotroreadetrabajoparaelnuevoproyecto.Paraellodebemos iraFile>OpenWorkspaces....ybuscamosC:\Lessons\PICkit3DebugExpressLessons\02 BlinkLEDyabrimosel02BlinkLED.mcwarchivo. Antesdeabrirunanuevareadetrabajo,MPLABnospreguntasiqueremosguardarla anterior,porloquelorecomendableesdecirquesi. CONFIGURANDOBITS Enesteejercicio,laconfiguracindelosbitsestndefinidasenlapartesuperiordelarchivo deBlinkLED.Ccomosemuestra: /**CONFIGURATIONBITS******************************/ #pragmaconfigFOSC=INTIO67,FCMEN=OFF,IESO=OFF//CONFIG1H #pragmaconfigPWRT=OFF,BOREN=SBORDIS,BORV=30//CONFIG2L #pragmaconfigWDTEN=OFF,WDTPS=32768//CONFIG2H #pragmaconfigMCLRE=OFF,LPT1OSC=OFF,PBADEN=ON,CCP2MX=PORTC //CONFIG3H #pragmaconfigSTVREN=ON,LVP=OFF,XINST=OFF//CONFIG4L #pragmaconfigCP0=OFF,CP1=OFF,CP2=OFF,CP3=OFF//CONFIG5L #pragmaconfigCPB=OFF,CPD=OFF//CONFIG5H #pragmaconfigWRT0=OFF,WRT1=OFF,WRT2=OFF,WRT3=OFF//CONFIG6L #pragmaconfigWRTB=OFF,WRTC=OFF,WRTD=OFF//CONFIG6H

Aqupodemosobservarquenosehadetectado laplacaconelpicyaquesinoseprogramaal pikit3 para que alimente a la placa, esta no podrserencontradadeningunamanera. Para ello debemos de configurar el pickit 3 paraelloyportanto vamosaProgrammer> Settings... Para dicho pic debemos alimentarlo como mximoa3,25voltsyportantodeslizaremosel cursor hasta que est en dicha tensin. Lo salvamos dando ok y debe aparecer en la

#pragmaconfigEBTR0=OFF,EBTR1=OFF,EBTR2=OFF,EBTR3=OFF//CONFIG7L #pragmaconfigEBTRB=OFF//CONFIG7H Comovimosenelejercicioanterior,losbitsseconfiguranutilizando #pargmaconfig y separndolospor comas.Cadamicrocontroladortienesuspropiascaractersticasylaspodemos encontrarenMPLABIDEHELP.Porejemplovamosabuscarlasdelpic18f45k20: 1 SeleccionarnosMPLABIDEmenHelp>Topics...ybuscarlacategoraLenguajes Tool. 2 PIC18ConfigSettingsluegoOK. 3 Cuandolaventanadeayudaseabra,seleccionamoslapestaaContenidosyexpandir laseccinConfigurationSettings. 4 Seleccionamosnuestropic18f45k20. Laconfiguracindelosbitsenesteejercicioesdiferentealaquetraepordefecto,porloque vamosaprestaratencinyvemoscomofunciona. Estaconfiguracinconfiguraalpicparaquetrabajeconelosciladorinterno porloquenonecesitaningnosciladordecristalexternoparafuncionar. Lafrecuenciapordefectoesde1MHzyaspodemosutilizarlospinesRA6 (osc1)yRA7(osc2)comobitsdeI/OdelapuertaAyaquenosevanausar comoentradasparaeloscilador. WDTEN=OFF EstaconfiguracinnospermiteapagarelWatchdogTimer(WDT)yaqueen esteejercicionolovamosausar.YasesabequesiusamoselWDTynolo refrescamos,steresetearelmicrocontrolador. LVP=OFF EstoapagaelmododeLowVoltageProgramingyportantoliberalapatita PGMoRB5yaqueLVPnolousaPICKIT3. Elrestodelosbitssonigualesalosquetraepordefecto,peronoestmalrecordarleal compiladordequeesstaynootralaconfiguracinquenosotrosdeseamos. Yahoraponemoselprogramaprincipal.Observaquelalinea#includehaaadidounnuevo ficheroytambinelsmbolo~delantedelLATDbits.LATD7 /**INCLUDES**************************************************/ #include"p18f45k20.h" #include"delays.h" /**DECLARATIONS*******************************************/ voidmain(void) { TRISD=0b01111111;//PORTDbit7tooutput(0);bits6:0areinputs(1) while(1) { LATDbits.LATD7=~LATDbits.LATD7;//toggleLATD Delay1KTCYx(50);//Delay50x1000=50,000cycles;200ms@1MHz } } Observaquesehaincluidolalinea#includedelays.h,esteheaderselocalizaaligualque FOSC=INTIO67

p18f45k20.h,oseadeC:\MCC18\h.Yportanto,tenemoslainstruccindeestalibrerautilizadaen elprogramaconlalneaDelay1KTCYx(50); Esta funcin crea unretardode 1000 instrucciones de ciclo multiplicado por lo quehay entre parntesisynosdara1000*50=50.000ciclosycomoennuestromicrocontroladorelcicloesde lasealdereloj,puesenestecaso(sinosciladores1MHzz)ser1mHz/4=250KHzzloquenosda unos200msquemasquesuficientelentoparaquenuestroojoloveaparpadear. LESSON3ROTACIONLED Esteprogramarealizaeldesplazamientodeledsencendiendounodetrsdeotro.Elarchivo 03RotateLED.cdeclaraunavariablecomogloballlamadaLED_Numberyasseasigna: /**VARIABLES*************************************************/ #pragmaudata //asignavariablesestticasnoinicializadas unsignedcharLED_Number; //8bitvariable Ladirectiva#pragmaudatasirveparadeciralcompiladorquelasvariablesdedatosquea continuacinsiguen,sedebendemeterenlosregistrosdelPIC(ojoesenelreaderegistros). Haydosdirectivaquesepuedenusarcon#pragma udata:Sealmacenandatos(registros)sininicializarenlosregistrosdelpic. idata:Losdatosinicializadossealmacenanenelespacioderegistrosdelpicylosdatos delainicializacinsonguardadosenlamemoriadeprogramaymovidosporelcdigo deinicializacindearranque,antesdequeempieceelprograma. Ladeclaracindedatospuedeperteneceraunaseccinconunnombre.Dichonombrede seccinpuedeasociarseaunscriptSECTIONparacolocarloenunreaparticulardememoria. Ladirectiva#pragmaudatasedebedeespecificarladireccindecomienzodelosdatosa almacenarenelpicyapartirdeestas,sernsecuencialesunadetrsdeotra.Supongamosque queremoscolocarlavariableLEDNUMBERaliniciodelbancoderegistrosnmero3,yportanto sedeberadeprogramaras: #pragmaudatamysection=0x300unsignedchar LED_Number; //8bitvariableunsignedint AnotherVariable; Aqumysectionesunaseccincondichonombreyqueempiezaenladireccin0x300ylos datosquevaarecibirserndeltipounsignedchar.LEDNumberserunavariableyseparadapor; lassiguientesvariables.Hayquedecirquenoeslomismoguardardatosde8bitsquede16como porejemploeltipodedatointegerqueesde16bitsloqueocupardosposicionesenlaseccin. Hastaahorahemosvistocomoseinsertandatosenelreaderegistros,yacontinuacin veremoscomometemosdatosenelreadeprograma. /**DECLARATIONS*******************************************/ //declareconstantdatainprogrammemorystartingataddress0x180 #pragmaromdataLesson3_Table=0x180 const rom unsigned char LED_LookupTable[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80}; #pragmacode //declareexecutableinstructions voidmain(void)

{ .. Podemosverdosdirectivasusadas: code:Laspropiasinstruccionesdelprograma.Compilarlasinstruccionesdelprogramaen lamemoriadeprogramadelpic. Romdata:Datosalmacenadosenlamemoriadeprograma.Sesueleusarconladirectiva romylosdatosserndeltipoconstante(nopuedenvariar)ycompiladosen espaciodememoriadeprograma. EnesteejerciciosevaautilizarunarraydedatosLED_LookupTableparaconvertirun nmerorepresentandolosleds07enunpatrndebitsparaconfigurarapropiadamenteelpuertoD que se denomina PORTD para poder encender un led tras otro. Por eso se utiliza un array constante,paraquelosdatosdedichoarraynocambienporculpadelprogramaoaccinindebida. Porlotanto,estaconstanteesdeclaradaenromdataseccinyusaromparahacerlaconstantey colocarlaenlapartedelamemoriadeprograma. LaseccinromdatahasidodeclaradatambinconunnombreLesson3_Tableyasignadaa unadireccin0X180. SeleccionaMPLABIDEProject>BuildAllparacompilarelejercicioydespusselecciona View>ProgramMemoryparavisualizarelcontenidocompiladodelamemoriadeprograma.

Observarcomoelladireccin0180estelarray(estinvertidoporelsistemadeprogramacin)se puedeobservar0201(invertidoser01/02)yel0804(04/08).... Sicolocamos#pragmacodeyacontinuacincolocamosmain(),elprogramasealmacenar enlaseccinindicadaenlamemoriadeprogramadelpic.Sinosehaespecificadoningunaseccin nitampocoladireccindeiniciodeprograma,elcompiladorcolocarelprogramaenlasiguiente seccindeprogramalibrequetengaelpic. Elprograma: /**VARIABLES*************************************************/ #pragmaudata unsignedcharLED_Number; //declarestaticallyallocateduninitializedvariables //8bitvariable

/**DECLARATIONS*******************************************/ //declareconstantdatainprogrammemorystartingataddress0x180 #pragmaromdataLesson3_Table=0x180 const rom unsigned char LED_LookupTable[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80}; #pragmacode //declareexecutableinstructions voidmain(void) { LED_Number=0; //initialize TRISD=0b00000000; //PORTDbits7:0arealloutputs(0) while(1) { //uselookuptabletooutputoneLEDonbasedonLED_Numbervalue LATD=LED_LookupTable[LED_Number]; LED_Number++; //rotatedisplayby1 if(LED_Number==8) LED_Number=0; //gobacktoLED0. Delay1KTCYx(50); //Delay50x1000=50,000cycles;200ms@1MHz } } InicializacindevariablesyI/Opuertos. Se configura trisd paraquetodas laspatitas del portd seansalidasylavariableglobal LED_Numbereselnumerodeledaencender. Primeroseinicializaconelvalor0en LED_Number ydespusseusacomoarray enel ndiceyelarraydevuelveelvalorporlaposicinqueleindicaLED_Number.Comoelvalorinicial deLED_Numberescero,elndicedelarrayescerotambin,porloquesuvaloradevolveresel primerdatodelarray,osea0x01.EstevaloresalmacenadoenellatchdelpuertoDquedandoen primerainstancialaformulaconelsiguientevalor: LATD=LED_lookupTable[LED_Number]siendosuvalorLATD=0x01 Seguimosyvemosqueahoraseincrementa LED_Number porloqueelprximovalora mostrarserelsiguiente(0x02).Secomparaelvalordelndice(LED_Number)porsisuvalores8, queencasodeafirmativovolveraaponeraLED_Numbera0(reset)oencasocontrarioejecutaun retardode200msyvuelvedenuevoalarrayindefinidamentehaciendogirarlosleds. Ejercicio4Rotaswitch Enesteejercicioseutilizaunswitchparahacerrotarlosledsdelejercicioanterior. Seutilizaladirectiva#defineyseasumequeellectoryasabeoporlomenosestfamiliarizado conellenguajeC. #definePin_SwitchPORTBbits.RB0 EstoharquecadavezquepongamosPin_SwitchelcompiladorlosustituyeporPORTBbits.RB0. Peroparaqueelcompiladorentiendaladirectiva#define sedebeincluirelarchivocabecera04 SwitchInput.h,veamoscomo: #include04SwitchInput.h

Existeunprogramaenaplicacionesqueusanlosswitchqueevitanelefectorebote.Esun efectoquealpulsarelswitch,rebotaloscontactoshaciendodeunapulsacinsimple,enuntrende pulsosqueprovocaraefectosindeseados.Supongamosquequeremoscontarlasvecesquepulsamos enelswitch,estealserpulsadounavezpodemosencontrarnosconlasorpresaquenuestrocontador puedacontar10100o3unidadesenvezdeuna,queeslaqueesperbamos. Paraevitaresteefectorebote,seaadeunretardode5ms,tiempomasquesuficientepara quelasealseaestableyeliminaremosdichoefecto.

Esteeselorganigramaparaevitardichoefecto.Observaqueesperaaquesepulseelswitch, cuandoesteespresionado,seincrementauncontadorycuandoestellegaa5entoncesdalasealde quesehapulsadodichoswitch.Encasodequeelcontadornohayallegadoa5serealizaunretardo de1msysevuelveaincrementarelcontadorhacindoselamismapreguntaunayotravezhasta quesecompletenlos5msquesercuandoelcircuitorealiceelorganigramaunas5vecesycada unadeellasde1ms. Elprograma: /**VARIABLES*************************************************/ #pragmaudata unsignedcharLED_Display; //declarestaticallyallocateduinitializedvariables //8bitvariable

/**DECLARATIONS*******************************************/ #pragmacode //declareexecutableinstructions voidmain(void) { unsignedcharSwitch_Count=0; LED_Display=1; //initializa TRISD=0b00000000; //PORTDbits7:0todassalidas(0) INTCON2bits.RBPU=0; //habilitaPORTBinternalpullupsresistencias WPUBbits.WPUB0=1; //enablepulluponRB0 ANSELH=0x00; //AN812aredigitalinputs(AN12onRB0) TRISBbits.TRISB0=1; //PORTBbit0(connectedtoswitch)isinput(1) while(1) { LATD=LED_Display; //enciendeelled LED_Display<<=1; //rotatedisplayby1 if(LED_Display==0) //rotatedbitout,sosetbit0 LED_Display=1;

while(Switch_Pin!=1); //waitforswitchtobereleased Switch_Count=5; do {//monitorswitchinputfor5lowsinarowtodebounceif (Switch_Pin==0) {//pressedstatedetected Switch_Count++; } else { Switch_Count=0; } Delay10TCYx(25); //delay250cyclesor1ms.} while(Switch_Count<DetectsInARow); Ojoalasvariables,yaquelavariableglobalsealmacenaenunregistrodelpicmientrasque lasvariableslocalessedestruyenalsalirdelafuncinquelacrea.As LED_Displayesglobal mientrasqueSwitch_Counteslocalysedestruyealfinalizarelprogramayaquesealmacenaenla piladelprograma. ElinterruptorestconectadoaRB0ycuandoesteespulsadosetiraamasa0porloque debeestarconresistenciaspulluphabilitadas yaquepuedeprovocarfallosdelecturasinose presiona dicho switch sin habilitar pullup del RB0. Pero esta patita comparte con la entrada analgicaAN12,esdecir,queelmismopinpuedeserdigitaloanalgico.Hayqueconfigurarlo comodigitalycomoentrada.Paraellovemoscomolohaceenelprograma: INTCON2bits.RBPU = 0; aqu podemos ver como configurar el registro INTCON2 el bit correspondientealpullupqueenestecasoesRBPUyloponemosacero. WPUBbits.WPUB0=1;Habilitamosaqu,elpullupdelRB0 ANSELH=0x00;ForzamosaquelasentradasanalgicasAN812seandigitalesponindolasa0. TRISBbits.TRISB0=1;ConfiguramosRB0comoentrada.

ObservalosregistrosAN812.Aquseusaunsistemaderotadodeledsmassimplequeenel ejercicioanteriorelcualusabaunatablaconunndiceparapodermostrarunpatrndebitsenla

salidayaparentareldesplazamiento.Enestecasousaremosalgomuchomassencillopararealizar elmismoefecto,enestecasosedesplazaelbitdemayorpesodeLED_Displayycomoesmostrado enLATDpuessemuestraenlasalida. LED_Display<<=1; Ejercicio5Temporizador En este ejercicio vamos a utilizar el temporizador TMR0 en vez de utilizar un bucle temporizado,dejandoaslibrealaCPUdedichoconteo,encargndosedelacuentaelTMR0. Veamossusregistrodeconfiguracin:

Elbit7activaonoeltemporizador. Elbit6seusaparaseleccionarentre8/16bits. Elbit5seleccionaentreentradaexternaociclosderelojinterno. Elbit4seusaparaactivarlacuentaenelflacodesubidadelasealoladebajada. Elbit0123seusanparaactivarelpreescaler(divisor)ysurangodedivisin.

ElTMR0eseltemporizador/contadordelafamilia18Fxxxxxqueutilizaelrelojinternoo losimpulsosexternosatravsdelapatitaTOCK1.Puederealizarcuentasde0255siseconfigura como 8 bits o, de 065535 si lo hace en modo 16 bits. Un bit de flag se activa cuando el temporizadorhallegadoarebasarlacuentayvuelvedenuevoacero. El preescaler se usa para generar una cuenta por cada impulso del reloj de entrada (recordemosquelafrecuenciainternaeslafrecuenciadeloscilador)ysielrangodelpreescaler esde1/8significaquedarunpulsoporcada8pulsosdereloj,sies1/16puescada16...... El preescaler se borra cuando se escribe en el temporizador, por lo que habr que configurarlocadavezqueseescribaeneltemporizador. Cuandoutilicemoseltemporizadorenmodo16bits,hayqueprestarespecialatencinyaque seusaneltemporizadorbajoyelaltoTMR0LyTMR0HubicadosenlazonaderegistrosSFRdel picyqueTMR0Leslebleyseescribe directamente,mientrasquelapartealtadelcontador TMR0Hnoesdirectamenteaccesible.EnsulugarseusaTMR0Hperoparapoderleerlo,primero debemosLEERELTMR0PRIMEROYDESPUESSEACTIVARTMR0HYPARAESCRIBIR ENELTEMPORIZADORPRIMEROSEESCRIBIRENTMR0HANTESQUETMR0L. Enelejerciciovamosatemporizarentre200y300msyvamosavercomohacemosestoa

travsdenuestropreescaler. HayqueconfigurarT0CONparaqueelresultadoseasatisfactorioyporelloenlatabla anteriorvemoscomoseconfiguranlosbitsdedichoregistro. Loponemosenmodo16bitsporloqueelbit6loponemosa0. Usaremoslosciclosinternosderelojporloqueelbit5sequedaa0. ComolatemporizacincoincideconeltiempoquequeramosnousaremoselbitPSAo bit numero 3 ya que 65536 x (1 / 250,000) = 262ms, es decir, si la cuenta del temporizadorllegaa65536ytardaencadaciclo1/250,000puesnosdalos262msque estdentrodenuestrorango. Elbit7seponea0yaquequedadesactivadoyseactivacadavezqueseescribeenel. Elrestodebitsnoimportasuconfiguracinporloqueeldatoaescribirdeformabinariaen elT0CONser0b0000100. Abrirelarchivo05Timer.cy05Timer.h.Enelarchivodecabecera.hpodemosencontrar lassiguientessentencias: typedefenum{LEFT2RIGHT,RIGHT2LEFT}LEDDirections; typedefenum{FALSE,TRUE}BOOL; Eltipodedatoenum,utilizaunnombreLEDDirectionsparaidentificarlosysoloadmitelos valoresqueestnentreparntesis,queenestecasoesLEFT2RIGHT,RIGHT2LEFT,esdecir,que siutilizamoslavariableLEDDirectios,susvaloresquepuedetomarsonestosdosynootros. QuizsleseamsfcillalineadelenumBOOLquelehemospuestoquesoloadmitacomo valoresFALSEYTRUE. Hayqueinicializarlascomocualquiervariablepero,soloconlosvaloresqueadmite.Ojo sontiposdevariablesnovariablesensi(comolosoninteger,char,double....).Veamoscomose inicializan: LEDDirectionsDirection=LEFT2RIGHT; BOOLSwitchPressed=FALSE; AqupodemosverquehemosdefinidounavariableDirectiondeltipoLEDDirectionsycon elvalorinicialLEFT2RIGHT(queeselvalorquedefinimoseneltipoenum).AsDirectionsolo puedetenerdosvaloresLEFT2RIGHTYRIGHT2LEFTnicamente. ParaeltipoBOOLhemosdefinidootravariablellamadaSwitchPressedysehainicializado conelvalorFALSE. LavariableDirectionserutilizadaparadeterminarladireccinderotacindelosledsyla variableSwitchpressedrecuerdaalprogramaquesehapresionadoelswitchelcualcambiarel sentidodelarotacindelosleds. //Inicializamoselcontador INTCONbits.TMR0IF=0; T0CON=0b00001000; //line1 //line2

//T0CON=0b00000001;(seignoraporelmomento) TMR0H=0; //line3 TMR0L=0; //line4 T0CONbits.TMR0ON=1; //line5 Estaeslapartedelprogramaqueinicializaeltemporizador,deshabilitalasinterrupciones

generadaporelmismoalsobrepasarlacuenta,escribeenelregistroT0CONelpatrndebitsa configurarparalatemporizacin,ascomolaescrituraeneltemporizadorenelordenpreferente siendoTMR0HlaprimeraenescribirseyluegoTMRL0laltima,yporltimohabilitamosel temporizador. Elprograma: //******************************************************************* //*SeeincludeddocumentationforLessoninstructions* //******************************************************************* /**CONFIGURATIONBITS******************************/ #pragmaconfigFOSC=INTIO67,FCMEN=OFF,IESO=OFF//CONFIG1H #pragmaconfigPWRT=OFF,BOREN=OFF,BORV=30//CONFIG2L #pragmaconfigWDTEN=OFF,WDTPS=32768//CONFIG2H #pragmaconfigMCLRE=ON,LPT1OSC=OFF,PBADEN=ON,CCP2MX=PORTC // CONFIG3H #pragmaconfigSTVREN=ON,LVP=OFF,XINST=OFF//CONFIG4L #pragmaconfigCP0=OFF,CP1=OFF,CP2=OFF,CP3=OFF//CONFIG5L #pragmaconfigCPB=OFF,CPD=OFF//CONFIG5H #pragmaconfigWRT0=OFF,WRT1=OFF,WRT2=OFF,WRT3=OFF//CONFIG6L #pragmaconfigWRTB=OFF,WRTC=OFF,WRTD=OFF//CONFIG6H #pragma config EBTR0 =OFF, EBTR1 = OFF,EBTR2 = OFF,EBTR3 =OFF // CONFIG7L #pragmaconfigEBTRB=OFF//CONFIG7H /**INCLUDES**************************************************/ #include"p18f45k20.h" //#include"delays.h"//nolongerbeingused. #include"05Timer.h"//headerfile /**VARIABLES*************************************************/ #pragmaudata //declarestaticallyallocateduinitializedvariables unsignedcharLED_Display; //8bitvariable /**DECLARATIONS*******************************************/ #pragmacode //declareexecutableinstructions voidmain(void) { LEDDirectionsDirection=LEFT2RIGHT; //esdeltipoenumenelarchivo.h BOOLSwitchPressed=FALSE; //tambindeltipoenumen.h LED_Display=1;//initializelavariableglobal //InitI/O TRISD=0b00000000; //PORTDbits7:0sontodassalidas(0) INTCON2bits.RBPU=0; //enablePORTBinternalpullups WPUBbits.WPUB0=1; //enablepulluponRB0 ANSELH=0x00;//AN812aredigitalinputs(AN12onRB0)paraconvertiradigitales TRISBbits.TRISB0=1;//PORTBbit0poneestacomoentrada. //InitTimer

INTCONbits.TMR0IF=0;//seborraelflagdecuentasobrepasada. T0CON=0b00001000;//Configuracindeltoconsinpreescaleer. //T0CON=0b00000001;//prescale1:4fourtimesthedelay. TMR0H=0;//borradodeltemporizadorpartealta TMR0L=0; //partebaja T0CONbits.TMR0ON=1;//comienzaatemporizar while(1) { if(Direction==LEFT2RIGHT)//recuerdaquesiinicializoconLEFT2RIGHT { LED_Display<<=1;//rotatedisplayby1from0to7 if(LED_Display==0) LED_Display=1;//rotatedbitout,sosetbit0 } if(Direction==RIGHT2LEFT) { LED_Display>>=1;//rotatedisplayby1from7to0 if(LED_Display==0) LED_Display=0x80;//rotatedbitout,sosetbit7 } LATD=LED_Display;//outputLED_DisplayvaluetoPORTDLEDs do {//compruebasielpulsadorestapulsado if(Switch_Pin==1)//recuerdaelelpulsadorseponeamasacuandosepulsa {//elpulsadornoestapulsado SwitchPressed=FALSE; } elseif(SwitchPressed==FALSE)//&&(Switch_Pin==0)duetoifelse {//elpulsadorestpresionado SwitchPressed=TRUE; //cambiaentoncesladireccin if(Direction==LEFT2RIGHT) Direction=RIGHT2LEFT;//aqucambialadireccinescribiendolocontrario. else Direction=LEFT2RIGHT; } }while(INTCONbits.TMR0IF==0);//serepitaelciclodowhilehastaTMR0llegueafin. //Timerexpired INTCONbits.TMR0IF=0;//ResetTimerflag } } EJERCICIO6 ELDEBUGGER Tenemosquedecir,queelpresenteejercicio,presentaporprimeravezelusodeldebugger usando para ello el programa anterior. Evidentemente su funcin es ver en tiempo real si los registros cambian, que valor tienen en un momento determinado.... etc. Esto es parecido al simuladorperoenestecasosereservaunreadememoriaenelmicrocontroladorparaefectuarel

debuggerodepuradordeprogramadeformaquesielcompiladorhizobiensutrabajo,dejeste reavacayreservadaparaestecometido. Elpickit3seusarcomoICDdebuggincircuityutilizarlosrecursosnoaccesiblesparael usuarioparadichocometidoenelpic. EnestecasolapatitaMCLR(mastercontrolreset)estreservadaparaelcometidoypor tantonosepodrusarniprogramarcomoentradaosalidaI/Onormal. LospinesPGCYPGDtampocoseusarancomopuertosI/Oyaquelosusaremosenel debuggin. Unreadelapiladememoriaseusaryportantonoaccesibleparaelusuario. Seutilizarunreadememoriadeprogramayderegistrosparaeldepuradoysequeda marcadoenelMPLABIDEcomounaR(reservado)yportanto,elusuarionopodrutilizar. Elpickit3nopuedeusarsecomodebuggerICDyprogramadoralmismotiempo,portanto siseusaeldebugger,elprogramadorsedesactiva.Debugger>SelectTool>2PICkit3esloque debemosdehacerparaseleccionarelpikit3comodebugger. Comenzamos: 1 2 3 4 EnlabarradeherramientasdelMPLABIDEseleccionamosDebugenvezde Release. Compilarelproyecto05(estoreservarenelpicelreaparasudebuggin). LoprogramamosDebugger>Program. Arrancamoseldebuggin.Debugger>Run.

Seobservaqueelpic18f45k20funcionacontotalnormalidad,peroestavezesten mododebuggin. Operacionesbsicas: HALTElprogramadelpic18f45k20sepuedepararencualquiermomento,sipulsamosF5 ovamosaDebugger>Halt.Semostrarunaflechaverdeindicadoelpuntodeparada. STEPSepermiteejecutarelprogrampasoapasodelassiguientesmaneras: STEPINTOseejecutapasoapasoperoalllegaraunafuncindellamadaseparay saltalaprimeralineadedichafuncin. STEPOVERseejecutapasoapasoyalllegaraunafuncindellamada,estaseejecuta enterayelsaltollegaalfinaldedichafuncioncall. STEPOUTseejecutapasoapasoyejecutasinpararlassubrutinas. RUNseejecutaelprogramahastaencontrarunpuntodebreakoseaparadoporelusuario conHALT. RESETSeejecutaDebugger>Processor>ResetSeejecutaunresetdelmicro,perosolosi el microcontrolador estaba previamente parado y por tanto empieza desde la primera instruccindeprograma. RESETSeejecutaconReset>ProcessorResetF6AlejecutarseMPLABIDEabreunnuevo archivoc018i.cinicializalapiladesoftwareCyasignatodoslosdatosdeinicializacinde variablespermitiendollevaralpicaunestadodejudicializacincompletayluegosaltaala instruccinmain()despusdeinicializarlasvariables. UsandopuntosdeParada. Lamejorformadeusarunpuntodeparadaparaqueelprogramaalejecutarse,seejecute bienyseparedondequeramos,esiralalineaquenosinteresayconelbotnsecundariodelratn pulsamos y ponemos el breakpoint ( Set breakpoint ), apareciendo un rombo rojo con una B indicandoqueahsepararelprograma.Realicemosconlalnea111oSwitchPressed=TRUE;y

talycomohemospuestoelpuntodeparadajustocuandosedebepresionarelbotn,elprograma continuayportantonosepara.Perosisepulsaelbotn,elprogramaquedarparadoporelbreak quehemoscolocado.

Elnmerodebreakpointsquesepuedeutilizardependemuchodelmicrocontroladorquese use,nuestropic18f45k20tiene3comomximo.SiabrimosDebugger>Breakpointspodemosver losbreakquesehanusadoylosmximosquepermitenuestropic(HWBP) EchandounvistazoalasvariablesyalosregistrosSFR. SepuedenverlosregistrosabriendoView>FileRegistersylosSFRconView>Special FunctionRegisters,sinembargonoserecomiendaquedichasventanasestnabiertasyaquese puedenleerdichosregistrosdesdelatarjetacuandoestenmodoRUNparadooenmodopasoa paso. Leer todos estos datos sobre el ICD BUS puede tomar un tiempo significativo debido principalmentealamemoraquecontengaelpic18f45k20ascomolavelocidaddesurelojinterno, asqueesmejorcerrarlasventanasdelosregistros. Lamejormaneradeverlosregistrosqueslointeresanesabriendounaventanallamada WatchyseabreView>Watch LosSFRquenosinterese, lo aadimos desde el campo seleccionablequeestmarcado en la figura de arriba como ADCON0ypulsandoelbotn ADD SFR de la misma ventana. Para nuestro ejercicio aadiremosPORTBYLATDyaquesonlosquehemosusadotantoparaelpulsadorcomoparala salidadelosleds. Lasvariablesquehemoscreadonosotroslaspodemosmonitorizarseleccionadolasdesdeel campoque nosquedaaladerecha(queenestecasomarca config)ypulsandoelbotn Add Symbol. AadiremosportantoparanuestroejercicioLED_Display,SwitchPressedyDirection.Ynos debedequedaralgoas:

RecordemosquenuestrasvariablesdeltipoenumcomosonDirectionySwitchPressedse mostraranenestecasocomovalornumricoynocomopalabrasescritas(let2righ,right2left....etc). ElformatodemuestradevaloresenelcampoValue,sepuedecambiarpinchandoconelratnyen Propertiesenelmenquenosaparece.

ConWatchpodemostambincambiarlosvaloresdelasvariablesyporsupuestoalcambiardicho valor, cambiar en realidad en el pic18f45k20 y por tanto si escribimos AA en el LATD se encendernlosledscorrespondientes. SeleccionaahoraPORTByseleccionasuspropiedadesybuscandoelformato,locambiamosa binario,pulsamosOKycerramoseldialogo.AhoraseverlainformacindePORTBenbinario conelbitdemaspesoalaizquierda(7). RealizamoselpasoapasopulsandoF8(stepover) queenestemodoseejecutalasubrutinay observaqueelPORTBdebetenerelswitch(PORTB0)a1yaquenosehapulsado,claroquesi pulsamoselbotnyejecutamosdenuevoconF8elvalorser0siemprequesemantengapulsado hastaqueseaejecutadalasubrutina.Recuerdasdondepusimoselpuntodebreak....

Comopodemosver,elpulsadorenestadonormales1porloquelasentenciaelseifnose cumpleysaltaaelretosdelprogramapordebajodeloscorchetes....Peroencasodequesise cumpla,separaralllegaralalinea111ydeberemospulsaroejecutarpasoapasoelprograma,ya quesehaquedadoenestadoHALT.PulsamosF8paraverelregistroPORTB0comocambiaa0. Practicaconelcdigoaadiendolosbreakpointsdondeteapetezcayobservalosregistro como cambian. Aade tambin TMR0L y TMR0H a la ventana WATCH y observa su comportamiento, sobre todo cuando estamos en modo paso a paso. Comprobar que no se incrementaporcadainstruccinyaquecadainstruccincompiladaenCcrearvariasinstrucciones en lenguaje ensamblador y el Timer0 es incrementado una vez por cada instruccin maquina ejecutada(noC).

También podría gustarte