UTILIZAÇÃO DO PICKit Flash Starter Kit da MIcrochip O PIC12F675 existente no kit de desenvolvimento é programado utilizando a ferramenta ilustrada na Figura 1. Após a geração do ficheiro que representa as instruções do nosso programa (ficheiro.hex), deve ser feito o Import HEX desse ficheiro. O ficheiro HEX é gerado automaticamente pelo MPLAB-IDE após compilação do programa. De seguida deve-se clicar no botão Write Device e esperar que a barra azul atinja a extremidade direita da janela e apareça a mensagem Write Successful (ver Figura 2). Finalizado o passo anterior, o kit encontra-se disponível para o teste do vosso programa! AVISO: não utilizem por enquanto nenhuma das outras opções da ferramenta. Figura 1. Ferramenta para programar o PIC12F675 do kit. Figura 2. Carregamento do ficheiro HEX no kit de desenvolvimento. 1. Primeiros exercícios O PIC12F675 executa a uma frequência aproximada de 4 MHz. Desactivem o WDT nos exemplos seguintes: 1
1. O nosso primeiro exemplo com o kit vai ser o exemplo desenvolvido numa das aulas anteriores e que tinha como objectivo pôr um LED a piscar com intervalos de 1 s. Neste exemplo será utilizado o LED D0. Na secção 4.1 é apresentada uma versão do programa. Contudo, falta afinar a rotina wait para que esta produza um atraso próximo de um segundo. 2. Altere o programa para que os LEDs D0 e D1 ascendam e apaguem alternadamente. De seguida experimente o último exemplo na situação em que o WDT está activado. O que acontece? Utilize o simulador para verificar o que se está a passar. Modifique o programa para que os LEDs pisquem convenientemente. 1.1 Explicação de como os LEDs se encontram ligados: Os 8 LEDs vermelhos (D0 a D7) da placa de desenvolvimento encontram-se ligados de acordo com a Figura 3 (RA1 corresponde ao porto de I/O GP1, RA2 ao porto GP2, etc.). A tabela da Figura 4 ilustra os níveis lógicos que são necessários aplicar aos portos GP5, GP4, GP2, e GP1, para apagar e acender um determinado LED. Esta topologia de ligações permite economizar no número de pinos de I/O necessários para controlar um LED de cada vez, e é utilizada também para ligar teclados. Com 4 pinos de I/O podemos controlar 12 LEDs. Figura 3. Esquema da montagem dos LEDs. Figura 4. Valores necessários para acender um determinado LED. Universidade do Algarve 2
2. Segundo conjunto de exercícios 3. No próximo exercício vamos considerar o caso em que utilizamos o botão SW1 (ligado ao pino de I/O RA3) para que, por cada toque no botão, o microcontrolador acenda o LED seguinte e apague o anterior (de D0 a D7). Na Figura 5 é apresentado um ASM Chart de uma solução possível [2]. Na secção 4.2 é apresentada uma versão do programa em que o teste ButtonPress() verifica apenas se o botão está premido ou não. Verifiquem o que acontece com esta versão. Identifiquem a causa para o que está a acontecer. Figura 5. ASM Chart retirado de [2] que representa o código assembly do exemplo. NOTA: em alguns interruptores existe um fenómeno designado por contact bounce e que ocorre sempre que um interruptor é accionado. Antes da posição de fechado ou de aberto os contactos fazem com que o sinal tenha oscilações durante um período de tempo logo após o botão ter sido premido ou largado (ver Figura 6). Muitas das vezes, este fenómeno é resolvido pela introdução de circuitos externos de filtragem. Outras vezes o sistema embebido não permite a adição de mais hardware e por isso o problema tem de ser resolvido por software. O fenómeno pode levar a que seja interpretado mais do que Universidade do Algarve 3
um premir no botão, quando na realidade o botão tinha sido premido uma única vez. Para solucionar o problema por software é necessário saber qual o período do contact bounce (usualmente esta informação é revelada pelo fabricante). Para o botão da placa utilizada vamos considerar que o período do contact bounce é inferior a 10 ms. Período do contact bounce Período do contact bounce 1 0 Figura 6. Modelo aproximado do sinal aos terminais do interruptor correspondente a um único premir do interruptor. 4. O que devem fazer na rotina ButtonPress() para que o programa anterior funcione? Realizem as alterações necessárias e testem o novo programa. 3. Referências 1. PICkit Flash Starter Kit v1.2, Microchip Technology Inc., http://www.microchip.com/download/tools/picmicro/demo/pickit/40244a.pdf 2. PICkit 1 FLASH Starter Kit User's Guide, Microchip Technology Inc., http://www.microchip.com/download/tools/picmicro/demo/pickit/40051c.pdf 3. PIC12F629/675 Data Sheet 8-Pin FLASH-Based 8-Bit CMOS Microcontrollers, Microchip Technology Inc., 2003, http://www.microchip.com/download/lit/pline/picmicro/families/12f6xx/41190c.pdf 4. Programas 4.1 Código Assembly para pôr a piscar o LED D0 ; Este programa põe o LED D0 a piscar com intervalos de X segundos. list p=12f675 ; list directive to define processor #include <p12f675.inc> ; processor specific variable definitions errorlevel -302 ; suppress message 302 from list file ; WDT disabled CONFIG _CP_OFF & _CPD_OFF & _BODEN_OFF & _MCLRE_OFF & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT ; WDT enabled ; CONFIG _CP_OFF & _CPD_OFF & _BODEN_OFF & _MCLRE_OFF & _WDT_ON & _PWRTE_ON & _INTRC_OSC_NOCLKOUT ; ' CONFIG' directive is used to embed configuration word within.asm file. ; The labels following the directive are located in the respective.inc file. ; See data sheet for additional information on configuration word settings. Universidade do Algarve 4
; define input/output designation for LEDs (what TRISIO will equal) #define TRIS_D0_D1 B'00001111' ; TRISIO setting for D0 and D1 ; define LED state (what GPIO will equal) #define D0_ON B'00010000' ; D0 LED ON #define D0_OFF B'00000000' ; D0 LED OFF ; utilizado para acender alternadamente D0 e D1 ;#define D1_ON B'00100000' ; D1 LED ON REG1 equ 20h REG2 equ 21h ; os valores seguintes permitem implementar 10000 ciclos de espera CNT1 equ d'255' CNT2 equ d'255' ;****************************** Start of Program ****************************** org 0x000 ; processor reset vector goto inicio inicio org 0x005 ; Start of Programm Memory Vector bsf STATUS,RP0 ; Bank 1 movwf OSCCAL ; update register with factory cal ; value movlw B'00111111' ; Set all I/O pins as inputs movlw B'10000000' ; Weak pullups: disabled movwf OPTION_REG clrf INTCON ; disable all interrupts, clear all ; flags bcf STATUS,RP0 ; Bank 0 clrf GPIO ; clear all outputs bsf STATUS,RP0 ; Bank 1 movlw TRIS_D0_D1 ; move predefined value to TRISIO ; programa principal: ciclo infinito loop ; Turns on D0 LED movlw D0_ON ; move predefined value to GPIO call wait ; espera aproximadamente 1 segundo ; Turns off D0 LED movlw D0_OFF ; move predefined value to GPIO call wait ; espera aproximadamante 1 segundo goto loop Universidade do Algarve 5
; sub-rotina time wait movlw CNT1 movwf REG1 lp1_1 decfsz REG1, F goto loop2 goto end_wait loop2 movlw CNT2 movwf REG2 lp2_1 decfsz REG2, F goto lp2_1 goto lp1_1 end_wait retlw 0 END 4.2 Código Assembly com o objectivo de acender incrementalmente os LEDs (de D0 a D7) à medida que se carrega no botão SW1 ;Description: ; This firmware implements a simple state machine. There are eight states: ; STATE1 = D0 LED on ; STATE2 = D1 LED on ; STATE3 = D2 LED on ; STATE4 = D3 LED on ; STATE5 = D4 LED on ; STATE6 = D5 LED on ; STATE7 = D6 LED on ; STATE8 = D7 LED on ; Press Switch 1 (SW1) on the PICkit(tm) demonstration board to cycle through ; the eight LED states. list p=12f629 ; list directive to define processor #include <p12f629.inc> ; processor specific variable definitions errorlevel -302 ; suppress message 302 from list file CONFIG _CP_OFF & _CPD_OFF & _BODEN_OFF & _MCLRE_OFF & _WDT_ON & _PWRTE_ON & _INTRC_OSC_NOCLKOUT ; ' CONFIG' directive is used to embed configuration word within.asm file. ; The labels following the directive are located in the respective.inc file. ; See data sheet for additional information on configuration word settings. ;************************** VARIABLE DEFINITIONS ****************************** STATE_LED EQU 0x20 ; LED state machine counter ;*************************** DEFINE STATEMENTS ******************************** ; input and output definitions #define SW1 GPIO,3 ; toggle switch ; define input/output designation for LEDs (what TRISIO will equal) #define TRIS_D0_D1 B'00001111' ; TRISIO setting for D0 and D1 Universidade do Algarve 6
#define TRIS_D2_D3 B'00101011' ; TRISIO setting for D2 and D3 #define TRIS_D4_D5 B'00011011' ; TRISIO setting for D4 and D5 #define TRIS_D6_D7 B'00111001' ; TRISIO setting for D6 and D7 ; define LED state (what GPIO will equal) #define D0_ON B'00010000' ; D0 LED #define D1_ON B'00100000' ; D1 LED #define D2_ON B'00010000' ; D2 LED #define D3_ON B'00000100' ; D3 LED #define D4_ON B'00100000' ; D4 LED #define D5_ON B'00000100' ; D5 LED #define D6_ON B'00000100' ; D6 LED #define D7_ON B'00000010' ; D7 LED ;****************************** Start of Program ****************************** org 0x000 ; processor reset vector goto Initialize ; Initialize ; Initialize Special Function Registers org 0x005 ; Start of Programm Memory Vector Initialize bsf STATUS,RP0 ; Bank 1 movwf OSCCAL ; update register with factory cal ; value movlw B'00111111' ; Set all I/O pins as inputs movlw B'10000001' ; Weak pullups: disabled movwf OPTION_REG ; TMR0 prescaler: 1:64 (TMR0 will ; overflow in 10.6ms) clrf INTCON ; disable all interrupts, clear all ; flags bcf STATUS,RP0 ; Bank 0 clrf GPIO ; clear all outputs clrf TMR0 ; clear Timer 0 clrf STATE_LED ; clear LED state machine counter ; State_Machine ; Implements a state machine that lights up the LEDs on the PICkit board ; sequentially when SW1 is pressed. State_Machine clrwdt ; clear Watch Dog Timer call Button_Press ; Increments STATE if button is pressed movf STATE_LED, w ; Mask out the high order bits of andlw B'00000111' ; STATE_LED addwf PCL, f ; The program clock (PCL) is incregoto State0 ; mented by STATE_LED in order goto State1 ; to go to the appropiate routine goto State2 goto State3 goto State4 goto State5 Universidade do Algarve 7
goto goto State6 State7 State0 ; Turns on D0 LED movlw TRIS_D0_D1 ; move predefined value to TRISIO movlw D0_ON ; move predefined value to GPIO State1 ; Turns on D1 LED movlw TRIS_D0_D1 ; move predefined value to TRISIO movlw D1_ON ; move predefined value to GPIO State2 ; Turns on D2 LED movlw TRIS_D2_D3 ; move predefined value to TRISIO movlw D2_ON ; move predefined value to GPIO State3 ; Turns on D3 LED movlw TRIS_D2_D3 ; move predefined value to TRISIO movlw D3_ON ; move predefined value to GPIO State4 ; Turns on D4 LED movlw TRIS_D4_D5 ; move predefined value to TRISIO movlw D4_ON ; move predefined value to GPIO State5 ; Turns on D5 LED movlw TRIS_D4_D5 ; move predefined value to TRISIO movlw D5_ON ; move predefined value to GPIO Universidade do Algarve 8
State6 ; Turns on D6 LED movlw TRIS_D6_D7 ; move predefined value to TRISIO movlw D6_ON ; move predefined value to GPIO State7 ; Turns on D7 LED movlw TRIS_D6_D7 ; move predefined value to TRISIO movlw D7_ON ; move predefined value to GPIO ; Button_Press ; Looks for button press Button_Press btfsc SW1 ; Is Switch 1 pushed? retlw 0 ; No, then return incf STATE_LED, f ; machines. retlw 0 end ; directive 'end of program' Universidade do Algarve 9