Вы находитесь на странице: 1из 203

www.mecatronicadegaragem.blogspot.

com

DETUA
Departamento de Electrnica e Telecomunicaes
Universidade de Aveiro

Microcontroladores PIC

Guia de Trabalhos Prticos do Professor

Jos Miguel Oliveira Gaspar <a20042@alunos.det.ua.pt>


Olmpia Rodrigues <a17510@alunos.det.ua.pt>

Alunos de seminrio da Licenciatura em Ensino de Electrnica e Informtica


ltima Reviso
4 de Maio de 2006
www.mecatronicadegaragem.blogspot.com
www.mecatronicadegaragem.blogspot.com

Guia realizado sob a orientao do


Prof. Doutor Jos Lus Azevedo <jla@det.ua.pt>
Prof. Auxiliar do Departamento de
Electrnica e Telecomunicaes da Universidade de Aveiro
www.mecatronicadegaragem.blogspot.com
www.mecatronicadegaragem.blogspot.com

Resumo

A elaborao deste guia insere-se no mbito do seminrio da Licenciatura em Ensino de Electr-


nica e Informtica. A motivao do trabalho vm ao encontro da lacuna documental existente sobre
microcontroladores no mbito da disciplina de Sistemas Digitais do ensino secundrio, por forma
minimizar a falta de recursos foram desenvolvidos dois guias de trabalhos prticos sobre microcon-
troladores, um para cada, aluno e professor.
Para o efeito escolheu-se um microcontrolador da famlia 16F87X da Microchip, para a realizao
dos diversos trabalhos prticos

iii
www.mecatronicadegaragem.blogspot.com

Agradecimentos

O nosso agradecimento vai para todos aqueles que connosco colaboraram para que este guia fosse
uma realidade. Em especial aos colegas da sala 317 que em muito contriburam durante todo o semi-
nrio.
www.mecatronicadegaragem.blogspot.com

Contedo

Resumo iii

Contedo ix

Lista de Figuras xii

Lista de Tabelas xiii

Introduo 1

1 Enquadramento geral . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

1.1 Trabalhos prticos a realizar . . . . . . . . . . . . . . . . . . . . . . . . . . 1

2 Algumas caractersticas do PIC16F876 . . . . . . . . . . . . . . . . . . . . . . . . . 3

3 Hardware - Placa PIC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

TP0 - Introduo ao Assembly e MPLAB IDE 5

1 Resumo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

2 Objectivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

3 Descrio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

3.1 Ambiente de desenvolvimento MPLAB IDE . . . . . . . . . . . . . . . . . 5

4 Trabalho a Realizar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

4.1 Criao de um projecto no MPLAB IDE . . . . . . . . . . . . . . . . . . . 8

4.2 Traduo do cdigo fonte em cdigo mquina . . . . . . . . . . . . . . . . . 10

4.3 Programao do PIC16F876 atravs da linha srie . . . . . . . . . . . . . . 11

4.4 Estrutura base de um programa em Assembly . . . . . . . . . . . . . . . . . 12

v
www.mecatronicadegaragem.blogspot.com

Guio Prtico Sobre micro-controladores PIC

4.5 Anlise do programa exemplo . . . . . . . . . . . . . . . . . . . . . . . . . 13

TP1 - Entrada/Sada 15

1 Resumo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

2 Objectivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

3 Descrio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

3.1 Registos TRIS e PORT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

3.2 Inicializao dos portos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

4 Trabalho a realizar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

5 Implementao em Assembly do PIC . . . . . . . . . . . . . . . . . . . . . . . . . . 20

5.1 Ponto 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

5.2 Ponto 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

5.3 Ponto 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

TP2 - Descodificador Hexadecimal / 7Seg, 1 display 31

1 Resumo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

2 Objectivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

3 Descrio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

3.1 Endereamento Indirecto, Registo FSR e INDF . . . . . . . . . . . . . . . . 31

3.2 Seleco do Banco de Memria . . . . . . . . . . . . . . . . . . . . . . . . 33

4 Trabalho a realizar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33

5 Implementao em Assembly do PIC . . . . . . . . . . . . . . . . . . . . . . . . . . 35

5.1 Ponto 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

5.2 Ponto 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39

TP3 - Descodificador Hexadecimal / 7Seg, 3 Displays 43

1 Resumo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

2 Objectivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

3 Descrio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

4 Trabalho a realizar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44

vi
www.mecatronicadegaragem.blogspot.com

ndice de Contedos

4.1 Descrio do registo STATUS . . . . . . . . . . . . . . . . . . . . . . . . . 45

5 Implementao em Assembly do PIC . . . . . . . . . . . . . . . . . . . . . . . . . . 47

TP4 Contador de 60 segundos, verso I 53

1 Resumo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53

2 Objectivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53

3 Descrio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53

3.1 Rotina Delay . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54

4 Trabalho a realizar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56

5 Implementao em Assembly do PIC . . . . . . . . . . . . . . . . . . . . . . . . . . 59

5.1 Ponto 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59

5.2 Ponto 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64

5.3 Ponto 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71

TP5 Relgio de 60 segundos, verso II 79

1 Resumo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79

2 Objectivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79

3 Descrio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79

3.1 Timer 0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80

3.2 Registo OPTION_REG . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82

3.3 Registo INTCON . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83

4 Trabalho a realizar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84

5 Implementao em Assembly do PIC . . . . . . . . . . . . . . . . . . . . . . . . . . 85

TP6 Semforo rodovirio(automveis/pees) 91

1 Resumo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91

2 Objectivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91

3 Descrio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91

3.1 Diagrama de estados - Semforo rodovirio . . . . . . . . . . . . . . . . . . 92

4 Trabalho a realizar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93

vii
www.mecatronicadegaragem.blogspot.com

Guio Prtico Sobre micro-controladores PIC

5 Implementao em Assembly do PIC . . . . . . . . . . . . . . . . . . . . . . . . . . 95

TP7 - Relgio 60 segundos, verso III 101

1 Resumo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101

2 Objectivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101

3 Descrio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101

3.1 Led pisca-pisca com boto ON/OFF por interrupo . . . . . . . . . . . . . 102

4 Trabalho a realizar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104

5 Implementao em Assembly do PIC . . . . . . . . . . . . . . . . . . . . . . . . . . 106

5.1 Ponto 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106

5.2 Ponto 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113

5.3 Ponto 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120

TP8 USART Universal Synchronous Asynchronous Receiver Transmitter 127

1 Resumo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127

2 Objectivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127

3 Descrio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127

3.1 Configurao dos pinos de transmisso/recepo . . . . . . . . . . . . . . . 128

3.2 Taxa de transmisso da USART . . . . . . . . . . . . . . . . . . . . . . . . 128

3.3 Operao de transmisso . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129

3.4 Operao de recepo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130

3.5 Registo TXSTA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131

3.6 Registo RCSTA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132

4 Trabalho a realizar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133

5 Implementao em Assembly do PIC . . . . . . . . . . . . . . . . . . . . . . . . . . 134

5.1 Ponto 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134

5.2 Ponto 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137

5.3 Ponto 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140

TP9 ADC - Converso Analgica / Digital 145

viii
www.mecatronicadegaragem.blogspot.com

ndice de Contedos

1 Resumo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145

2 Objectivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145

3 Descrio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145

3.1 Entrada Analgica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145

3.2 Resultado da converso A/D . . . . . . . . . . . . . . . . . . . . . . . . . . 146

3.3 Mecanismo de aquisio da ADC . . . . . . . . . . . . . . . . . . . . . . . 147

3.4 Etapas na programao da ADC (polling) . . . . . . . . . . . . . . . . . . . 148

3.5 Registo ADCON0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149

3.6 Registo ADCON1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150

4 Trabalho a realizar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151

5 Implementao em Assembly do PIC . . . . . . . . . . . . . . . . . . . . . . . . . . 153

5.1 Ponto 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153

5.2 Ponto 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161

5.3 Ponto 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168

Apendix A 177

Apendix B 179

ix
www.mecatronicadegaragem.blogspot.com

Guio Prtico Sobre micro-controladores PIC

x
www.mecatronicadegaragem.blogspot.com

Lista de Figuras

1 Disposio dos componentes na placa de CI DETUA . . . . . . . . . . . . . . . . . 4

2 Esquema da placa PIC DETUA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

3 Janela associada ao processo de simulao de um programa no MPLAB IDE . . . . . 7

4 Projecto em MPLAB IDE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

5 Visualizao de janelas de informao memria do PIC . . . . . . . . . . . . . . . . 8

6 fase 1 - criao de um novo projecto . . . . . . . . . . . . . . . . . . . . . . . . . . 8

7 fase 2 - seleco do microcontrolador. . . . . . . . . . . . . . . . . . . . . . . . . . 9

8 Adicionar um ficheiro fonte existente ou criar um novo. . . . . . . . . . . . . . . . . 9

9 Traduo do cdigo fonte em cdigo mquina. . . . . . . . . . . . . . . . . . . . . . 10

10 WinPIC Loader . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

11 Configurao de uma linha em E/S . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

12 Diagrama do circuito, led on/off. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

13 Diagrama temporal da sada temporizada . . . . . . . . . . . . . . . . . . . . . . . . 18

14 Diagrama do circuito para o contador up/down . . . . . . . . . . . . . . . . . . . . . 19

15 Acesso memria . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

16 Endereamento Indirecto cdigo de demonstrao . . . . . . . . . . . . . . . . . . . 32

17 Seleco do banco de memria . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33

18 Diagrama do circuito, 1 display de 7 segmentos . . . . . . . . . . . . . . . . . . . . 34

19 Processo de refrescamento dos displays . . . . . . . . . . . . . . . . . . . . . . . . 44

20 Seleco dos bancos de memria RAM. . . . . . . . . . . . . . . . . . . . . . . . . 45

21 Diagrama de fluxo da rotina Delay . . . . . . . . . . . . . . . . . . . . . . . . . . . 54

22 Diagrama do circuito para para visualizao do valor 0x60 . . . . . . . . . . . . . 56

xi
www.mecatronicadegaragem.blogspot.com

Guio Prtico Sobre micro-controladores PIC

23 Diagrama do circuito, exemplifica a passagem de 60 59 . . . . . . . . . . . . . 57

24 Diagrama do circuito, exemplifica o trmino da contagem . . . . . . . . . . . . . . . 57

25 Diagrama do circuito com sw, antes de se pressionar no boto . . . . . . . . . . . . . 58

26 Diagrama do circuito com sw, aps pressionar no boto . . . . . . . . . . . . . . . . 58

27 registo contador de 8 bits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79

28 Diagrama de blocos do timer 0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80

29 Semforo rodovirio (automveis/pees) . . . . . . . . . . . . . . . . . . . . . . . . 91

30 Diagrama de estados do trabalho prtico . . . . . . . . . . . . . . . . . . . . . . . . 92

31 Diagrama do circuito, semforo rodovirio . . . . . . . . . . . . . . . . . . . . . . . 93

32 Exemplo de uma interrupo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102

33 Diagrama do circuito, interrupo do RBO/INT . . . . . . . . . . . . . . . . . . . . 104

34 Atribuio do porto srie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128

35 Operao de transmisso assncrona . . . . . . . . . . . . . . . . . . . . . . . . . . 129

36 Operaco de recepco assncrona . . . . . . . . . . . . . . . . . . . . . . . . . . . 130

37 Ligao srie entre o PIC e o Computador . . . . . . . . . . . . . . . . . . . . . . . 133

38 ADC, entradas analgicas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146

39 Formato do resultado de 10 bits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146

40 Mecanismo de aquisio da ADC . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147

41 Diagrama do circuito do voltmetro digital, visualizao com displays 7 segmentos . 151

42 Diagrama do circuito do voltmetro digital, visualizao terminal srie . . . . . . . . 151

43 Mapa de memria RAM, registos do PIC e registos de uso geral . . . . . . . . . . . 177

xii
www.mecatronicadegaragem.blogspot.com

Lista de Tabelas

1 Descrio dos temas a abordar. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

2 HEX 7 segmentos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

3 Descrio do estado dos leds . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92

4 Tempo minmo entre estados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93

5 Taxa de transmisso em modo assncrono (BRGH = 1) . . . . . . . . . . . . . . . . 128

xiii
www.mecatronicadegaragem.blogspot.com
www.mecatronicadegaragem.blogspot.com

Introduo

1 Enquadramento geral

Os trabalhos prticos apresentados neste guia foram organizados de modo a que o aluno adquira, numa
perspectiva evolutiva, conceitos fundamentais associados programao de microcontroladores.
Cada um dos trabalhos d nfase ao desenvolvimento de uma temtica especfica, podendo cada
um deles ser realizado independentemente um dos outros. Contudo, para um aluno sem experin-
cia prvia que utilize a programao de microcontroladores aconselhvel que os trabalhos sejam
realizados pela ordem em que so apresentados, resultando esta recomendao em dois aspectos fun-
damentais: a) os trabalhos esto organizados com um grau de dificuldade crescente, sendo importante
que os conceitos a abordados, sejam compreendidos, antes de se passar aos seguintes; b) o cdigo
realizado num dado trabalho possa ser reaproveitado em trabalhos posteriores.

1.1 Trabalhos prticos a realizar

Trabalho Durao Descrio


0 1 aula Familiarizao c/ a linguagem assembly e ambiente de desenvolvimento MPLAB
1 3 aulas Entrada/Sada - Configurao dos portos do PIC
2 1 aula Implementao de uma lookup table
3 2 aulas Implementao de um sistema de visualizao por multiplexagem no tempo
4 2 aulas Contagem de tempo por contagem de instrues
5 1 aula Contagem de tempo com recurso a timers
6 2 aulas Implementao de uma mquina de estados
7 3 aulas Programao com interrupes (Interrupt driven I/O)
8 2 aulas Comunicao srie assncrona (USART)
9 4 aulas Converso Analgia Digital (ADC)

Tabela 1: Descrio dos temas a abordar.

A tabela 1 fornece uma curta descrio dos temas a abordar em cada trabalho prtico. O primeiro
trabalho prtico TP0 tem como principal objectivo a familiarizao com a linguagem assembly e o
ambiente de desenvolvimento MPLAB IDE. Com este trabalho pretende-se que o aluno tome conheci-
mento das potencialidades que ambiente de desenvolvimento disponibiliza na realizao dos trabalhos

1
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

futuros; o trabalho seguinte TP1, continua com a familiarizao do aluno com novos conceitos, desta
vez a familiarizao do aluno com a linguagem assembly do PIC para programao dos portos de
entrada e sada na leitura e escrita de dados.
No trabalho prtico 2, TP2, pretende-se que o aluno adquira os conhecimentos necessrios de
modo a compreender o acesso a variveis na memria RAM por endereamento indirecto. Para tal,
pretende-se implementar um descodificador hexadecimal / 7 segmentos atravs de um nico display.
No seguimento deste trabalho, surge o trabalho 3 (TP3), em que se pretende uma ampliao do
trabalho anterior a 3 displays de 7 segmentos, com o objectivo de construir um programa que permita a
visualizao de dados nos displays, recorrendo ao refrescamento destes por multiplexagem no tempo.
No trabalho prtico seguinte (TP4), recorre-se a contagem de tempo por contagem de instrues,
usando para tal uma rotina de contagem de tempo por contagem de instrues (rotina Delay).
O trabalho prtico 5 (TP5), tem como um objectivo principal a introduo programao do timer
0 do PIC. Com este, vai-se poder alargar a gama de contagem de tempo, algo que com a utilizao da
rotina Delay no possvel.
Com o trabalho 6 (TP6), pretende-se construir uma mquina de estados que implementa um se-
mforo rodovirio para pees e automveis, com o objectivo de aprofundar os conhecimentos acerca
do timer 0.
Nos trabalhos prticos 4 e 5 implementou-se um relgio de 60seg recorrendo rotina Delay e
timer 0, respectivamente. Ambos implementados recorrendo transferncia de informao por pol-
ling. Durante o trabalho 7 (TP7) pretende-se implementar novamente um relgio, recorrendo agora
transferncia de informao por interrupo. Para isso necessria a compreenso do conceito de
interrupo de um programa.
Com o grau de dificuldade a crescer, os dois ltimos trabalhos reflectem essa complexidade nos
conceitos a adquirir. Assim, o trabalho 8 (TP8) tem como objectivo, a comunicao srie entre um
computador (anfitrio) e o PIC, elaborando para tal um programa que implemente um terminal srie,
recorrendo a rotinas para envio e recepo de caracter ou caracteres.
Por fim, o trabalho 9 (TP9) tem como objectivo principal a introduo converso A/D, im-
plementando para esse fim 2 trabalhos: um voltmetro digital bsico, e um sistema de medio de
distncias recorrendo a um sensor infravermelhos.

2
www.mecatronicadegaragem.blogspot.com

Introduo

2 Algumas caractersticas do PIC16F876

O PIC16F876, fabricado com a tecnologia CMOS dispe de:

Processador RISC (Reduce Instrution Set Computer)

35 instrues de 14 bits;
Frequncia mxima de funcionamento - 20Mhz (frequncia do cristal);
Cada ciclo de relgio corresponde frequncia do cristal / 4 = 5Mhz, efectuando a cada
segundo 5 MIPS (milhes de instrues por segundo);
Tempo de execuo das instrues normais: 1 ciclo de relgio;
Tempo de execuo das instrues de salto condicional (decfsz, incfsz, btfss, btfsc), quando
a executada a instruo de salto: 2 ciclos de relgio;
Tempo de execuo de instrues de salto incondicional (goto): 2 ciclos de relgio.

As seguintes caractersticas da memria;

Memria de programa (FLASH) de 8K (words) de 14 bits;


Cada instruo codificada numa word de 14 bits;
Memria de dados RAM de 368 bytes;
Memria de dados EEPROM de 256 bytes;
Stack de 8 nveis.

As seguintes caractersticas de perifricos:

22 linhas de entrada/sada, agrupadas em 3 portos (PORTA 6 linhas, PORTB e PORTC


8 linhas);
3 timers, 2 de 8 bits e 1 de 16 bits;
Conversor analgico digital de 10 bits, com um mximo de 5 canais de entrada anal-
gica;
USART (Universal Synchronous Asynchronous Receiver Transmitter);
13 tipos de interrupes, por exemplo externa RB0/INT, TMR0 timer overflow.

3 Hardware - Placa PIC

No propsito do guio descrever o funcionamento da placa PIC, este feito no site da disciplina.
Neste pode-se encontrar todas as informaes relevantes sobre o layout e funcionamento da placa.
Contudo para que o aluno/professor se se enquadrem com o hardware apresenta-se nas pginas se-
guintes o esquema elctrico do circuito bem como a disposio dos componentes na placa de circuito
impresso.

3
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

Figura 1: Disposio dos componentes na placa de CI DETUA

Figura 2: Esquema da placa PIC DETUA

4
www.mecatronicadegaragem.blogspot.com

TP0 - Introduo ao Assembly e MPLAB IDE


Tema a desenvolver Durao
Familiarizao com o Assemly e MPLAB IDE 1 aula

1 Resumo

Pretende-se mostrar com este trabalho os passos necessrios criao de um projecto no ambiente de
desenvolvimento MPLAB IDE (programa de software destinado a desenvolver aplicaes para micro-
controladores da Microchip) e traduo para cdigo mquina do cdigo fonte associado, recorrendo
a um pequeno exemplo em linguagem Assembly. Mostra-se ainda, o processo de programao do
PIC16F876 atravs da linha srie.

2 Objectivos

Criao de um projecto no ambiente de desenvolvimento MPLAB IDE.


Conhecer o processo de traduo de cdigo fonte para cdigo mquina.
Conhecer o processo de programao do microcontrolador atravs do WinPIC Loader.
Introduo programao em linguagem Assembly.

3 Descrio

3.1 Ambiente de desenvolvimento MPLAB IDE

O MPLAB IDE um ambiente de desenvolvimento integrado que permite a edio, o debugging e a


traduo para cdigo mquina de programas em linguagem Assembly. Disponibiliza essencialmente,
as seguintes ferramentas:

Editor com reconhecimento das instrues do PIC e directivas do Assembler em syntax high-
light.
Visualizao dos registos (memria RAM), da memria de programa e da EEPROM .
MPLAB SIM, simulador de eventos, com as seguintes caractersticas:
Possibilidade de alterao do cdigo fonte do programa, permitindo a sua re-execuo
imediata;

5
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

Possibilidade de modificao dos valores dos registos e posies de memria do PIC em


intervalos de tempo pr determinados.
Possibilidade de modificao do valor lgico presente nas entradas do PIC.
Simulao da evoluo do programa atravs da criao de um cenrio de estmulos exter-
nos.

No desenvolvimento inicial de um programa, muito provvel que este contenha erros de con-
cepo que o impedem de realizar correctamente as tarefas para o qual foi projectado. Se porventura
isso acontecer, necessrio voltar a analisar o cdigo, de modo a encontrar a origem dos problemas.
Em programas com alguma complexidade este processo lento, e muitas vezes ineficiente, dado que
necessrio carregar vrias vezes o programa no PIC, de modo a testar o seu funcionamento. Este
um dos casos em que o simulador de software MPLAB SIM til uma vez que permite simular
o programa no PC, como se este estivesse a ser executado no PIC. Outra das vantagens da utilizao
do simulador a possibilidade da criao a priori de cenrios de teste que servem de entrada para o
simulador. A figura 3 mostra a janela associada ao processo de simulao do programa exemplo.
O ambiente de edio do projecto do programa exemplo mostrado na figura 4. A janela lo-
calizada no canto superior esquerdo representa o Project Manager, que contm as referncias aos
ficheiros que compem o projecto; logo abaixo desta, temos o Memory Usage Gauge, que mostra a
informao da quantidade de memria do programa e dados usada; no lado direito temos o editor;
finalmente abaixo encontra-se a janela de output (sada), que fornece informaes sobre o estado do
programa aquando da traduo de cdigo Assembly para cdigo mquina.
No MPLAB IDE, a visualizao da memria (ver figura 5) feita atravs das seguintes janelas:

Program Memory mostra os endereos de memria o Opcode e a mnemnica correspondente


do programa, alocados dentro da gama de memria disponvel para o processador seleccionado.
Se o PIC seleccionado suportar memria externa, e se esta estiver activa, a mesma tambm ser
visualizada.
File Register mostra todos os registos do dispositivo seleccionado (corresponde memria
RAM do PIC).
EEPROM mostra a memria de dados EEPROM para qualquer microcontrolador que disponha
deste tipo de memria (por exemplo o PIC16F876).

6
www.mecatronicadegaragem.blogspot.com

TP0 - Introduo ao Assembly e MPLAB IDE

Figura 3: Janela associada ao processo de simulao de um programa no MPLAB IDE

Figura 4: Projecto em MPLAB IDE

7
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

Figura 5: Visualizao de janelas de informao memria do PIC

4 Trabalho a Realizar

4.1 Criao de um projecto no MPLAB IDE

1. Uma vez aberto o programa MPLAB IDE, na rea de trabalho, selecciona-se no menu principal
Project New.

2. Quando a dialog box New Project surgir introduz-se no campo Project Name exemplo, e
no campo Project Directory c:\aulas\exemplo (ver figura 6).

Figura 6: fase 1 - criao de um novo projecto .

8
www.mecatronicadegaragem.blogspot.com

TP0 - Introduo ao Assembly e MPLAB IDE

3. Escolha do microcontrolador associado ao projecto: ir ao menu Configure Select Device ...


seleccionar o PIC16F876 e clicar OK (ver figura 7).

Figura 7: fase 2 - seleco do microcontrolador.

4. Ao projecto que acabou de se criar, associa-se agora o ficheiro com o cdigo fonte do programa;
se este no existir cria-se um novo (para criar um novo clicar em File New). Antes de iniciar
o processo de edio, deve-se guardar o ficheiro com a extenso ".asm", de modo a activar
a funcionalidade syntax highlight (menu File Save As... guardando o ficheiro no directrio
c:\aulas\exemplo criado anteriormente). Neste exemplo o cdigo fonte j se encontra
num ficheiro no directrio do projecto. Este ficheiro pode ser adicionado ao projecto clicando
com o boto direito do rato em cima de Source Files Add Files... (ver figura 8(b)).

(a) Novo ficheiro. (b) Adicionar ficheiro.

Figura 8: Adicionar um ficheiro fonte existente ou criar um novo.

9
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

5. Dado que o projecto usa oMPlink, necessrio associar-se um linker script; este ficheiro define
os comandos do linker para cada PIC, especificando o seguinte:

Regies de memria de dados e programa do PIC.

Mapeamento de seces lgicas no cdigo fonte, em regies de programa e dados.

Esto disponveis ficheiros originais de script para todos os PIC, localizados por defeito no
seguinte directrio: c:\Program Files\Microchip\MPASM Suite\LKR. Para adi-
cionar o ficheiro pretendido, clicar com o boto direito do rato em cima de Script Files Add
Files....

4.2 Traduo do cdigo fonte em cdigo mquina

1. Aps a edio do cdigo fonte em Assembly do programa passa-se fase de traduo do cdigo
fonte em cdigo mquina. Para isso clica-se no cone Build All disponvel na toolbar do
ambiente de desenvolvimento. No caso de o programa no apresentar erros de syntax, o grfico
de sada que mostra a evoluo da compilao ficar completo a 100% e de cor verde; caso
contrrio ficar vermelho, o que indica a existncia de um ou mais erros.
Na ausncia de erros de syntax, criado o ficheiro de sada que tem como nome principal o
nome do projecto com extenso ".hex".

(a) Evoluo do assembling. (b) Ocorreu um erro.

Figura 9: Traduo do cdigo fonte em cdigo mquina.

10
www.mecatronicadegaragem.blogspot.com

TP0 - Introduo ao Assembly e MPLAB IDE

4.3 Programao do PIC16F876 atravs da linha srie

Aps a traduo bem sucedida do cdigo fonte em cdigo mquina, passa-se fase de programao
do PIC. Para tal, necessrio que, previamente, tenha sido instalado no PIC um pequeno programa
(o boot-loader) que gere a comunicao com o computador de desenvolvimento e que escreve o
programa na memria Flash.

O que o boot-loader?

O boot-loader um programa que permite re-programar o PIC sem ter de o retirar do circuito onde
est montado e sem ter que recorrer a um programador ( i.e., a um aparelho para programar os PICs ).

Como funciona?

O boot-loader funciona em conjunto com um programa que corre no PC, designado por WinPIC
Loader ( disponvel para DOS / Windows / Linux ) que controla o envio de um ficheiro em formato
Intel Hex para o PIC.
Sempre que o PIC ligado, inicia-se a execuo do boot-loader. Este comea por inquirir o PC
sobre o que fazer. Se no obtm resposta dentro de um tempo limite e se existir um programa vlido
na memria do PIC, ento o boot-loader inicia a execuo desse programa. No caso em que obtm
uma resposta vlida, inicia o processo de transferncia e armazenamento de um novo programa.

Como re-programar?

1. Compilar o programa que se pretende transferir para o PIC usando o MPLAB. O compilador
produz um ficheiro em formato Intel Hex ( extenso ".hex").
2. Executar o programa WinPIC Loader, clicar em File Open seleccionar o ficheiro ".hex"
respectivo, clicar OK.
3. Premir o boto de reset da placa PIC. A transferncia e programao iniciam-se de imediato. A
progresso assinalada na janela WinPIC Loader no campo, Progress:.
4. Finalmente, para executar o programa, premir novamente o boto de reset da placa PIC.

Figura 10: WinPIC Loader

11
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

4.4 Estrutura base de um programa em Assembly


list p=16f876 ; - directiva "list", define
; o processador a usar
radix decimal ; - directiva "radix" especifica
; a definio das variveis
#include "p16f876.inc" ; - directiva "include" inclui
; ficheiro adicional

;------------ Definio de constantes -------------------------------

;------------ Definio de variveis --------------------------------

;------------ Definio de macros -----------------------------------

;====================================================================
;
ORG 0x0000 ; - directiva "ORG" origem do
; programa "ORG 0x0000" vector
; de reset
clrf PCLATH ; - instruo "clrf PCLATH" apaga
; todos os bits do registo garante
; que a memria do programa
; iniciada na pgina 0
goto main ; - instruo "goto main" salta para
; o endereo de memria do programa
; principal
;
;------------ Rotina Main -------------------------------------------
;
ORG 0x0005 ; - "0x0005" 1 endereo livre da
; memria de programa
;
main ; - label programa principal
;
goto main ; Cdigo assembly do
; programa principal
;
;************ ROTINAS ***********************************************
;
;
;
;
;********************************************************************
END ; - directiva "END" fim do programa

12
www.mecatronicadegaragem.blogspot.com

TP0 - Introduo ao Assembly e MPLAB IDE

4.5 Anlise do programa exemplo

O objectivo do programa manter o led (ligado ao bit 0 do PORTB, RB0), acesso durante um tempo
t1 e apagado durante um tempo t2.
Para efectuar a contagem de tempo utiliza-se a rotina Delay (ver cdigo Assembly pgina, 14).
Esta rotina permite a parametrizao na gama [1..255] a que corresponde uma contagem de tempo
na gama [0,1s..2,5s]. O registo W utilizado para a passagem do parmetro da entrada para a rotina.
O trecho de cdigo abaixo indicado, representa o cdigo da rotina main do programa. Inicialmente
feita a configurao do PORTB do PIC como sada, para que seja possvel a activao/desactivao
do led (RB0). De seguida o programa entra num ciclo infinito forando a sada RB0 ao estado ON
durante 0,5s e ao estado OFF durante 1s.
A primeira instruo (bsf PORTB,RB0) coloca na sada (RB0) o nvel lgico 1 (5 volts). A
seguinte instruo (movlw 50) coloca no registo W o valor do parmetro de entrada da rotina De-
lay, invocada de seguida, o que vai fazer com que o led esteja acesso durante 0,5s. A instruo
(bcf PORTB,RB0) coloca na sada (RB0) o nvel lgico 0 (0 volts). A rotina Delay novamente
invocada tendo agora como valor de entrada 100, o que vai fazer com que o led esteja apagado durante
um tempo t2. Este ciclo repete-se sempre.

main Bank1 ; Memria RAM -> Bank 1


movlw b11111110 ; RB[0] output
movwf TRISB ; RB[7:1] inputs
Bank0 ; Memria RAM -> Bank 0
loop ; while(1)
; {
bsf PORTB,RB0 ; Set LED in RB0 ON
;
movlw 50 ; 50 -> W(reg)
call Delay ; delay( 0,5 seg )
;
bcf PORTB,RB0 ; Set LED in RB0 OFF
;
movlw 100 ; 100 -> W(reg)
call Delay ; delay( 0,10 seg )
;
goto loop ; }

13
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

;===================================================================;
; Delay ;
; Pode gerar delays entre 10 mS e 2,5 S ;
; O valor de entrada e passado em W (1..255) ;
; ;
; Notas: o loop base e de 1 uS (T=200 nS <=> 4*1/20MHz) ;
; ;
;===================================================================;
Delay
movwf delay_mult ; Carrega o valor mltiplo
Del_m10 movlw 50 ; de 10 mS
movwf delay_k50 ; 50 => 10 mS
Del_50 movlw 200 ; 200 => 200 uS
movwf delay_k200 ; Carrega o valor
Del_200 nop ; correspondente a 200 uS
nop
decfsz delay_k200,f ; Decrementa "delay_k200".
; O resultado colocadao em
; "delay_k200"
goto Del_200 ; while( delay_k200 > 0 )
decfsz delay_k50,f ;
goto Del_50 ; while( delay_k50 > 0 )
decfsz delay_mult,f ; Decrementa "delay_mult".
; O resultado colocadao
; em "delay_mult"
goto Del_m10 ; while( delay_mult > 0 )
return

Elementos de Apoio

Manual terico da disciplina.


DataSheet PIC16F876(DS30292C) Microchip, captulo 3. - I/O Ports, pgina 29.
DataSheet PIC16F876(DS30292C) Microchip, captulo 13 - Instrution Set Summary, p-
gina 135.

14
www.mecatronicadegaragem.blogspot.com

TP1 - Entrada/Sada
Tema a desenvolver Durao
Entrada e Sada bsica 2 aulas

1 Resumo

Programao e interface dos portos do PIC, atravs da implementao de programas em linguagem


Assembly para leitura e escrita de dados nas linhas de entrada/sada (E/S) que compem os portos.

2 Objectivos

Familiarizao do aluno com a linguagem assembly do PIC;


Programao dos registos associados aos portos de E/S;
Leitura e escrita de dados nos portos;
No final do trabalho, dever estar compreendido o mecanismo bsico de E/S do PIC.

3 Descrio

O PIC16F876 dispe de um total de 22 linhas de E/S de 1 bit. Estas esto organizados em 3 portos,
denominados de porto A, porto B e porto C. Cada porto tem associado um par de registos: TRIS e
PORT (ver descrio mais frente). O porto A agrupa 5 linhas de 1 bit configurveis, como entrada
ou como sada, identificadas pelas siglas RA0, RA1, RA2, RA3 e RA4. Cada um dos portos B e C
agrupa 8 linhas configurveis como entrada ou como sada identificadas pelas siglas Rx0, Rx1, Rx2,
Rx3, Rx4, Rx5, Rx6 e Rx7, em que x pode tomar o valor B ou C.
Algumas destas 22 linhas tm atribudas diversas funes (que no a de simples linha de en-
trada/sada), podendo o programador configurar por software a funo efectivamente desempenhada.
De entre as funes disponveis destacam-se as seguintes:

Entrada analgica, disponvel, por exemplo na linha RA0/AN0 (2);


Interrupo externa, disponvel em RB0/INT (21);
Entrada de clock externo do Timer 0, disponvel em RA4/T0CKL (6);

15
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

Transmisso de dados em comunicao srie, RC6/TX (16);


Recepo de dados em comunicao srie, RC7/RX (18);

3.1 Registos TRIS e PORT

O registo PORT um registo de dados, aqui que a informao presente nas linhas de entrada ou
sada recolhida ou disponibilizada. Cada porto tem associado um registo de dados prprio, PORTA,
PORTB e PORTC.
O registo TRIS um registo programvel de 1 byte (8 bits) disponvel no banco 1 (memria
RAM), que controla se uma linha em particular uma entrada ou uma sada. Existe um registo TRIS
para cada porto. O TRISA controla o estado de E/S das 6 linhas do porto A, enquanto que TRISB
e TRISC controlam respectivamente o estado de E/S das 8 linhas do porto B e porto C. Uma vez
configurada as direces pretendidas das linhas do porto, por programao do registo TRIS, pode-se
efectuar leituras ou escritas no porto usando o registo PORT.

Utilizao dos registos TRIS e PORT

Todos os bits contidos nos registos mencionados, correspondem univocamente a uma linha de en-
trada/sada de um bit. Por exemplo, o bit 0 do registo PORTA e do registo TRISA, correspondem
linha RA0, o bit 1 linha RA1 e assim por diante. Um 1 no bit 0 do registo TRIS configura a linha
como entrada enquanto um 0 configura a linha como sada. Uma maneira intuitiva de relembrar o
conceito, advm do facto de o 1 ser parecido com o I que provm da inicial da palavra inglesa
Input e o 0 ser parecido com O que provm de Output.
A figura 11 mostra um esquema conceptual da configurao atravs do registo TRISB, de um
porto. A linha RB0 est configurada como entrada ou como sada? Qual ser o nvel lgico presente
no bit 0 do registo PORTB?
Observa-se na figura que o bit 0 do registo TRISB est definido a 1, logo a linha RB0 est
configurada como entrada. Quanto ao valor do bit 0 no registo PORTB, temos de considerar dois
momentos, uma vez que a entrada varia no tempo: ao primeiro momento corresponde o nvel lgico
0 e ao segundo o nvel lgico 1.

Figura 11: Configurao de uma linha em E/S

16
www.mecatronicadegaragem.blogspot.com

TP1 - Entrada e sada bsica

3.2 Inicializao dos portos

Quando necessrio usar uma ou mais linhas de E/S de um determinado porto, importante fazer-se a
sua inicializao logo no inicio da rotina main do programa. A inicializao no mais que a confi-
gurao da direco dos dados presentes nas linhas de E/S, por configurao do registo TRIS.
importante realar que, se porventura a inicializao das linhas de E/S no for feita, estas por
defeito (aquando do reset do PIC) encontram-se todas como entrada. Assim se uma das funciona-
lidades do programa a desenvolver for a recepo de informao digital em todas as linhas de um
determinado porto ( excepo do porto A), este no necessita de ser inicializado.
RA4 a nica linha do porto A que pode ser configurada como entrada digital pelo registo TRISA,
para as restantes necessrio tambm a configurao do registo ADCON1 (descrio feita no trabalho
prtico 9).
O trecho de cdigo Assembly seguinte, exemplifica uma inicializao por programao de todos
os portos do PIC. Este mostra, para cada porto, 3 formas de configurao do registo TRIS:

1. Transferncia para o registo W do literal em binrio, e consequente escrita em TRIS;


2. Colocao de todos os bits do registo TRIS a zero;
3. Read modify write, coloca apenas o bit correspondente a zero.

;---------------- I/O - Config -------------------------------------;

Bank1 ; DATA memory (RAM) Bank1


;
config 1 movlw b00010000 ; RA[7:5 & 3:0] sadas
movwf TRISA ; RA[4] entradas
;
config 2 clrf TRISB ; RB[7:0]
;
config 3 bcf TRISC,RC0 ; RC[7:1] entradas
; RC[0] sada
;
Bank0 ; DATA memory (RAM) Bank0
clrf PORTA ; Apaga todos os bits do PORTA
clrf PORTB ; Apaga todos os bits do PORTB
clrf PORTC ; Apaga todos os bits do PORTC

17
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

4 Trabalho a realizar

1. Alterao do programa exemplo exemplo.asm de modo a que, atravs do boto de presso S2


da placa PIC ligado a RA4 (ver esquema da figura 12), seja possvel controlar o estado do led
ligado ao pino RB0; boto premido led ligado, boto no premido led desligado.

Figura 12: Diagrama do circuito, led on/off.

2. Mantendo o circuito, alterar o programa anterior por forma a permitir o controlo temporizado
do led ligado a RB0.
Inicialmente o led activado por presso no boto ligado a RA4. Aps se ter deixado de
premir o boto, manter durante um tempo t o led acesso. A figura 13, mostra o comportamento
pretendido para a sada, com t=2,5s.

Figura 13: Diagrama temporal da sada temporizada

18
www.mecatronicadegaragem.blogspot.com

TP1 - Entrada e sada bsica

3. Construo de um programa, que implemente um contador binrio up/down. O incremento ou


decremento deve ser feito com um intervalo de tempo fixo (aproximadamente de 0,5 segundos),
atravs de 4 leds, ligados aos portos RB3 a RB0 da placa PIC (ver esquema da figura 14).
Inicialmente feito o incremento de valores em binrio no PORTB, contudo, se premir conti-
nuamente o boto de presso ligado a RA4, dever-se-, visualizar o seu decremento. A figura
14 mostra tambm a visualizao do valor 5 correspondente ao valor binrio 0101, sendo que
o bit mais significativo corresponde ao led3 ligado a RB3.

Figura 14: Diagrama do circuito para o contador up/down

Elementos de Apoio

Manual terico da disciplina.


DataSheet PIC16F876(DS30292C) Microchip, captulo 3. - I/O Ports, pgina 29.
DataSheet PIC16F876(DS30292C) Microchip, captulo 11. - Analog-to-Digital Converter
(A/D) Module, pgina 111.
DataSheet PIC16F876(DS30292C) Microchip, captulo 13 - Instrution Set Summary, p-
gina 135.

19
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

5 Implementao em Assembly do PIC

5.1 Ponto 1
; Trabalho Prtico n 1 Ponto I
; Alterao do programa "exemplo.asm" incluso de boto on/off
;
; Resumo:
; Led pisca-pisca (DUTTY CYCLE varivel), com switch on/off.
;
; 5 V
; |
; /
; \
; / RES 10K
; ___________ \ SW
; | | | __|__
; | PIC16F876 |-<-- RA4 ---------*---------o o----- 0V
; | |
; | | /-----\ RES 220
; | |->-- RB0 ------| LED |------\/\/\/---- 0V
; | | \-----/
; |___________|
;
; figura 1. esquema de ligao PIC.
;
;********************************************************************
; *
; Nome ficheiro: trab1p1.asm *
; ltima actualizao 22/Julho /2005 *
; *
; Autores: Jos Miguel Gaspar *
; Olmpia Rodrigues *
; *
; Orientador: Prof. Jos Lus Azevedo *
; *
; Universidade de Aveiro *
; Seminrio EEI 2004/2005 *
; *
;********************************************************************
; *
; Ficheiro necessrio: 16f876.lkr *
; *
;********************************************************************
list p=16f876 ; - directiva list, define
; o processor a usar
radix decimal ; - directiva radix especifica
; definio das variveis
#include "p16f876.inc" ; - directiva include inclui
; ficheiro adicional
errorlevel -302 ; Turn off banking message
; known tested (good) code
;--------------------------------------------------------------------
; Constantes
;--------------------------------------------------------------------
RA0 EQU 0
RA1 EQU 1
RA2 EQU 2
RA3 EQU 3
RA4 EQU 4
RA5 EQU 5
RB0 EQU 0
RB1 EQU 1
RB2 EQU 2
RB3 EQU 3
RB4 EQU 4
RB5 EQU 5

20
www.mecatronicadegaragem.blogspot.com

TP1 - Entrada e sada bsica

RB6 EQU 6
RB7 EQU 7
RC0 EQU 0
RC1 EQU 1
RC2 EQU 2
RC3 EQU 3
RC4 EQU 4
RC5 EQU 5
RC6 EQU 6
RC7 EQU 7
;----------------------------------------------------------------------
; Variveis (REGISTOS DE USO GERAL) Bank0
;----------------------------------------------------------------------
UDATA 0x20
delay_mult RES 1 ; Variaveis de controlo
delay_k50 RES 1 ; dos loops da rotina Delay
delay_k200 RES 1 ;
start_stop RES 1 ; start_stop FLAG
;--------------------------------------------------------------------
; Macros to select the register Banks
;--------------------------------------------------------------------
Bank0 MACRO ; Macro to select data RAM Bank 0
bcf STATUS,RP0
bcf STATUS,RP1
ENDM
Bank1 MACRO ; Macro to select data RAM Bank 1
bsf STATUS,RP0
bcf STATUS,RP1
ENDM
Bank2 MACRO ; Macro to select data RAM Bank 2
bcf STATUS,RP0
bsf STATUS,RP1
ENDM
Bank3 MACRO ; Macro to select data RAM Bank 3
bsf STATUS,RP0
bsf STATUS,RP1
ENDM
;********************************************************************
ORG 0x0000 ; - directiva "ORG" origem do
; programa "ORG 0x0000" vector
; de reset
clrf PCLATH ; - instruo "clrf PCLATH" apaga
; todos os bits do registo garante
; que a memria do programa
; iniciada na pgina 0
goto main ; - instruo "goto main" salta para
; o endereo de memria do programa
; principal
;--------------------------------------------------------------------
; Rotina Main
;--------------------------------------------------------------------
ORG 0x0005 ; Program Memory PAGE 0
main ; Programa principal.
Bank1 ; DATA memory (RAM) Bank1
movlw b11111110 ; RB[0] output
movwf TRISB ; RB[7:1] inputs
movlw b00010000 ; RA[7:5 & 3:0] outputs
movwf TRISA ; RA[4] input
Bank0 ; DATA memory (RAM) Bank0
clrf PORTB ; Inicializao PORTB
clrf PORTA ; Inicializao PORTA
loop ; while(1) {

21
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

btfsc PORTA,RA4 ; switch ON ?


goto $-1 ;
;
bcf PORTB,RB0 ; Set LED in RB0 ON
;
movlw 20 ;
call Delay ; delay( 0,20 seg )
;
bsf PORTB,RB0 ; Set RB0 OFF
movlw 20 ;
call Delay ; delay( 0,20 seg )
;
goto loop ; }
;********************************************************************

;************************** ROTINAS *********************************


;********************************************************************
;********************************************************************
;===================================================================;
; Delay ;
; Pode gerar delays entre 10 mS e 2,5 S ;
; O valor de entrada e passado em W (1..255) ;
; ;
; Notas: o loop base e de 1 uS (T=200 nS <=> 4*1/20MHz) ;
; ;
;===================================================================;
Delay
movwf delay_mult ; Carrega o valor multiplo
Del_m10 movlw 50 ; de 10 mS
movwf delay_k50 ; 50 => 10 mS
Del_50 movlw 200 ; 200 => 200 uS
movwf delay_k200 ; Carrega o valor
Del_200 nop ; correspondente a 200 uS
nop
decfsz delay_k200,f ; Decrementa "delay_k200".
; O resultado colocadao em
; "delay_k200"
goto Del_200 ; while( delay_k200 > 0 )
decfsz delay_k50,f ;
goto Del_50 ; while( delay_k50 > 0 )
decfsz delay_mult,f ; Decrementa "delay_mult".
; O resultado colocadao
; em "delay_mult"
goto Del_m10 ; while( delay_mult > 0 )
return
;********************************************************************
END ; directive end of program

22
www.mecatronicadegaragem.blogspot.com

TP1 - Entrada e sada bsica

5.2 Ponto 2

; Trabalho Prtico n 1 Ponto II


; Sada temporizada, com visualizao atravs de um led
;
; Resumo:
; Implementao de um programa em assembly que permita o activao
; temporizada de um led, aps a presso de um switch, (ver figura 2).
;
; 5 V
; |
; /
; \
; / RES 10K
; ___________ \ SW
; | | | __|__
; | PIC16F876 |-<-- RA4 ----------*---------o o----- 0V
; | |
; | | /-----\ RES 220
; | |->-- RB1 ------| LED |------\/\/\/---- 0V
; |___________| \-----/
;
;
; figura 1. esquema de ligao PIC.
;
; ON | OFF
; ________________
; | |
; switch _______| |_____________________________
;
; ON | OFF
; ______________________________________
; | |
; led _______| | |________
; | |
; |<---- TEMPO_ON ----->|
;
; figura 2. diagrama temporal sada/entrada
;
;********************************************************************
; *
; NomeFicheiro: trab1p2.asm *
; ltima actualizao: 22/Julho/2005 *
; *
; Autores: Jos Miguel Gaspar *
; Olmpia Rodrigues *
; *
; Orientador: Prof. Jos Lus Azevedo *
; *
; Universidade de Aveiro *
; Seminrio EEI 2004/2004 *
; *
;********************************************************************
; *
; Ficheiro necessrio: 16f876.lkr *
; *
;********************************************************************
list p=16f876 ; - directiva list, define
; o processor a usar
radix decimal ; - directiva radix especifica
; definio das variveis
#include "p16f876.inc" ; - directiva include inclui
; ficheiro adicional
errorlevel -302 ; Turn off banking message
; known tested (good) cod
;--------------------------------------------------------------------
; Constantes

23
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

;--------------------------------------------------------------------
RA0 EQU 0
RA1 EQU 1
RA2 EQU 2
RA3 EQU 3
RA4 EQU 4
RA5 EQU 5
RB0 EQU 0
RB1 EQU 1
RB2 EQU 2
RB3 EQU 3
RB4 EQU 4
RB5 EQU 5
RB6 EQU 6
RB7 EQU 7
RC0 EQU 0
RC1 EQU 1
RC2 EQU 2
RC3 EQU 3
RC4 EQU 4
RC5 EQU 5
RC6 EQU 6
RC7 EQU 7
TEMPO_ON EQU 255 ; Gama [1..255] = [10ms..2,5s]
;----------------------------------------------------------------------
; Variveis (REGISTOS DE USO GERAL) Bank0
;----------------------------------------------------------------------
UDATA 0x20
delay_mult RES 1 ; Variaveis de controlo
delay_k50 RES 1 ; dos loops da rotina Delay
delay_k200 RES 1 ;
;--------------------------------------------------------------------
; Macros to select the register Banks
;--------------------------------------------------------------------
Bank0 MACRO ; Macro to select data RAM Bank 0
bcf STATUS,RP0
bcf STATUS,RP1
ENDM
Bank1 MACRO ; Macro to select data RAM Bank 1
bsf STATUS,RP0
bcf STATUS,RP1
ENDM
Bank2 MACRO ; Macro to select data RAM Bank 2
bcf STATUS,RP0
bsf STATUS,RP1
ENDM
Bank3 MACRO ; Macro to select data RAM Bank 3
bsf STATUS,RP0
bsf STATUS,RP1
ENDM

;********************************************************************
vector_reset ORG 0x00 ; Processor reset vector
clrf PCLATH ; Ensure page bits are cleared
goto main ; Go to beginning of program
;--------------------------------------------------------------------
; Rotina Main
;--------------------------------------------------------------------

24
www.mecatronicadegaragem.blogspot.com

TP1 - Entrada e sada bsica

ORG 0x20 ; Program Memory PAGE 0


main ; Programa principal.
call InitCfg ;
; While(1){
loop btfsc PORTB,RB0 ; Testa se o SW em RB0
goto $-1 ; pressionado ?
;
bsf PORTB,RB1 ; Set LED em RB1 ON
;
btfss PORTB,RB0 ; Testa se SW em RA0 deixa
goto $-1 ; de ser pressionado ?
;
movlw TEMPO_ON ;
call Delay ; delay( 2,5 seg )
bcf PORTB, RB1 ; Set LED em RB1 OFF
;
goto loop ; }
;********************************************************************

;************************** ROTINAS *********************************


;********************************************************************
;********************************************************************
;===================================================================;
; InitCfg ;
; Configurao inicial dos registros associados ;
; ao programa principal, PORTOS I/O ;
; ;
; Retorna em Bank0 ;
; ;
;===================================================================;
InitCfg
;----------------- I/O - InitCfg -----------------------------------;
Bank1 ; DATA memory (RAM) Bank0
movlw b11111101 ; RB[1] output
movwf TRISB ; RB[7:2 & 0] inputs
Bank0 ; DATA memory (RAM) Bank0
clrf PORTB ; Inicializao PORTB.
return
;===================================================================;
; Delay ;
; Pode gerar delays entre 10 mS e 2,5 S ;
; O valor de entrada e passado em W (1..255) ;
; Retorna em Bank0 ;
; ;
; Notas: o loop base e de 1 uS (T=200 nS <=> 4*1/20MHz) ;
; ;
;===================================================================;
Delay
movwf delay_mult ; Carrega o valor multiplo
Del_m10 movlw 50 ; de 10 mS
movwf delay_k50 ; 50 => 10 mS
Del_50 movlw 200 ; 200 => 200 uS
movwf delay_k200 ; Carrega o valor
Del_200 nop ; correspondente a 200 uS
nop
decfsz delay_k200,f ; Decrementa "delay_k200".
; O resultado colocadao em
; "delay_k200"
goto Del_200 ; while( delay_k200 > 0 )
decfsz delay_k50,f ;
goto Del_50 ; while( delay_k50 > 0 )
decfsz delay_mult,f ; Decrementa "delay_mult".
; O resultado colocadao
; em "delay_mult"
goto Del_m10 ; while( delay_mult > 0 )

25
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

return
;********************************************************************
END ; directive end of program

26
www.mecatronicadegaragem.blogspot.com

TP1 - Entrada e sada bsica

5.3 Ponto 3

; Trabalho Prtico n 1 - Ponto III


; Implementao de um contador binrio up/down
;
; Resumo:
; Inicialmente conta up ao presionar RC2, inverte o sentido
; da contagem, se deixar de precionar RC2 volta situao
; inicial de conta up
;
; 5 V
; |
; /
; \
; / RES
; ___________ \ SW
; | | | __|__
; | PIC16F876 |-<-- RC2 ---------*---------o o----- 0V
; | |
; | | /----\ RES
; | |->-- RB0 -----| LED1 |------\/\/\/---- 0V
; | | \----/
; | | /----\ RES
; | |->-- RB1 -----| LED2 |------\/\/\/---- 0V
; | | \----/
; | | /----\ RES
; | |->-- RB2 -----| LED3 |------\/\/\/---- 0V
; | | \----/
; | | /----\ RES
; | |->-- RB3 -----| LED4 |------\/\/\/---- 0V
; |___________| \----/
;
; figura 1. esquema de ligao PIC.
;
;********************************************************************
; *
; NomeFicheiro: trab1p3.asm *
; Data: 3/Junho/2005 *
; Verso: 1.0 *
; *
; Autores: Jos Miguel Gaspar *
; Olmpia Rodrigues *
; *
; Orientador: Prof. Jos Lus Azevedo *
; *
; Universidade de Aveiro *
; Seminrio EEI 2004/2004 *
; *
;********************************************************************
; *
; Ficheiro necessrio: P16F876.INC *
; *
;********************************************************************
list p=16f876 ; - directiva list, define
; o processor a usar
radix decimal ; - directiva radix especifica
; definio das variveis
#include "p16f876.inc" ; - directiva include inclui
; ficheiro adicional
errorlevel -302 ; Turn off banking message
; known tested (good) coe
;--------------------------------------------------------------------
; Constantes
;--------------------------------------------------------------------
RA0 EQU 0
RA1 EQU 1

27
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

RA2 EQU 2
RA3 EQU 3
RA4 EQU 4
RA5 EQU 5
RB0 EQU 0
RB1 EQU 1
RB2 EQU 2
RB3 EQU 3
RB4 EQU 4
RB5 EQU 5
RB6 EQU 6
RB7 EQU 7
RC0 EQU 0
RC1 EQU 1
RC2 EQU 2
RC3 EQU 3
RC4 EQU 4
RC5 EQU 5
RC6 EQU 6
RC7 EQU 7
;----------------------------------------------------------------------
; Variveis (REGISTOS DE USO GERAL) Bank0
;----------------------------------------------------------------------
UDATA 0x20
delay_mult RES 1 ; Variaveis de controlo
delay_k50 RES 1 ; dos loops da rotina Delay
delay_k200 RES 1 ;
;--------------------------------------------------------------------
; Macros to select the register Banks
;--------------------------------------------------------------------
Bank0 MACRO ; Macro to select data RAM Bank 0
bcf STATUS,RP0
bcf STATUS,RP1
ENDM
Bank1 MACRO ; Macro to select data RAM Bank 1
bsf STATUS,RP0
bcf STATUS,RP1
ENDM
Bank2 MACRO ; Macro to select data RAM Bank 2
bcf STATUS,RP0
bsf STATUS,RP1
ENDM
Bank3 MACRO ; Macro to select data RAM Bank 3
bsf STATUS,RP0
bsf STATUS,RP1
ENDM
;********************************************************************
ORG 0x0000 ; - directiva "ORG" origem do
; programa "ORG 0x0000" vector
; de reset
clrf PCLATH ; - instruo "clrf PCLATH" apaga
; todos os bits do registo garante
; que a memria do programa
; iniciada na pgina 0
goto main ; - instruo "goto main" salta para
; o endereo de memria do programa
; principal
;--------------------------------------------------------------------
; Rotina Main
;--------------------------------------------------------------------
ORG 0x0005 ; Program Memory PAGE 0
main ; Programa principal.
call InitCfg ;
incrementa ;

28
www.mecatronicadegaragem.blogspot.com

TP1 - Entrada e sada bsica

incf PORTB,f ; add 1 to port B


;
movlw 75 ;
call Delay ; delay( 3/4 seg )
;
btfsc PORTA,RA4 ; RA4 est ON ?
goto incrementa ;
decrementa ;
decf PORTB,f ; sub 1 to port B
;
movlw 75 ;
call Delay ; delay( 3/4 seg )
;
btfss PORTA,RA4 ; RA4 est OFF ?
goto decrementa ;
goto incrementa ;
;********************************************************************

;************************** ROTINAS *********************************


;********************************************************************
;********************************************************************
;===================================================================;
; InitCfg ;
; Configurao inicial dos registros associados ;
; ao programa principal, PORTOS I/O ;
; ;
; Retorna em Bank0 ;
; ;
;===================================================================;
InitCfg
;----------------- I/O - InitCfg -----------------------------------;
Bank1 ; DATA memory (RAM) Bank1
movlw b11110000 ; RA[3:0] outputs
movwf TRISB ; RA[7:4] inputs
movlw b00001000 ; RA[7:5 & 3:0] outputs
movwf TRISA ; RA[4] inputs
;
Bank0 ; DATA memory (RAM) Bank0
clrf PORTB ; Inicializao PORTB.
return
;===================================================================;
; Delay ;
; Pode gerar delays entre 10 mS e 2,5 S ;
; O valor de entrada e passado em W (1..255) ;
; Retorna em Bank0 ;
; ;
; Notas: o loop base e de 1 uS (T=200 nS <=> 4*1/20MHz) ;
; ;
;===================================================================;
Delay
movwf delay_mult ; Carrega o valor multiplo
Del_m10 movlw 50 ; de 10 mS
movwf delay_k50 ; 50 => 10 mS
Del_50 movlw 200 ; 200 => 200 uS
movwf delay_k200 ; Carrega o valor
Del_200 nop ; correspondente a 200 uS
nop
decfsz delay_k200,f ; Decrementa "delay_k200".
; O resultado colocadao em
; "delay_k200"
goto Del_200 ; while( delay_k200 > 0 )
decfsz delay_k50,f ;
goto Del_50 ; while( delay_k50 > 0 )
decfsz delay_mult,f ; Decrementa "delay_mult".
; O resultado colocadao
; em "delay_mult"
goto Del_m10 ; while( delay_mult > 0 )

29
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

return
;********************************************************************
END ; directive end of program

30
www.mecatronicadegaragem.blogspot.com

TP2 - Descodificador Hexadecimal / 7Seg, 1 display


Tema a desenvolver Durao
Implementao de uma lookup table 1 aula

1 Resumo

Com este trabalho, pretende-se consolidar os conhecimentos adquiridos nos trabalhos anteriores e
estudar o modo de acesso a variveis em memria RAM, por endereamento indirecto.

2 Objectivos

Implementao de um descodificador hexadecimal / 7Segmentos por software.


Utilizao de subrotinas na estrutura do programa.
Compreenso dos conceitos associados ao acesso a variveis na memria RAM por enderea-
mento indirecto.

3 Descrio

3.1 Endereamento Indirecto, Registo FSR e INDF

O FSR (File Select Register). usado no acesso em endereamento


indirecto ou indexado de outros registos, em particular dos registos de uso
geral. Se um registo com endereamento entre [0x20-0x7F] (Banco 0 de
memria RAM) carregado no FSR, o contedo desse registo pode ser lido
ou escrito atravs do registo de endereamento indirecto (INDF), localizado
no topo de cada banco de memria (ver mapa de registos do PIC, Anexo A).
Este mtodo pode ser usado no acesso a um grupo de dados localizados em
memria RAM, atravs da leitura ou escrita de dados em INDF, a seleco
do prximo elemento do grupo feito atravs do incremento de FSR (ver
figura 16). O endereamento indirecto ou indexado, particularmente til
na salvaguarda em memria RAM, de um grupo de dados lidos de um dado
Figura 15: Acesso memria porto E/S, e, por exemplo no acesso a arrays ou tabelas.

31
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

Endereamento Indirecto - Exemplo

Uma demonstrao de endereamento indirecto, o trecho de cdigo Assembly seguinte, em que o


objectivo apagar posies consecutivas de memria RAM, localizadas entre 0x20h e 0x2F. Inicial-
mente feita a inicializao de FSR com o primeiro valor do grupo de valores a ser apagado, ou seja
FSR opera como ponteiro para o valor 0 do array (bloco de valores), sendo incrementado a cada
operao de escrita. Em cada ciclo "NEXT", est-se na realidade a apagar (clrf INDF) os contedos
das posies de memria apontadas por FSR, usando para isso o registo INDF, que no um registo
fsico e que s mostra o contedo do endereo guardado em FSR.

movlw 0x20 ; inicializa ponteiro


movwf FSR ; copia para a RAM
movlw n_val ; n de posies mem
movwf i ; contador
NEXT clrf INDF ; apaga registo INDF
incf FSR,F ; incrementa ponteiro
decfsz i,f ; contador--
goto NEXT ; apaga o prximo
CONTINUE
: ; continua

Figura 16: Endereamento Indirecto cdigo de demonstrao

32
www.mecatronicadegaragem.blogspot.com

TP2 - Descodificador Hexadecimal / 7Seg, 1 display

3.2 Seleco do Banco de Memria

A memria de dados (RAM) encontra-se organizada em bancos distintos (Banco 0, 1, 2 e 3) 4 no


total, sendo que o acesso a cada um deles feito atravs de seleco. A seleco pode ser feita atravs
de endereamento directo (ver registo STATUS pgina 45) ou indirecto. neste ltimo o bit mais
significativo do registo FSR, usado como bit menos significativo na seleco do banco de memria
a aceder; os restantes 7 bits so usados na especificao do registo dentro do banco de memria
seleccionado. O bit mais significativo para seleco do banco de memria, dado pelo bit IRP do
registo de STATUS. Para mais detalhes ver descrio sobre o registo STATUS, pgina 45 do guia.

Figura 17: Seleco do banco de memria

4 Trabalho a realizar

1. Visualizao, num display de 7 segmentos, de um digito codificado em hexadecimal (ver dia-


grama do circuito, figura 18).
Para isso necessria a construo de uma rotina que receba um digito em hexadecimal e de-
volva o correspondente valor para activao de cada um dos segmentos do display. Este valor
dever ser depois enviado para o PORTB.
Para melhor compreender o conceito, a tabela 2 mostra a correspondncia entre os dgitos he-
xadecimal de entrada e o valor a enviar para cada um dos 7 segmentos do display. Por exemplo,
para visualizar o digito 7 necessrio que o segmento a,b e c estejam activos, isto , mover para
o PORTB o valor em binrio b00001110.

2. Construir finalmente um contador [0..F] crescente/decrescente por presso nos botes S1/S2
respectivamente (S1 encontra-se ligado a RB0, S2 encontra-se ligado a RA4).

33
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

Figura 18: Diagrama do circuito, 1 display de 7 segmentos

PORTB Segmentos do Display


Valor BCD
RB7 g RB6 f RB5 e RB4 d RB3 c RB2 b RB1 a
0 0 1 1 1 1 1 1
1 0 0 0 0 1 1 0
2 1 0 1 1 0 1 1
3 1 0 0 1 1 1 1
4 1 1 0 0 1 1 0
5 1 1 0 1 1 0 1
6 1 1 1 1 1 0 0
7 0 0 0 0 1 1 1
8 1 1 1 1 1 1 1
9 1 1 0 0 1 1 1
A 1 1 1 0 1 1 1
B 1 1 1 1 1 0 0
C 0 1 1 1 0 0 1
D 1 0 1 1 1 1 0
E 1 1 1 1 0 0 1
F 1 1 1 0 0 0 1

Tabela 2: Valores Hexadecimal 7 segmentos.

Elementos de Apoio

Manual terico da disciplina.


DataSheet PIC16F876(DS30292C) Microchip, captulo 2. - Memory Organization, sec-
o 2.5 - Indirect Addressing, INDF and FSR Registers pgina 27.
DataSheet PIC16F876(DS30292C) Microchip, captulo 3. - I/O Ports, pgina 29.
DataSheet PIC16F876(DS30292C) Microchip, captulo 13 - Instrution Set Summary, p-
gina 135.

34
www.mecatronicadegaragem.blogspot.com

TP2 - Descodificador Hexadecimal / 7Seg, 1 display

5 Implementao em Assembly do PIC

5.1 Ponto 1
; Trabalho Prtico n 2 I
; Implementao descodificador hex para 1 display de 7 segmentos
;
;********************************************************************
; *
; Nome ficheiro: trab2.asm *
; ltima reviso 3/Junho/2005 *
; *
; Autores: Jos Miguel Gaspar *
; Olmpia Rodrigues *
; *
; Orientador: Prof. Jos Lus Azevedo *
; *
; Universidade de Aveiro *
; Seminrio EEI 2004/2004 *
; *
;********************************************************************
; *
; Ficheiro necessrio: p16f876.lkr *
; *
;********************************************************************
list p=16f876 ; list directive to define
radix decimal ; processor
#include "p16f876.inc" ; processor specific variable
; definitions
errorlevel -302 ; Turn off banking message
; known tested (good) code
;--------------------------------------------------------------------
; Constantes
;--------------------------------------------------------------------
RA0 EQU 0
RA1 EQU 1
RA2 EQU 2
RA3 EQU 3
RA4 EQU 4
RA5 EQU 5
RB0 EQU 0
RB1 EQU 1
RB2 EQU 2
RB3 EQU 3
RB4 EQU 4
RB5 EQU 5
RB6 EQU 6
RB7 EQU 7
RC0 EQU 0
RC1 EQU 1
RC2 EQU 2
RC3 EQU 3
RC4 EQU 4
RC5 EQU 5
RC6 EQU 6
RC7 EQU 7
;--------------------------------------------------------------------
; Displays de 7 segmentos -|gfedcba-|
;--------------------------------------------------------------------
seg7_0 EQU b01111110 ; Valor 0
seg7_1 EQU b00001100 ; Valor 1
seg7_2 EQU b10110110 ; Valor 2
seg7_3 EQU b10011110 ; Valor 3
seg7_4 EQU b11001100 ; Valor 4
seg7_5 EQU b11011010 ; Valor 5

35
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

seg7_6 EQU b11111000 ; Valor 6


seg7_7 EQU b00001110 ; Valor 7
seg7_8 EQU b11111110 ; Valor 8
seg7_9 EQU b11001110 ; Valor 9
seg7_A EQU b11101110 ; Valor A
seg7_B EQU b11111000 ; Valor B
seg7_C EQU b01110010 ; Valor C
seg7_D EQU b10111100 ; Valor D
seg7_E EQU b11110010 ; Valor E
seg7_F EQU b11100010 ; Valor F
;--------------------------------------------------------------------
; Variveis (REGISTOS DE USO GERAL) Bank0
;--------------------------------------------------------------------
RAM UDATA 0x20
seg70 RES 1 ; Valor 0 endereo
seg71 RES 1 ; Valor 1 endereo
seg72 RES 1 ; Valor 2 endereo
seg73 RES 1 ; Valor 3 endereo
seg74 RES 1 ; Valor 4 endereo
seg75 RES 1 ; Valor 5 endereo
seg76 RES 1 ; Valor 6 endereo
seg77 RES 1 ; Valor 7 endereo
seg78 RES 1 ; Valor 8 endereo
seg79 RES 1 ; Valor 9 endereo
seg7A RES 1 ; Valor A endereo
seg7B RES 1 ; Valor B endereo
seg7C RES 1 ; Valor C endereo
seg7D RES 1 ; Valor D endereo
seg7E RES 1 ; Valor E endereo
seg7F RES 1 ; Valor F endereo
bcd_in RES 1 ; variavel bcd a afixar
delay_mult RES 1 ; Variaveis de controlo
delay_k50 RES 1 ; dos loops da rotina Delay
delay_k200 EQU 1 ;

;--------------------------------------------------------------------
; Macros to select the register Banks
;--------------------------------------------------------------------
Bank0 MACRO ; Macro to select data RAM Bank 0
bcf STATUS,RP0
bcf STATUS,RP1
ENDM
Bank1 MACRO ; Macro to select data RAM Bank 1
bsf STATUS,RP0
bcf STATUS,RP1
ENDM
Bank2 MACRO ; Macro to select data RAM Bank 2
bcf STATUS,RP0
bsf STATUS,RP1
ENDM
Bank3 MACRO ; Macro to select data RAM Bank 3
bsf STATUS,RP0
bsf STATUS,RP1
ENDM
;********************************************************************
ORG 0x0000 ; Processor reset vector
clrf PCLATH ; Ensure page bits are cleared
goto main ; Go to beginning of program
;--------------------------------------------------------------------
; Rotina Main
;--------------------------------------------------------------------
ORG 0x0005 ; Program Memory PAGE 0

36
www.mecatronicadegaragem.blogspot.com

TP2 - Descodificador Hexadecimal / 7Seg, 1 display

main ; Programa principal.


call InitCfg ; rotina de configurao
bsf PORTA,RA1 ; seleciona o display em RA1
loop ; while(1) {
movlw 0x07 ; valor a ser enviado para o
; display 7 segmentos
movwf bcd_in ;
call bcd_7seg ; bcd_7seg(bcd_in)
;
goto loop ; }
;********************************************************************

;************************** ROTINAS *********************************


;********************************************************************
;********************************************************************
;===================================================================;
; InitCfg ;
; Configurao inicial dos registros associados ;
; ao programa principal, PORTOS I/O ;
; ;
; Retorna em Bank0 ;
; ;
;===================================================================;
InitCfg
;----------------- Analog 2 Digital - InitCfg ----------------------;
Bank1 ; DATA memory (RAM) Bank1
movlw 0x06 ; W(reg) = 0x06
movwf ADCON1 ; ADCON1 (PORTA I/O digital)
;----------------- I/O - InitCfg -----------------------------------;
movlw b00010000 ; RA[7:5 & 3:0] outputs
movwf TRISA ; RA[4] input
movlw b00000001 ; RB[7:1] outputs
movwf TRISB ; RB[0] input
Bank0 ; DATA memory (RAM) Bank0
clrf PORTA ; Inicializao PORTA.
clrf PORTB ; Inicializao PORTB.
clrf bcd_in ; Inicializao BCD_IN.
;--------------------------------------------------------------------
; Inicializao dos registros associados aos displays 7seg
;--------------------------------------------------------------------
movlw seg7_0 ; Set 7segment valor 0
movwf seg70 ; Save valor 0
movlw seg7_1 ; Set 7segment valor 1
movwf seg71 ; Save valor 1
movlw seg7_2 ; Set 7segment valor 2
movwf seg72 ; Save valor 2
movlw seg7_3 ; Set 7segment valor 3
movwf seg73 ; Save valor 3
movlw seg7_4 ; Set 7segment valor 4
movwf seg74 ; Save valor 4
movlw seg7_5 ; Set 7segment valor 5
movwf seg75 ; Save valor 5
movlw seg7_6 ; Set 7segment valor 6
movwf seg76 ; Save valor 6
movlw seg7_7 ; Set 7segment valor 7
movwf seg77 ; Save valor 7
movlw seg7_8 ; Set 7segment valor 8
movwf seg78 ; Save valor 8
movlw seg7_9 ; Set 7segment valor 9
movwf seg79 ; Save valor 9
movlw seg7_A ; Set 7segment valor A
movwf seg7A ; Save valor A
movlw seg7_B ; Set 7segment valor B
movwf seg7B ; Save valor B

37
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

movlw seg7_C ; Set 7segment valor C


movwf seg7C ; Save valor C
movlw seg7_D ; Set 7segment valor D
movwf seg7D ; Save valor D
movlw seg7_E ; Set 7segment valor E
movwf seg7E ; Save valor E
movlw seg7_F ; Set 7segment valor F
movwf seg7F ; Save valor F
return
;===================================================================;
; bcd_7seg ;
; Input: bcd_in - valor BCD de entrada ;
; Output: no devolve nada (void) ;
; ;
; Resumo: routina => BCD to 7segment display, envia o valor ;
; passado em bcd_in para a PORTB por ;
; endereamento indirecto por registo. ;
; Retorna em Bank0 ;
;===================================================================;
bcd_7seg
movlw seg70 ; Incio da tabela de valores
addwf bcd_in,w ; & do val a mostrar da tabela
movwf FSR ; Set do endereo da tabela
movf INDF,w ; leitura do valor de 7seg
movwf PORTB ; envio do valor para o PORTB
return
;===================================================================;
; Delay ;
; Pode gerar delays entre 10 mS e 2,5 S ;
; O valor de entrada e passado em W (1..255) ;
; ;
; Notas: o loop base e de 1 uS (T=200 nS <=> 4*1/20MHz) ;
; ;
; Retorna em Bank0 ;
;===================================================================;
Delay
movwf delay_mult ; Carrega o valor multiplo
Del_m10 movlw 50 ; de 10 mS
movwf delay_k50 ; 50 => 10 mS
Del_50 movlw 200 ; 200 => 200 uS
movwf delay_k200 ; Carrega o valor
Del_200 nop ; correspondente a 200 uS
nop
decfsz delay_k200,f ; Decrementa "delay_k200".
; O resultado colocadao em
; "delay_k200"
goto Del_200 ; while( delay_k200 > 0 )
decfsz delay_k50,f ;
goto Del_50 ; while( delay_k50 > 0 )
decfsz delay_mult,f ; Decrementa "delay_mult".
; O resultado colocadao
; em "delay_mult"
goto Del_m10 ; while( delay_mult > 0 )
return ;
;********************************************************************
END ; directive end of program

38
www.mecatronicadegaragem.blogspot.com

TP2 - Descodificador Hexadecimal / 7Seg, 1 display

5.2 Ponto 2
; Trabalho Prtico n 2 II
; Implementao contador crescente para 1 display de 7 segmentos
;
;********************************************************************
; *
; Nome ficheiro: trab2p2.asm *
; ltima reviso 3/Junho/2005 *
; *
; Autores: Jos Miguel Gaspar *
; Olmpia Rodrigues *
; *
; Orientador: Prof. Jos Lus Azevedo *
; *
; Universidade de Aveiro *
; Seminrio EEI 2004/2004 *
; *
;********************************************************************
; *
; Ficheiro necessrio: p16f876.lkr *
; *
;********************************************************************
list p=16f876 ; list directive to define
radix decimal ; processor
#include "p16f876.inc" ; processor specific variable
; definitions
errorlevel -302 ; Turn off banking message
; known tested (good) code
;--------------------------------------------------------------------
; Constantes
;--------------------------------------------------------------------
RA0 EQU 0
RA1 EQU 1
RA2 EQU 2
RA3 EQU 3
RA4 EQU 4
RA5 EQU 5
RB0 EQU 0
RB1 EQU 1
RB2 EQU 2
RB3 EQU 3
RB4 EQU 4
RB5 EQU 5
RB6 EQU 6
RB7 EQU 7
RC0 EQU 0
RC1 EQU 1
RC2 EQU 2
RC3 EQU 3
RC4 EQU 4
RC5 EQU 5
RC6 EQU 6
RC7 EQU 7
;--------------------------------------------------------------------
; Displays de 7 segmentos -|gfedcba-|
;--------------------------------------------------------------------
seg7_0 EQU b01111110 ; Valor 0
seg7_1 EQU b00001100 ; Valor 1
seg7_2 EQU b10110110 ; Valor 2
seg7_3 EQU b10011110 ; Valor 3
seg7_4 EQU b11001100 ; Valor 4
seg7_5 EQU b11011010 ; Valor 5
seg7_6 EQU b11111000 ; Valor 6
seg7_7 EQU b00001110 ; Valor 7
seg7_8 EQU b11111110 ; Valor 8
seg7_9 EQU b11001110 ; Valor 9

39
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

seg7_A EQU b11101110 ; Valor A


seg7_B EQU b11111000 ; Valor B
seg7_C EQU b01110010 ; Valor C
seg7_D EQU b10111100 ; Valor D
seg7_E EQU b11110010 ; Valor E
seg7_F EQU b11100010 ; Valor F
;--------------------------------------------------------------------
; Variveis (REGISTOS DE USO GERAL) Bank0
;--------------------------------------------------------------------
RAM UDATA 0x20
seg70 RES 1 ; Valor 0 endereo
seg71 RES 1 ; Valor 1 endereo
seg72 RES 1 ; Valor 2 endereo
seg73 RES 1 ; Valor 3 endereo
seg74 RES 1 ; Valor 4 endereo
seg75 RES 1 ; Valor 5 endereo
seg76 RES 1 ; Valor 6 endereo
seg77 RES 1 ; Valor 7 endereo
seg78 RES 1 ; Valor 8 endereo
seg79 RES 1 ; Valor 9 endereo
seg7A RES 1 ; Valor A endereo
seg7B RES 1 ; Valor B endereo
seg7C RES 1 ; Valor C endereo
seg7D RES 1 ; Valor D endereo
seg7E RES 1 ; Valor E endereo
seg7F RES 1 ; Valor F endereo
bcd_in RES 1 ; variavel bcd a afixar
delay_mult RES 1 ; Variaveis de controlo
delay_k50 RES 1 ; dos loops da rotina Delay
delay_k200 EQU 1 ;

;--------------------------------------------------------------------
; Macros to select the register Banks
;--------------------------------------------------------------------
Bank0 MACRO ; Macro to select data RAM Bank 0
bcf STATUS,RP0
bcf STATUS,RP1
ENDM
Bank1 MACRO ; Macro to select data RAM Bank 1
bsf STATUS,RP0
bcf STATUS,RP1
ENDM
Bank2 MACRO ; Macro to select data RAM Bank 2
bcf STATUS,RP0
bsf STATUS,RP1
ENDM
Bank3 MACRO ; Macro to select data RAM Bank 3
bsf STATUS,RP0
bsf STATUS,RP1
ENDM
;********************************************************************
ORG 0x0000 ; Processor reset vector
clrf PCLATH ; Ensure page bits are cleared
goto main ; Go to beginning of program
;--------------------------------------------------------------------
; Rotina Main
;--------------------------------------------------------------------
ORG 0x0005 ; Program Memory PAGE 0
main ; Programa principal.
call InitCfg ; rotina de configurao
bsf PORTA,RA1 ; seleciona o display em RA3

40
www.mecatronicadegaragem.blogspot.com

TP2 - Descodificador Hexadecimal / 7Seg, 1 display

loop ; while(1) {
btfss PORTA,RA4 ; Se SW em RB4, for selecionado
incf bcd_in,f ; incrementa bcd_in
call bcd_7seg ; bcd_7seg(bcd_in)
movlw 20 ; W(reg) = 20
call Delay ; delay( 0,20 seg )
btfss PORTB,RB0 ; Se SW em RB0, for selecionado
decf bcd_in,f ; decrementa bcd_in
goto loop ; }
;********************************************************************

;************************** ROTINAS *********************************


;********************************************************************
;********************************************************************
;===================================================================;
; InitCfg ;
; Configurao inicial dos registros associados ;
; ao programa principal, PORTOS I/O ;
; ;
; Retorna em Bank0 ;
; ;
;===================================================================;
InitCfg
;----------------- Analog 2 Digital - InitCfg ----------------------;
Bank1 ; DATA memory (RAM) Bank1
movlw 0x06 ; W(reg) = 0x06
movwf ADCON1 ; ADCON1 (PORTA I/O digital)
;----------------- I/O - InitCfg -----------------------------------;
movlw b00010000 ; RA[7:5 & 3:0] outputs
movwf TRISA ; RA[4] input
movlw b00000001 ; RB[7:1] outputs
movwf TRISB ; RB[0] input
Bank0 ; DATA memory (RAM) Bank0
clrf PORTA ; Inicializao PORTA.
clrf PORTB ; Inicializao PORTB.
clrf bcd_in ; Inicializao BCD_IN.
;--------------------------------------------------------------------
; Inicializao dos registros associados aos displays 7seg
;--------------------------------------------------------------------
movlw seg7_0 ; Set 7segment valor 0
movwf seg70 ; Save valor 0
movlw seg7_1 ; Set 7segment valor 1
movwf seg71 ; Save valor 1
movlw seg7_2 ; Set 7segment valor 2
movwf seg72 ; Save valor 2
movlw seg7_3 ; Set 7segment valor 3
movwf seg73 ; Save valor 3
movlw seg7_4 ; Set 7segment valor 4
movwf seg74 ; Save valor 4
movlw seg7_5 ; Set 7segment valor 5
movwf seg75 ; Save valor 5
movlw seg7_6 ; Set 7segment valor 6
movwf seg76 ; Save valor 6
movlw seg7_7 ; Set 7segment valor 7
movwf seg77 ; Save valor 7
movlw seg7_8 ; Set 7segment valor 8
movwf seg78 ; Save valor 8
movlw seg7_9 ; Set 7segment valor 9
movwf seg79 ; Save valor 9
movlw seg7_A ; Set 7segment valor A
movwf seg7A ; Save valor A

41
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

movlw seg7_B ; Set 7segment valor B


movwf seg7B ; Save valor B
movlw seg7_C ; Set 7segment valor C
movwf seg7C ; Save valor C
movlw seg7_D ; Set 7segment valor D
movwf seg7D ; Save valor D
movlw seg7_E ; Set 7segment valor E
movwf seg7E ; Save valor E
movlw seg7_F ; Set 7segment valor F
movwf seg7F ; Save valor F
return
;===================================================================;
; bcd_7seg ;
; Input: bcd_in - valor BCD de entrada ;
; Output: no devolve nada (void) ;
; ;
; Resumo: routina => BCD to 7segment display, envia o valor ;
; passado em bcd_in para a PORTB por ;
; endereamento indirecto por registo. ;
; Retorna em Bank0 ;
;===================================================================;
bcd_7seg
movlw seg70 ; Incio da tabela de valores
addwf bcd_in,w ; & do val a mostrar da tabela
movwf FSR ; Set do endereo da tabela
movf INDF,w ; leitura do valor de 7seg
movwf PORTB ; envio do valor para o PORTB
return
;===================================================================;
; Delay ;
; Pode gerar delays entre 10 mS e 2,5 S ;
; O valor de entrada e passado em W (1..255) ;
; ;
; Notas: o loop base e de 1 uS (T=200 nS <=> 4*1/20MHz) ;
; ;
; Retorna em Bank0 ;
;===================================================================;
Delay
movwf delay_mult ; Carrega o valor multiplo
Del_m10 movlw 50 ; de 10 mS
movwf delay_k50 ; 50 => 10 mS
Del_50 movlw 200 ; 200 => 200 uS
movwf delay_k200 ; Carrega o valor
Del_200 nop ; correspondente a 200 uS
nop
decfsz delay_k200,f ; Decrementa "delay_k200".
; O resultado colocadao em
; "delay_k200"
goto Del_200 ; while( delay_k200 > 0 )
decfsz delay_k50,f ;
goto Del_50 ; while( delay_k50 > 0 )
decfsz delay_mult,f ; Decrementa "delay_mult".
; O resultado colocadao
; em "delay_mult"
goto Del_m10 ; while( delay_mult > 0 )
return ;
;********************************************************************
END ; directive end of program

42
www.mecatronicadegaragem.blogspot.com

TP3 - Descodificador Hexadecimal / 7Seg, 3 Displays

Tema a desenvolver Durao


Sistema de visualizao com refrescamento, 2 aulas
por multiplexagem no tempo

1 Resumo

Ampliao do trabalho prtico anterior a 3 displays de 7 segmentos.

2 Objectivos

Implementao de um sistema de visualizao hexadecimal com 3 displays, com a construo


de uma rotina para refrescamento dos 3 displays por multiplexagem no tempo.

Aprofundar os conhecimentos adquiridos durante o trabalho prtico 3.

3 Descrio

O princpio de funcionamento deste circuito em tudo igual ao circuito do trabalho anterior, o nmero
dos displays que vai ser alterado. Sero 3 os displays que tero de ser refrescados no tempo, para
que os valores enviados possam ser visualizados em simultneo.
Analisando os diagramas dos circuitos (ver pgina 19) entende-se que apenas um valor enviado,
de cada vez para um s display, (s um interruptor se encontra fechado). Note-se ainda que os todos
os segmentos dos displays esto ligados mesma sada (PORTB RB[7..1]) do PIC. Assim e tendo
em conta que os dados na sada so diferentes, aquando do envio de informao para cada display
ao mesmo tempo. Estes devem ser actualizados periodicamente com uma taxa fixa (taxa de refres-
camento aprox. = 10ms). uma vez que o olho humano no tem a percepo do envio da informao
enviada aos trs displays ao mesmo tempo.

43
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

(a) (b)

(c)

Figura 19: Processo de refrescamento dos displays

4 Trabalho a realizar

1. Construo de um sistema de visualizao em 3 displays de 7 segmentos, de valores codificados


em hexadecimal. Para isso, sugere-se o reaproveitamento da "bcd_7seg" construda no trabalho
anterior. De modo a que a rotina "bcd_7seg" seja chamada por uma outra rotina, esta controla
o envio da informao para cada display em momentos distintos, ao longo do tempo.

Elementos de Apoio

Manual terico da disciplina.


DataSheet PIC16F876(DS30292C) Microchip, captulo 2. - Memory Organization, sec-
o 2.5 - Indirect Addressing, INDF and FSR Registers pgina 27.
DataSheet PIC16F876(DS30292C) Microchip, captulo 3. - I/O Ports, pgina 29.
DataSheet PIC16F876(DS30292C) Microchip, captulo 13 - Instrution Set Summary, p-
gina 135.

44
www.mecatronicadegaragem.blogspot.com

TP3 - Descodificador Hexadecimal / 7Seg, 3 displays

4.1 Descrio do registo STATUS

O registo STATUS, fornece informaes sobre o resultado de instrues aritmticas realizadas na


ALU (Unidade Aritmtica e Lgica do CPU), do banco de memria seleccionado e do estado de reset.

bit 7 IRP: Usado na seleco do banco de memria em endereamento indirecto.

1 = Bank 2,3 (100h - 1FFh)


0 = Bank 0,1 ( 00h - FFh)

Como se observa na figura 20(a), o banco de memria especificado com o bit IRP e o bit mais
significativo do registo FSR. Mais detalhes sobre o registo FSR, ver pgina 31 do guia.
Um endereo dentro do banco seleccionado especificado pelos 7 bits menos significativos do
registo FSR.
Uma vez que o registos STATUS e FSR so comuns a todos os bancos de memria RAM, no
existe obstculo na operao, mesmo que o banco de memria RAM seja alterado.

(a) Seleco com, IRP e FSR bits (b) Seleco com RP1:RP0 bits

Figura 20: Seleco dos bancos de memria RAM.

bit 6-5 RP1:RP0: Usados na seleco do banco de memria em endereamento directo.

11 = Bank 3 (180h - 1FFh)


10 = Bank 2 (100h - 17Fh)
01 = Bank 1 ( 80h - FFh)
00 = Bank 0 ( 00h - 7Fh)

Na figura 20(b), o banco de memria pretendido especificado com os bits RP1:RP0. Uma forma
de optimizar este procedimento de alternncia entre bancos atravs do uso de MACROS. Para isso,
basta definir inicialmente uma macro para cada banco de memria RAM. No exemplo seguinte temos

45
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

uma macro para o Bank1 de memria RAM, a generalizao para outros bancos possvel desde de
que, seja respeitada a configurao dos bits RP1:RP0.

Bank1 MACRO ; Macro to select data RAM Bank 1


bsf STATUS,RP0; Set 1 - bit RP0
bcf STATUS,RP1; Set 0 - bit RP1
ENDM ;

bit 4 TO: Condio de time-out do watchdog timer, permitida apenas leitura.

1 = Aps power-on, reset, instruo de CLRWDT, ou com instruo de SLEEP.


0 = Ocorrncia de time-out do watchdog timer.

bit 3 PD: Condio de power-down (poupana de energia), permitida apenas leitura.

1 = Aps power-up, ou aps a execuo da instruo de CLRWDT.


0 = Pela execuo da instruo de SLEEP.

bit 2 Z: Flag de Z (zero flag).

1 = Quando o resultado de operao lgica ou aritmtica zero


0 = Quando o resultado de operao lgica ou aritmtica no zero.

NOTA: Provavelmente uma das flags mais utilizadas, usada na deteco de zero no resultado de uma
operao lgica ou aritmtica.

bit 1 DC: Flag de Digit Carry.

1 = Quando o ocorre carry no bit 3 do resultado.


0 = Quando no ocorre carry no bit 3 do resultado.

NOTA: A flag activa, aquando da execuo de uma operao, ADDWF, ADDLW, SUBLW ou
SUBWF, causando carry no bit 3 do resultado (operaes de 4 bits).

bit 0 C: Flag de carry

1 = Quando o ocorre carry no bit 8 do resultado.


0 = Quando no ocorre carry no bit 8 do resultado.

NOTA: Esta flag activa, quando a operao sobre o registo causa um carry no bit 8 do resultado
(operaes de 8 bits).

46
www.mecatronicadegaragem.blogspot.com

TP3 - Descodificador Hexadecimal / 7Seg, 3 displays

5 Implementao em Assembly do PIC

; Trabalho Prtico n 3
; Implementao descodificador hex para 3 displays de 7 segmentos
; taxa mxima
;
;********************************************************************
; *
; NomeFicheiro: trab3.asm *
; Data: 3/Junho/2005 *
; Verso: 1.0 *
; *
; Autores: Jos Miguel Gaspar *
; Olmpia Rodrigues *
; *
; Orientador: Prof. Jos Lus Azevedo *
; *
; Universidade de Aveiro *
; Seminrio EEI 2004/2004 *
; *
;********************************************************************
; *
; Ficheiro necessrio: P16F876.INC *
; *
;********************************************************************
list p=16f876 ; list directive to define
radix decimal ; processor
#include "p16f876.inc" ; processor specific variable
; definitions
errorlevel -302 ; Turn off banking message
; known tested (good) code
;--------------------------------------------------------------------
; Constantes
;--------------------------------------------------------------------
RA0 EQU 0
RA1 EQU 1
RA2 EQU 2
RA3 EQU 3
RA4 EQU 4
RA5 EQU 5
RB0 EQU 0
RB1 EQU 1
RB2 EQU 2
RB3 EQU 3
RB4 EQU 4
RB5 EQU 5
RB6 EQU 6
RB7 EQU 7
RC0 EQU 0
RC1 EQU 1
RC2 EQU 2
RC3 EQU 3
RC4 EQU 4
RC5 EQU 5
RC6 EQU 6
RC7 EQU 7
;--------------------------------------------------------------------
; Displays de 7 segmentos -|gfedcba-|
;--------------------------------------------------------------------
seg7_0 EQU b01111110 ; Valor 0
seg7_1 EQU b00001100 ; Valor 1
seg7_2 EQU b10110110 ; Valor 2
seg7_3 EQU b10011110 ; Valor 3
seg7_4 EQU b11001100 ; Valor 4
seg7_5 EQU b11011010 ; Valor 5
seg7_6 EQU b11111000 ; Valor 6

47
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

seg7_7 EQU b00001110 ; Valor 7


seg7_8 EQU b11111110 ; Valor 8
seg7_9 EQU b11001110 ; Valor 9
seg7_A EQU b11101110 ; Valor A
seg7_B EQU b11111000 ; Valor B
seg7_C EQU b01110010 ; Valor C
seg7_D EQU b10111100 ; Valor D
seg7_E EQU b11110010 ; Valor E
seg7_F EQU b11100010 ; Valor F
;--------------------------------------------------------------------
; Variveis (REGISTOS DE USO GERAL) Bank0
;--------------------------------------------------------------------
variaveis UDATA 0x20
seg70 RES 1 ; Valor 0 endereo
seg71 RES 1 ; Valor 1 endereo
seg72 RES 1 ; Valor 2 endereo
seg73 RES 1 ; Valor 3 endereo
seg74 RES 1 ; Valor 4 endereo
seg75 RES 1 ; Valor 5 endereo
seg76 RES 1 ; Valor 6 endereo
seg77 RES 1 ; Valor 7 endereo
seg78 RES 1 ; Valor 8 endereo
seg79 RES 1 ; Valor 9 endereo
seg7A RES 1 ; Valor A endereo
seg7B RES 1 ; Valor B endereo
seg7C RES 1 ; Valor C endereo
seg7D RES 1 ; Valor D endereo
seg7E RES 1 ; Valor E endereo
seg7F RES 1 ; Valor F endereo
bcd_in RES 1 ; variavel bcd a afixar
delay_mult RES 1 ; Variaveis de controlo
delay_k50 RES 1 ; dos loops da rotina Delay
delay_k200 RES 1 ;
aux RES 1
disp_7seg RES 1
;--------------------------------------------------------------------
; Macros to select the register Banks
;--------------------------------------------------------------------
Bank0 MACRO ; Macro to select data RAM Bank 0
bcf STATUS,RP0
bcf STATUS,RP1
ENDM
Bank1 MACRO ; Macro to select data RAM Bank 1
bsf STATUS,RP0
bcf STATUS,RP1
ENDM
Bank2 MACRO ; Macro to select data RAM Bank 2
bcf STATUS,RP0
bsf STATUS,RP1
ENDM
Bank3 MACRO ; Macro to select data RAM Bank 3
bsf STATUS,RP0
bsf STATUS,RP1
ENDM
;********************************************************************
ORG 0x0000 ; Processor reset vector
clrf PCLATH ; Ensure page bits are cleared
goto main ; Go to beginning of program
;--------------------------------------------------------------------
; Rotina Main

48
www.mecatronicadegaragem.blogspot.com

TP3 - Descodificador Hexadecimal / 7Seg, 3 displays

;--------------------------------------------------------------------
ORG 0x0005 ; Program Memory PAGE 0
main ; Programa principal.
call InitCfg ; rotina de configurao
loop ; while(1){
clrf disp_7seg ; disp_7seg = 0
movlw 0x0f ; 0x0f -> W(reg)
call prt_disp7seg ; prt_disp7seg(W(reg))
movlw 0x0f
call prt_disp7seg ; prt_disp7seg(W(reg))
movlw 0x00
call prt_disp7seg ; prt_disp7seg(W(reg))
goto loop ; }

;********************************************************************

;************************** ROTINAS *********************************


;********************************************************************
;********************************************************************
;===================================================================;
; InitCfg ;
; Configurao inicial dos registros associados ;
; ao programa principal, PORTOS I/O ;
; ;
; Retorna em Bank0 ;
; ;
;===================================================================;
InitCfg
;----------------- I/O - InitCfg -----------------------------------;
Bank1 ; DATA memory (RAM) Bank1
clrf TRISA ; All bits outputs
movlw b00000001 ; RB[7:1] outputs
movwf TRISB ; RB[0] input
Bank0 ; DATA memory (RAM) Bank0
clrf PORTA ; Inicializao registos 0x00
clrf PORTB ;
clrf bcd_in ;
clrf aux ;
;--------------------------------------------------------------------
; Inicializao dos registros associados aos displays 7seg
;--------------------------------------------------------------------
movlw seg7_0 ; Set 7segment valor 0
movwf seg70 ; Save valor 0
movlw seg7_1 ; Set 7segment valor 1
movwf seg71 ; Save valor 1
movlw seg7_2 ; Set 7segment valor 2
movwf seg72 ; Save valor 2
movlw seg7_3 ; Set 7segment valor 3
movwf seg73 ; Save valor 3
movlw seg7_4 ; Set 7segment valor 4
movwf seg74 ; Save valor 4
movlw seg7_5 ; Set 7segment valor 5
movwf seg75 ; Save valor 5
movlw seg7_6 ; Set 7segment valor 6
movwf seg76 ; Save valor 6
movlw seg7_7 ; Set 7segment valor 7
movwf seg77 ; Save valor 7
movlw seg7_8 ; Set 7segment valor 8
movwf seg78 ; Save valor 8
movlw seg7_9 ; Set 7segment valor 9

49
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

movwf seg79 ; Save valor 9


movlw seg7_A ; Set 7segment valor A
movwf seg7A ; Save valor A
movlw seg7_B ; Set 7segment valor B
movwf seg7B ; Save valor B
movlw seg7_C ; Set 7segment valor C
movwf seg7C ; Save valor C
movlw seg7_D ; Set 7segment valor D
movwf seg7D ; Save valor D
movlw seg7_E ; Set 7segment valor E
movwf seg7E ; Save valor E
movlw seg7_F ; Set 7segment valor F
movwf seg7F ; Save valor F
return
;===================================================================;
; Input: W(reg) = BCD_IN - valor BCD de entrada ;
; Output: no devolve nada (void) ;
; ;
; Retorna em Bank0 ;
;===================================================================;
prt_disp7seg
movwf bcd_in
call display ; display(bcd_in,disp_7seg);
movlw 1 ; W(reg) = 1
call Delay ; delay( 10ms )
incf disp_7seg,f ; disp_7seg ++;
return
;===================================================================;
; Input: BCD_IN - valor BCD de entrada ;
; Input: DISP_7SEG - seleo do display a ser refrescado ;
; Output: no devolve nada (void) ;
; ;
; Resumo: Subroutina de Controlo dos displays ;
; Retorna em Bank0 ;
;===================================================================;
display
movf PORTA,w ; w = PORTA
andlw 0xF1 ;
movwf aux ; aux = w & 0xf1
disp_0 movfw disp_7seg ; switch(disp_7seg)
sublw 0x00 ;
btfss STATUS,Z ;
goto disp_1 ;
movfw aux ; case_0
iorlw 0x08 ; w = aux | 0x08
goto break ; break
disp_1 movfw disp_7seg ; switch(dis_7seg)
sublw 0x01 ;
btfss STATUS,Z ;
goto disp_2 ;
movfw aux ; case_1
iorlw 0x04 ; w = aux | 0x04
goto break ; break
disp_2 movfw aux ; case_2
iorlw 0x02 ; w = aux | 0x02
break movwf PORTA ; escrita na porta
call bcd_7seg ; bcd_7seg(bcd_in);
return

50
www.mecatronicadegaragem.blogspot.com

TP3 - Descodificador Hexadecimal / 7Seg, 3 displays

;===================================================================;
; bcd_7seg ;
; Input: bcd_in - valor BCD de entrada ;
; Output: no devolve nada (void) ;
; ;
; Resumo: routina => BCD to 7segment display, envia o valor ;
; passado em bcd_in para a PORTB por ;
; endereamento indirecto por registo. ;
; Retorna em Bank0 ;
;===================================================================;
bcd_7seg
movlw seg70 ; Incio da tabela de valores
addwf bcd_in,w ; & do val a mostrar da tabela
movwf FSR ; Set do endereo da tabela
movf INDF,w ; leitura do valor de 7seg
movwf PORTB ; envio do valor para o PORTB
return
;===================================================================;
; Delay ;
; Pode gerar delays entre 10 mS e 2,5 S ;
; O valor de entrada e passado em W (1..255) ;
; ;
; Notas: o loop base e de 1 uS (T=200 nS <=> 4*1/20MHz) ;
; ;
; Retorna em Bank0 ;
;===================================================================;
Delay
movwf delay_mult ; Carrega o valor multiplo
Del_m10 movlw 50 ; de 10 mS
movwf delay_k50 ; 50 => 10 mS
Del_50 movlw 200 ; 200 => 200 uS
movwf delay_k200 ; Carrega o valor
Del_200 nop ; correspondente a 200 uS
nop
decfsz delay_k200,f ; Decrementa "delay_k200".
; O resultado colocadao em
; "delay_k200"
goto Del_200 ; while( delay_k200 > 0 )
decfsz delay_k50,f ;
goto Del_50 ; while( delay_k50 > 0 )
decfsz delay_mult,f ; Decrementa "delay_mult".
; O resultado colocadao
; em "delay_mult"
goto Del_m10 ; while( delay_mult > 0 )
return ;
;********************************************************************
END ; directive end of program

51
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

NOTAS:

52
www.mecatronicadegaragem.blogspot.com

TP4 - Contador de 60 segundos, verso I


Tema a desenvolver Durao
Contagem de tempo, por contagem de instrues 2 aulas

1 Resumo

Implementao de um contador de 60 seg., usando contagem do tempo por execuo de um programa.

2 Objectivos

Manipulao da rotina Delay para contagem de tempo;


Envio de informao para dois displays a partir de um registo de 8 bits;
Construo de uma rotina de decremento de uma varivel em BCD.

3 Descrio

O tempo de execuo de uma instruo normal de 1 ciclo de relgio (200 ns), com a excepo das
instrues de salto condicional, decfsz, incfsz, btfss, btfsc, (apenas quando executada a instruo de
salto) e as de salto incondicional, goto, que levam 2 ciclos de relgio (400 ns). Assim e de forma
precisa, pode-se o contar tempo recorrendo contagem de instrues de um determinado trecho de
cdigo, exemplo:
; n de ciclos de instrues
;---------------------------
delay movlw 100 ; 1
movwf timer ; + 1
loop nop ; + (1 x 100)
nop ; + (1 x 100)
decfsz timer,f ; + (1 x 100)
goto loop ; + (2 x 99) + 1
;---------------------------
return ; Total 501
O tempo que o processador leva a executar cada um dos primeiros 99 ciclos de loop de 1s,
uma vez que, a instruo nop demora 1 ciclo de relgio, decfsz 1 ciclo de relgio e goto 2 ciclos de
relgio. O ltimo ciclo de loop demora menos 200ns, dado que a instruo goto no executada.
Logo o tempo total de aproximadamente 100s (mais exactamente 99,8s).

53
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

3.1 Rotina Delay

Disponvel deste o primeiro trabalho, a rotina Delay implementa a funcionalidade de contagem de


tempo por contagem de instrues. Um exemplo disso, o trabalho prtico 0, onde o atraso efectuado
pela rotina Delay, til no controle do tempo de on/off do led.
A figura 21, mostra o diagrama de fluxo da rotina Delay, mostrando as vrias etapas na contagem
do tempo.

Figura 21: Diagrama de fluxo da rotina Delay

54
www.mecatronicadegaragem.blogspot.com

TP4 - 60 segundos, verso I

Abaixo mostra-se o cdigo Assembly da rotina Delay, de notar que, o ciclo base de 1s da rotina,
foi feito um pouco imagem do trecho de cdigo exemplo descrito no incio do trabalho, recorrendo s
instrues de nop (no operation), decfsz (decrement skip if zero) e goto. No entanto, envoltos no ciclo
base esto mais dois ciclos de loop que provocam um aumento do valor de instrues executadas o
que implica necessariamente um aumento de tempo. Estes ciclos Del_200 e Del_50, respectivamente
de 1s200 = 200s e 1s20050 = 10ms, permitem que para uma entrada compreendida entre
[1..255] podemos ter atrasos de entre 10ms e 2,5s.

;===================================================================;
; Delay ;
; Pode gerar delays entre 10 mS e 2,5 S ;
; O valor de entrada e passado em W (1..255) ;
; ;
; Notas: o loop base e de 1 uS (T=200 nS <=> 4*1/20MHz) ;
; ;
;===================================================================;
Delay
movwf delay_mult ; Carrega o valor mltiplo
Del_m10 movlw 50 ; de 10 mS
movwf delay_k50 ; 50 => 10 mS
Del_50 movlw 200 ; 200 => 200 uS
movwf delay_k200 ; Carrega o valor
Del_200 nop ; correspondente a 200 uS
nop
decfsz delay_k200,f ; Decrementa "delay_k200".
; O resultado colocadao em
; "delay_k200"
goto Del_200 ; while( delay_k200 > 0 )
decfsz delay_k50,f ;
goto Del_50 ; while( delay_k50 > 0 )
decfsz delay_mult,f ; Decrementa "delay_mult".
; O resultado colocadao
; em "delay_mult"
goto Del_m10 ; while( delay_mult > 0 )
return

55
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

4 Trabalho a realizar

1. Implementao de um programa que permita a visualizao (com refrescamento a cada 10ms)


em dois displays de 7 segmentos, de um valor presente em uma varivel (registo de uso geral),
inicializada com o valor 0x60. A visualizao deve ser feita utilizando as rotinas "display" e
"bcd_7seg" desenvolvidas nos trabalhos anteriores. A figura 22 mostra o esquema de ligao
pretendido, bem como a estratgia a usar na codificao dos bits a enviar para cada display de
7 segmentos.

Figura 22: Diagrama do circuito para para visualizao do valor 0x60

2. Construir uma rotina que implemente a contagem decrescente do valor 0x60 presente na va-
rivel, inicializada no ponto anterior. O decremento deve ser feito em decimal, ou seja de 60s
59s at 0s (ver figura 23).
Esta rotina deve ser chamada, a cada segundo, no programa que implementa a visualizao da
varivel descrita no ponto anterior. O programa principal deve, ao detectar a chegada da varivel
a 0, enviar para os displays a mensagem End (ver figura 24)

56
www.mecatronicadegaragem.blogspot.com

TP4 - 60 segundos, verso I

Figura 23: Diagrama do circuito, exemplifica a passagem de 60 59

Figura 24: Diagrama do circuito, exemplifica o trmino da contagem

3. Depois do contador de 60s estar a funcionar correctamente, deve adicionar-se um boto de


presso que implemente apenas o START do incio da contagem dos 60s (ver figuras 25 e 26).

57
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

Figura 25: Diagrama do circuito com sw, antes de se pressionar no boto

Figura 26: Diagrama do circuito com sw, aps pressionar no boto

Elementos de Apoio

Manual terico da disciplina.


DataSheet PIC16F876(DS30292C) Microchip, captulo 3. - I/O Ports, pgina 29.
DataSheet PIC16F876(DS30292C) Microchip, captulo 13 - Instrution Set Summary, p-
gina 135.

58
www.mecatronicadegaragem.blogspot.com

TP4 - 60 segundos, verso I

5 Implementao em Assembly do PIC

5.1 Ponto 1
; Trabalho Prtico n 4 II
;
; Implementao de relgio de 60 segundos, com rotina Delay
;
;********************************************************************
; *
; NomeFicheiro: trab4p1.asm *
; Data: 3/Junho/2005 *
; Verso: 1.0 *
; *
; Autores: Jos Miguel Gaspar *
; Olmpia Rodrigues *
; *
; Orientador: Prof. Jos Lus Azevedo *
; *
; Universidade de Aveiro *
; Seminrio EEI 2004/2004 *
; *
;********************************************************************
; *
; Ficheiro necessrio: P16F876.LKR *
; *
;********************************************************************
list p=16f876 ; - directiva list, define
; o processor a usar
radix decimal ; - directiva radix especifica
; definio das variveis
#include "p16f876.inc" ; - directiva include inclui
; ficheiro adicional
errorlevel -302 ; Turn off banking message
; known tested (good) code
;--------------------------------------------------------------------
; Constantes
;--------------------------------------------------------------------
RA0 EQU 0
RA1 EQU 1
RA2 EQU 2
RA3 EQU 3
RA4 EQU 4
RA5 EQU 5
RB0 EQU 0
RB1 EQU 1
RB2 EQU 2
RB3 EQU 3
RB4 EQU 4
RB5 EQU 5
RB6 EQU 6
RB7 EQU 7
RC0 EQU 0
RC1 EQU 1
RC2 EQU 2
RC3 EQU 3
RC4 EQU 4
RC5 EQU 5
RC6 EQU 6
RC7 EQU 7

;--------------------------------------------------------------------
; Displays de 7 segmentos -|gfedcba-|

59
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

;--------------------------------------------------------------------
seg7_0 EQU b01111110 ; Valor 0
seg7_1 EQU b00001100 ; Valor 1
seg7_2 EQU b10110110 ; Valor 2
seg7_3 EQU b10011110 ; Valor 3
seg7_4 EQU b11001100 ; Valor 4
seg7_5 EQU b11011010 ; Valor 5
seg7_6 EQU b11111000 ; Valor 6
seg7_7 EQU b00001110 ; Valor 7
seg7_8 EQU b11111110 ; Valor 8
seg7_9 EQU b11001110 ; Valor 9
seg7_A EQU b11101110 ; Valor A
seg7_B EQU b11111000 ; Valor B
seg7_C EQU b01110010 ; Valor C
seg7_D EQU b10111100 ; Valor D
seg7_E EQU b11110010 ; Valor E
seg7_F EQU b11100010 ; Valor F
seg7_n EQU b10101000 ; Valor n
seg7_null EQU b00000000 ; Valor Null
;--------------------------------------------------------------------
; Variveis (REGISTOS DE USO GERAL) Bank0
;--------------------------------------------------------------------
variaveis UDATA 0x20
seg70 RES 1 ; Valor 0 endereo
seg71 RES 1 ; Valor 1 endereo
seg72 RES 1 ; Valor 2 endereo
seg73 RES 1 ; Valor 3 endereo
seg74 RES 1 ; Valor 4 endereo
seg75 RES 1 ; Valor 5 endereo
seg76 RES 1 ; Valor 6 endereo
seg77 RES 1 ; Valor 7 endereo
seg78 RES 1 ; Valor 8 endereo
seg79 RES 1 ; Valor 9 endereo
seg7A RES 1 ; Valor A endereo
seg7B RES 1 ; Valor B endereo
seg7C RES 1 ; Valor C endereo
seg7D RES 1 ; Valor D endereo
seg7E RES 1 ; Valor E endereo
seg7F RES 1 ; Valor F endereo
seg7n RES 1 ; Valor n endereo
seg7null RES 1 ; Valor null endereo
bcd_in RES 1 ; endereo de entrada BCD
counter RES 1 ; valor a ser decrementado
disp_7seg RES 1 ; seleo do display de 7_seg
delay_mult RES 1 ; Variaveis de controlo
delay_k50 RES 1 ; dos loops
delay_k200 RES 1 ; da rotina Delay
delay_cnt RES 1
aux RES 1
;--------------------------------------------------------------------
; Macros to select the register Banks
;--------------------------------------------------------------------
Bank0 MACRO ; Macro to select data RAM Bank 0
bcf STATUS,RP0
bcf STATUS,RP1
ENDM
Bank1 MACRO ; Macro to select data RAM Bank 1
bsf STATUS,RP0
bcf STATUS,RP1
ENDM
Bank2 MACRO ; Macro to select data RAM Bank 2

60
www.mecatronicadegaragem.blogspot.com

TP4 - 60 segundos, verso I

bcf STATUS,RP0
bsf STATUS,RP1
ENDM
Bank3 MACRO ; Macro to select data RAM Bank 3
bsf STATUS,RP0
bsf STATUS,RP1
ENDM
;********************************************************************
ORG 0x0000 ; Processor reset vector
clrf PCLATH ; Ensure page bits are cleared
goto main ; Go to beginning of program
;--------------------------------------------------------------------
; Rotina Main
;--------------------------------------------------------------------
ORG 0x0005 ; Program Memory PAGE 0
main ; Programa principal.
call InitCfg ; rotina de configurao
movlw 0x60 ;
movwf counter ; Valor Inicial do contador seg
loop movlw 0 ;
movwf disp_7seg ; display 2
movfw counter ;
andlw 0xf ;
call display ; display(W,disp_7seg);
movlw 1 ;
call delay ; Delay(10 ms)
movlw 1 ;
movwf disp_7seg ; display 1
swapf counter,w ;
andlw 0x0f ;
call display ; display(W,disp_7seg);
movlw 1 ;
call delay ; Delay(10 ms)
goto loop ;
;********************************************************************

;************************** ROTINAS *********************************


;********************************************************************
;********************************************************************
;===================================================================;
; InitCfg ;
; Configurao inicial dos registros associados ;
; ao programa principal, PORTOS I/O ;
; ;
; Retorna em Bank0 ;
; ;
;===================================================================;
InitCfg
;----------------- I/O - InitCfg -----------------------------------;
Bank1 ; DATA memory (RAM) Bank1
movlw b00010000 ; RA[7:5 & 3:0] outputs
movwf TRISA ; RA[4] input
movlw b00000001 ; RB[7:1] outputs
movwf TRISB ; RB[0] input
Bank0 ; DATA memory (RAM) Bank0
clrf PORTA ; inicializao PORTA
clrf PORTB ; inicializao PORTB
clrf disp_7seg ; disp_7seg = 0;
;--------------------------------------------------------------------
; Inicializao dos registros associados aos displays 7seg

61
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

;--------------------------------------------------------------------
movlw seg7_0 ; Set 7segment valor 0
movwf seg70 ; Save valor 0
movlw seg7_1 ; Set 7segment valor 1
movwf seg71 ; Save valor 1
movlw seg7_2 ; Set 7segment valor 2
movwf seg72 ; Save valor 2
movlw seg7_3 ; Set 7segment valor 3
movwf seg73 ; Save valor 3
movlw seg7_4 ; Set 7segment valor 4
movwf seg74 ; Save valor 4
movlw seg7_5 ; Set 7segment valor 5
movwf seg75 ; Save valor 5
movlw seg7_6 ; Set 7segment valor 6
movwf seg76 ; Save valor 6
movlw seg7_7 ; Set 7segment valor 7
movwf seg77 ; Save valor 7
movlw seg7_8 ; Set 7segment valor 8
movwf seg78 ; Save valor 8
movlw seg7_9 ; Set 7segment valor 9
movwf seg79 ; Save valor 9
movlw seg7_A ; Set 7segment valor A
movwf seg7A ; Save valor A
movlw seg7_B ; Set 7segment valor B
movwf seg7B ; Save valor B
movlw seg7_C ; Set 7segment valor C
movwf seg7C ; Save valor C
movlw seg7_D ; Set 7segment valor D
movwf seg7D ; Save valor D
movlw seg7_E ; Set 7segment valor E
movwf seg7E ; Save valor E
movlw seg7_F ; Set 7segment valor F
movwf seg7F ; Save valor F
movlw seg7_n ; Set 7segment pattern N
movwf seg7n ; Save pattern N
movlw seg7_null ; Set 7segment pattern NULL
movwf seg7null ; Save pattern N
return
;===================================================================;
; Input: BCD_IN - valor BCD de entrada ;
; Input: DISP_7SEG - seleo do display a ser refrescado ;
; Output: no devolve nada (void) ;
; ;
; Resumo: Subroutina de Controlo dos displays ;
; Retorna em Bank0 ;
;===================================================================;
display
movwf bcd_in ;
movfw PORTA ; w = PORTA
andlw 0xF1 ;
movwf aux ; aux = w & 0xf1
disp_0 movfw disp_7seg ; switch(disp_7seg)
sublw 0x00 ;
btfss STATUS,Z ;
goto disp_1 ;
movfw aux ; case_0
iorlw 0x08 ; w = aux | 0x08
goto break ; break
disp_1 movfw disp_7seg ; switch(dis_7seg)
sublw 0x01 ;
btfss STATUS,Z ;
goto disp_2 ;
movfw aux ; case_1
iorlw 0x04 ; w = aux | 0x04

62
www.mecatronicadegaragem.blogspot.com

TP4 - 60 segundos, verso I

goto break ; break


disp_2 movfw aux ; case_2
iorlw 0x02 ; w = aux | 0x02
break movwf PORTA ; escrita na porta
call bcd_7seg ; bcd_7seg(bcd_in);
return
;===================================================================;
; bcd_7seg ;
; Input: bcd_in - valor BCD de entrada ;
; Output: no devolve nada (void) ;
; ;
; Resumo: routina => BCD to 7segment display, envia o valor ;
; passado em bcd_in para a PORTB por ;
; endereamento indirecto por registo. ;
; Retorna em Bank0 ;
;===================================================================;
bcd_7seg
movlw seg70 ; Incio da tabela de valores
addwf bcd_in,w ; endereo do valor a mostrar
movwf FSR ; Set do endereo da tabela
movf INDF,w ; leitura do valor de 7seg
movwf PORTB ; envio do valor para o PORTB
return
;===================================================================;
; Delay ;
; Pode gerar delays entre 10 mS e 2,5 S ;
; O valor de entrada e passado em W (1..255) ;
; ;
; Notas: o loop base e de 1 uS (T=200 nS <=> 4*1/20MHz) ;
; ;
; Retorna em Bank0 ;
;===================================================================;
delay
movwf delay_mult ; Carrega o valor multiplo
Del_m10 movlw 50 ; de 10 mS
movwf delay_k50 ; 50 => 10 mS
Del_50 movlw 200 ; 200 => 200 uS
movwf delay_k200 ; Carrega o valor
Del_200 nop ; correspondente a 200 uS
nop
decfsz delay_k200,f ; Decrementa "delay_k200".
; O resultado colocadao em
; "delay_k200"
goto Del_200 ; while( delay_k200 > 0 )
decfsz delay_k50,f ;
goto Del_50 ; while( delay_k50 > 0 )
decfsz delay_mult,f ; Decrementa "delay_mult".
; O resultado colocadao
; em "delay_mult"
goto Del_m10 ; while( delay_mult > 0 )
return
;********************************************************************
END ; directive end of program

63
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

5.2 Ponto 2
; Trabalho Prtico n 4 II
;
; Implementao de relgio de 60 segundos, com rotina Delay
;
;********************************************************************
; *
; NomeFicheiro: trab4p2.asm *
; Data: 3/Junho/2005 *
; Verso: 1.0 *
; *
; Autores: Jos Miguel Gaspar *
; Olmpia Rodrigues *
; *
; Orientador: Prof. Jos Lus Azevedo *
; *
; Universidade de Aveiro *
; Seminrio EEI 2004/2004 *
; *
;********************************************************************
; *
; Ficheiro necessrio: P16F876.LKR *
; *
;********************************************************************
list p=16f876 ; - directiva list, define
; o processor a usar
radix decimal ; - directiva radix especifica
; definio das variveis
#include "p16f876.inc" ; - directiva include inclui
; ficheiro adicional
errorlevel -302 ; Turn off banking message
; known tested (good) code
;--------------------------------------------------------------------
; Constantes
;--------------------------------------------------------------------
RA0 EQU 0
RA1 EQU 1
RA2 EQU 2
RA3 EQU 3
RA4 EQU 4
RA5 EQU 5
RB0 EQU 0
RB1 EQU 1
RB2 EQU 2
RB3 EQU 3
RB4 EQU 4
RB5 EQU 5
RB6 EQU 6
RB7 EQU 7
RC0 EQU 0
RC1 EQU 1
RC2 EQU 2
RC3 EQU 3
RC4 EQU 4
RC5 EQU 5
RC6 EQU 6
RC7 EQU 7

;--------------------------------------------------------------------
; Displays de 7 segmentos -|gfedcba-|
;--------------------------------------------------------------------
seg7_0 EQU b01111110 ; Valor 0

64
www.mecatronicadegaragem.blogspot.com

TP4 - 60 segundos, verso I

seg7_1 EQU b00001100 ; Valor 1


seg7_2 EQU b10110110 ; Valor 2
seg7_3 EQU b10011110 ; Valor 3
seg7_4 EQU b11001100 ; Valor 4
seg7_5 EQU b11011010 ; Valor 5
seg7_6 EQU b11111000 ; Valor 6
seg7_7 EQU b00001110 ; Valor 7
seg7_8 EQU b11111110 ; Valor 8
seg7_9 EQU b11001110 ; Valor 9
seg7_A EQU b11101110 ; Valor A
seg7_B EQU b11111000 ; Valor B
seg7_C EQU b01110010 ; Valor C
seg7_D EQU b10111100 ; Valor D
seg7_E EQU b11110010 ; Valor E
seg7_F EQU b11100010 ; Valor F
seg7_n EQU b10101000 ; Valor n
seg7_null EQU b00000000 ; Valor Null
;--------------------------------------------------------------------
; Variveis (REGISTOS DE USO GERAL) Bank0
;--------------------------------------------------------------------
variaveis UDATA 0x20
seg70 RES 1 ; Valor 0 endereo
seg71 RES 1 ; Valor 1 endereo
seg72 RES 1 ; Valor 2 endereo
seg73 RES 1 ; Valor 3 endereo
seg74 RES 1 ; Valor 4 endereo
seg75 RES 1 ; Valor 5 endereo
seg76 RES 1 ; Valor 6 endereo
seg77 RES 1 ; Valor 7 endereo
seg78 RES 1 ; Valor 8 endereo
seg79 RES 1 ; Valor 9 endereo
seg7A RES 1 ; Valor A endereo
seg7B RES 1 ; Valor B endereo
seg7C RES 1 ; Valor C endereo
seg7D RES 1 ; Valor D endereo
seg7E RES 1 ; Valor E endereo
seg7F RES 1 ; Valor F endereo
seg7n RES 1 ; Valor n endereo
seg7null RES 1 ; Valor null endereo
bcd_in RES 1 ; endereo de entrada BCD
counter RES 1 ; valor a ser decrementado
disp_7seg RES 1 ; seleo do display de 7_seg
delay_mult RES 1 ; Variaveis de controlo
delay_k50 RES 1 ; dos loops
delay_k200 RES 1 ; da rotina Delay
delay_cnt RES 1
aux RES 1
;--------------------------------------------------------------------
; Macros to select the register Banks
;--------------------------------------------------------------------
Bank0 MACRO ; Macro to select data RAM Bank 0
bcf STATUS,RP0
bcf STATUS,RP1
ENDM
Bank1 MACRO ; Macro to select data RAM Bank 1
bsf STATUS,RP0
bcf STATUS,RP1
ENDM
Bank2 MACRO ; Macro to select data RAM Bank 2
bcf STATUS,RP0
bsf STATUS,RP1
ENDM

65
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

Bank3 MACRO ; Macro to select data RAM Bank 3


bsf STATUS,RP0
bsf STATUS,RP1
ENDM
;********************************************************************
ORG 0x0000 ; Processor reset vector
clrf PCLATH ; Ensure page bits are cleared
goto main ; Go to beginning of program
;--------------------------------------------------------------------
; Rotina Main
;--------------------------------------------------------------------
ORG 0x0005 ; Program Memory PAGE 0
main ; Programa principal.
call InitCfg ; rotina de configurao
init_count movlw 0 ;
movwf disp_7seg ; display 2
movfw counter ;
andlw 0xf ;
call display ; display(W,disp_7seg);
movlw 1 ;
call delay ; Delay(10 ms)
movlw 1 ;
movwf disp_7seg ; display 1
swapf counter,w ;
andlw 0x0f ;
call display ; display(W,disp_7seg);
movlw 1 ;
call delay ; Delay(10 ms)

do_main movlw 1 ; do{


call delay ; delay ( 10ms )
if_main btfsc disp_7seg,0; if(disp_7seg == 0)
goto else_main ; {
movfw counter ; w = counter
andlw 0x0F ; w = w & 0x0F
; W = counter & 0x0F
goto display_main ;
else_main ; } else
swapf counter,w ;
andlw 0x0F ;
btfsc STATUS,Z ;
goto $+3 ;
; W = counter >> 4
display_main call display ; display(W,disp_7seg);
incf disp_7seg,w ;
andlw 0x01 ;
movwf disp_7seg ; disp_7seg=(++disp_7seg)&0x01
decfsz delay_cnt,f ; if((timer0_cnt--) == 0 )
goto do_main ; {
movlw 100 ;
movwf delay_cnt ; timer0_cnt = 100;
call countdown ; countdown(counter);
btfss STATUS,Z ; }while(STATUS,Z == 0);
goto do_main ; Yes, repeat COUNT
; No, TIME OUT
loop clrf disp_7seg
movlw 0x0d
call prt_disp7seg
movlw 0x10
call prt_disp7seg
movlw 0x0E
call prt_disp7seg

66
www.mecatronicadegaragem.blogspot.com

TP4 - 60 segundos, verso I

goto loop
;********************************************************************

;************************** ROTINAS *********************************


;********************************************************************
;********************************************************************
;===================================================================;
; InitCfg ;
; Configurao inicial dos registros associados ;
; ao programa principal, PORTOS I/O ;
; ;
; Retorna em Bank0 ;
; ;
;===================================================================;
InitCfg
;----------------- I/O - InitCfg -----------------------------------;
Bank1 ; DATA memory (RAM) Bank1
movlw b00010000 ; RA[7:5 & 3:0] outputs
movwf TRISA ; RA[4] input
movlw b00000001 ; RB[7:1] outputs
movwf TRISB ; RB[0] input
Bank0 ; DATA memory (RAM) Bank0
clrf PORTA ; inicializao PORTA
clrf PORTB ; inicializao PORTB
clrf disp_7seg ; disp_7seg = 0;
movlw 0x60 ;
movwf counter ; Valor Inicial do contador seg
;--------------------------------------------------------------------
; Inicializao dos registros associados aos displays 7seg
;--------------------------------------------------------------------
movlw seg7_0 ; Set 7segment valor 0
movwf seg70 ; Save valor 0
movlw seg7_1 ; Set 7segment valor 1
movwf seg71 ; Save valor 1
movlw seg7_2 ; Set 7segment valor 2
movwf seg72 ; Save valor 2
movlw seg7_3 ; Set 7segment valor 3
movwf seg73 ; Save valor 3
movlw seg7_4 ; Set 7segment valor 4
movwf seg74 ; Save valor 4
movlw seg7_5 ; Set 7segment valor 5
movwf seg75 ; Save valor 5
movlw seg7_6 ; Set 7segment valor 6
movwf seg76 ; Save valor 6
movlw seg7_7 ; Set 7segment valor 7
movwf seg77 ; Save valor 7
movlw seg7_8 ; Set 7segment valor 8
movwf seg78 ; Save valor 8
movlw seg7_9 ; Set 7segment valor 9
movwf seg79 ; Save valor 9
movlw seg7_A ; Set 7segment valor A
movwf seg7A ; Save valor A
movlw seg7_B ; Set 7segment valor B
movwf seg7B ; Save valor B
movlw seg7_C ; Set 7segment valor C
movwf seg7C ; Save valor C
movlw seg7_D ; Set 7segment valor D
movwf seg7D ; Save valor D
movlw seg7_E ; Set 7segment valor E
movwf seg7E ; Save valor E
movlw seg7_F ; Set 7segment valor F
movwf seg7F ; Save valor F
movlw seg7_n ; Set 7segment pattern N

67
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

movwf seg7n ; Save pattern N


movlw seg7_null ; Set 7segment pattern NULL
movwf seg7null ; Save pattern N
return
;===================================================================;
; Input: W(reg) = BCD_IN - valor BCD de entrada ;
; Output: no devolve nada (void) ;
; ;
; Retorna em Bank0 ;
;===================================================================;
prt_disp7seg
movwf bcd_in
call display ; display(bcd_in,disp_7seg);
movlw 1 ; W(reg) = 1
call delay ; delay( 10ms )
incf disp_7seg,f ; disp_7seg ++;
return
;===================================================================;
; Input: W - valor BCD de entrada ;
; Input: DISP_7SEG - seleo do display a ser refrescado ;
; Output: no devolve nada (void) ;
; ;
; Resumo: Subroutina de Controlo dos displays ;
; Retorna em Bank0 ;
;===================================================================;
display
movwf bcd_in ;
movfw PORTA ; w = PORTA
andlw 0xF1 ;
movwf aux ; aux = w & 0xf1
disp_0 movfw disp_7seg ; switch(disp_7seg)
sublw 0x00 ;
btfss STATUS,Z ;
goto disp_1 ;
movfw aux ; case_0
iorlw 0x08 ; w = aux | 0x08
goto break ; break
disp_1 movfw disp_7seg ; switch(dis_7seg)
sublw 0x01 ;
btfss STATUS,Z ;
goto disp_2 ;
movfw aux ; case_1
iorlw 0x04 ; w = aux | 0x04
goto break ; break
disp_2 movfw aux ; case_2
iorlw 0x02 ; w = aux | 0x02
break movwf PORTA ; escrita na porta
call bcd_7seg ; bcd_7seg(bcd_in);
return
;===================================================================;
; bcd_7seg ;
; Input: bcd_in - valor BCD de entrada ;
; Output: no devolve nada (void) ;
; ;
; Resumo: routina => BCD to 7segment display, envia o valor ;
; passado em bcd_in para a PORTB por ;
; endereamento indirecto por registo. ;
; Retorna em Bank0 ;

68
www.mecatronicadegaragem.blogspot.com

TP4 - 60 segundos, verso I

;===================================================================;
bcd_7seg
movlw seg70 ; Incio da tabela de valores
addwf bcd_in,w ; endereo do valor a mostrar
movwf FSR ; Set do endereo da tabela
movf INDF,w ; leitura do valor de 7seg
movwf PORTB ; envio do valor para o PORTB
return
;===================================================================;
; Input: COUNTER - valor de entrada ;
; Output: COUNTER - valor decrementado uma unidade ;
; Flag de Zero afectada: ;
; Z=0 if COUNTER != FF ;
; Z=1 if COUNTER == FF ;
; Retorna em Bank0 ;
;===================================================================;
countdown
decf counter,f ; counter--
movfw counter ; w = counter
sublw 0xFF ;
btfsc STATUS,Z ; if( w == 0xFF )
return ; return
movfw counter ; w = counter
andlw 0x0F ; w = w & 0x0F
sublw 0x0F ;
btfss STATUS, Z ; if( w != 0x0F)
goto dif_xf ; goto dif_xf
movfw counter ; w = counter
andlw 0xF0 ; w = w & 0xF0
iorlw 0x09 ; w = w | 0x09
movwf counter ; counter = w
dif_xf: bcf STATUS,Z ; reset ZERO flag
return
;===================================================================;
; Delay ;
; Pode gerar delays entre 10 mS e 2,5 S ;
; O valor de entrada e passado em W (1..255) ;
; ;
; Notas: o loop base e de 1 uS (T=200 nS <=> 4*1/20MHz) ;
; ;
; Retorna em Bank0 ;
;===================================================================;
delay
movwf delay_mult ; Carrega o valor multiplo
Del_m10 movlw 50 ; de 10 mS
movwf delay_k50 ; 50 => 10 mS
Del_50 movlw 200 ; 200 => 200 uS
movwf delay_k200 ; Carrega o valor
Del_200 nop ; correspondente a 200 uS
nop
decfsz delay_k200,f ; Decrementa "delay_k200".
; O resultado colocadao em
; "delay_k200"
goto Del_200 ; while( delay_k200 > 0 )
decfsz delay_k50,f ;
goto Del_50 ; while( delay_k50 > 0 )
decfsz delay_mult,f ; Decrementa "delay_mult".
; O resultado colocadao
; em "delay_mult"
goto Del_m10 ; while( delay_mult > 0 )
return
;********************************************************************

69
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

END ; directive end of program

70
www.mecatronicadegaragem.blogspot.com

TP4 - 60 segundos, verso I

5.3 Ponto 3
; Trabalho Prtico n 4 III
;
; Implementao de relgio de 60 segundos, com rotina Delay
;
;********************************************************************
; *
; NomeFicheiro: trab4p3.asm *
; Data: 3/Junho/2005 *
; Verso: 1.0 *
; *
; Autores: Jos Miguel Gaspar *
; Olmpia Rodrigues *
; *
; Orientador: Prof. Jos Lus Azevedo *
; *
; Universidade de Aveiro *
; Seminrio EEI 2004/2004 *
; *
;********************************************************************
; *
; Ficheiro necessrio: P16F876.LKR *
; *
;********************************************************************
list p=16f876 ; - directiva list, define
; o processor a usar
radix decimal ; - directiva radix especifica
; definio das variveis
#include "p16f876.inc" ; - directiva include inclui
; ficheiro adicional
errorlevel -302 ; Turn off banking message
; known tested (good) code
;--------------------------------------------------------------------
; Constantes
;--------------------------------------------------------------------
RA0 EQU 0
RA1 EQU 1
RA2 EQU 2
RA3 EQU 3
RA4 EQU 4
RA5 EQU 5
RB0 EQU 0
RB1 EQU 1
RB2 EQU 2
RB3 EQU 3
RB4 EQU 4
RB5 EQU 5
RB6 EQU 6
RB7 EQU 7
RC0 EQU 0
RC1 EQU 1
RC2 EQU 2
RC3 EQU 3
RC4 EQU 4
RC5 EQU 5
RC6 EQU 6
RC7 EQU 7

;--------------------------------------------------------------------
; Displays de 7 segmentos -|gfedcba-|
;--------------------------------------------------------------------

71
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

seg7_0 EQU b01111110 ; Valor 0


seg7_1 EQU b00001100 ; Valor 1
seg7_2 EQU b10110110 ; Valor 2
seg7_3 EQU b10011110 ; Valor 3
seg7_4 EQU b11001100 ; Valor 4
seg7_5 EQU b11011010 ; Valor 5
seg7_6 EQU b11111000 ; Valor 6
seg7_7 EQU b00001110 ; Valor 7
seg7_8 EQU b11111110 ; Valor 8
seg7_9 EQU b11001110 ; Valor 9
seg7_A EQU b11101110 ; Valor A
seg7_B EQU b11111000 ; Valor B
seg7_C EQU b01110010 ; Valor C
seg7_D EQU b10111100 ; Valor D
seg7_E EQU b11110010 ; Valor E
seg7_F EQU b11100010 ; Valor F
seg7_n EQU b10101000 ; Valor n
seg7_null EQU b00000000 ; Valor Null
;--------------------------------------------------------------------
; Variveis (REGISTOS DE USO GERAL) Bank0
;--------------------------------------------------------------------
variaveis UDATA 0x20
seg70 RES 1 ; Valor 0 endereo
seg71 RES 1 ; Valor 1 endereo
seg72 RES 1 ; Valor 2 endereo
seg73 RES 1 ; Valor 3 endereo
seg74 RES 1 ; Valor 4 endereo
seg75 RES 1 ; Valor 5 endereo
seg76 RES 1 ; Valor 6 endereo
seg77 RES 1 ; Valor 7 endereo
seg78 RES 1 ; Valor 8 endereo
seg79 RES 1 ; Valor 9 endereo
seg7A RES 1 ; Valor A endereo
seg7B RES 1 ; Valor B endereo
seg7C RES 1 ; Valor C endereo
seg7D RES 1 ; Valor D endereo
seg7E RES 1 ; Valor E endereo
seg7F RES 1 ; Valor F endereo
seg7n RES 1 ; Valor n endereo
seg7null RES 1 ; Valor null endereo
bcd_in RES 1 ; endereo de entrada BCD
counter RES 1 ; valor a ser decrementado
disp_7seg RES 1 ; seleo do display de 7_seg
delay_mult RES 1 ; Variaveis de controlo
delay_k50 RES 1 ; dos loops
delay_k200 RES 1 ; da rotina Delay
delay_cnt RES 1
aux RES 1
;--------------------------------------------------------------------
; Macros to select the register Banks
;--------------------------------------------------------------------
Bank0 MACRO ; Macro to select data RAM Bank 0
bcf STATUS,RP0
bcf STATUS,RP1
ENDM
Bank1 MACRO ; Macro to select data RAM Bank 1
bsf STATUS,RP0
bcf STATUS,RP1
ENDM
Bank2 MACRO ; Macro to select data RAM Bank 2
bcf STATUS,RP0
bsf STATUS,RP1

72
www.mecatronicadegaragem.blogspot.com

TP4 - 60 segundos, verso I

ENDM
Bank3 MACRO ; Macro to select data RAM Bank 3
bsf STATUS,RP0
bsf STATUS,RP1
ENDM
;********************************************************************
ORG 0x0000 ; Processor reset vector
clrf PCLATH ; Ensure page bits are cleared
goto main ; Go to beginning of program
;--------------------------------------------------------------------
; Rotina Main
;--------------------------------------------------------------------
ORG 0x0005 ; Program Memory PAGE 0
main ; Programa principal.
call InitCfg ; rotina de configurao
init_count movlw 0 ;
movwf disp_7seg ; display 2
movfw counter ;
andlw 0xf ;
call display ; display(W,disp_7seg);
movlw 1 ;
call delay ; Delay(10 ms)
movlw 1 ;
movwf disp_7seg ; display 1
swapf counter,w ;
andlw 0x0f ;
call display ; display(W,disp_7seg);
movlw 1 ;
call delay ; Delay(10 ms)
btfsc PORTA,RA4 ; START ON
goto init_count ; NO?
; YES
do_main movlw 1 ; do{
call delay ; delay ( 10ms )
if_main btfsc disp_7seg,0 ; if(disp_7seg == 0)
goto else_main ; {
movfw counter ; ; w = counter
andlw 0x0F ; ; w = w & 0x0F
; W = counter & 0x0F
goto display_main ;
else_main ; } else
swapf counter,w ;
andlw 0x0F ;
btfsc STATUS,Z ;
goto $+3 ;
; W = counter >> 4
display_main call display ; display(W,disp_7seg);
incf disp_7seg,w ;
andlw 0x01 ;
movwf disp_7seg ; disp_7seg=(++disp_7seg)&0x01
decfsz delay_cnt,f ; if((timer0_cnt--) == 0 )
goto do_main ; {
movlw 100 ;
movwf delay_cnt ; timer0_cnt = 100;
call countdown ; countdown(counter);
btfss STATUS,Z ; }while(STATUS,Z == 0);
goto do_main ; Yes, repeat COUNT
; No, TIME OUT
loop clrf disp_7seg
movlw 0x0d
call prt_disp7seg
movlw 0x10
call prt_disp7seg

73
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

movlw 0x0E
call prt_disp7seg
goto loop
;********************************************************************

;************************** ROTINAS *********************************


;********************************************************************
;********************************************************************
;===================================================================;
; InitCfg ;
; Configurao inicial dos registros associados ;
; ao programa principal, PORTOS I/O ;
; ;
; Retorna em Bank0 ;
; ;
;===================================================================;
InitCfg
;----------------- I/O - InitCfg -----------------------------------;
Bank1 ; DATA memory (RAM) Bank1
movlw b00010000 ; RA[7:5 & 3:0] outputs
movwf TRISA ; RA[4] input
movlw b00000001 ; RB[7:1] outputs
movwf TRISB ; RB[0] input
Bank0 ; DATA memory (RAM) Bank0
clrf PORTA ; inicializao PORTA
clrf PORTB ; inicializao PORTB
clrf disp_7seg ; disp_7seg = 0;
movlw 0x60 ;
movwf counter ; Valor Inicial do contador seg
;--------------------------------------------------------------------
; Inicializao dos registros associados aos displays 7seg
;--------------------------------------------------------------------
movlw seg7_0 ; Set 7segment valor 0
movwf seg70 ; Save valor 0
movlw seg7_1 ; Set 7segment valor 1
movwf seg71 ; Save valor 1
movlw seg7_2 ; Set 7segment valor 2
movwf seg72 ; Save valor 2
movlw seg7_3 ; Set 7segment valor 3
movwf seg73 ; Save valor 3
movlw seg7_4 ; Set 7segment valor 4
movwf seg74 ; Save valor 4
movlw seg7_5 ; Set 7segment valor 5
movwf seg75 ; Save valor 5
movlw seg7_6 ; Set 7segment valor 6
movwf seg76 ; Save valor 6
movlw seg7_7 ; Set 7segment valor 7
movwf seg77 ; Save valor 7
movlw seg7_8 ; Set 7segment valor 8
movwf seg78 ; Save valor 8
movlw seg7_9 ; Set 7segment valor 9
movwf seg79 ; Save valor 9
movlw seg7_A ; Set 7segment valor A
movwf seg7A ; Save valor A
movlw seg7_B ; Set 7segment valor B
movwf seg7B ; Save valor B
movlw seg7_C ; Set 7segment valor C
movwf seg7C ; Save valor C
movlw seg7_D ; Set 7segment valor D
movwf seg7D ; Save valor D
movlw seg7_E ; Set 7segment valor E
movwf seg7E ; Save valor E
movlw seg7_F ; Set 7segment valor F

74
www.mecatronicadegaragem.blogspot.com

TP4 - 60 segundos, verso I

movwf seg7F ; Save valor F


movlw seg7_n ; Set 7segment pattern N
movwf seg7n ; Save pattern N
movlw seg7_null ; Set 7segment pattern NULL
movwf seg7null ; Save pattern N
return
;===================================================================;
; Input: W(reg) = BCD_IN - valor BCD de entrada ;
; Output: no devolve nada (void) ;
; ;
; Retorna em Bank0 ;
;===================================================================;
prt_disp7seg
movwf bcd_in
call display ; display(bcd_in,disp_7seg);
movlw 1 ; W(reg) = 1
call delay ; delay( 10ms )
incf disp_7seg,f ; disp_7seg ++;
return
;===================================================================;
; Input: BCD_IN - valor BCD de entrada ;
; Input: DISP_7SEG - seleo do display a ser refrescado ;
; Output: no devolve nada (void) ;
; ;
; Resumo: Subroutina de Controlo dos displays ;
; Retorna em Bank0 ;
;===================================================================;
display
movwf bcd_in ;
movfw PORTA ; w = PORTA
andlw 0xF1 ;
movwf aux ; aux = w & 0xf1
disp_0 movfw disp_7seg ; switch(disp_7seg)
sublw 0x00 ;
btfss STATUS,Z ;
goto disp_1 ;
movfw aux ; case_0
iorlw 0x08 ; w = aux | 0x08
goto break ; break
disp_1 movfw disp_7seg ; switch(dis_7seg)
sublw 0x01 ;
btfss STATUS,Z ;
goto disp_2 ;
movfw aux ; case_1
iorlw 0x04 ; w = aux | 0x04
goto break ; break
disp_2 movfw aux ; case_2
iorlw 0x02 ; w = aux | 0x02
break movwf PORTA ; escrita na porta
call bcd_7seg ; bcd_7seg(bcd_in);
return
;===================================================================;
; bcd_7seg ;
; Input: bcd_in - valor BCD de entrada ;
; Output: no devolve nada (void) ;
; ;
; Resumo: routina => BCD to 7segment display, envia o valor ;
; passado em bcd_in para a PORTB por ;

75
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

; endereamento indirecto por registo. ;


; Retorna em Bank0 ;
;===================================================================;
bcd_7seg
movlw seg70 ; Incio da tabela de valores
addwf bcd_in,w ; endereo do valor a mostrar
movwf FSR ; Set do endereo da tabela
movf INDF,w ; leitura do valor de 7seg
movwf PORTB ; envio do valor para o PORTB
return
;===================================================================;
; Input: COUNTER - valor de entrada ;
; Output: COUNTER - valor decrementado uma unidade ;
; Flag de Zero afectada: ;
; Z=0 if COUNTER != FF ;
; Z=1 if COUNTER == FF ;
; Retorna em Bank0 ;
;===================================================================;
countdown
decf counter,f ; counter--
movfw counter ; w = counter
sublw 0xFF ;
btfsc STATUS,Z ; if( w == 0xFF )
return ; return
movfw counter ; w = counter
andlw 0x0F ; w = w & 0x0F
sublw 0x0F ;
btfss STATUS, Z ; if( w != 0x0F)
goto dif_xf ; goto dif_xf
movfw counter ; w = counter
andlw 0xF0 ; w = w & 0xF0
iorlw 0x09 ; w = w | 0x09
movwf counter ; counter = w
dif_xf: bcf STATUS,Z ; reset ZERO flag
return
;===================================================================;
; Delay ;
; Pode gerar delays entre 10 mS e 2,5 S ;
; O valor de entrada e passado em W (1..255) ;
; ;
; Notas: o loop base e de 1 uS (T=200 nS <=> 4*1/20MHz) ;
; ;
; Retorna em Bank0 ;
;===================================================================;
delay
movwf delay_mult ; Carrega o valor multiplo
Del_m10 movlw 50 ; de 10 mS
movwf delay_k50 ; 50 => 10 mS
Del_50 movlw 200 ; 200 => 200 uS
movwf delay_k200 ; Carrega o valor
Del_200 nop ; correspondente a 200 uS
nop
decfsz delay_k200,f ; Decrementa "delay_k200".
; O resultado colocadao em
; "delay_k200"
goto Del_200 ; while( delay_k200 > 0 )
decfsz delay_k50,f ;
goto Del_50 ; while( delay_k50 > 0 )
decfsz delay_mult,f ; Decrementa "delay_mult".
; O resultado colocadao
; em "delay_mult"
goto Del_m10 ; while( delay_mult > 0 )
return

76
www.mecatronicadegaragem.blogspot.com

TP4 - 60 segundos, verso I

;********************************************************************
END ; directive end of program

77
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

NOTAS:

78
www.mecatronicadegaragem.blogspot.com

TP5 - Relgio de 60 segundos, verso II


Tema a desenvolver Durao
Contagem de tempo com recurso a timers 1 aula

1 Resumo

Implementao de um relgio de 60s, usando um temporizador (timer 0) para contagem de tempo.

2 Objectivos

Introduo programao do timer 0, compreenso dos conceitos associados configurao;


Modificar o programa desenvolvido em TP4, implementado o refrescamento dos displays por
timers;

3 Descrio

Em muitos programas escritos para microcon-


troladores, muitas vezes necessrio medir tempo
de determinados eventos ou efectuar contagens. Por
exemplo, um sensor ligado a uma roda de bici-
cleta pode dar-nos o n de rotaes em cada se-
gundo/minuto, isto conseguido com um registo
contador que conta as voltas completas da roda, e
um registo timer que conta os pulsos de relgio, si-
nalizando com um sinal interno a passagem de 1 se-
gundo/minuto.
Um registo contador/timer conta o nmero de Figura 27: registo contador de 8 bits
pulsos digitais aplicados sua entrada. Se o sinal de relgio usado de uma frequncia conhecida,
estamos perante um registo timer, uma vez que o tempo de durao da contagem igual ao valor
apurado multiplicado pelo perodo de relgio.
A figura 27 mostra um registo contador/timer de 8 bits, com entrada no bit menos significativo
(LSB) direita. O valor binrio guardado no registo incrementa a cada pulso aplicado. Trs pulsos

79
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

relgio foram aplicados inicialmente, mostrando o contador o valor binrio 3. Depois de 255 pul-
sos de relgio terem sido aplicados, o prximo pulso efectua a passagem, de 11111111 (0xFF) a
00000000 (0x00), sendo que a passagem sinalizada atravs de um sinal de sada, a este sinal d-se
o nome de timer overflow. Pode ser gerado por interrupo (ver trabalho prtico 7), ou por polling, a
vantagem de usar uma interrupo para o timer clara uma vez que o programa pode realizar outras
operaes, enquanto aguarda pela sinalizao do overflow.

3.1 Timer 0

Especificao do timer 0

O temporizador / contador de 8 bits, TIMER 0 pode contar at 0xFF (255);

Permite leitura e escrita;

Pr-divisor de 8 bits programvel;

Seleco de clock interno (FOSC/4) ou externo;

Activao por overflow do bit 2 INTCON TOIF, na passagem de 0xFF para 0x00;

Seleco de flanco ascendente ou descendente do clock externo;

Pode gerar interrupes de fim de contagem, bit 2 INTCON TOIF, desde que o bit 7
INTCON GIE, esteja activo.

Figura 28: Diagrama de blocos do timer 0

80
www.mecatronicadegaragem.blogspot.com

TP5 - 60 segundos, verso II

A figura 28 mostra o diagrama de blocos para o timer 0. A linha a vermelho, descreve deste a
entrada at ao timer o modo de seleco do sinal (relgio) de funcionamento. A seleco do sinal
entrada feita pelo bit TOCS do registo OPTION_REG (ver pgina 82), sendo que este o clock
interno do PIC, 5Mhz, (1 ciclo de instruo de relgio do micro). A seleco efectuada usa ainda
um pr-divisor ou contador programvel (prescaler) de 8 bits, este permite dividir o sinal de entrada
por um mximo de 256 (sinal de sada com pr diviso mxima = 19,5Khz). O nmero de contagens
do pr-divisor determinado pelos bits PS0, PS1, PS2 (bits 0, 1, & 2) do registo OPTION_REG.
Finalmente o sinal de relgio chega ao mdulo timer 0, este um contador binrio de 8 bits podendo
contar at 256. Durante a contagem, quando detectada a passagem de 255(0xFF) a 0(0x00), ou
seja o overflow, activado um sinal atravs de uma flag, (bit 2 do registo INTCON - TOIF, pgina
83). Esta flag deve ser reposta a zero por programao, de maneira a permitir a sinalizao de novo
overflow.
O cdigo Assembly seguinte mostra uma possvel programao do timer 0 por polling, para uma
contagem a cada 10 ms, na activao a 1 ou a 0 do registo switch. De notar que o valor carregado no
registo TMR0 o valor de partida de contagem do mdulo timer 0, ou seja uma contagem crescente
at 256.

;---------------- TRM0 - InitCfg ------------------------------------;


Bank1 ; DATA memory (RAM) Bank1
clrf OPTION_REG ; clear OPTION_REG
bsf OPTION_REG,PS2 ;
bsf OPTION_REG,PS1 ; TMR0 prescaler rate
bsf OPTION_REG,PS0 ; 1:256
;
Bank0 ; DATA memory (RAM) Bank0
movlw 60 ;
movwf TMR0 ; Set Hardware timer0 Value
;
clrf switch ; switch take val => 1/0
;
loop btfss INTCON,T0IF ; while(TOIF == 0) {}
goto $-1 ;
bcf INTCON,T0IF ; "reset flag" T0IF = 0;
movlw 60 ;
movwf TMR0 ; Set Hardware timer0 Value
;
incf switch,w ;
andlw 0x01 ; Toogle
movwf switch ;
;
goto loop ; repeat again

81
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

3.2 Registo OPTION_REG

bit 7 RBP U : Activao dos pull-ups em PORTB .


1 = Desactiva os pull-ups em PORTB.
0 = Activa os pull-ups em PORTB (individualmente em cada latch).

bit 6 INTEDG: Seleco da transio de interrupo.


1 = Transio de 0 para 1 do pino RB0/INT.
0 = Transio de 1 para 0 do pino RB0/INT.

bit 5 T0CS: Bit de seleco da fonte de clock do TIMER 0.


1 = Atravs do pino RA4/T0CKL.
0 = Clock de ciclo das instrues do PIC (CLKO).

bit 4 T0SE: Seleco da transio de incremento do TMR0.


1 = Incremento na transio de 1 para 0 do pino RB4/T0CKL.
0 = Incremento na transio de 0 para 1 do pino RB4/T0CKL.

bit 3 PSA: Atribuio do prescaler.


1 = Prescaler atribudo ao wachdogtimer (WDT).
0 = Prescaler atribudo ao timer 0.

bit 2-0 TMR0IF: Bits de seleco do valor da taxa do prescaler.


Valor dos bits Taxa do TMR0 Taxa do WDT
000 1:2 1:1
001 1:4 1:2
010 1:8 1:4
011 1:16 1:8
100 1:32 1:16
101 1:64 1:32
110 1:128 1:64
111 1:256 1:128

82
www.mecatronicadegaragem.blogspot.com

TP5 - 60 segundos, verso II

3.3 Registo INTCON

O INTCON contm vrios bits que inibem e desinibem as respectivas fontes de interrupo:

bit 7 GIE: Activao global das interrupes do PIC.


1 = Activa todas as interrupes.
0 = Desactiva todas as interrupes.

bit 6 PEIE: Activao das interrupes dos perifricos.


1 = Activa todas as interrupes dos perifricos.
0 = Desactiva todas as interrupes dos perifricos.

bit 5 T0IE: Activao da interrupo de overflow do timer 0.


1 = Activa a interrupo do timer 0.
0 = Desactiva a interrupo do timer 0.

bit 4 INTE: Activao da linha de interrupo RB0/INT.


1 = Activa RB0/INT.
0 = Desactiva RB0/INT.

bit 3 RBIE: Mudana de interrupo atravs do Porto RB.


1 = Activa a mudana de interrupo no Porto RB.
0 = Desactiva a mudana de interrupo no Porto RB.

bit 2 T0IF: Flag de overflow do timer 0.


1 = Indicao de overflow do timer 0, (reposio a 0 por programao).
0 = Ainda no acorreu overflow do timer 0.

bit 1 INTF: Flag de interrupo da linha RB0/INT.


1 = Ocorreu uma interrupo atravs da linha RB0/INT (reposio a 0 por programao).
0 = No ocorreu qualquer interrupo na linha RB0/INT.

bit 0 RBIF: Flag de interrupo, alterao no porto RB.


1 = Quando pelo menos um dos portos RB7:RB4 mudam de estado
(reposio a 0 por programao).
0 = Nenhum dos pinos RB7:RB4 mudou de estado.

83
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

4 Trabalho a realizar

1. Voltar ao trabalho trabalho prtico 4 (ponto 3, relgio de 60s com boto START), substituir a
contagem de tempo efectuada pela rotina Delay no refrescamento dos displays de 7 segmentos,
pelo timer 0.
Perguntas:

(a) Notou alguma diferena no funcionamento do programa, com a incluso do timer 0?

(b) Que vantagens existem na utilizao de timers em virtude de rotinas Delay?

(c) D exemplos do dia dia, em que o uso de timers ou contadores relevante?

Elementos de Apoio

Manual terico da disciplina.


DataSheet PIC16F876(DS30292C) Microchip, captulo 3. - I/O Ports, pgina 29.
DataSheet PIC16F876(DS30292C) Microchip, captulo 5. - Timer 0 Module, pgina 47.
DataSheet PIC16F876(DS30292C) Microchip, captulo 13 - Instrution Set Summary, p-
gina 135.

84
www.mecatronicadegaragem.blogspot.com

TP5 - 60 segundos, verso II

5 Implementao em Assembly do PIC

; Trabalho n 5
; Implementao de relgio de 60 segundos, V. II c/ timer0
;
; Objecivos:
; Introduo Programao de Timers
;
;********************************************************************
; *
; Nome ficheiro: trab5.asm *
; Data: 1/Junho/2005 *
; Verso: 1.0 *
; *
; Autores: Jos Miguel Gaspar *
; Olmpia Rodrigues *
; Orientador: Prof. Jos Lus Azevedo *
; *
; Universidade de Aveiro *
; Seminrio EEI 2004/2005 *
; *
;********************************************************************
; *
; Ficheiro necessrio: p16f876.lkr *
; *
;********************************************************************
list p=16f876 ; list directive to define
radix decimal ; processor
#include "p16f876.inc" ; processor specific variable
; definitions
errorlevel -302 ; Turn off banking message
; known tested (good) code
;--------------------------------------------------------------------
; Constantes
;--------------------------------------------------------------------
RA0 EQU 0
RA1 EQU 1
RA2 EQU 2
RA3 EQU 3
RA4 EQU 4
RA5 EQU 5
RB0 EQU 0
RB1 EQU 1
RB2 EQU 2
RB3 EQU 3
RB4 EQU 4
RB5 EQU 5
RB6 EQU 6
RB7 EQU 7
RC0 EQU 0
RC1 EQU 1
RC2 EQU 2
RC3 EQU 3
RC4 EQU 4
RC5 EQU 5
RC6 EQU 6
RC7 EQU 7
TMR0_HW_VAL1 EQU 60 ; 10ms aprox.
TMR0_HW_VAL2 EQU 120 ; 5ms aprox.
TMR0_SFW_VAL EQU 100 ;
;--------------------------------------------------------------------
;Displays de 7 segementos -|gfedcba-|
;--------------------------------------------------------------------

85
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

seg7_0 EQU b01111110 ; Valor 0


seg7_1 EQU b00001100 ; Valor 1
seg7_2 EQU b10110110 ; Valor 2
seg7_3 EQU b10011110 ; Valor 3
seg7_4 EQU b11001100 ; Valor 4
seg7_5 EQU b11011010 ; Valor 5
seg7_6 EQU b11111000 ; Valor 6
seg7_7 EQU b00001110 ; Valor 7
seg7_8 EQU b11111110 ; Valor 8
seg7_9 EQU b11001110 ; Valor 9
seg7_A EQU b11101110 ; Valor A
seg7_B EQU b11111000 ; Valor B
seg7_C EQU b01110010 ; Valor C
seg7_D EQU b10111100 ; Valor D
seg7_E EQU b11110010 ; Valor E
seg7_F EQU b11100010 ; Valor F
seg7_n EQU b10101000 ; Valor n
seg7_null EQU b00000000 ; Valor Null
;----------------------------------------------------------------------
; Variveis (REGISTOS DE USO GERAL)
;----------------------------------------------------------------------
variaveis UDATA 0x20
seg70 RES 1 ; Valor 0 endereo
seg71 RES 1 ; Valor 1 endereo
seg72 RES 1 ; Valor 2 endereo
seg73 RES 1 ; Valor 3 endereo
seg74 RES 1 ; Valor 4 endereo
seg75 RES 1 ; Valor 5 endereo
seg76 RES 1 ; Valor 6 endereo
seg77 RES 1 ; Valor 7 endereo
seg78 RES 1 ; Valor 8 endereo
seg79 RES 1 ; Valor 9 endereo
seg7A RES 1 ; Valor A endereo
seg7B RES 1 ; Valor B endereo
seg7C RES 1 ; Valor C endereo
seg7D RES 1 ; Valor D endereo
seg7E RES 1 ; Valor E endereo
seg7F RES 1 ; Valor F endereo
seg7n RES 1 ; Valor n endereo
seg7null RES 1 ; Valor null endereo
timer0_cnt RES 1 ; Software timer0_count Value
bcd_in RES 1 ; endereo de entrada BCD
disp_7seg RES 1 ; seleo do display de 7_seg
aux RES 1
counter RES 1 ; valor a ser decrementado
;--------------------------------------------------------------------
; Macros to select the register Banks
;--------------------------------------------------------------------
Bank0 MACRO ; Macro to select data RAM Bank 0
bcf STATUS,RP0
bcf STATUS,RP1
ENDM
Bank1 MACRO ; Macro to select data RAM Bank 1
bsf STATUS,RP0
bcf STATUS,RP1
ENDM
Bank2 MACRO ; Macro to select data RAM Bank 2
bcf STATUS,RP0
bsf STATUS,RP1
ENDM
Bank3 MACRO ; Macro to select data RAM Bank 3
bsf STATUS,RP0
bsf STATUS,RP1

86
www.mecatronicadegaragem.blogspot.com

TP5 - 60 segundos, verso II

ENDM
;********************************************************************
ORG 0x0000 ; Processor reset vector
clrf PCLATH ; Ensure page bits are cleared
goto main ; Go to beginning of program
;--------------------------------------------------------------------
; Rotina Main
;--------------------------------------------------------------------
ORG 0x0005
main ; Programa principal.
call InitCfg ; rotina de configurao
do_main ; do{
btfss INTCON,T0IF ; while(TOIF == 0) {}
goto $-1 ;
bcf INTCON,T0IF ; T0IF = 0;
movlw TMR0_HW_VAL1 ;
movwf TMR0 ; Set Hardware timer0 Value
if_main btfsc disp_7seg,0 ; if(disp_7seg == 0)
goto else_main ; {
movfw counter ; w = counter
andlw 0x0F ; w = w & 0x0F
movwf bcd_in ; bcd_in = counter & 0x0F
goto display_main;
else_main ; } else
swapf counter,w ;
andlw 0x0F ;
btfsc STATUS,Z ;
goto $+3 ; if (STATUS,Z==1)
movwf bcd_in ; bcd_in = counter >> 4;
display_main call display ; display(bcd_in,disp_7seg);
incf disp_7seg,w ;
andlw 0x01 ;
movwf disp_7seg ; disp_7seg = (++disp_7seg) & 0x01;
decfsz timer0_cnt,f ;
goto do_main ;
movlw TMR0_SFW_VAL ; if((timer0_cnt--) == 0 )
movwf timer0_cnt ; timer0_cnt = 100;
call countdown ; countdown(counter)
btfss STATUS,Z ; }while(STATUS,Z == 0);
goto do_main ; Yes, repeat COUNT
; No, TIME OUT
loop ; while(1){
clrf disp_7seg ; disp_7seg = 0
movlw 0x0d ; Val_disp0
call prt_disp7seg ; prt_disp7seg(W(reg))
movlw 0x10 ; Val_disp1
call prt_disp7seg ; prt_disp7seg(W(reg))
movlw 0x0e ; Val_disp2
call prt_disp7seg ; prt_disp7seg(W(reg))
goto loop ; }
;********************************************************************

;************************** ROTINAS *********************************


;********************************************************************
;********************************************************************
;===================================================================;
; InitCfg ;
; Configurao inicial dos registros associados ;
; ao programa principal, PORTOS I/O, Timer0. ;
; ;
; Retorna em Bank0 ;

87
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

; ;
; Notas: ;
;===================================================================;
InitCfg
;----------------- I/O - InitCfg -----------------------------------;
Bank1 ; DATA memory (RAM) Bank1
clrf TRISA ; RA[7:0] outputs
movlw b00000001 ; RB[7:1] outputs
movwf TRISB ; RB[1] input
;----------------- TRM0 - InitCfg ----------------------------------;
clrf OPTION_REG ; clear OPTION_REG
bsf OPTION_REG,PS2 ;
bsf OPTION_REG,PS1 ; TMR0 Rate
bsf OPTION_REG,PS0 ; 1:256
Bank0 ; DATA memory (RAM) Bank0
clrf disp_7seg ;
movlw 0x59 ;
movwf counter ; Valor Inicial do contador seg
;--------------------------------------------------------------------
; Inicializao dos registros associados aos displays 7seg
;--------------------------------------------------------------------
movlw seg7_0 ; Set 7segment valor 0
movwf seg70 ; Save valor 0
movlw seg7_1 ; Set 7segment valor 1
movwf seg71 ; Save valor 1
movlw seg7_2 ; Set 7segment valor 2
movwf seg72 ; Save valor 2
movlw seg7_3 ; Set 7segment valor 3
movwf seg73 ; Save valor 3
movlw seg7_4 ; Set 7segment valor 4
movwf seg74 ; Save valor 4
movlw seg7_5 ; Set 7segment valor 5
movwf seg75 ; Save valor 5
movlw seg7_6 ; Set 7segment valor 6
movwf seg76 ; Save valor 6
movlw seg7_7 ; Set 7segment valor 7
movwf seg77 ; Save valor 7
movlw seg7_8 ; Set 7segment valor 8
movwf seg78 ; Save valor 8
movlw seg7_9 ; Set 7segment valor 9
movwf seg79 ; Save valor 9
movlw seg7_A ; Set 7segment valor A
movwf seg7A ; Save valor A
movlw seg7_B ; Set 7segment valor B
movwf seg7B ; Save valor B
movlw seg7_C ; Set 7segment valor C
movwf seg7C ; Save valor C
movlw seg7_D ; Set 7segment valor D
movwf seg7D ; Save valor D
movlw seg7_E ; Set 7segment valor E
movwf seg7E ; Save valor E
movlw seg7_F ; Set 7segment valor F
movwf seg7F ; Save valor F
movlw seg7_n ; Set 7segment pattern N
movwf seg7n ; Save pattern N
movlw seg7_null ; Set 7segment pattern NULL
movwf seg7null ; Save pattern N
;---------------------------------------------------------------------------
; Programao do Timer0
;---------------------------------------------------------------------------
movlw TMR0_HW_VAL1 ; Set Hardware timer0 Value
movwf TMR0 ; Set TMR0

88
www.mecatronicadegaragem.blogspot.com

TP5 - 60 segundos, verso II

movlw TMR0_SFW_VAL ; Set Software timer0_count Value


movwf timer0_cnt ; Save time0_count adjust
return
;===================================================================;
; Input: BCD_IN - valor BCD de entrada ;
; Input: DISP_7SEG - seleo do display a ser refrescado ;
; Output: ;
; ;
; Resumo: Subroutina de Controlo dos displays ;
;===================================================================;
display
movf PORTA,w ; w = PORTA
andlw 0xF1 ;
movwf aux ; aux = w & 0xf1
disp_0 movfw disp_7seg ; switch(disp_7seg)
sublw 0x00 ;
btfss STATUS,Z ;
goto disp_1 ;
movfw aux ; case_0
iorlw 0x08 ; w = aux | 0x08
goto break ; break
disp_1 movfw disp_7seg ; switch(dis_7seg)
sublw 0x01 ;
btfss STATUS,Z ;
goto disp_2 ;
movfw aux ; case_1
iorlw 0x04 ; w = aux | 0x04
goto break ; break
disp_2 movfw aux ; case_2
iorlw 0x02 ; w = aux | 0x02
break movwf PORTA ; escrita na porta
call bcd_7seg ; bcd_7seg(bcd_in);
return
;===================================================================;
; Input: bcd_in - valor BCD de entrada ;
; Output: ;
; ;
; Resumo: Subroutina => BCD to 7segment display, envia o valor ;
; passado em bcd_in para a PORTB ;
;===================================================================;
bcd_7seg
movlw seg70 ; Incio da tabela de valores
addwf bcd_in,w ; & do val a mostrar da tabela
movwf FSR ; Set do endereo da tabela
movf INDF,w ; leitura do valor de 7seg
movwf PORTB ; envio do valor para o PORTB
return
;===================================================================;
; Input: W(reg) = BCD_IN - valor BCD de entrada ;
; Output: ;
; ;
; Resumo: ;
;===================================================================;
prt_disp7seg
movwf bcd_in ; bcd_in = w
call display ; display(bcd_in,disp_7seg);
btfss INTCON,T0IF ; while(TOIF == 0) {}
goto $-1 ;
bcf INTCON,T0IF ; T0IF = 0;
movlw 120 ; Set Hardware timer0 Value

89
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

movwf TMR0 ; Set TMR0


incf disp_7seg,f ; disp_7seg ++;
return
;===================================================================;
; Input: COUNTER - valor de entrada ;
; Output: COUNTER - valor decrementado ;
; Flag de Zero afectada: Z=0 if COUNTER != FF ;
; Z=1 if COUNTER == FF ;
; Resumo: ;
; ;
; ;
;===================================================================;
countdown
decf counter,f ; counter--
movfw counter ; w = counter
sublw 0xFF ;
btfsc STATUS,Z ; if( w == 0xFF )
return ; return
movfw counter ; w = counter
andlw 0x0F ; w = w & 0x0F
sublw 0x0F ;
btfss STATUS, Z ; if( w != 0x0F)
goto dif_xf ; goto dif_xf
movfw counter ; w = counter
andlw 0xF0 ; w = w & 0xF0
iorlw 0x09 ; w = w | 0x09
movwf counter ; counter = w
dif_xf: bcf STATUS,Z ; reset ZERO flag
return
END

90
www.mecatronicadegaragem.blogspot.com

TP6 - Semforo rodovirio (automveis/pees)

Tema a desenvolver Durao


Implementao de uma mquina de estados 2 aulas

1 Resumo

Construo de uma mquina de estados que implemente um semforo para automveis e pees.

2 Objectivos

Aprofundar os conhecimentos sobre timers.

Implementao de uma mquina de estados por software.

3 Descrio

Figura 29: Semforo rodovirio (automveis/pees)

91
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

3.1 Diagrama de estados - Semforo rodovirio

A figura 30 um exemplo de um diagrama de estados, que mostra a interaco entre os vrios estados
propostos no trabalho prtico, este exemplifica a maneira como so efectuadas as transies entre
estados ao longo do tempo. De notar que os tempos t1 a t5 representam os tempos em que os estados
esto em execuo. A tabela 3 descreve a activao (ON) dos leds durante a execuo dos estados.

Figura 30: Diagrama de estados do trabalho prtico

Estados vermelho_auto amarelo_auto verde_auto vermelho_pees verde_pees


S0 on on
S1 on on
S2 on on
S3 on on
S4 on intermitente
S5 on on

Tabela 3: Descrio do estado dos leds

92
www.mecatronicadegaragem.blogspot.com

TP6 - Semforo rodovirio

4 Trabalho a realizar
1. Dispondo de 5 leds ( 2 vermelhos, 2 verdes e 1 amarelo ), implementar na placa branca dois
semforos, um para automveis e outro para pees, ligados respectivamente em RB1, RB2,
RB3 e RB4,RB5 (ver figura 31 ).

Figura 31: Diagrama do circuito, semforo rodovirio

2. Desenvolvimento de um programa em assembly para controlo dos semforos, de acordo com o


diagrama de estados da figura 30, que efectue a contagem de tempo na transio dos estados,
com auxlio do timer 0. A tabela 4, define o tempo mnimo que deve ser respeitado entre cada
transio de estados.

estados boto t(segundos)


presso
S0 activo
S1 1,5
S2 1
S3 4
S4 3
S5 1,5

Tabela 4: Tempo minmo entre estados

93
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

Elementos de Apoio

Manual terico da disciplina.


DataSheet PIC16F876(DS30292C) Microchip, captulo 3. - I/O Ports, pgina 29.
DataSheet PIC16F876(DS30292C) Microchip, captulo 5. - Timer 0 Module, pgina 47.
DataSheet PIC16F876(DS30292C) Microchip, captulo 13 - Instrution Set Summary, p-
gina 135.

94
www.mecatronicadegaragem.blogspot.com

TP6 - Semforo rodovirio

5 Implementao em Assembly do PIC

; Trabalho n 6
;
; Semforo Rodovirio (automveis & pees)
;
;
;********************************************************************
; *
; NomeFicheiro: trab6.asm *
; Data: 3/Junho/2005 *
; Verso: 1.0 *
; *
; Autores: Jos Miguel Gaspar *
; Olmpia Rodrigues *
; *
; Orientador: Prof. Jos Lus Azevedo *
; *
; Universidade de Aveiro *
; Seminrio EEI 2004/2004 *
; *
;********************************************************************
; *
; Ficheiro necessrio: P16F876.LKR *
; *
;********************************************************************
list p=16f876 ; list directive to define
radix decimal ; processor
#include "p16f876.inc" ; processor specific variable
; definitions
errorlevel -302 ; Turn off banking message
; known tested (good) code
;====================================================================
; Constantes
;====================================================================
RB0 EQU 0
RB1 EQU 1
RB2 EQU 2
RB3 EQU 3
RB4 EQU 4
RB5 EQU 5
RB6 EQU 6
RB7 EQU 7
RA0 EQU 0
RA1 EQU 1
RA2 EQU 2
RA3 EQU 3
RA4 EQU 4
RA5 EQU 5
RA6 EQU 6
RA7 EQU 7
TMR0_SFW_VAL EQU 50 ; Set Software timer0_count Value
TMR0_HW_VAL EQU 60 ; Set Hardware timer0 Value
;====================================================================
; Constantes de tempo de espera nos estados em unidades de 0,5 seg
;====================================================================
t_verd2amar_A EQU 3 ; tempo,s1 = 1,5s
t_amar2verm_A EQU 2 ; tempo,s2 = 1s
t_verde_P EQU 8 ; tempo,s3 = 4s
t_verd_interm EQU 6 ; tempo,s4 = 3s
t_verm_A_P EQU 3 ; tempo,s5 = 1,5s

95
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

;======================================================================
; Definicoes - PORTA
;======================================================================
;
;INPUTS
SW1 EQU RA4 ; SW1 est ligado a RA4
;====================================================================
; Definicoes - PORTB
;====================================================================
;
;OUTPUTS
LED_VERM_A EQU RB1 ; LED1 est ligado a RB1
LED_AMAR_A EQU RB2 ; LED2 est ligado a RB2
LED_VERD_A EQU RB3 ; LED3 est ligado a RB3
LED_VERM_P EQU RB4 ; LED4 est ligado a RB4
LED_VERD_P EQU RB5 ; LED5 est ligado a RB5
;====================================================================
; Variaveis
;====================================================================
variaveis UDATA 0x20
delay_mult RES 1 ; Variaveis de controlo dos loops
delay_k50 RES 1 ; da rotina Delay
delay_k200 RES 1
conta_verd2amar_A RES 1
conta_amar2verm_A RES 1
conta_verde_P RES 1
conta_verd_interm RES 1
conta_verm_A_P RES 1
estado RES 1
timer0_cnt RES 1
;====================================================================
; Macros to select the register Banks
;====================================================================
Bank0 MACRO ; Macro to select data RAM Bank 0
bcf STATUS,RP0
bcf STATUS,RP1
ENDM
Bank1 MACRO ; Macro to select data RAM Bank 1
bsf STATUS,RP0
bcf STATUS,RP1
ENDM
Bank2 MACRO ; Macro to select data RAM Bank 2
bcf STATUS,RP0
bsf STATUS,RP1
ENDM
Bank3 MACRO ; Macro to select data RAM Bank 3
bsf STATUS,RP0
bsf STATUS,RP1
ENDM
;====================================================================
; Macros to select the states
;====================================================================
macro_inicial MACRO ; Macro to select state 0
bsf PORTB,LED_VERD_A ; LED VERDE AUTOMOVEIS ON
bcf PORTB,LED_AMAR_A ; LED AMARELO AUTOMOVEIS OFF
bcf PORTB,LED_VERM_A ; LED VERMELHO AUTOMOVEIS OFF
bcf PORTB,LED_VERD_P ; LED VERDE PEOES OFF
bsf PORTB,LED_VERM_P ; LED VERMELHO PEOES ON

96
www.mecatronicadegaragem.blogspot.com

TP6 - Semforo rodovirio

ENDM
macro_verd2amar_A MACRO ; Macro to select state 1
bcf PORTB,LED_VERD_A ; LED VERDE AUTOMOVEIS OFF
bsf PORTB,LED_AMAR_A ; LED AMARELO AUTOMOVEIS ON
bcf PORTB,LED_VERM_A ; LED VERMELHO AUTOMOVEIS OFF
bcf PORTB,LED_VERD_P ; LED VERDE PEOES OFF
bsf PORTB,LED_VERM_P ; LED VERMELHO PEOES ON
ENDM
macro_amar2verm_A MACRO ; Macro to select state 2
bcf PORTB,LED_VERD_A ; LED VERDE AUTOMOVEIS OFF
bcf PORTB,LED_AMAR_A ; LED AMARELO AUTOMOVEIS OFF
bsf PORTB,LED_VERM_A ; LED VERMELHO AUTOMOVEIS ON
bcf PORTB,LED_VERD_P ; LED VERDE PEOES OFF
bsf PORTB,LED_VERM_P ; LED VERMELHO PEOES ON
ENDM
macro_verde_P MACRO ; Macro to select state 3
bcf PORTB,LED_VERD_A ; LED VERDE AUTOMOVEIS OFF
bcf PORTB,LED_AMAR_A ; LED AMARELO AUTOMOVEIS OFF
bsf PORTB,LED_VERM_A ; LED VERMELHO AUTOMOVEIS ON
bsf PORTB,LED_VERD_P ; LED VERDE PEOES ON
bcf PORTB,LED_VERM_P ; LED VERMELHO PEOES OFF
ENDM
macro_verd_interm MACRO ; Macro to select state 4
bcf PORTB,LED_VERD_A ; LED VERDE AUTOMOVEIS OFF
bcf PORTB,LED_AMAR_A ; LED AMARELO AUTOMOVEIS OFF
bsf PORTB,LED_VERM_A ; LED VERMELHO AUTOMOVEIS ON
bsf PORTB,LED_VERD_P ; LED VERDE PEOES ON
bcf PORTB,LED_VERM_P ; LED VERMELHO PEOES OFF
ENDM
macro_verm_A_P MACRO ; Macro to select state 4
bcf PORTB,LED_VERD_A ; LED VERDE AUTOMOVEIS OFF
bcf PORTB,LED_AMAR_A ; LED AMARELO AUTOMOVEIS OFF
bsf PORTB,LED_VERM_A ; LED VERMELHO AUTOMOVEIS ON
bcf PORTB,LED_VERD_P ; LED VERDE PEOES OFF
bsf PORTB,LED_VERM_P ; LED VERMELHO PEOES ON
ENDM
;********************************************************************
ORG 0x0000 ; Processor reset vector
clrf PCLATH ; Ensure page bits are cleared
goto main ; Go to beginning of program

;--------------------------------------------------------------------
; Rotina Main
;--------------------------------------------------------------------
ORG 0x0005 ;
main ; Programa principal.
call InitCfg
loop ; do{
btfss INTCON,T0IF ; while(TOIF == 0){}
goto $-1 ;
bcf INTCON,T0IF ; T0IF = 0;
movlw TMR0_HW_VAL ; Set Hardware timer0 Value
movwf TMR0 ; Set TMR0
decfsz timer0_cnt,f ; if(timer0_cnt == 0)
goto loop ; {
movlw d50 ;
movwf TMR0_SFW_VAL ; timer0_cnt = 100;
; while( timer0_cnt !=0 )
switch movfw estado ; w = estado
sublw 0x00

97
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

btfsc STATUS,Z
goto estado_inicial
movfw estado
sublw 0x01
btfsc STATUS,Z
goto estado_verd2amar_A
movfw estado
sublw 0x02
btfsc STATUS,Z
goto estado_amar2verm_A
movfw estado
sublw 0x03
btfsc STATUS,Z
goto estado_verde_P
movfw estado
sublw 0x04
btfsc STATUS,Z
goto estado_verd_interm
movfw estado
sublw 0x05
btfsc STATUS,Z
nop
goto estado_verm_A_P
estado_inicial ; estado inicial
macro_inicial
btfsc PORTA,SW1 ; while(sw1 == 0) {}
goto estado_inicial
incf estado,f ; estado++;
movlw t_verd2amar_A
movwf conta_verd2amar_A
movlw t_amar2verm_A
movwf conta_amar2verm_A
movlw t_verde_P
movwf conta_verde_P
movlw t_verd_interm
movwf conta_verd_interm
movlw t_verm_A_P
movwf conta_verm_A_P
goto loop ; break;
estado_verd2amar_A
macro_verd2amar_A
decfsz conta_verd2amar_A,f ; if (count_amar_a == 0)
goto loop ; {
incf estado,f ; estado++:
goto loop ; break;
estado_amar2verm_A
macro_amar2verm_A
decfsz conta_amar2verm_A,f ; if (count_verm_a == 0)
goto loop ; {
incf estado,f ; estado++:
goto loop ; break;
estado_verde_P
macro_verde_P
decfsz conta_verde_P ,f ; if (count_verd_p == 0)
goto loop ; {
incf estado,f ; estado++:
goto loop ; break;
estado_verd_interm
macro_verd_interm ; led verde peoes on
btfss conta_verd_interm,0

98
www.mecatronicadegaragem.blogspot.com

TP6 - Semforo rodovirio

goto off_led
bsf PORTB,LED_VERD_P
goto fim
off_led bcf PORTB,LED_VERD_P
fim decfsz conta_verd_interm,f ; if (count_inter_p == 0)
goto loop
incf estado,f
goto loop
estado_verm_A_P
macro_verm_A_P
decfsz conta_verm_A_P,f ; if (count_verd_p == 0)
goto loop ; {
clrf estado ; estado=0;
goto loop ; break;

;===================================================================;
; InitCfg ;
; Configurao inicial dos registros associados ;
; ao programa principal ;
; ;
; Retorna em Bank0 ;
; ;
;===================================================================;
InitCfg
;----------------- Analog 2 Digital - InitCfg ----------------------;
Bank1 ; DATA memory (RAM) Bank1
movlw 0x06 ; W = 0x06
movwf ADCON1 ; ADCON1 (PORTA I/O digital)
;----------------- I/O - InitCfg -----------------------------------;
movlw b0001000 ; R4 inputs
movwf TRISA ;
movlw b1100000 ; R[5:0] outputs
movwf TRISB ; R[7:6] inputs
;----------------- TRM0 - InitCfg ----------------------------------;
clrf OPTION_REG ; clear OPTION_REG
bsf OPTION_REG,PS2 ;
bsf OPTION_REG,PS1 ; TMR0 Rate
bsf OPTION_REG,PS0 ; 1:256
Bank0 ; DATA memory (RAM) Bank0
clrf estado ; estado = 0;
clrf PORTA ; Inicializao PORTA
;---------------------------------------------------------------------------
; Programao do Timer0
;---------------------------------------------------------------------------
movlw TMR0_HW_VAL ; Set Hardware timer0 Value
movwf TMR0 ; Set TMR0
movlw TMR0_SFW_VAL ; Set Software timer0_count Value
movwf timer0_cnt ; Save time0_count adjust
return
END ; end of program

99
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

NOTAS:

100
www.mecatronicadegaragem.blogspot.com

TP7 - Relgio 60 segundos, verso III


Tema a desenvolver Durao
Programao com interrupes (Interrupt driven I/O) 3 aulas

1 Resumo

Pretende-se com este trabalho prtico, introduzir o conceito da transferncia de informao I/O por
interrupo, ilustrado-o com uma soluo do trabalho 1 (led controlado por boto de presso) por
interrupo.
No final do trabalho, utilizaremos o exemplo desenvolvido nos trabalhos 4 e 5 (relgio de 60s),
para gerar interrupes atravs do timer 0 e da linha INT0/RB0 do PIC.

2 Objectivos

Compreenso da rotina de atendimento interrupo RSI ( Rotina de Servio de atendimento


Interrupo ) descrita em exemplo;
Construo de rotinas de atendimento interrupo.
Gerao de interrupes atravs da linha de interrupo RB0/INT do PIC.
Gerao de interrupes atravs da flag de overflow TOIF do timer 0 do PIC, para refrescamento
dos displays de 7 segmentos, e decremento da varivel contadora do relgio.

3 Descrio

O PIC16F876 tem a possibilidade de contar com um sistema de interrupes. Este sistema, consiste
num mecanismo atravs do qual um acontecimento interno ou externo, (assncrono relativamente ao
programa), pode interromper a execuo, do programa em curso. automaticamente produzido um
salto para a rotina de atendimento (RSI), onde executado o cdigo que processa o evento gerador da
interrupo, uma vez terminada a RSI, a execuo do programa interrompido retomada.
Existem 13 fontes de interrupo no PIC16F876, vejamos algumas:

External RB0/INT pin, INTF.


TMR0 timer overflow, T0IF.
PORTB<7:4> interrupt-on-change, RBIF.

101
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

Figura 32: Exemplo de uma interrupo

A figura 32, representa o esquema simples de uma interrupo genrica. Antes da RSI pro-
priamente dita, feito automticamente o reset do bit GIE, (bit 7 do registo INTCON), ou seja a
desactivao de todas as interrupes durante o atendimento. O endereo de retorno guardado na
stack, sendo atribudo ao PC (program counter) o endereo 0x0004 (o que equivale a um salto para o
endereo 4 da memria de programa).
dever do programador, salvaguardar o contexto dos seguintes registos, W(reg), STATUS e
PCLATH. Uma vez dentro da RSI, a fonte de interrupo pode ser determinada por polling aos bits
de interrupo; das fontes de interrupo utilizadas. Os mesmos devem ser repostos a zero antes da
terminao da RSI, evitando-se desse modo a gerao (no desejada) de uma nova interrupo.

activar as interrupes globais, evitando assim interrupes recursivas.


Para melhor compreender o conceito, mostra-se em exemplo da rotina de atendimento interrup-
o para o trabalho prtico 1, ver pgina 104.

3.1 Led pisca-pisca com boto ON/OFF por interrupo

Nos trechos de cdigo assembly seguintes, mostra-se em primeiro lugar o programa principal, inici-
almente com a configurao dos registos TRISB e INTCON, cuja descrio pode ser encontrada nas
pginas 16 e 83 respectivamente. De seguida o programa entra num ciclo infinito forando a sada
RB0 ao estado ON durante 0,5s e ao estado OFF durante 1s.

102
www.mecatronicadegaragem.blogspot.com

TP7 - 60 segundos, verso III

Em segundo lugar temos a rotina de atendimento interrupo (RSI), activada sempre que a linha
RB0/INT activa a zero. A rotina de atendimento implementa o toggle (activao ou desactivao
de um bit), de um registo denominado de start_stop. Este registo testado continuamente no ciclo
infinito descrito em cima.

ORG 0x0000 ; Processor reset vector


clrf PCLATH ; Ensure page bits are cleared
goto main ; Go to beginning of program
ORG 0x0004 ; Processor Interrupt Vector
goto interrupt_start ; Go to ISR

;--------------------------------------------------------------------
; Rotina Main
;--------------------------------------------------------------------
ORG 0x0005
main ;Aqui comea o programa principal

;----------------- I/O - InitCfg -----------------------------------;


Bank1 ; DATA memory (RAM) Bank1
movlw b00000010 ; RB1 output
movwf TRISB ; RB[7:2 & 0] inputs

;----------------- Interrupts enable bits --------------------------;


Bank0 ; DATA memory (RAM) Bank0
bsf INTCON,GIE ; Global Int. Enable bit
bsf INTCON,INTE ; External Int. enable bit

;-------------------------------------------------------------------;
clrf PORTB ; Inicializao PORTB.
clrf start_stop ;
while_1 ; while(1) {
btfsc start_stop,0 ; while (start_stop == 1) {}
goto $-1 ;

bsf PORTB,RB1 ; Set RB1 ON


movlw 25 ;
call Delay ; delay( 0,25 seg )
bcf PORTB,RB1 ; Set RB1 OFF
movlw 25 ;
call Delay ; delay( 0,25 seg )

goto while_1 ; }

103
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

;************************** ISR *************************************


;********************************************************************
;********************************************************************
interrupt_start
movwf w_save ; salvaguarda do W reg.
swapf STATUS,W ;
clrf STATUS ; DATA memory (RAM) Bank0
movwf status_save ; salvaguarda do STATUS reg.
movf PCLATH,W ;
movwf pclath_save ; salvaguarda do PCLATH reg.
clrf PCLATH ; pgina 0, de memria de
; programa
bcf INTCON,INTF ; reset, do bit INTF
incf start_stop,w ;
andlw 0x01 ;
movwf start_stop ; toggle do start_stop (0/1)
;
interrupt_end movf pclath_save,w; restauro do PCLATH reg.
movwf PCLATH ;
swapf status_save,w; restauro da DATA memory (RAM)
; Bank? inicial
movwf STATUS ;
swapf w_save,f ; restauro do W reg.
swapf w_save,w ;

retfie ; retorno ao prog. principal

4 Trabalho a realizar

1. Modificar o programa (contador de 60s, verso II ) implementado em TP5, este deve agora
implementar o START / STOP do relgio de 60 segundos, em qualquer altura da contagem
decrescente. O diagrama do circuito pretendido, mostrado na figura 33.

Figura 33: Diagrama do circuito, interrupo do RBO/INT

104
www.mecatronicadegaragem.blogspot.com

TP7 - 60 segundos, verso III

2. Configurar o timer 0 de modo a que este gere interrupes por overflow, construir a rotina RSI
que ao ser activada pelo TOIF (bit 2 do registo INTCON), sinalizando o overflow do timer 0
do PIC. Esta deve implementar o refrescamento dos displays de 7 segmentos a cada 10ms e
decremento da varivel contadora a cada segundo.

3. Finalmente, acrescentar mais uma interrupo rotina anterior, desta vez gerada pela linha
INT0/RB0 do PIC, de modo a implementar o START/STOP do relgio de de 60 segundos.
Nota: A RSI anterior, deve ser capaz de distinguir qual o interrupo gerada, timer 0 ou
RB0/INT, e agir em conformidade como a interrupo gerada.

Elementos de Apoio

Manual terico da disciplina.


DataSheet PIC16F876(DS30292C) Microchip, captulo 3. - I/O Ports, pgina 29.
DataSheet PIC16F876(DS30292C) Microchip, captulo 5. - Timer 0 Module, pgina 47.
DataSheet PIC16F876(DS30292C) Microchip, captulo 12. - Special Features Of Tje Cpu,
seco 12.10 - Interrupts, pgina 129.
DataSheet PIC16F876(DS30292C) Microchip, captulo 13 - Instrution Set Summary, p-
gina 135.

105
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

5 Implementao em Assembly do PIC

5.1 Ponto 1
; Trabalho n 7p1
; Implementao de relgio de 60 segundos V.II com start/stop
;
; Objectivos:
; Introduo Programao de Timers
; Com Interrupt_SR para Boto Start/stop
;
;********************************************************************
; *
; Nome ficheiro: trab7p1.asm *
; Data: 1/Junho/2005 *
; Verso: 1.0 *
; *
; Autores: Jos Miguel Gaspar *
; Olmpia Rodrigues *
; Orientador: Jos Lus Azevedo *
; *
; Universidade de Aveiro *
; Seminrio EEI 2004/2005 *
; *
;********************************************************************
; *
; Ficheiro necessrio: p16f876.lkr *
; *
;********************************************************************
list p=16f876 ; list directive to define
radix decimal ; processor
#include "p16f876.inc" ; processor specific variable
; definitions
errorlevel -302 ; Turn off banking message
; known tested (good) code
;--------------------------------------------------------------------
; Constantes
;--------------------------------------------------------------------
RB0 EQU 0
RB1 EQU 1
RB2 EQU 2
RB3 EQU 3
RB4 EQU 4
RB5 EQU 5
RB6 EQU 6
RB7 EQU 7
RA0 EQU 0
RA1 EQU 1
RA2 EQU 2
RA3 EQU 3
RA4 EQU 4
RA5 EQU 5
TMR0_HW_VAL1 EQU 60 ; 10ms aprox.
TMR0_HW_VAL2 EQU 120 ; 5ms aprox.
TMR0_SFW_VAL EQU 100 ;
;--------------------------------------------------------------------
; Displays de 7seg -|gfedcba-|
;--------------------------------------------------------------------
seg7_0 EQU b01111110 ; Valor 0
seg7_1 EQU b00001100 ; Valor 1
seg7_2 EQU b10110110 ; Valor 2
seg7_3 EQU b10011110 ; Valor 3

106
www.mecatronicadegaragem.blogspot.com

TP7 - 60 segundos, verso III

seg7_4 EQU b11001100 ; Valor 4


seg7_5 EQU b11011010 ; Valor 5
seg7_6 EQU b11111000 ; Valor 6
seg7_7 EQU b00001110 ; Valor 7
seg7_8 EQU b11111110 ; Valor 8
seg7_9 EQU b11001110 ; Valor 9
seg7_A EQU b11101110 ; Valor A
seg7_B EQU b11111000 ; Valor B
seg7_C EQU b01110010 ; Valor C
seg7_D EQU b10111100 ; Valor D
seg7_E EQU b11110010 ; Valor E
seg7_F EQU b11100010 ; Valor F
seg7_n EQU b10101000 ; Valor n
seg7_null EQU b00000000 ; Valor Null
;----------------------------------------------------------------------
; Variveis (REGISTOS DE USO GERAL)
;----------------------------------------------------------------------
seg70 EQU 0x20 ; Valor 0 endereo
seg71 EQU 0x21 ; Valor 1 endereo
seg72 EQU 0x22 ; Valor 2 endereo
seg73 EQU 0x23 ; Valor 3 endereo
seg74 EQU 0x24 ; Valor 4 endereo
seg75 EQU 0x25 ; Valor 5 endereo
seg76 EQU 0x26 ; Valor 6 endereo
seg77 EQU 0x27 ; Valor 7 endereo
seg78 EQU 0x28 ; Valor 8 endereo
seg79 EQU 0x29 ; Valor 9 endereo
seg7A EQU 0x2A ; Valor A endereo
seg7B EQU 0x2B ; Valor B endereo
seg7C EQU 0x2C ; Valor C endereo
seg7D EQU 0x2D ; Valor D endereo
seg7E EQU 0x2E ; Valor E endereo
seg7F EQU 0x2F ; Valor F endereo
seg7n EQU 0x30 ; Valor n endereo
seg7null EQU 0x31 ; Valor null endereo
timer0_cnt EQU 0x32 ; Software timer0_count Value
bcd_in EQU 0x33 ; endereo de entrada BCD
disp_7seg EQU 0x34 ; seleo do display de 7_seg
aux EQU 0x35
counter EQU 0x36 ; valor a ser decrementado
start_stop EQU 0x37
w_save EQU 0x38 ; SAVE W
status_save EQU 0x39 ; SAVE STATUS REG
pclath_save EQU 0x3A ; SAVE PCLATH REG
;--------------------------------------------------------------------
; Macros to select the register Banks
;--------------------------------------------------------------------
Bank0 MACRO ; Macro to select data RAM Bank 0
bcf STATUS,RP0
bcf STATUS,RP1
ENDM
Bank1 MACRO ; Macro to select data RAM Bank 1
bsf STATUS,RP0
bcf STATUS,RP1
ENDM
Bank2 MACRO ; Macro to select data RAM Bank 2
bcf STATUS,RP0
bsf STATUS,RP1
ENDM
Bank3 MACRO ; Macro to select data RAM Bank 3
bsf STATUS,RP0

107
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

bsf STATUS,RP1
ENDM
;********************************************************************
ORG 0x00 ; Processor reset vector
clrf PCLATH; Ensure page bits are cleared
goto main ; Go to beginning of program
ORG 0x04 ; Processor Interrupt Vector
goto interrupt_start ; Go to interrupt servi
; rotine
;--------------------------------------------------------------------
; Rotina Main
;--------------------------------------------------------------------
ORG 0x20
main ; Programa principal.
call InitCfg ; rotina de configurao
do_main ; do{
btfss INTCON,T0IF ; while(TOIF == 0) {}
goto $-1 ;
bcf INTCON,T0IF ; T0IF = 0;
movlw TMR0_HW_VAL1 ;
movwf TMR0 ; Set Hardware timer0 Value
if_main btfsc disp_7seg,0 ; if(disp_7seg == 0)
goto else_main ; {
movfw counter ; w = counter
andlw 0x0F ; w = w & 0x0F
movwf bcd_in ; bcd_in = counter & 0x0F
goto display_main
else_main ; } else
swapf counter,w ;
andlw 0x0F ;
btfsc STATUS,Z ;
goto $+3 ; if (STATUS,Z==1)
movwf bcd_in ; bcd_in = counter >> 4
display_main call display ; display(bcd_in,disp_7seg);
incf disp_7seg,w ;
andlw 0x01 ;
movwf disp_7seg ; disp_7seg = (++disp_7seg) & 0x01;
btfsc start_stop,0 ;
goto do_main ;
decfsz timer0_cnt,f ;
goto do_main ;
movlw TMR0_SFW_VAL ; if((timer0_cnt--) == 0 )
movwf timer0_cnt ; timer0_cnt = 100;
call countdown ; countdown(counter)
btfss STATUS,Z ; }while(STATUS,Z == 0);
goto do_main ; Yes, repeat COUNT
; No, TIME OUT
loop ; while(1){
clrf disp_7seg ; disp_7seg = 0
movlw 0x0d ; Val_disp0
call prt_disp7seg ; prt_disp7seg(W(reg))
movlw 0x10 ; Val_disp1
call prt_disp7seg ; prt_disp7seg(W(reg))
movlw 0x0e ; Val_disp2
call prt_disp7seg ; prt_disp7seg(W(reg))
goto loop ; }
;********************************************************************

;************************** ROTINAS *********************************


;********************************************************************
;********************************************************************

108
www.mecatronicadegaragem.blogspot.com

TP7 - 60 segundos, verso III

;===================================================================;
; InitCfg ;
; Configurao inicial dos registros associados ;
; ao programa principal, PORTOS I/O, Timer0. ;
; ;
; Retorna em Bank0 ;
; ;
; Notas: ;
;===================================================================;
InitCfg
Bank1 ; memoria do programa em Bank1
movlw 0x06 ; W = 0x06
movwf ADCON1 ; ADCON1 (PORTA I/O digital)
movlw 0xf1 ;
movwf TRISA ; RA<3:1> outputs
movlw 0x01 ;
movwf TRISB ; RB<7:1> outputs
movlw 0x47 ; INTEDG = 1
movwf OPTION_REG ; RBPU/TOCS/PSA=0, PS2:PS0=111
Bank0 ; memoria do programa em Bank0
movlw 0x90 ; GIE=1, INTE = 1
movwf INTCON ; Global Interrupts enable
clrf disp_7seg ;
clrf start_stop ;
movlw 0x59 ;
movwf counter ; Valor Inicial do contador seg
;--------------------------------------------------------------------
; Inicializao dos registros associados aos displays 7seg
;--------------------------------------------------------------------
movlw seg7_0 ; Set 7segment valor 0
movwf seg70 ; Save valor 0
movlw seg7_1 ; Set 7segment valor 1
movwf seg71 ; Save valor 1
movlw seg7_2 ; Set 7segment valor 2
movwf seg72 ; Save valor 2
movlw seg7_3 ; Set 7segment valor 3
movwf seg73 ; Save valor 3
movlw seg7_4 ; Set 7segment valor 4
movwf seg74 ; Save valor 4
movlw seg7_5 ; Set 7segment valor 5
movwf seg75 ; Save valor 5
movlw seg7_6 ; Set 7segment valor 6
movwf seg76 ; Save valor 6
movlw seg7_7 ; Set 7segment valor 7
movwf seg77 ; Save valor 7
movlw seg7_8 ; Set 7segment valor 8
movwf seg78 ; Save valor 8
movlw seg7_9 ; Set 7segment valor 9
movwf seg79 ; Save valor 9
movlw seg7_A ; Set 7segment valor A
movwf seg7A ; Save valor A
movlw seg7_B ; Set 7segment valor B
movwf seg7B ; Save valor B
movlw seg7_C ; Set 7segment valor C
movwf seg7C ; Save valor C
movlw seg7_D ; Set 7segment valor D
movwf seg7D ; Save valor D
movlw seg7_E ; Set 7segment valor E
movwf seg7E ; Save valor E
movlw seg7_F ; Set 7segment valor F
movwf seg7F ; Save valor F
movlw seg7_n ; Set 7segment pattern N
movwf seg7n ; Save pattern N
movlw seg7_null ; Set 7segment pattern NULL

109
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

movwf seg7null ; Save pattern N


;---------------------------------------------------------------------------
; Programao do Timer0
;---------------------------------------------------------------------------
movlw TMR0_HW_VAL1 ; Set Hardware timer0 Value
movwf TMR0 ; Set TMR0
movlw TMR0_SFW_VAL ; Set Software timer0_count Value
movwf timer0_cnt ; Save time0_count adjust
return
;===================================================================;
; Input: BCD_IN - valor BCD de entrada ;
; Input: DISP_7SEG - seleo do display a ser refrescado ;
; Output: ;
; ;
; Resumo: Subroutina de Controlo dos displays ;
;===================================================================;
display
movf PORTA,w ; w = PORTA
andlw 0xF1 ;
movwf aux ; aux = w & 0xf1
disp_0 movfw disp_7seg ; switch(disp_7seg)
sublw 0x00 ;
btfss STATUS,Z ;
goto disp_1 ;
movfw aux ; case_0
iorlw 0x08 ; w = aux | 0x08
goto break ; break
disp_1 movfw disp_7seg ; switch(dis_7seg)
sublw 0x01 ;
btfss STATUS,Z ;
goto disp_2 ;
movfw aux ; case_1
iorlw 0x04 ; w = aux | 0x04
goto break ; break
disp_2 movfw aux ; case_2
iorlw 0x02 ; w = aux | 0x02
break movwf PORTA ; escrita na porta
call bcd_7seg ; bcd_7seg(bcd_in);
return
;===================================================================;
; Input: bcd_in - valor BCD de entrada ;
; Output: ;
; ;
; Resumo: Subroutina => BCD to 7segment display, envia o valor ;
; passado em bcd_in para a PORTB ;
;===================================================================;
bcd_7seg
movlw seg70 ; Incio da tabela de valores
addwf bcd_in,w ; & do val a mostrar da tabela
movwf FSR ; Set do endereo da tabela
movf INDF,w ; leitura do valor de 7seg
movwf PORTB ; envio do valor para o PORTB
return
;===================================================================;
; Input: W(reg) = BCD_IN - valor BCD de entrada ;
; Output: ;
; ;
; Resumo: ;

110
www.mecatronicadegaragem.blogspot.com

TP7 - 60 segundos, verso III

;===================================================================;
prt_disp7seg
movwf bcd_in ; bcd_in = w
call display ; display(bcd_in,disp_7seg);
btfss INTCON,T0IF ; while(TOIF == 0) {}
goto $-1 ;
bcf INTCON,T0IF ; T0IF = 0;
movlw 120 ; Set Hardware timer0 Value
movwf TMR0 ; Set TMR0
incf disp_7seg,f ; disp_7seg ++;
return
;===================================================================;
; Input: COUNTER - valor de entrada ;
; Output: COUNTER - valor decrementado ;
; Flag de Zero afectada: Z=0 if COUNTER != FF ;
; Z=1 if COUNTER == FF ;
; Resumo: ;
; ;
; ;
;===================================================================;
countdown
decf counter,f ; counter--
movfw counter ; w = counter
sublw 0xFF ;
btfsc STATUS,Z ; if( w == 0xFF )
return ; return (Z flag ON)
movfw counter ; w = counter
andlw 0x0F ; w = w & 0x0F
sublw 0x0F ;
btfss STATUS, Z ; if( w != 0x0F)
goto dif_xf ; goto dif_xf
movfw counter ; w = counter
andlw 0xF0 ; w = w & 0xF0
iorlw 0x09 ; w = w | 0x09
movwf counter ; counter = w
dif_xf: bcf STATUS,Z ; reset ZERO flag
return
;====================================================================;
;teste_sw ;
; ;
; Subrotina de teste do SW start/stop ;
; ;
;====================================================================;
teste_sw
bcf INTCON,INTF
incf start_stop,w ;
andlw 0x01
movwf start_stop ; start_stop = (++start_stop) & 0x01
return
;********************************************************************

;************************** ISR *************************************


;********************************************************************
;********************************************************************
interrupt_start
movwf w_save ;Salvaguarda W register
swapf STATUS,W
clrf STATUS
movwf status_save ;Salvaguarda do STATUS reg
movf PCLATH,W
movwf pclath_save
clrf PCLATH

111
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

call teste_sw
interrupt_end
movf pclath_save,w
movwf PCLATH
swapf status_save,w
movwf STATUS ;Recover STATUS reg
swapf w_save,f ;Read saved W register
swapf w_save,w ;Recover W register
retfie
END

112
www.mecatronicadegaragem.blogspot.com

TP7 - 60 segundos, verso III

5.2 Ponto 2
; Trabalho n 7p2
; Implementao de relgio de 60 segundos c/ timer interrupts
;
; Observaes:
; Implementado com com Timers a gerar interrupo a cada 10ms.
;
;********************************************************************
; *
; Nome ficheiro: trab7p2_3.asm *
; Data: 1/Junho/2005 *
; Verso: 1.0 *
; *
; Autores: Jos Miguel Gaspar *
; Olmpia Rodrigues *
; Orientador: Prof. Jos Lus Azevedo *
; *
; Universidade de Aveiro *
; Seminrio EEI 2004/2005 *
; *
;********************************************************************
; *
; Ficheiro necessrio: P16F876.INC *
; *
;********************************************************************

list p=16f876 ; list directive to define


radix decimal ; processor
#include "p16f876.inc" ; processor specific variable
; definitions
errorlevel -302 ; Turn off banking message
; known tested (good) code
;--------------------------------------------------------------------
; Constantes
;--------------------------------------------------------------------
RA0 EQU 0
RA1 EQU 1
RA2 EQU 2
RA3 EQU 3
RA4 EQU 4
RA5 EQU 5
RB0 EQU 0
RB1 EQU 1
RB2 EQU 2
RB3 EQU 3
RB4 EQU 4
RB5 EQU 5
RB6 EQU 6
RB7 EQU 7
RC0 EQU 0
RC1 EQU 1
RC2 EQU 2
RC3 EQU 3
RC4 EQU 4
RC5 EQU 5
RC6 EQU 6
RC7 EQU 7

TMR0_HW_VAL1 EQU 60 ; 10ms aprox.


TMR0_HW_VAL2 EQU 120 ; 5ms aprox.
TMR0_SFW_VAL EQU 100 ;

113
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

;--------------------------------------------------------------------
;Displays de 7 segementos -|gfedcba-|
;--------------------------------------------------------------------
seg7_0 EQU b01111110 ; Valor 0
seg7_1 EQU b00001100 ; Valor 1
seg7_2 EQU b10110110 ; Valor 2
seg7_3 EQU b10011110 ; Valor 3
seg7_4 EQU b11001100 ; Valor 4
seg7_5 EQU b11011010 ; Valor 5
seg7_6 EQU b11111000 ; Valor 6
seg7_7 EQU b00001110 ; Valor 7
seg7_8 EQU b11111110 ; Valor 8
seg7_9 EQU b11001110 ; Valor 9
seg7_A EQU b11101110 ; Valor A
seg7_B EQU b11111000 ; Valor B
seg7_C EQU b01110010 ; Valor C
seg7_D EQU b10111100 ; Valor D
seg7_E EQU b11110010 ; Valor E
seg7_F EQU b11100010 ; Valor F
seg7_n EQU b10101000 ; Valor n
seg7_null EQU b00000000 ; Valor Null
;----------------------------------------------------------------------
; Variveis (REGISTOS DE USO GERAL)
;----------------------------------------------------------------------
variaveis UDATA 0x20
seg70 RES 1 ; Valor 0 endereo
seg71 RES 1 ; Valor 1 endereo
seg72 RES 1 ; Valor 2 endereo
seg73 RES 1 ; Valor 3 endereo
seg74 RES 1 ; Valor 4 endereo
seg75 RES 1 ; Valor 5 endereo
seg76 RES 1 ; Valor 6 endereo
seg77 RES 1 ; Valor 7 endereo
seg78 RES 1 ; Valor 8 endereo
seg79 RES 1 ; Valor 9 endereo
seg7A RES 1 ; Valor A endereo
seg7B RES 1 ; Valor B endereo
seg7C RES 1 ; Valor C endereo
seg7D RES 1 ; Valor D endereo
seg7E RES 1 ; Valor E endereo
seg7F RES 1 ; Valor F endereo
seg7n RES 1 ; Valor n endereo
seg7null RES 1 ; Valor null endereo
timer0_cnt RES 1 ; Software timer0_count Value
bcd_in RES 1 ; endereo de entrada BCD
counter RES 1 ; valor a ser decrementado
disp_7seg RES 1 ; seleo do display de 7_seg
aux RES 1
start_stop RES 1
w_save RES 1 ; SAVE W
status_save RES 1 ; SAVE STATUS REG
pclath_save RES 1 ; SAVE PCLATH REG

;--------------------------------------------------------------------
; Macros to select the register Banks
;--------------------------------------------------------------------
Bank0 MACRO ; Macro to select data RAM Bank 0
bcf STATUS,RP0
bcf STATUS,RP1
ENDM
Bank1 MACRO ; Macro to select data RAM Bank 1
bsf STATUS,RP0
bcf STATUS,RP1
ENDM

114
www.mecatronicadegaragem.blogspot.com

TP7 - 60 segundos, verso III

Bank2 MACRO ; Macro to select data RAM Bank 2


bcf STATUS,RP0
bsf STATUS,RP1
ENDM
Bank3 MACRO ; Macro to select data RAM Bank 3
bsf STATUS,RP0
bsf STATUS,RP1
ENDM
;********************************************************************
ORG 0x0000 ; Processor reset vector
clrf PCLATH ; Ensure page bits are cleared
goto main ; Go to beginning of program
ORG 0x04 ; Interrupt vector
goto interrupt_start ; Go to interrupt Service
; Rotine
;--------------------------------------------------------------------
; Rotina Main
;--------------------------------------------------------------------
ORG 0x0005
main ; Programa principal.
call InitCfg ; rotina de configurao
do_main ; do{
movf counter,w ; leitura da flag Z
btfss STATUS,Z ; }while(STATUS,Z == 0);
goto do_main ; Z = 0, Jump to do_main
; Z = 1, Time OUT
clrf INTCON ; Interruption disable
loop
clrf disp_7seg
movlw 0x0d ; print - d
call prt_disp7seg
movlw 0x10 ; print - n
call prt_disp7seg
movlw 0x0E ; print - E
call prt_disp7seg
goto loop
;********************************************************************

;************************** ROTINAS *********************************


;********************************************************************
;********************************************************************
;===================================================================;
; InitCfg ;
; Configurao inicial dos registros associados ;
; ao programa principal, PORTOS I/O, Timer0. ;
; ;
; Retorna em Bank0 ;
; ;
; Notas: ;
;===================================================================;
InitCfg
;----------------- Analog 2 Digital - InitCfg ----------------------;
Bank1 ; DATA memory (RAM) Bank1
movlw 0x06 ; W = 0x06
movwf ADCON1 ; ADCON1 (PORTA I/O digital)
;----------------- I/O - InitCfg -----------------------------------;
movlw b11110001 ; RA[3:1] outputs
movwf TRISA ; RA[7:4 & 0] inputs
movlw b00000001 ; RB[7:1] outputs

115
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

movwf TRISB ; RB[0] input


;----------------- TRM0 - InitCfg ----------------------------------;
clrf OPTION_REG ; clear OPTION_REG
bsf OPTION_REG,INTEDG ; INTEDG = 1
bsf OPTION_REG,PS2 ;
bsf OPTION_REG,PS1 ; TMR0 Rate
bsf OPTION_REG,PS0 ; 1:256
Bank0 ; DATA memory (RAM) Bank0
movlw TMR0_HW_VAL1 ; Set Hardware timer0 Value
movwf TMR0 ; Set TMR0
movlw TMR0_SFW_VAL ; Set Software timer0_count Value
movwf timer0_cnt ; Save time0_count adjust
;----------------- Interrupts enable bits --------------------------;
clrf INTCON
bsf INTCON,GIE ; Global Int. Enable bit
bsf INTCON,T0IE ; TMR0 Overflow Int. enable
bsf INTCON,INTE ; External Int. enable bit
clrf disp_7seg ;
movlw 0x59 ;
movwf counter ; Valor Inicial do contador seg
;--------------------------------------------------------------------
; Inicializao dos registros associados aos displays 7seg
;--------------------------------------------------------------------
movlw seg7_0 ; Set 7segment valor 0
movwf seg70 ; Save valor 0
movlw seg7_1 ; Set 7segment valor 1
movwf seg71 ; Save valor 1
movlw seg7_2 ; Set 7segment valor 2
movwf seg72 ; Save valor 2
movlw seg7_3 ; Set 7segment valor 3
movwf seg73 ; Save valor 3
movlw seg7_4 ; Set 7segment valor 4
movwf seg74 ; Save valor 4
movlw seg7_5 ; Set 7segment valor 5
movwf seg75 ; Save valor 5
movlw seg7_6 ; Set 7segment valor 6
movwf seg76 ; Save valor 6
movlw seg7_7 ; Set 7segment valor 7
movwf seg77 ; Save valor 7
movlw seg7_8 ; Set 7segment valor 8
movwf seg78 ; Save valor 8
movlw seg7_9 ; Set 7segment valor 9
movwf seg79 ; Save valor 9
movlw seg7_A ; Set 7segment valor A
movwf seg7A ; Save valor A
movlw seg7_B ; Set 7segment valor B
movwf seg7B ; Save valor B
movlw seg7_C ; Set 7segment valor C
movwf seg7C ; Save valor C
movlw seg7_D ; Set 7segment valor D
movwf seg7D ; Save valor D
movlw seg7_E ; Set 7segment valor E
movwf seg7E ; Save valor E
movlw seg7_F ; Set 7segment valor F
movwf seg7F ; Save valor F
movlw seg7_n ; Set 7segment pattern N
movwf seg7n ; Save pattern N
movlw seg7_null ; Set 7segment pattern NULL
movwf seg7null ; Save pattern N
return

116
www.mecatronicadegaragem.blogspot.com

TP7 - 60 segundos, verso III

;===================================================================;
; Input: W(reg) - valor BCD de entrada ;
; Input: DISP_7SEG - seleo do display a ser refrescado ;
; Output: no tm parmetro de sada ;
; ;
; Resumo: Subroutina de Controlo dos displays ;
; Prottipo em Linguagem C ;
; void display(unsigned char bcd_in, unsigned char disp_7seg) ;
;===================================================================;
display
movwf bcd_in ;
movf PORTA,w ; w = PORTA
andlw 0xF1 ;
movwf aux ; aux = w & 0xf1
disp_0 movfw disp_7seg ; switch(disp_7seg)
sublw 0x00 ;
btfss STATUS,Z ;
goto disp_1 ;
movfw aux ; case_0
iorlw 0x08 ; w = aux | 0x08
goto break ; break
disp_1 movfw disp_7seg ; switch(dis_7seg)
sublw 0x01 ;
btfss STATUS,Z ;
goto disp_2 ;
movfw aux ; case_1
iorlw 0x04 ; w = aux | 0x04
goto break ; break
disp_2 movfw aux ; case_2
iorlw 0x02 ; w = aux | 0x02
break movwf PORTA ; escrita na porta
call bcd_7seg ; bcd_7seg(bcd_in);
return
;===================================================================;
; Input: bcd_in - valor BCD de entrada ;
; Output: ;
; ;
; Resumo: Subroutina => BCD to 7segment display, envia o valor ;
; passado em bcd_in para a PORTB ;
;===================================================================;
bcd_7seg
movlw seg70 ; Incio da tabela de valores
addwf bcd_in,w ; & do val a mostrar da tabela
movwf FSR ; Set do endereo da tabela
movf INDF,w ; leitura do valor de 7seg
movwf PORTB ; envio do valor para o PORTB
return
;===================================================================;
; Input: W(reg) = BCD_IN - valor BCD de entrada ;
; Output: ;
; ;
; Resumo: ;
;===================================================================;
prt_disp7seg
call display ; display(bcd_in,disp_7seg);
btfss INTCON,T0IF ; while(TOIF == 0) {}
goto $-1 ;
bcf INTCON,T0IF ; T0IF = 0;
movlw 120 ; Set Hardware timer0 Value
movwf TMR0 ; Set TMR0

117
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

incf disp_7seg,f ; disp_7seg ++;


return
;===================================================================;
; Input: COUNTER - valor de entrada ;
; Output: COUNTER - valor decrementado ;
; Flag de Zero afectada: Z=0 if COUNTER != FF ;
; Z=1 if COUNTER == FF ;
; Resumo: ;
; ;
; ;
;===================================================================;
countdown
decf counter,f ; counter--
movfw counter ; w = counter
sublw 0xFF ;
btfsc STATUS,Z ; if( w == 0xFF )
return ; return
movfw counter ; w = counter
andlw 0x0F ; w = w & 0x0F
sublw 0x0F ;
btfss STATUS, Z ; if( w != 0x0F)
goto dif_xf ; goto dif_xf
movfw counter ; w = counter
andlw 0xF0 ; w = w & 0xF0
iorlw 0x09 ; w = w | 0x09
movwf counter ; counter = w
dif_xf: bcf STATUS,Z ; reset ZERO flag
return

;********************************************************************

;************************** ISR *************************************


;********************************************************************
;********************************************************************
interrupt_start
movwf w_save ;Salvaguarda W register
swapf STATUS,W
clrf STATUS
movwf status_save ;Salvaguarda do STATUS reg
movf PCLATH,W
movwf pclath_save
clrf PCLATH
;**************** Timer0 interruption process *********************
timer_int
bcf INTCON,T0IF ; Clear timer0 int flag
movlw TMR0_HW_VAL1 ; Set Hard timer value
movwf TMR0 ; Set TMR0
btfsc disp_7seg,0 ; if(disp_7seg == 0)
goto else_isr ; {
movfw counter ; w = counter
andlw 0x0F ; w = w & 0x0F
movwf bcd_in ; bcd_in = counter & 0x0F
goto display_isr
else_isr ; } else
swapf counter,w ;
andlw 0x0F ;
btfsc STATUS,Z ;
goto $+3 ; if (STATUS,Z==1)
movwf bcd_in ; bcd_in = counter >> 4 ;
display_isr call display ; display(bcd_in,disp_7seg);
incf disp_7seg,w ;
andlw 0x01 ;

118
www.mecatronicadegaragem.blogspot.com

TP7 - 60 segundos, verso III

movwf disp_7seg ; disp_7seg = (++disp_7seg) & 0x01;


btfsc start_stop,0 ; if (start_stop == 1)
goto interrupt_end; {
decfsz timer0_cnt,f ; if((timer0_cnt--) == 0 )
goto interrupt_end; {
movlw TMR0_SFW_VAL ;
movwf timer0_cnt ; timer0_cnt = 100;
call countdown ; countdown(counter);
; }
; }
;************ FIM do processo de Interrupt ************************
interrupt_end
movf pclath_save,w
movwf PCLATH
swapf status_save,w
movwf STATUS ;Recover STATUS reg
swapf w_save,f ;Read saved W register
swapf w_save,w ;Recover W register
retfie
END

119
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

5.3 Ponto 3
; Trabalho n 7p3
; Implementao de relgio de 60 segundos c/ timer interrupts
; e interrupo de start stop apartir de (RB0)
; distino da interrupo gerada dentro da rotina de servio
; interrupo
;
; Observaes:
; Implementado com com Timers a gerar interrupo a cada 10ms.
;
;********************************************************************
; *
; Nome ficheiro: trab7p2_3.asm *
; Data: 1/Junho/2005 *
; Verso: 1.0 *
; *
; Autores: Jos Miguel Gaspar *
; Olmpia Rodrigues *
; Orientador: Prof. Jos Lus Azevedo *
; *
; Universidade de Aveiro *
; Seminrio EEI 2004/2005 *
; *
;********************************************************************
; *
; Ficheiro necessrio: P16F876.LKR *
; *
;********************************************************************

list p=16f876 ; list directive to define


radix decimal ; processor
#include "p16f876.inc" ; processor specific variable
; definitions
errorlevel -302 ; Turn off banking message
; known tested (good) code
;--------------------------------------------------------------------
; Constantes
;--------------------------------------------------------------------
RA0 EQU 0
RA1 EQU 1
RA2 EQU 2
RA3 EQU 3
RA4 EQU 4
RA5 EQU 5
RB0 EQU 0
RB1 EQU 1
RB2 EQU 2
RB3 EQU 3
RB4 EQU 4
RB5 EQU 5
RB6 EQU 6
RB7 EQU 7
RC0 EQU 0
RC1 EQU 1
RC2 EQU 2
RC3 EQU 3
RC4 EQU 4
RC5 EQU 5
RC6 EQU 6
RC7 EQU 7

TMR0_HW_VAL1 EQU 60 ; 10ms aprox.

120
www.mecatronicadegaragem.blogspot.com

TP7 - 60 segundos, verso III

TMR0_HW_VAL2 EQU 120 ; 5ms aprox.


TMR0_SFW_VAL EQU 100 ;
;--------------------------------------------------------------------
;Displays de 7 segementos -|gfedcba-|
;--------------------------------------------------------------------
seg7_0 EQU b01111110 ; Valor 0
seg7_1 EQU b00001100 ; Valor 1
seg7_2 EQU b10110110 ; Valor 2
seg7_3 EQU b10011110 ; Valor 3
seg7_4 EQU b11001100 ; Valor 4
seg7_5 EQU b11011010 ; Valor 5
seg7_6 EQU b11111000 ; Valor 6
seg7_7 EQU b00001110 ; Valor 7
seg7_8 EQU b11111110 ; Valor 8
seg7_9 EQU b11001110 ; Valor 9
seg7_A EQU b11101110 ; Valor A
seg7_B EQU b11111000 ; Valor B
seg7_C EQU b01110010 ; Valor C
seg7_D EQU b10111100 ; Valor D
seg7_E EQU b11110010 ; Valor E
seg7_F EQU b11100010 ; Valor F
seg7_n EQU b10101000 ; Valor n
seg7_null EQU b00000000 ; Valor Null
;----------------------------------------------------------------------
; Variveis (REGISTOS DE USO GERAL)
;----------------------------------------------------------------------
variaveis UDATA 0x20
seg70 RES 1 ; Valor 0 endereo
seg71 RES 1 ; Valor 1 endereo
seg72 RES 1 ; Valor 2 endereo
seg73 RES 1 ; Valor 3 endereo
seg74 RES 1 ; Valor 4 endereo
seg75 RES 1 ; Valor 5 endereo
seg76 RES 1 ; Valor 6 endereo
seg77 RES 1 ; Valor 7 endereo
seg78 RES 1 ; Valor 8 endereo
seg79 RES 1 ; Valor 9 endereo
seg7A RES 1 ; Valor A endereo
seg7B RES 1 ; Valor B endereo
seg7C RES 1 ; Valor C endereo
seg7D RES 1 ; Valor D endereo
seg7E RES 1 ; Valor E endereo
seg7F RES 1 ; Valor F endereo
seg7n RES 1 ; Valor n endereo
seg7null RES 1 ; Valor null endereo
timer0_cnt RES 1 ; Software timer0_count Value
bcd_in RES 1 ; endereo de entrada BCD
counter RES 1 ; valor a ser decrementado
disp_7seg RES 1 ; seleo do display de 7_seg
aux RES 1
start_stop RES 1
w_save RES 1 ; SAVE W
status_save RES 1 ; SAVE STATUS REG
pclath_save RES 1 ; SAVE PCLATH REG

;--------------------------------------------------------------------
; Macros to select the register Banks
;--------------------------------------------------------------------
Bank0 MACRO ; Macro to select data RAM Bank 0
bcf STATUS,RP0
bcf STATUS,RP1
ENDM
Bank1 MACRO ; Macro to select data RAM Bank 1

121
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

bsf STATUS,RP0
bcf STATUS,RP1
ENDM
Bank2 MACRO ; Macro to select data RAM Bank 2
bcf STATUS,RP0
bsf STATUS,RP1
ENDM
Bank3 MACRO ; Macro to select data RAM Bank 3
bsf STATUS,RP0
bsf STATUS,RP1
ENDM
;********************************************************************
ORG
0x0000 ; Processor reset vector
clrf
PCLATH ; Ensure page bits are cleared
goto
main ; Go to beginning of program
ORG
0x04 ; Interrupt vector
goto
interrupt_start ; Go to interrupt Service
; Rotine
;--------------------------------------------------------------------
; Rotina Main
;--------------------------------------------------------------------
ORG 0x0005
main ; Programa principal.
call InitCfg ; rotina de configurao
do_main ; do{
movf counter,w ; leitura da flag Z
btfss STATUS,Z ; }while(STATUS,Z == 0);
goto do_main ; Z = 0, Jump to do_main
; Z = 1, Time OUT
clrf INTCON ; Interruption disable
loop
clrf disp_7seg
movlw 0x0d ; print - d
call prt_disp7seg
movlw 0x10 ; print - n
call prt_disp7seg
movlw 0x0E ; print - E
call prt_disp7seg
goto loop
;********************************************************************

;************************** ROTINAS *********************************


;********************************************************************
;********************************************************************
;===================================================================;
; InitCfg ;
; Configurao inicial dos registros associados ;
; ao programa principal, PORTOS I/O, Timer0. ;
; ;
; Retorna em Bank0 ;
; ;
; Notas: ;
;===================================================================;
InitCfg
;----------------- Analog 2 Digital - InitCfg ----------------------;
Bank1 ; DATA memory (RAM) Bank1
movlw 0x06 ; W = 0x06
movwf ADCON1 ; ADCON1 (PORTA I/O digital)
;----------------- I/O - InitCfg -----------------------------------;

122
www.mecatronicadegaragem.blogspot.com

TP7 - 60 segundos, verso III

movlw b11110001 ; RA[3:1] outputs


movwf TRISA ; RA[7:4 & 0] inputs
movlw b00000001 ; RB[7:1] outputs
movwf TRISB ; RB[0] input
;----------------- TRM0 - InitCfg ----------------------------------;
clrf OPTION_REG ; clear OPTION_REG
bsf OPTION_REG,INTEDG ; INTEDG = 1
bsf OPTION_REG,PS2 ;
bsf OPTION_REG,PS1 ; TMR0 Rate
bsf OPTION_REG,PS0 ; 1:256
Bank0 ; DATA memory (RAM) Bank0
movlw TMR0_HW_VAL1 ; Set Hardware timer0 Value
movwf TMR0 ; Set TMR0
movlw TMR0_SFW_VAL ; Set Software timer0_count Value
movwf timer0_cnt ; Save time0_count adjust
;----------------- Interrupts enable bits --------------------------;
clrf INTCON
bsf INTCON,GIE ; Global Int. Enable bit
bsf INTCON,T0IE ; TMR0 Overflow Int. enable
bsf INTCON,INTE ; External Int. enable bit
clrf disp_7seg ;
movlw 0x59 ;
movwf counter ; Valor Inicial do contador seg
;--------------------------------------------------------------------
; Inicializao dos registros associados aos displays 7seg
;--------------------------------------------------------------------
movlw seg7_0 ; Set 7segment valor 0
movwf seg70 ; Save valor 0
movlw seg7_1 ; Set 7segment valor 1
movwf seg71 ; Save valor 1
movlw seg7_2 ; Set 7segment valor 2
movwf seg72 ; Save valor 2
movlw seg7_3 ; Set 7segment valor 3
movwf seg73 ; Save valor 3
movlw seg7_4 ; Set 7segment valor 4
movwf seg74 ; Save valor 4
movlw seg7_5 ; Set 7segment valor 5
movwf seg75 ; Save valor 5
movlw seg7_6 ; Set 7segment valor 6
movwf seg76 ; Save valor 6
movlw seg7_7 ; Set 7segment valor 7
movwf seg77 ; Save valor 7
movlw seg7_8 ; Set 7segment valor 8
movwf seg78 ; Save valor 8
movlw seg7_9 ; Set 7segment valor 9
movwf seg79 ; Save valor 9
movlw seg7_A ; Set 7segment valor A
movwf seg7A ; Save valor A
movlw seg7_B ; Set 7segment valor B
movwf seg7B ; Save valor B
movlw seg7_C ; Set 7segment valor C
movwf seg7C ; Save valor C
movlw seg7_D ; Set 7segment valor D
movwf seg7D ; Save valor D
movlw seg7_E ; Set 7segment valor E
movwf seg7E ; Save valor E
movlw seg7_F ; Set 7segment valor F
movwf seg7F ; Save valor F
movlw seg7_n ; Set 7segment pattern N
movwf seg7n ; Save pattern N
movlw seg7_null ; Set 7segment pattern NULL
movwf seg7null ; Save pattern N

123
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

return
;===================================================================;
; Input: W(reg) - valor BCD de entrada ;
; Input: DISP_7SEG - seleo do display a ser refrescado ;
; Output: no tm parmetro de sada ;
; ;
; Resumo: Subroutina de Controlo dos displays ;
; Prottipo em Linguagem C ;
; void display(unsigned char bcd_in, unsigned char disp_7seg) ;
;===================================================================;
display
movwf bcd_in ;
movf PORTA,w ; w = PORTA
andlw 0xF1 ;
movwf aux ; aux = w & 0xf1
disp_0 movfw disp_7seg ; switch(disp_7seg)
sublw 0x00 ;
btfss STATUS,Z ;
goto disp_1 ;
movfw aux ; case_0
iorlw 0x08 ; w = aux | 0x08
goto break ; break
disp_1 movfw disp_7seg ; switch(dis_7seg)
sublw 0x01 ;
btfss STATUS,Z ;
goto disp_2 ;
movfw aux ; case_1
iorlw 0x04 ; w = aux | 0x04
goto break ; break
disp_2 movfw aux ; case_2
iorlw 0x02 ; w = aux | 0x02
break movwf PORTA ; escrita na porta
call bcd_7seg ; bcd_7seg(bcd_in);
return
;===================================================================;
; Input: bcd_in - valor BCD de entrada ;
; Output: ;
; ;
; Resumo: Subroutina => BCD to 7segment display, envia o valor ;
; passado em bcd_in para a PORTB ;
;===================================================================;
bcd_7seg
movlw seg70 ; Incio da tabela de valores
addwf bcd_in,w ; & do val a mostrar da tabela
movwf FSR ; Set do endereo da tabela
movf INDF,w ; leitura do valor de 7seg
movwf PORTB ; envio do valor para o PORTB
return
;===================================================================;
; Input: W(reg) = BCD_IN - valor BCD de entrada ;
; Output: ;
; ;
; Resumo: ;
;===================================================================;
prt_disp7seg
call display ; display(bcd_in,disp_7seg);
btfss INTCON,T0IF ; while(TOIF == 0) {}
goto $-1 ;
bcf INTCON,T0IF ; T0IF = 0;

124
www.mecatronicadegaragem.blogspot.com

TP7 - 60 segundos, verso III

movlw 120 ; Set Hardware timer0 Value


movwf TMR0 ; Set TMR0
incf disp_7seg,f ; disp_7seg ++;
return
;===================================================================;
; Input: COUNTER - valor de entrada ;
; Output: COUNTER - valor decrementado ;
; Flag de Zero afectada: Z=0 if COUNTER != FF ;
; Z=1 if COUNTER == FF ;
; Resumo: ;
; ;
; ;
;===================================================================;
countdown
decf counter,f ; counter--
movfw counter ; w = counter
sublw 0xFF ;
btfsc STATUS,Z ; if( w == 0xFF )
return ; return
movfw counter ; w = counter
andlw 0x0F ; w = w & 0x0F
sublw 0x0F ;
btfss STATUS, Z ; if( w != 0x0F)
goto dif_xf ; goto dif_xf
movfw counter ; w = counter
andlw 0xF0 ; w = w & 0xF0
iorlw 0x09 ; w = w | 0x09
movwf counter ; counter = w
dif_xf: bcf STATUS,Z ; reset ZERO flag
return
;====================================================================;
;teste_sw ;
; ;
; Subrotina de teste do SW start/stop ;
; ;
;====================================================================;
teste_sw
bcf INTCON,INTF
incf start_stop,w ;
andlw 0x01
movwf start_stop ; start_stop = (++start_stop) & 0x01
return
;********************************************************************

;************************** ISR *************************************


;********************************************************************
;********************************************************************
interrupt_start
movwf w_save ;Salvaguarda W register
swapf STATUS,W
clrf STATUS
movwf status_save ;Salvaguarda do STATUS reg
movf PCLATH,W
movwf pclath_save
clrf PCLATH
btfsc INTCON,INTF ; if ( INTF == 1 )
call teste_sw ; call teste_sw
; else
;**************** Timer0 interruption process *********************
timer_int
bcf INTCON,T0IF ; Clear timer0 int flag

125
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

movlw TMR0_HW_VAL1 ; Set Hard timer value


movwf TMR0 ; Set TMR0
btfsc disp_7seg,0 ; if(disp_7seg == 0)
goto else_isr ; {
movfw counter ; w = counter
andlw 0x0F ; w = w & 0x0F
movwf bcd_in ; bcd_in = counter & 0x0F
goto display_isr
else_isr ; } else
swapf counter,w ;
andlw 0x0F ;
btfsc STATUS,Z ;
goto $+3 ; if (STATUS,Z==1)
movwf bcd_in ; bcd_in = counter >> 4 ;
display_isr call display ; display(bcd_in,disp_7seg);
incf disp_7seg,w ;
andlw 0x01 ;
movwf disp_7seg ; disp_7seg = (++disp_7seg) & 0x01;
btfsc start_stop,0 ; if (start_stop == 1)
goto interrupt_end; {
decfsztimer0_cnt,f ; if((timer0_cnt--) == 0 )
goto interrupt_end; {
movlw TMR0_SFW_VAL ;
movwf timer0_cnt ; timer0_cnt = 100;
call countdown ; countdown(counter);
; }
; }
;************ FIM do processo de Interrupt ************************
interrupt_end
movf pclath_save,w
movwf PCLATH
swapf status_save,w
movwf STATUS ;Recover STATUS reg
swapf w_save,f ;Read saved W register
swapf w_save,w ;Recover W register
retfie
END

126
www.mecatronicadegaragem.blogspot.com

TP8 - USART do PIC

Tema a desenvolver Durao


Comunicao srie assncrona (USART) 2 aulas

1 Resumo

Neste trabalho prtico, ser explorada a USART (Universal Synchronous Asynchronous Receiver
Transmitter) do PIC16F876, no modo assncrono full duplex, na comunicao srie entre o PIC e o
computador do laboratrio, atravs de um programa que implementa um terminal srie.

2 Objectivos

Compreenso dos passos de programao da USART, para recepo e transmisso de dados.

Elaborao de rotinas para transmisso e recepo de um carcter.

Elaborao de uma rotina para transmisso de um array de caracteres (strings).

3 Descrio

A USART, uma das duas portas de comunicao integradas no PIC16F876. Este circuito permite
a configurao para comunicao sncrono ou assncrono, embora neste trabalho apenas estejamos
interessados no modo de comunicao assncrona.
Na comunicao com a USART cada bloco de dados composto por 8 bits (contudo pode ser
utilizado um bit adicional para implementar um esquema de deteco de erros, de comunicao por
verificao de paridade).
O funcionamento da USART, definido atravs da programao de dois registos de controlo,
TXSTA (registo de controlo/estado de transmisso) e RCSTA (registo de controlo/estado de recepo),
mais detalhes ver pginas 131 e 132 respectivamente.

127
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

3.1 Configurao dos pinos de transmisso/recepo

No modo assncrono, usa-se o pino (17)


RC6 / TX / CK para transmisso de dados,
sendo o pino (18) RC7 / RX / DT usado para
recepo de dados. Para a USART funcio-
nar correctamente, a entrada (linha RX), e a
sada (linha TX) tm de ser definidos no re-
gisto TRISC, (ver configurao de um porto
pgina 16). Assim, o bit 6 do porto C, de-
finido em modo sada valor 0 e o bit 7 Figura 34: Atribuio do porto srie

definido em modo entrada valor 1. Usando, RC6 e RC7 como porto para a USART, o bit SPEN do
registo RCSTA, deve ser activado a 1.

3.2 Taxa de transmisso da USART

A taxa de transmisso da USART, controlada pelo BRG (Baud Rate Generator). Esta definida pelo
valor a colocar no registo SPBRG, este registo controla o perodo do sinal de sada de um free run
timer de 8 bits. Em modo assncrono, o bit BRGH no registo TXSTA, usado para controlar a taxa
de transmisso entre low speed e high speed, usar high speed na maioria dos casos vantajoso, uma
vez que reduz a taxa de erro.
As taxas de transmisso disponveis, para o PIC com uma FOSC de 20MHz esto descritas na
tabela 5.

Taxa de transmisso (BAUD RATE) Valor (decimal) a colocar em SPBRG


9600 129
19200 64
28800 42
33600 36
57600 20
115200 10

Tabela 5: Taxa de transmisso em modo assncrono (BRGH = 1)

128
www.mecatronicadegaragem.blogspot.com

TP8 - USART do PIC

3.3 Operao de transmisso

no registo TXREG que so carregados os dados a transmitir, estes so depois enviados de forma
automtica para o registo interno TSR e posteriormente transmitidos pelo porto TX. A transmisso de
dados activada pelo bit TXEN do registo TXSTA. O bit menos significativo (LSB, Least Significant
Bit), transferido em primeiro lugar.
Uma vez transmitido o contedo do registo TXREG para TSR, o TXIF (bit indicador do estado do
buffer em PIR1) sinaliza que o registo de transmisso da USART est vazio, tomando o valor 1. Os
dados podem ser continuamente transmitidos, se primeiro fr detectada a sinalizao de TXIF, e de
seguida fr efectuada uma escrita no registo TXREG. O TXIF no pode ser apagado por programao:
automticamente forado a 0 quando os dados so movidos para TXREG;

Figura 35: Operao de transmisso assncrona

Passos a seguir na configurao de uma Transmisso Assncrona.

1. Inicializar o registo SPBRG com a taxa de transferncia apropriada (ver tabela 5);

2. Activao da porta srie em modo assncrono, pondo a 0 o bit SYNC do registo TXSTA e a
1 o bit SPEN do registo RCSTA;

3. Por forma activar a transmisso o bit TXEN (registo TXSTA) activo a 1. Nessa altura o
registo TXREG est em condies de ser escrito e o bit TXIF do registo PIR1 vem a 1;

4. Enviar os dados para o TXREG e comear a transmisso.

129
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

3.4 Operao de recepo

Os dados recebidos pela porta RX so recolhidos no registo RSR, atravs do circuito de recolha de
dados (Data Recovery). Os dados so recolhidos pelo registo RSR, de acordo com a taxa de transmis-
so especificada pelo registo SPBRG e pelo bit BRGH do registo TXSTA (ver pgina 131).
Aquando da deteco do stop bit, o contedo do registo RSR transferido para o registo RCREG.
O bit RCIF do registo PIR1, toma o valor 1 quando os dados so escritos no registo RCREG, (sina-
lizando a recepo de nova informao). Os dados podem ser continuamente recebidos, se primeiro
fr detectada a sinalizao e de seguida efectuar-se uma leitura do registo RCREG. O RCIF no pode
ser apagado por programao, este 0 quando os dados so lidos de RCREG.

Figura 36: Operaco de recepco assncrona

Passos a seguir na configurao na Recepo Assncrona.

1. Inicializar o registo SPBRG com a taxa de transmisso apropriada;

2. Activao da porta srie em modo assncrono, pondo a 0 o bit SYNC do registo TXSTA e a
1 o bit SPEN do registo RCSTA;

3. Permitir a recepo, activando o bit CREN do registo RCSTA;

4. Quando a recepo estiver terminada, a flag RCIF do registo PIR1 activado;

5. Para ler os oito bits recebidos, dever ser lido o registo RCREG.

130
www.mecatronicadegaragem.blogspot.com

TP8 - USART do PIC

3.5 Registo TXSTA

bit 7 CSRC: Seleco da origem do relgio.


Modo Assncrono:
Dontt care.
Modo Sncrono:
1 = Modo master (relgio gerado internamente por BRG).
0 = Modo slave (relgio gerado externamente).

bit 6 TX9: Transmisso com 9 bits.


1 = Activa a transmisso a 9 bits.
0 = Desactiva a transmisso a 9 bits.

bit 5 TXEN: Activa transmisso.


1 = Activa transmisso.
0 = Desactiva transmisso.

bit 4 CREN: Modo de comunicao da USART.


1 = Modo Assncrono.
0 = Modo Sncrono.

bit 3 No Implementado: leitura a 0.

bit 2 BRGH: Bit de seleco de HIGH Baud Rate.


Modo Assncrono:
1 = HIGH SPEED.
0 = LOW SPEED.
Modo Sncrono:
No usado neste modo

bit 1 TRMT: Transmit Shift Register, bit de estado.


1 = TSR vazio.
0 = TSR cheio.

bit 0 TX9D: Nono bit, na transmisso de dados, (usado para paridade).

131
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

3.6 Registo RCSTA

bit 7 SPEN: Activao da porta srie do PIC.


1 = Porta srie activada (configura RC7/RX/DT e RC6/TX/CK pinos como portos srie) .
0 = Porta srie desactivada.

bit 6 RX9: Recepo com 9 bits.


1 = Activa a recepo a 9 bits.
0 = Desactiva a recepo a 9 bits.

bit 5 SREN: Activa recepo nica.


Modo Assncrono:
Dontt care.
Modo Sncrono - master:
1 = Activa recepo nica.
0 = Desactiva recepo nica. NOTA: Este bit apagado, aps uma recepo completa.
Modo Sncrono - slave:
Dontt care.

bit 4 CREN: Activa a recepo contnua.


Modo Assncrono:
1 = Activa recepo contnua.
0 = Desactiva recepo contnua.
Modo Sncrono:
1 = Activa recepo contnua, at bit CREN activo ser desactivado (CREN supra sucede SREN).
0 = Desactiva recepo contnua.

bit 3 ADDEN: Activa a deteco de endereo.


Modo Assncrono 9-bit (RX9 = 1):
1 = Activa deteco de endereo, activa interrupo e carga do buffer de recepo, quando
RSR<8> activo.
0 = Desactiva deteco de endereo, todos os bytes so recebidos, e o nono bit pode ser
usado como bit de paridade.

bit 2 FERR: Indicao de erro de frame (leitura apenas).


1 = Indicao de framing error.
NOTA:
Pode ser actualizado lendo o registo RCREG e efectuando a recepo do prximo byte vlido).
0 = No ocorreu framing error.

bit 1 OERR: Indicao de erro do bit overrun (leitura apenas).


1 = Ocorreu um erro de overrun (reposio a 0 por reposio a zero de CREN).
0 = No ocorreu erro de overrun.

bit 0 RX9D: Nono bit, na recepo de dados (usado para paridade).

132
www.mecatronicadegaragem.blogspot.com

TP8 - USART do PIC

4 Trabalho a realizar

1. Implementar um programa em assembly que permita a transmisso de 1 carcter, para o pro-


grama terminal do computador anfitrio (host computer terminal).

2. Implementar um programa em assembly que permita a recepo de 1 carcter, e posterior trans-


misso (atravs da rotina criada anteriormente) para o host computer terminal.

3. Implementar um programa em assembly que permita o envio de um array de caracteres, para o


host computer terminal. Inicialmente o programa deve enviar para o terminal a string "Digite ->
(p,i,e,x)?", e consoante o carcter seleccionado (premido), ser enviada para o terminal a string
correspondente:

(a) Quando recebido o carcter p enviada a mensagem "PIC - Ola, Mundo";


(b) Se recebido o carcter i ou e sero enviadas as strings respectivas s mensagens ora em
Ingls ora em Espanhol.
(c) Quando recebido o carcter x, ser enviada a mensagem "PIC - BYE BYE user". No
entanto se um outro carcter for recebido, dever ser enviada para o terminal a mensagem
seguinte "Caracter Invalido".

Figura 37: Ligao srie entre o PIC e o Computador

Elementos de Apoio

Manual terico da disciplina.


DataSheet PIC16F876(DS30292C) Microchip, captulo 10. - Addressable Universal syn-
chronous Asyncronous Receiver Transmiter (USART), pgina 95.
DataSheet PIC16F876(DS30292C) Microchip, captulo 13 - Instrution Set Summary, p-
gina 135.

133
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

5 Implementao em Assembly do PIC

5.1 Ponto 1
; Trabalho n 8p1
; Comunicao Srie (USART)
;
; Objectivos:
;
; - Compreenso dos passos de programao da USART, para recepo e transmisso
; - Elaborao de rotinas para transmisso e recepo de um caracter.
; - Elaborao de uma rotina para transmisso de um array de caracteres (string
;
;
;********************************************************************
; *
; Nome ficheiro: trab8.asm *
; Data: 1/Junho/2005 *
; Verso: 1.0 *
; *
; Autores: Jos Miguel Gaspar *
; Olmpia Rodrigues *
; Orientador: Prof. Jos Lus Azevedo *
; *
; Universidade de Aveiro *
; Seminrio EEI 2004/2005 *
; *
;********************************************************************
; *
; Ficheiro necessrio: P16F876.LKR *
; *
;********************************************************************
list p=16f876 ; list directive to define
radix decimal ; processor
#include "p16f876.inc" ; processor specific variable
; definitions
errorlevel -302 ; Turn off banking message
; known tested (good) code
;--------------------------------------------------------------------
; Constantes
;--------------------------------------------------------------------
RC0 EQU 0
RC1 EQU 1
RC2 EQU 2
RC3 EQU 3
RC4 EQU 4
RC5 EQU 5
RC6 EQU 6
RC7 EQU 7
RB0 EQU 0
RB1 EQU 1
RB2 EQU 2
RB3 EQU 3
RB4 EQU 4
RB5 EQU 5
RB6 EQU 6
RB7 EQU 7
RA0 EQU 0
RA1 EQU 1
RA2 EQU 2
RA3 EQU 3
RA4 EQU 4
RA5 EQU 5
;--------------------------------------------------------------------

134
www.mecatronicadegaragem.blogspot.com

TP8 - USART do PIC

; Variveis (REGISTOS DE USO GERAL)


;--------------------------------------------------------------------
variaveis UDATA 0x20
ptr_pos RES 1
ptr_count RES 1
retrive_char RES 1
;--------------------------------------------------------------------
; Macros to select the register Banks
;--------------------------------------------------------------------
Bank0 MACRO ; Macro to select data RAM Bank 0
bcf STATUS,RP0
bcf STATUS,RP1
ENDM
Bank1 MACRO ; Macro to select data RAM Bank 1
bsf STATUS,RP0
bcf STATUS,RP1
ENDM
Bank2 MACRO ; Macro to select data RAM Bank 2
bcf STATUS,RP0
bsf STATUS,RP1
ENDM
Bank3 MACRO ; Macro to select data RAM Bank 3
bsf STATUS,RP0
bsf STATUS,RP1
ENDM
;********************************************************************
ORG 0x00 ; Processor reset vector
clrf PCLATH ; Ensure page bits are cleared
goto main ; Go to beginning of program
;====================================================================
ORG 0x20
main ; Aqui comea o programa principal
call InitCfg ; rotina de configurao
while_1
movlw P ;
call tx_char ; envio do caracter "P"
movlw
call tx_char ; envio de 1 espao
goto while_1 ; loop infinito

;******************************************************************

;************************** ROTINAS *******************************


;******************************************************************
;******************************************************************
;===================================================================;
; InitCfg ;
; Configurao inicial dos registros associados ;
; ao programa principal, PORTOS I/O, USART ;
; ;
; ;
; Notas: ;
;===================================================================;
InitCfg
;----------------- Config USART ------------------------------------;
Bank1 ; memoria do programa em Bank1
movlw 10 ; 115.2 Kbaud @ 20MHz

135
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

movwf SPBRG
clrf TXSTA
bsf TXSTA,TXEN
bsf TXSTA,BRGH
Bank0 ; memoria do programa em Bank0
clrf RCSTA
bsf RCSTA,SPEN ; SPEN = 1
bsf RCSTA,CREN ; CREN = 1
;----------------- I/O Config --------------------------------------;
Bank1
bcf TRISC,RC6 ; RC6 = TX output
Bank0
clrf ptr_pos
clrf ptr_count
clrf retrive_char
return
;===================================================================;
; Transmit Char = tx_char ;
; Input: W(reg) - Character ASCII a transmitir ;
; Output: no devolve nada ;
; ;
; Resumo: ;
; A rotina tx_char, aguarda que a FLAG TXIF de PIR1 seja 1, ;
; sinalizando assim a autorizao de envio de um char atravs de ;
; TXREG. ;
; Prottipo em Linguagem C ;
; void tx_char(char c) ;
;===================================================================;
tx_char
btfss PIR1,TXIF ; while( TXIF == 0) {}
goto $-1 ;
movwf TXREG ;
return
END

136
www.mecatronicadegaragem.blogspot.com

TP8 - USART do PIC

5.2 Ponto 2
; Trabalho n 8 ; pergunta 2
; Comunicao Srie (USART)
;
; Objectivos:
;
; - Compreenso dos passos de programao da USART, para recepo e transmisso
; - Elaborao de rotinas para transmisso e recepo de um caracter.
; - Elaborao de uma rotina para transmisso de um array de caracteres (string
;
;
;********************************************************************
; *
; Nome ficheiro: trab8.asm *
; Data: 1/Junho/2005 *
; Verso: 1.0 *
; *
; Autores: Jos Miguel Gaspar *
; Olmpia Rodrigues *
; Orientador: Prof. Jos Lus Azevedo *
; *
; Universidade de Aveiro *
; Seminrio EEI 2004/2005 *
; *
;********************************************************************
; *
; Ficheiro necessrio: P16F876.LKR *
; *
;********************************************************************
list p=16f876 ; list directive to define
radix decimal ; processor
#include "p16f876.inc" ; processor specific variable
; definitions
errorlevel -302 ; Turn off banking message
; known tested (good) code
;--------------------------------------------------------------------
; Constantes
;--------------------------------------------------------------------
RC0 EQU 0
RC1 EQU 1
RC2 EQU 2
RC3 EQU 3
RC4 EQU 4
RC5 EQU 5
RC6 EQU 6
RC7 EQU 7
RB0 EQU 0
RB1 EQU 1
RB2 EQU 2
RB3 EQU 3
RB4 EQU 4
RB5 EQU 5
RB6 EQU 6
RB7 EQU 7
RA0 EQU 0
RA1 EQU 1
RA2 EQU 2
RA3 EQU 3
RA4 EQU 4
RA5 EQU 5
;--------------------------------------------------------------------
; Variveis (REGISTOS DE USO GERAL)
;--------------------------------------------------------------------
variaveis UDATA 0x20

137
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

ptr_pos RES 1
ptr_count RES 1
retrive_char RES 1
;--------------------------------------------------------------------
; Macros to select the register Banks
;--------------------------------------------------------------------
Bank0 MACRO ; Macro to select data RAM Bank 0
bcf STATUS,RP0
bcf STATUS,RP1
ENDM
Bank1 MACRO ; Macro to select data RAM Bank 1
bsf STATUS,RP0
bcf STATUS,RP1
ENDM
Bank2 MACRO ; Macro to select data RAM Bank 2
bcf STATUS,RP0
bsf STATUS,RP1
ENDM
Bank3 MACRO ; Macro to select data RAM Bank 3
bsf STATUS,RP0
bsf STATUS,RP1
ENDM
;********************************************************************
ORG 0x00 ; Processor reset vector
clrf PCLATH ; Ensure page bits are cleared
goto main ; Go to beginning of program
;====================================================================
ORG 0x20
main ; Aqui comea o programa principal
call InitCfg ; rotina de configurao
while_1
call rx_char ; recepo de 1 caracter
call tx_char ; envio do caracter recebido
movlw
call tx_char ; envio de 1 espao
goto while_1 ; loop infinito

;******************************************************************

;************************** ROTINAS *******************************


;******************************************************************
;******************************************************************
;===================================================================;
; InitCfg ;
; Configurao inicial dos registros associados ;
; ao programa principal, PORTOS I/O, USART ;
; ;
; ;
; Notas: ;
;===================================================================;
InitCfg
;----------------- Config USART ------------------------------------;
Bank1 ; memoria do programa em Bank1
movlw 10 ; 115.2 Kbaud @ 20MHz
movwf SPBRG
clrf TXSTA

138
www.mecatronicadegaragem.blogspot.com

TP8 - USART do PIC

bsf TXSTA,TXEN
bsf TXSTA,BRGH
Bank0 ; memoria do programa em Bank0
clrf RCSTA
bsf RCSTA,SPEN ; SPEN = 1
bsf RCSTA,CREN ; CREN = 1
;----------------- I/O Config --------------------------------------;
Bank1
bcf TRISC,RC6 ; RC6 = TX output
Bank0
clrf ptr_pos
clrf ptr_count
clrf retrive_char
return
;===================================================================;
; Transmit Char = tx_char ;
; Input: W(reg) - Character ASCII a transmitir ;
; Output: no devolve nada ;
; ;
; Resumo: ;
; A rotina tx_char, aguarda que a FLAG TXIF de PIR1 seja 1, ;
; sinalizando assim a autorizao de envio de um char atravs de ;
; TXREG. ;
; Prottipo em Linguagem C ;
; void tx_char(char c) ;
;===================================================================;
tx_char
btfss PIR1,TXIF ; while( TXIF == 0) {}
goto $-1 ;
movwf TXREG ;
return
;===================================================================;
; Receive Char = rx_char ;
; Input: no tm parmetro de entrada ;
; Output: W(reg) - Character ASCII recebido atravs da USART ;
; ;
; Resumo: ;
; A rotina rx_char, aguarda que a FLAG RCIF de PIR1 seja 1, ;
; sinalizando assim a chegada de um char ao registo RCREG. ;
; Prottipo em Linguagem C ;
; char rx_char(void) ;
;===================================================================;
rx_char
btfss PIR1,RCIF ; while( RCIF == 0) {}
goto $-1
movfw RCREG
return
END

139
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

5.3 Ponto 3
; Trabalho n 8 pergunta 3
; Comunicao Srie (USART)
;
; Objectivos:
;
; - Compreenso dos passos de programao da USART, para recepo e transmisso
; - Elaborao de rotinas para transmisso e recepo de um caracter.
; - Elaborao de uma rotina para transmisso de um array de caracteres (string
;
;
;********************************************************************
; *
; Nome ficheiro: trab8.asm *
; Data: 1/Junho/2005 *
; Verso: 1.0 *
; *
; Autores: Jos Miguel Gaspar *
; Olmpia Rodrigues *
; Orientador: Prof. Jos Lus Azevedo *
; *
; Universidade de Aveiro *
; Seminrio EEI 2004/2005 *
; *
;********************************************************************
; *
; Ficheiro necessrio: P16F876.LKR *
; *
;********************************************************************
list p=16f876 ; list directive to define
radix decimal ; processor
#include "p16f876.inc" ; processor specific variable
; definitions
errorlevel -302 ; Turn off banking message
; known tested (good) code
;--------------------------------------------------------------------
; Constantes
;--------------------------------------------------------------------
RC0 EQU 0
RC1 EQU 1
RC2 EQU 2
RC3 EQU 3
RC4 EQU 4
RC5 EQU 5
RC6 EQU 6
RC7 EQU 7
RB0 EQU 0
RB1 EQU 1
RB2 EQU 2
RB3 EQU 3
RB4 EQU 4
RB5 EQU 5
RB6 EQU 6
RB7 EQU 7
RA0 EQU 0
RA1 EQU 1
RA2 EQU 2
RA3 EQU 3
RA4 EQU 4
RA5 EQU 5
;--------------------------------------------------------------------
; Variveis (REGISTOS DE USO GERAL)
;--------------------------------------------------------------------
variaveis UDATA 0x20

140
www.mecatronicadegaragem.blogspot.com

TP8 - USART do PIC

ptr_pos RES 1
ptr_count RES 1
retrive_char RES 1
;--------------------------------------------------------------------
; Macros to select the register Banks
;--------------------------------------------------------------------
Bank0 MACRO ; Macro to select data RAM Bank 0
bcf STATUS,RP0
bcf STATUS,RP1
ENDM
Bank1 MACRO ; Macro to select data RAM Bank 1
bsf STATUS,RP0
bcf STATUS,RP1
ENDM
Bank2 MACRO ; Macro to select data RAM Bank 2
bcf STATUS,RP0
bsf STATUS,RP1
ENDM
Bank3 MACRO ; Macro to select data RAM Bank 3
bsf STATUS,RP0
bsf STATUS,RP1
ENDM
;********************************************************************
ORG 0x00 ; Processor reset vector
clrf PCLATH ; Ensure page bits are cleared
goto main ; Go to beginning of program
;====================================================================
ORG 0x20
stan_table ;table for standard code
addwf PCL,f
; "XXXXXXXXXXXXXXXXXXXX"
; ptr:
dt "Digite -> (p,i,e,x)?" ;0
dt "PIC - Ola, Mundo " ;20
dt "PIC - Hola, Mundo " ;40
dt "PIC - Hello, World " ;60
dt "Caracter Invalido " ;80
dt "PIC - BYE BYE user " ;100
main ; Aqui comea o programa principal
call InitCfg
movlw 0
movwf ptr_pos
call ptr_string
while_1
call rx_char
movwf retrive_char
sublw p
btfsc STATUS,Z
goto PORTUGUES
movfw retrive_char
sublw e
btfsc STATUS,Z
goto ESPANHOL
movfw retrive_char
sublw i
btfsc STATUS,Z
goto INGLES
movfw retrive_char
sublw x
btfsc STATUS,Z
goto EXIT

141
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

movlw 80
movwf ptr_pos
call ptr_string
goto while_1
PORTUGUES
movlw 20
movwf ptr_pos
call ptr_string
goto while_1
ESPANHOL
movlw 40
movwf ptr_pos
call ptr_string
goto while_1
INGLES
movlw 60
movwf ptr_pos
call ptr_string
goto while_1
EXIT
movlw 100
movwf ptr_pos
call ptr_string
goto SAIDA
;******************************************************************

;************************** ROTINAS *******************************


;******************************************************************
;******************************************************************
;===================================================================;
; InitCfg ;
; Configurao inicial dos registros associados ;
; ao programa principal, PORTOS I/O, USART ;
; ;
; ;
; Notas: ;
;===================================================================;
InitCfg
;----------------- Config USART ------------------------------------;
Bank1 ; memoria do programa em Bank1
movlw 10 ; 115.2 Kbaud @ 20MHz
movwf SPBRG
clrf TXSTA
bsf TXSTA,TXEN
bsf TXSTA,BRGH
Bank0 ; memoria do programa em Bank0
clrf RCSTA
bsf RCSTA,SPEN ; SPEN = 1
bsf RCSTA,CREN ; CREN = 1
;----------------- I/O Config --------------------------------------;
Bank1
bcf TRISC,RC6 ; RC6 = TX output
Bank0
clrf ptr_pos
clrf ptr_count
clrf retrive_char
return
;===================================================================;
; Transmit Char = tx_char ;
; Input: W(reg) - Character ASCII a transmitir ;
; Output: no devolve nada ;
; ;

142
www.mecatronicadegaragem.blogspot.com

TP8 - USART do PIC

; Resumo: ;
; A rotina tx_char, aguarda que a FLAG TXIF de PIR1 seja 1, ;
; sinalizando assim a autorizao de envio de um char atravs de ;
; TXREG. ;
; Prottipo em Linguagem C ;
; void tx_char(char c) ;
;===================================================================;
tx_char
btfss PIR1,TXIF ; while( TXIF == 0) {}
goto $-1 ;
movwf TXREG ;
return
;===================================================================;
; Receive Char = rx_char ;
; Input: no tm parmetro de entrada ;
; Output: W(reg) - Character ASCII recebido atravs da USART ;
; ;
; Resumo: ;
; A rotina rx_char, aguarda que a FLAG RCIF de PIR1 seja 1, ;
; sinalizando assim a chegada de um char ao registo RCREG. ;
; Prottipo em Linguagem C ;
; char rx_char(void) ;
;===================================================================;
rx_char
btfss PIR1,RCIF ; while( RCIF == 0) {}
goto $-1
movfw RCREG
return
;===================================================================;
; print_string - prt_string ;
; Input: prt_pos - localizao do caracter na tabela ;
; Output: no tm parametro de sada ;
; ;
; Resumo: ;
; Esta rotina imprime no ecra 20 caracteres, posicionadas na dt ;
; (tabela de dados) atravs do parametro prt_pos. ;
; ;
; Prottipo em Linguagem C ;
; void prt_string(unsigned char prt_pos) ;
;===================================================================;
ptr_string
movlw 20 ; print 20 character / line
movwf ptr_count
prt_next_char
movlw HIGH stan_table
movwf PCLATH
movf ptr_pos,w ; character table location
call stan_table ; retrieve 1 character
call tx_char ; send character to USART
incf ptr_pos,f ; get next character to send
decfsz ptr_count,f ; move pointer to next char
goto prt_next_char
movlw \r
call tx_char
movlw \n
call tx_char
return
SAIDA
END

143
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

NOTAS:

144
www.mecatronicadegaragem.blogspot.com

TP9 - Conversor A/D do PIC


Tema a desenvolver Durao
Converso Analgia -> Digital (ADC) 4 aulas

1 Resumo

Converso A/D de valores de tenso (analgicos) provenientes de diferentes dispositivos. Interface


atravs de sensor infravermelhos e potencimetro com visualizao de resultados em displays de 7
segmentos ou atravs do PC (terminal srie).

2 Objectivos

Introduo ao estudo do conversor A/D (ADC) do PIC.


Implementao de um voltmetro digital bsico.
Medio de distncias atravs de um sensor de infravermelhos.

3 Descrio

No processamento de sinais-analgicos h, muitas vezes, vantagem em os converter para sinais di-


gitais, de modo a que possam se processados por um microprocessador. Os elemento que efectua a
converso de um sinal analgico num digital (um valor numa determinada voltagem) designado por
"conversor analgico digital" ADC.
O PIC16F876 dispe de uma ADC de 10 bits, o que significa que o resultado pode ser represen-
tado com uma resoluo de 1/1024 gama mxima. possvel distinguir valores com cerca de 5mV de
resoluo aproximadamente (5/1024 = 0.004883), supondo que a gama mxima de valores a medir
de 5V, ou seja toda a gama entre 0V..5V.

3.1 Entrada Analgica

No PIC16F876, podemos seleccionar como entrada analgica, por programao 1 dos 5 canais dis-
ponveis (entradas RA0 - RA5, excepto RA4). O registo ADCON1 configura as linhas RA0 - RA5
(execpo RA4) do PIC como entradas analgicas/digitais ou referncia; a entrada seleccionada deve

145
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

ser programada como entrada afectando o bit correspondente no registo TRISA. Mais detalhes ver
configurao de um porto com entradas analgicas, pgina 16.
ligao da entrada analgica com o conversor A/D, d-se o nome de canal (channel), a seleco
do canal a ser activado feita pelo registo ADCON0 (bits CHS2-CHS0), ver pgina 149.

Figura 38: ADC, entradas analgicas

3.2 Resultado da converso A/D

O par de registos ADRESH e ADRESL de 8 bits cada, forma o local onde so colocados os 10 bits do
resultado da converso, estes registos formam assim em conjunto um registo de 16 bits.
A ADC, implementa duas formas no modo como formata o resultado de 10 bits nos registos
ADRESH e ADRESL, justificado este ora esquerda ou direita (restantes bits extra so carregados
a 0), ver figura 39. A seleco do formato feita pelo bit ADFM do registro ADCON1, os bits , .

Figura 39: Formato do resultado de 10 bits

146
www.mecatronicadegaragem.blogspot.com

TP9 - Conversor A/D do PIC

3.3 Mecanismo de aquisio da ADC

O condensador de amostragem (CHOLD) do mdulo conversor A/D, carregado pela tenso aplicada
entrada analgica. A tenso de CHOLD convertida para valores digitais atravs do conversor A/D.
Uma vez que o condensador no carrega instantaneamente, necessrio aguardar um certo tempo,
designado por tempo de HOLD, aps a seleco da entrada analgica pretendida nos bits CHS0-3 do
ADCON0 (ver pgina 149).
Uma vez que este tempo no implementado por hardware, da responsabilidade do programador
implementar no programa um tempo de espera de aproximadamente 20s, entre a seleco da entrada
analgica e o inicio da converso A/D. Durante este tempo, o CHOLD est desligado da entrada
analgica.
A converso A/D iniciada quando o bit GO do registo ADCON0 activado a 1. Quando a
converso acaba o bit GO reposto a 0 por hardware. Existem duas maneiras de detectar o fim de
converso da ADC, a primeira atravs de polling ao bit GO at este ser 0, a segunda mais elegante,
atravs de uma interrupo global. No caso de usar interrupes, o bit ADIE do registo PIE, assim
como o bit do GIE do registo INTCON, devem estar activos a 1. Quando o fim de converso for
detectado, o bit ADIF do registo PIR1 activo 1 e a interrupo global ocorre.
A figura 147 mostra o circuito no qual o condensador CHOLD carregado por VA.
CHOLD carregado quando o interruptor (SS) fechado. O dodo foi colocado por proteco no
sentido de evitar situaes de tenso superiores a VDD ou inferiores a VSS na entrada analgica.

Figura 40: Mecanismo de aquisio da ADC

Legenda:

CHOLD: Condensador de amostragem / reteno ( 120pF )


RSS: Resistncia de amostragem ( cerca de 7K-ohm a VDD=5V )
SS: Interruptor
RIC: Resistncia de ligao ( =<1K-ohm )

147
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

CPIN: Condensador de entrada ( 5pF )


ANx: Entrada Analgica
RS: Impedncia da entrada analgica ( =<10K-ohm )
VA: Fonte de tenso analgica

3.4 Etapas na programao da ADC (polling)

1. Configurao do conversor A/D ( Processo inicial)

Configurao das entradas analgicas / tenso de referncia / I/0 digital ADCON1/PCFG0-3.


Seleco do clock de converso da ADC, ADCON0/ADCS0-1
Ligar o conversor A/D, ADCON0/ADON

2. Configurao do canal de entrada

Seleco do canal de entrada, ADCON0/CHS0-2

3. Tempo guarda de carga do condensador CHOLD

Aguardar at o CHOLD esteja completamente carregado, aprox. 20s

4. Incio da converso

Activar o bit GO, ADCON0/GO = 1

5. Aguardar o fim de converso da ADC

Fazer polling ao bit GO at que este seja 0

6. Leitura do resultado da converso A/D

Ler o resultado no par de registos, ADRESH,ADRESL

7. Para a prxima converso, ir para item 1 ou 2 como desejado

148
www.mecatronicadegaragem.blogspot.com

TP9 - Conversor A/D do PIC

3.5 Registo ADCON0

bit 7-6 ADCS1,ADCS0: Bits de seleco do clock do conversor A/D.


00 = FOSC/2.
01 = FOSC/8.
10 = FOSC/32.
11 = FRC (clock derivado do oscilador interno da ADC).

bit 5-3 CH2: Bits de seleco do canal analgico .


000 = canal 0, (RA0/AN0).
001 = canal 1, (RA1/AN1).
010 = canal 2, (RA2/AN2).
011 = canal 3, (RA4/AN3).
100 = canal 4, (RA5/AN4).

bit 2 GO/DON E: Bit de estado da converso A/D.


1 = Converso A/D a decorrer ( activar a 1 inicia a converso A/D).
0 = converso A/D a parada ( este bit automaticamente reset pelo PIC quando a converso
A/D
completada).

bit 1 No Implementado: leitura a 0.

bit 0 ADON: Conversor A/D ligado.


1 = Conversor A/D ligado e em actividade.
0 = Conversor A/D desligado, no consome corrente.

149
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

3.6 Registo ADCON1

bit 7 ADFM: Seleco do formato da converso A/D.


0 = Justificado direita. 6 bits mais significativos do ADRESH colocados a 0.
1 = Justificado esquerda. 6 bits menos significativos do ADRESL colocados a 0.

bit 6 ADCS2: Bit de seleco do clock de converso.


ADCON1 ADCON0 Clock de converso
<ADCS2> <ADCS1:ADCS0>
0 00 Fosc/2
0 01 Fosc/8
0 10 Fosc/32
0 11 Frc (clock derivado do oscilador RC, interno da ADC)
1 00 Fosc/4
1 01 Fosc/16
1 10 Fosc/64
1 11 Frc (clock derivado do oscilador RC, interno da ADC)

bit 5-4 No Implementado: leitura a 0.

bit 3-0 PCFG3:PCFG0: Bits de controlo das entradas analgicas do PIC.


PCFG RA5 RA3 RA2 RA1 RA0
<3:0>
0000 A A A A A
0001 A Vref+ A A A
0010 D A A A A
0011 D Vref+ A A A
0100 D A D A A
0101 D Vref+ A A A
011x D D D D D
1000 A Vref+ Vref- A A
1001 A A A A A
1010 A Vref+ A A A
1011 A Vref+ Vref- A A
1100 D Vref+ Vref- A A
1101 D Vref+ Vref- A A
1110 D D D D A
1111 D Vref+ Vref- D A
A = entrada analgica, D = entrada ou sada, digital, Vref = tenso de referncia

150
www.mecatronicadegaragem.blogspot.com

TP9 - Conversor A/D do PIC

4 Trabalho a realizar

1. Construo de um voltmetro digital simples. Este voltmetro faz a leitura de uma tenso elc-
trica entre 0V e 5V apresentando o resultado da converso A/D, nos displays de 7 segmentos.
O valor convertido afixado com um casa decimal (0.0 a 5.0V).
De modo a implementar esta funcionalidade, deve-se programar a ADC com os seguintes pa-
rmetros: entrada analgica RA0, seleco do clock do conversor A/D = FOSC/32, resoluo
de 8 bits na sada. NOTA: Uma vez que a escala de valores retornados da ADC [0..255], deve
implementar uma mudana de escala para valores entre [0..50].
Implementao de uma rotina de hexadecimal + decimal, de modo a poder afixar nos displays
de 7 segmentos o valor convertido.

Figura 41: Diagrama do circuito do voltmetro digital, visualizao com displays 7 segmentos

2. Finda a parte 1 do trabalho prtico, o passo seguinte alterar o programa anterior, de modo a
que seja possvel o envio dos valores de tenso atravs da porta srie, para o PC.

Figura 42: Diagrama do circuito do voltmetro digital, visualizao terminal srie

151
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

3. Neste ponto do trabalho, pretende-se medir distncias com o auxlio a um sensor de infraver-
melhos, com visualizao da distncia nos displays de 7 segmentos. O sistema de medio deve
efectuar medies entre [10..40cm] com uma resoluo de 1 cm. Fora desta gama deve indicar,
atravs das mensagens, OFF e End que se encontra entre 0..10cm e entre 40.., respectiva-
mente.
Sugesto: Implementar uma rotina de clculo da distancia, tendo em conta os valores de cali-
brao do sensor fornecidos.
NOTA: Os valores de calibrao do sensor esto disponveis para consulta no site da disciplina.

152
www.mecatronicadegaragem.blogspot.com

TP9 - Conversor A/D do PIC

5 Implementao em Assembly do PIC

5.1 Ponto 1
; Trabalho n 9 PARTE_I
; Voltimetro digital
;
; Resumo:
; Voltimetro digital 0..5 Volts
; visualizao atravs dos displays de 7 segmentos
;
;********************************************************************
; *
; Nome ficheiro: trab9Volt.asm *
; Data: 1/Junho/2005 *
; Verso: 1.0 *
; *
; Autores: Jos Miguel Gaspar *
; Olmpia Rodrigues *
; Orientador: Prof. Jos Lus Azevedo *
; *
; Universidade de Aveiro *
; Seminrio EEI 2004/2005 *
; *
;********************************************************************
; *
; Ficheiro necessrio: P16F876.INC *
; *
;********************************************************************

list p=16f876 ; list directive to define


radix decimal ; processor
#include "p16f876.inc" ; processor specific variable
; definitions
errorlevel -302 ; Turn off banking message
; known tested (good) code
;--------------------------------------------------------------------
; Constantes
;--------------------------------------------------------------------
RC0 EQU 0
RC1 EQU 1
RC2 EQU 2
RC3 EQU 3
RC4 EQU 4
RC5 EQU 5
RC6 EQU 6
RC7 EQU 7
RB0 EQU 0
RB1 EQU 1
RB2 EQU 2
RB3 EQU 3
RB4 EQU 4
RB5 EQU 5
RB6 EQU 6
RB7 EQU 7
RA0 EQU 0
RA1 EQU 1
RA2 EQU 2
RA3 EQU 3
RA4 EQU 4
RA5 EQU 5
TMR0_HW_VAL1 EQU 255 ; 25us aproximadamente

153
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

TMR0_HW_VAL2 EQU 0 ; 6ms aproximadamente


ANALOG_CHANNEL EQU 0 ; Analog Channel 0(AN0)
N_SHIFTS EQU 5
;--------------------------------------------------------------------
;Displays de 7 segementos -|gfedcba-|
;--------------------------------------------------------------------
seg7_0 EQU b01111110 ; Valor 0
seg7_1 EQU b00001100 ; Valor 1
seg7_2 EQU b10110110 ; Valor 2
seg7_3 EQU b10011110 ; Valor 3
seg7_4 EQU b11001100 ; Valor 4
seg7_5 EQU b11011010 ; Valor 5
seg7_6 EQU b11111000 ; Valor 6
seg7_7 EQU b00001110 ; Valor 7
seg7_8 EQU b11111110 ; Valor 8
seg7_9 EQU b11001110 ; Valor 9
seg7_A EQU b11101110 ; Valor A
seg7_B EQU b11111000 ; Valor B
seg7_C EQU b01110010 ; Valor C
seg7_D EQU b10111100 ; Valor D
seg7_E EQU b11110010 ; Valor E
seg7_F EQU b11100010 ; Valor F
seg7_n EQU b10101000 ; Valor n
seg7_null EQU b00000000 ; Valor Null
;----------------------------------------------------------------------
; Variveis (REGISTOS DE USO GERAL)
;----------------------------------------------------------------------
variaveis UDATA 0x20
seg70 RES 1 ; Valor 0 endereo
seg71 RES 1 ; Valor 1 endereo
seg72 RES 1 ; Valor 2 endereo
seg73 RES 1 ; Valor 3 endereo
seg74 RES 1 ; Valor 4 endereo
seg75 RES 1 ; Valor 5 endereo
seg76 RES 1 ; Valor 6 endereo
seg77 RES 1 ; Valor 7 endereo
seg78 RES 1 ; Valor 8 endereo
seg79 RES 1 ; Valor 9 endereo
seg7A RES 1 ; Valor A endereo
seg7B RES 1 ; Valor B endereo
seg7C RES 1 ; Valor C endereo
seg7D RES 1 ; Valor D endereo
seg7E RES 1 ; Valor E endereo
seg7F RES 1 ; Valor F endereo
seg7n RES 1 ; Valor n endereo
seg7null RES 1 ; Valor null endereo
;--------------------------------------------------------------------
aux RES 1
valor_tensao RES 1
dig_high RES 1
dig_low RES 1
divdo RES 1
disp_7seg RES 1
bcd_in RES 1
i RES 1
j RES 1
value_xg_high RES 1
value_xg_low RES 1
value_low RES 1
value_high RES 1
buffer_32 RES 32
;--------------------------------------------------------------------
; Macros to select the register Banks
;--------------------------------------------------------------------

154
www.mecatronicadegaragem.blogspot.com

TP9 - Conversor A/D do PIC

Bank0 MACRO ; Macro to select data RAM Bank 0


bcf STATUS,RP0
bcf STATUS,RP1
ENDM
Bank1 MACRO ; Macro to select data RAM Bank 1
bsf STATUS,RP0
bcf STATUS,RP1
ENDM
Bank2 MACRO ; Macro to select data RAM Bank 2
bcf STATUS,RP0
bsf STATUS,RP1
ENDM
Bank3 MACRO ; Macro to select data RAM Bank 3
bsf STATUS,RP0
bsf STATUS,RP1
ENDM
;********************************************************************
ORG 0x00 ; Processor reset vector
clrf PCLATH ; Ensure page bits are cleared
goto main ; Go to beginning of program
;====================================================================
ORG 0x20
main ;Aqui comea o programa principal
call InitCfg
while_1
movlw buffer_32 ; inicialize pointer
call write_buff_32; void write_buffer(char* buff)
movlw buffer_32 ; char media_32(char* buff)
call media_32 ;
call xg_scale ;
call h2d ;
movwf valor_tensao ;
btfss INTCON,T0IF ; while(TOIF == 0) {}
goto $-1 ;
bcf INTCON,T0IF ; T0IF = 0;
movlw TMR0_HW_VAL2 ;
movwf TMR0 ; Set Hardware timer0 Value
if_main btfsc disp_7seg,0 ; if(disp_7seg == 0)
goto else_main ; {
movfw valor_tensao ; w = valor_tensao
andlw 0x0F ; w = w & 0x0F
goto display_main ;
else_main ; } else
swapf valor_tensao,w
andlw 0x0F ;
btfsc STATUS,Z ;
goto $+3 ; if (STATUS,Z==1)
display_main call display ; display(bcd_in,disp_7seg);
incf disp_7seg,w ;
andlw 0x01 ;
movwf disp_7seg ; disp_7seg = (++disp_7seg) & 0x01;
goto while_1 ;
;******************************************************************

;************************** ROTINAS *******************************


;******************************************************************
;******************************************************************
;===================================================================;
; InitCfg ;

155
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

; Configurao inicial dos registros associados ;


; ao programa principal, PORTOS I/O, Timer0, ADC. ;
; ;
; ;
; Notas: ;
;===================================================================;
InitCfg
;--------------- Analog 2 Digital - Config -------------------------;
Bank1 ; DATA memory (RAM) Bank1
clrf ADCON1
bsf ADCON1,PCFG3 ; PCFG3 = 1
bsf ADCON1,PCFG2 ; PCFG2 = 1
bsf ADCON1,PCFG1 ; PCFG1 = 1
bcf ADCON1,PCFG0 ; PCFG0 = 0
; RA0 = input analgico
Bank0 ; DATA memory (RAM) Bank0
clrf ADCON0
bsf ADCON0,ADCS1 ;
bcf ADCON0,ADCS0 ; FOSC / 32
bsf ADCON0,ADON ; ADC ON
;---------------- I/O - Config -------------------------------------;
Bank1 ; memoria do programa em Bank1
movlw b11110001 ; RA[3:1] outputs
movwf TRISA ; RA[7:4 & 1] inputs
movlw b00000001 ; RB[7:1] outputs
movwf TRISB ; RB[1] input
;----------------- TRM0 - Config ------------------------------------;
clrf OPTION_REG ; clear OPTION_REG
bsf OPTION_REG,INTEDG ; INTEDG = 1
bsf OPTION_REG,PS2 ;
bsf OPTION_REG,PS1 ; TMR0 Rate
bcf OPTION_REG,PS0 ; 1:128
Bank0 ; DATA memory (RAM) Bank0
movlw TMR0_HW_VAL1 ; Set Hardware timer0 Value
movwf TMR0 ; Set TMR0
;----------------- OTHER - Config ----------------------------------;
clrf PORTA ;
clrf PORTB ;
clrf disp_7seg ; clear registers
;-------------------------------------------------------------------;
; Inicializao dos registros associados aos displays 7seg ;
;-------------------------------------------------------------------;
movlw seg7_0 ; Set 7segment valor 0
movwf seg70 ; Save valor 0
movlw seg7_1 ; Set 7segment valor 1
movwf seg71 ; Save valor 1
movlw seg7_2 ; Set 7segment valor 2
movwf seg72 ; Save valor 2
movlw seg7_3 ; Set 7segment valor 3
movwf seg73 ; Save valor 3
movlw seg7_4 ; Set 7segment valor 4
movwf seg74 ; Save valor 4
movlw seg7_5 ; Set 7segment valor 5
movwf seg75 ; Save valor 5
movlw seg7_6 ; Set 7segment valor 6
movwf seg76 ; Save valor 6
movlw seg7_7 ; Set 7segment valor 7
movwf seg77 ; Save valor 7
movlw seg7_8 ; Set 7segment valor 8
movwf seg78 ; Save valor 8
movlw seg7_9 ; Set 7segment valor 9
movwf seg79 ; Save valor 9

156
www.mecatronicadegaragem.blogspot.com

TP9 - Conversor A/D do PIC

movlw seg7_A ; Set 7segment valor A


movwf seg7A ; Save valor A
movlw seg7_B ; Set 7segment valor B
movwf seg7B ; Save valor B
movlw seg7_C ; Set 7segment valor C
movwf seg7C ; Save valor C
movlw seg7_D ; Set 7segment valor D
movwf seg7D ; Save valor D
movlw seg7_E ; Set 7segment valor E
movwf seg7E ; Save valor E
movlw seg7_F ; Set 7segment valor F
movwf seg7F ; Save valor F
movlw seg7_n ; Set 7segment pattern N
movwf seg7n ; Save pattern N
movlw seg7_null ; Set 7segment pattern NULL
movwf seg7null ; Save pattern N
return
;===================================================================;
; Input: W(reg) - ponteito para o endereo de buffer_32 ;
; Output: - no tm parametro de sada ;
; Resumo: ;
; Recolhe 32 valores da ADC[0..255], escrevendo os mesmos em 32 ;
; posies consecutivas de memria RAM ;
; ;
; Prottipo em Linguagem C ;
; void write_buff_32(char* buffer_32) ;
;===================================================================;
write_buff_32
movwf FSR ; initialize pointer
write_again movlw ANALOG_CHANNEL ; w(reg) = analog_channel
call analog2digital ; analog2digital(char W(reg))
movwf INDF ; write INDF register
incf FSR,f ; inc pointer
btfss FSR,5 ; all done?
goto write_again ; no write again
; yes return
return
;===================================================================;
; Input: W(reg) - Canal de entrada AN<X> em que X[0:7] ;
; Output: W(reg) - valor de sada convertido pela ADC ;
; (formato digital) escala (0..255) em que 0 = gnd ;
; e 255 = VREF+ = 5V ;
; Resumo: ;
; Devolve em W(reg) valor digital convertido pela ADC. ;
; ;
; Prottipo em Linguagem C ;
; char analog2digital(unsigned char canal_ADC) ;
;===================================================================;
analog2digital
andlw 0x07 ;
movwf aux ; aux = 0x07 & w
bcf STATUS,C ;
rlf aux,f ;
rlf aux,f ;
rlf aux,f ;
movlw 0xC7 ;
andwf ADCON0,w ;
iorwf aux,w ;
movwf ADCON0 ;
btfss INTCON,T0IF ; while(TOIF == 0) {}
goto $-1 ;
bcf INTCON,T0IF ; T0IF = 0;
movlw TMR0_HW_VAL1 ; Set Hardware timer0 Value
movwf TMR0 ; Set TMR0
bsf ADCON0,GO ; incio da converso

157
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

btfsc ADCON0,GO ;
goto $-1 ;
movfw ADRESH ;
;
return ;
;===================================================================;
; Input: W(reg) - ponteiro para o buffer ;
; Output: W(reg) - mdia aritmtica das 32 amostras ;
; ;
; Resumo: ;
; Soma os 32 resultados de converso da ADC, presentes no buffer de ;
; de 32 posies, devolvendo a sua mdia aritmtica. ;
; ;
; Prottipo em Linguagem C ;
; char media_32(char* buffer_32) ;
;===================================================================;
media_32 clrf value_low ; initialize register
clrf value_high ; initialize register
movwf FSR ; initialize pointer
read_again movfw INDF ; read INDF register to W(reg)
call soma ; soma(char W(reg))
incf FSR,f ; inc pointer
btfss FSR,5 ; all done?
goto read_again ; no read again
; yes continue
movlw N_SHIFTS ;
movwf aux ;
divide_again bcf STATUS,C ; next - > Carry = flag = 0
rrf value_high,f ; msb_value_high = 0
rrf value_low,f ;
decfsz aux,f ; all done?
goto divide_again ; no divide again
movfw value_low ; yes return (value_low in W)
return
;===================================================================;
; Input: W(reg) - valor de 8 bits a somar com os 8 bits menos ;
; significativos de value low ;
; Output: no tm parmetro de sada ;
; Resumo: ;
; Soma o valor actual com o anterior se existir CARRY, incrementa ;
; o valor de value_high de uma unidade. ;
; ;
; Prottipo em Linguagem C ;
; void soma(unsigned char val_buffer_32) ;
;===================================================================;
soma
addwf value_low,f ; value_low + W(reg)
btfsc STATUS,C ; exist CARRY?
incf value_high,f ; yes, inc value_high
return ; no, return
;===================================================================;
; Input: W(reg) - valor hex na escala de (0..255) ;
; Output: W(reg) - valor hex na escala de (0..50) ;
; Resumo: ;
; Mudana de escala [0..255] -> [0..50] ;
; ;
; Prottipo em Linguagem C ;
; char xg_scale(unsigned char val) ;
;===================================================================;
xg_scale
movwf value_xg_low ;
movlw 0x32 ;
movwf i ; i = 0x32
movfw value_xg_low ;
clrf value_xg_high ;

158
www.mecatronicadegaragem.blogspot.com

TP9 - Conversor A/D do PIC

add_again addwf value_xg_low,w ; w = w + value_xg_low


btfsc STATUS,C ; exist CARRY?
incf value_xg_high,f; yes, inc value_xg_high
decfsz i,f ; no, decrement i
goto add_again ; if ( i != 0 )
movfw value_xg_high ; if ( i == 0 )
return ;
;===================================================================;
; Input: W(reg) - valor de 8 bits em hexadecimal 0x?? ;
; Output: W(reg) - valor de 8 bits equivalente em decimal ;
; Resumo: ;
; ;
; Equivalente em Linguagem C ;
; char h2d (char value_low) ;
; { ;
; return((value_low/10 << 4) + (value_low % 10); ;
; } ;
;===================================================================;
h2d movwf divdo ; temp = w = value_low ;
clrf j ; j = 0;
movlw 10 ; while( divdo >= 10)
next_sub subwf divdo,f ; se o subtraendo >= ao subtractor => CY
; se o subtraendo < ao subtractor => CY
btfss STATUS,C ; divdo -=divdo;
goto fwd ; }
incf j,f ;
goto next_sub ;
fwd
addwf divdo,f ;
swapf j,w
addwf divdo,w ; w = temp + count w => valor
; decimal correspondente a
return ; value_low(hex)
;===================================================================;
; Input: W(reg) - valor BCD de entrada ;
; Input: DISP_7SEG - seleo do display a ser refrescado ;
; Output: no tm parmetro de sada ;
; ;
; Resumo: Subroutina de Controlo dos displays ;
; Prottipo em Linguagem C ;
; void display(unsigned char bcd_in, unsigned char disp_7seg) ;
;===================================================================;
display
movwf bcd_in ;
movf PORTA,w ; w = PORTA
andlw 0xF1 ;
movwf aux ; aux = w & 0xf1
disp_0 movfw disp_7seg ; switch(disp_7seg)
sublw 0x00 ;
btfss STATUS,Z ;
goto disp_1 ;
movfw aux ; case_0
iorlw 0x08 ; w = aux | 0x08
goto break ; break
disp_1 movfw disp_7seg ; switch(dis_7seg)
sublw 0x01 ;
btfss STATUS,Z ;
goto disp_2 ;
movfw aux ; case_1
iorlw 0x04 ; w = aux | 0x04
goto break ; break
disp_2 movfw aux ; case_2
iorlw 0x02 ; w = aux | 0x02

159
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

break movwf PORTA ; escrita na porta


call bcd_7seg ; bcd_7seg(bcd_in);
return
;===================================================================;
; Input: bcd_in - valor BCD de entrada ;
; Output: no tm parmetro de sada ;
; ;
; Resumo: Subroutina => BCD to 7segment display, envia o valor ;
; passado em bcd_in para a PORTB ;
;===================================================================;
bcd_7seg
movlw seg70 ; Incio da tabela de valores
addwf bcd_in,w ; & do val a mostrar da tabela
movwf FSR ; Set do endereo da tabela
movf INDF,w ; leitura do valor de 7seg
movwf PORTB ; envio do valor para o PORTB
return
END ; directive end of program

160
www.mecatronicadegaragem.blogspot.com

TP9 - Conversor A/D do PIC

5.2 Ponto 2
; Trabalho n 9 PARTE_II
; Voltimetro digital
;
; Resumo:
; Voltimetro digital 0..5 Volts
; visualizao atravs da USART do PIC
;
;********************************************************************
; *
; Nome ficheiro: trab9VoltUart.asm *
; Data: 1/Junho/2005 *
; Verso: 1.0 *
; *
; Autores: Jos Miguel Gaspar *
; Olmpia Rodrigues *
; Orientador: Prof. Jos Lus Azevedo *
; *
; Universidade de Aveiro *
; Seminrio EEI 2004/2005 *
; *
;********************************************************************
; *
; Ficheiro necessrio: P16F876.INC *
; *
;********************************************************************

list p=16f876 ; list directive to define


radix decimal ; processor
#include "p16f876.inc" ; processor specific variable
; definitions
errorlevel -302 ; Turn off banking message
; known tested (good) code
;--------------------------------------------------------------------
; Constantes
;--------------------------------------------------------------------
RC0 EQU 0
RC1 EQU 1
RC2 EQU 2
RC3 EQU 3
RC4 EQU 4
RC5 EQU 5
RC6 EQU 6
RC7 EQU 7
RB0 EQU 0
RB1 EQU 1
RB2 EQU 2
RB3 EQU 3
RB4 EQU 4
RB5 EQU 5
RB6 EQU 6
RB7 EQU 7
RA0 EQU 0
RA1 EQU 1
RA2 EQU 2
RA3 EQU 3
RA4 EQU 4
RA5 EQU 5
TMR0_HW_VAL1 EQU 255 ; 25us aproximadamente
ANALOG_CHANNEL EQU 0 ; Analog Channel 0(AN0)
N_SHIFTS EQU 5 ;

161
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

;----------------------------------------------------------------------
; Variveis (REGISTOS DE USO GERAL)
;----------------------------------------------------------------------
variaveis UDATA 0x20
aux RES 1
valor_tensao RES 1
dig_high RES 1
dig_low RES 1
divdo RES 1
i RES 1
j RES 1
value_xg_high RES 1
value_xg_low RES 1
value_low RES 1
value_high RES 1
prt_count RES 1
prt_pos RES 1
buffer_32 RES 32
;--------------------------------------------------------------------
; Macros to select the register Banks
;--------------------------------------------------------------------
Bank0 MACRO ; Macro to select data RAM Bank 0
bcf STATUS,RP0
bcf STATUS,RP1
ENDM
Bank1 MACRO ; Macro to select data RAM Bank 1
bsf STATUS,RP0
bcf STATUS,RP1
ENDM
Bank2 MACRO ; Macro to select data RAM Bank 2
bcf STATUS,RP0
bsf STATUS,RP1
ENDM
Bank3 MACRO ; Macro to select data RAM Bank 3
bsf STATUS,RP0
bsf STATUS,RP1
ENDM
;********************************************************************
ORG 0x0000 ; Processor reset vector
clrf PCLATH ; Ensure page bits are cleared
goto main ; Go to beginning of program
;====================================================================
ORG 0x0005
data_table ;table for strings
addwf PCL,f
; "XXXXXXXXXXXXXXXXXXXX"
; ptr_string:
dt "Valor U digite v ";posio - 0
dt " - Volts ";posio - 20
; "XXXXXXXXXXXXXXXXXXXX"
main ;Aqui comea o programa principal
call InitCfg
movlw 0 ; posio 0 da dt
call prt_string
while_1
movlw buffer_32 ; inicialize pointer
call write_buff_32; void write_buffer(char* buff)
movlw buffer_32 ; char media_32(char* buff)

162
www.mecatronicadegaragem.blogspot.com

TP9 - Conversor A/D do PIC

call media_32 ;
call xg_scale ;
call itoa ;
call rx_char ;
sublw v ;
btfss STATUS,Z ;
goto $-3 ;
movfw dig_high ; unidades de tenso
call tx_char ;
movlw . ; .
call tx_char ;
movfw dig_low ; decimas de tensao
call tx_char ;
movlw 20 ; posio 20 da dt
call prt_string
goto while_1
;********************************************************************

;************************** ROTINAS *********************************


;********************************************************************
;********************************************************************
;===================================================================;
; InitCfg ;
; Configurao inicial dos registros associados ;
; ao programa principal, PORTS I/O, Timer0, ADC, USART ;
; ;
; Retorna em Bank0 ;
; ;
;===================================================================;
InitCfg
;----------------- Config USART ------------------------------------;
Bank1 ; DATA memory (RAM) Bank1
movlw 10 ; 115.2 Kbaud @ 20MHz
movwf SPBRG
clrf TXSTA
bsf TXSTA,TXEN
bsf TXSTA,BRGH
Bank0 ; DATA memory (RAM) Bank0
clrf RCSTA
bsf RCSTA,SPEN ; SPEN = 1
bsf RCSTA,CREN ; CREN = 1
;--------------- Analog 2 Digital - Config -------------------------;
Bank1 ; DATA memory (RAM) Bank1
clrf ADCON1
bsf ADCON1,PCFG3 ; PCFG3 = 1
bsf ADCON1,PCFG2 ; PCFG2 = 1
bsf ADCON1,PCFG1 ; PCFG1 = 1
bcf ADCON1,PCFG0 ; PCFG0 = 0
; RA0 = input analgico
Bank0 ; DATA memory (RAM) Bank0
clrf ADCON0
bsf ADCON0,ADCS1 ;
bcf ADCON0,ADCS0 ; FOSC / 32
bsf ADCON0,ADON ; ADC ON
;---------------- I/O - Config -------------------------------------;
Bank1 ; memoria do programa em Bank1
movlw b00000001 ; RA[7:1] outputs

163
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

movwf TRISA ; RA[0] input


;----------------- TRM0 - Config ------------------------------------;
clrf OPTION_REG ; clear OPTION_REG
bsf OPTION_REG,INTEDG ; INTEDG = 1
bsf OPTION_REG,PS2 ;
bsf OPTION_REG,PS1 ; TMR0 Rate
bcf OPTION_REG,PS0 ; 1:128
Bank0 ; DATA memory (RAM) Bank0
movlw TMR0_HW_VAL1 ; Set Hardware timer0 Value
movwf TMR0 ; Set TMR0
return
;===================================================================;
; Transmit Char = tx_char ;
; Input: W(reg) - Character ASCII a transmitir ;
; Output: no devolve nada ;
; ;
; Resumo: ;
; A rotina tx_char, aguarda que a FLAG TXIF de PIR1 seja 1, ;
; sinalizando assim a autorizao de envio de um char atravs de ;
; TXREG. ;
; Prottipo em Linguagem C ;
; void tx_char(char c) ;
;===================================================================;
tx_char
btfss PIR1,TXIF ; while( TXIF == 0) {}
goto $-1 ;
movwf TXREG ;
return
;===================================================================;
; Receive Char = rx_char ;
; Input: no tm parmetro de entrada ;
; Output: W(reg) - Character ASCII recebido atravs da USART ;
; ;
; Resumo: ;
; A rotina rx_char, aguarda que a FLAG RCIF de PIR1 seja 1, ;
; sinalizando assim a chegada de um char ao registo RCREG. ;
; Prottipo em Linguagem C ;
; char rx_char(void) ;
;===================================================================;
rx_char
btfss PIR1,RCIF ; while( RCIF == 0) {}
goto $-1
movfw RCREG
return
;===================================================================;
; print_string - prt_string ;
; Input: prt_pos - localizao do caracter na tabela ;
; Output: no tm parametro de sada ;
; ;
; Resumo: ;
; Esta rotina imprime no ecra 20 caracteres, posicionadas na dt ;
; (tabela de dados) atravs do parametro prt_pos. ;
; ;
; Prottipo em Linguagem C ;
; void prt_string(unsigned char prt_pos) ;
;===================================================================;
prt_string
movwf prt_pos
movlw 20 ; print 20 character / line
movwf prt_count
prt_next_char
movlw HIGH data_table; initialize PCLATH reg

164
www.mecatronicadegaragem.blogspot.com

TP9 - Conversor A/D do PIC

movwf PCLATH ; before using addwf PCL,f


; when returning from routine
movfw prt_pos ; character table location
call data_table ; retrieve 1 character
call tx_char ; send character to USART
incf prt_pos,f ; get next character to send
decfsz prt_count,f ; move pointer to next char
goto prt_next_char
movlw \r
call tx_char
movlw \n
call tx_char
return
;===================================================================;
; Input: W(reg) - ponteito para o endereo de buffer_32 ;
; Output: - no tm parametro de sada ;
; Resumo: ;
; Recolhe 32 valores da ADC[0..255], escrevendo os mesmos em 32 ;
; posies consecutivas de memria RAM ;
; ;
; Prottipo em Linguagem C ;
; void write_buff_32(char* buffer_32) ;
;===================================================================;
write_buff_32
movwf FSR ; initialize pointer
write_again movlw ANALOG_CHANNEL ; w(reg) = analog_channel
call analog2digital ; analog2digital(char W(reg))
movwf INDF ; write INDF register
incf FSR,f ; inc pointer
btfss FSR,5 ; all done?
goto write_again ; no write again
; yes return
return
;===================================================================;
; Input: W(reg) - Canal de entrada AN<X> em que X[0:7] ;
; Output: W(reg) - valor de sada convertido pela ADC ;
; (formato digital) escala (0..255) em que 0 = gnd ;
; e 255 = VREF+ = 5V ;
; Resumo: ;
; Devolve em W(reg) valor digital convertido pela ADC. ;
; ;
; Prottipo em Linguagem C ;
; char analog2digital(unsigned char canal_ADC) ;
;===================================================================;
analog2digital
andlw 0x07 ;
movwf aux ; aux = 0x07 & w
bcf STATUS,C ;
rlf aux,f ;
rlf aux,f ;
rlf aux,f ;
movlw 0xC7 ;
andwf ADCON0,w ;
iorwf aux,w ;
movwf ADCON0 ;
btfss INTCON,T0IF ; while(TOIF == 0) {}
goto $-1 ;
bcf INTCON,T0IF ; T0IF = 0;
movlw TMR0_HW_VAL1 ; Set Hardware timer0 Value
movwf TMR0 ; Set TMR0
bsf ADCON0,GO ; incio da converso
btfsc ADCON0,GO ;
goto $-1 ;
movfw ADRESH ;

165
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

;
return ;
;===================================================================;
; Input: W(reg) - ponteiro para o buffer ;
; Output: W(reg) - mdia aritmtica das 32 amostras ;
; ;
; Resumo: ;
; Soma os 32 resultados de converso da ADC, presentes no buffer de ;
; de 32 posies, devolvendo a sua mdia aritmtica. ;
; ;
; Prottipo em Linguagem C ;
; char media_32(char* buffer_32) ;
;===================================================================;
media_32 clrf value_low ; initialize register
clrf value_high ; initialize register
movwf FSR ; initialize pointer
read_again movfw INDF ; read INDF register to W(reg)
call soma ; soma(char W(reg))
incf FSR,f ; inc pointer
btfss FSR,5 ; all done?
goto read_again ; no read again
; yes continue
movlw N_SHIFTS ;
movwf aux ;
divide_again bcf STATUS,C ; next - > Carry = flag = 0
rrf value_high,f ; msb_value_high = 0
rrf value_low,f ;
decfsz aux,f ; all done?
goto divide_again ; no divide again
movfw value_low ; yes return (value_low in W)
return
;===================================================================;
; Input: W(reg) - valor de 8 bits a somar com os 8 bits menos ;
; significativos de value low ;
; Output: no tm parmetro de sada ;
; Resumo: ;
; Soma o valor actual com o anterior se existir CARRY, incrementa ;
; o valor de value_high de uma unidade. ;
; ;
; Prottipo em Linguagem C ;
; void soma(unsigned char val_buffer_32) ;
;===================================================================;
soma
addwf value_low,f ; value_low + W(reg)
btfsc STATUS,C ; exist CARRY?
incf value_high,f ; yes, inc value_high
return ; no, return
;===================================================================;
; Input: W(reg) - valor hex na escala de (0..255) ;
; Output: W(reg) - valor hex na escala de (0..50) ;
; Resumo: ;
; Mudana de escala [0..255] -> [0..50] ;
; ;
; Prottipo em Linguagem C ;
; char xg_scale(unsigned char val) ;
;===================================================================;
xg_scale
movwf value_xg_low ;
movlw 0x32 ;
movwf i ; i = 0x32
movfw value_xg_low ;
clrf value_xg_high ;
add_again addwf value_xg_low,w ; w = w + value_xg_low
btfsc STATUS,C ; exist CARRY?
incf value_xg_high,f; yes, inc value_xg_high

166
www.mecatronicadegaragem.blogspot.com

TP9 - Conversor A/D do PIC

decfsz i,f ; no, decrement i


goto add_again ; if ( i != 0 )
movfw value_xg_high ; if ( i == 0 )
return ;
;===================================================================;
; Input: W(reg) - valor de 8 bits em hexadecimal 0x?? ;
; Output: W(reg) - valor de 8 bits equivalente em decimal ;
; Resumo: ;
; ;
; Equivalente em Linguagem C ;
; char h2d (char value_low) ;
; { ;
; return((value_low/10 << 4) + (value_low % 10); ;
; } ;
;===================================================================;
h2d movwf divdo ; temp = w = value_low ;
clrf j ; j = 0;
movlw 10 ; while( divdo >= 10)
next_sub subwf divdo,f ; se o subtraendo >= ao subtractor => CY
; se o subtraendo < ao subtractor => CY
btfss STATUS,C ; divdo -=divdo;
goto fwd ; }
incf j,f ;
goto next_sub ;
fwd
addwf divdo,f ;
swapf j,w
addwf divdo,w ; w = temp + count w => valor
; decimal correspondente a
return ; value_low(hex)
;===================================================================;
; Input: w = valor de entrada em decimal a converter ASCII ;
; Output: dig_high = unidades ;
; dig_low = decimas ;
; Resumo: ;
; Devolve o valor ascii das unidades e das decimas ;
; do valor em tenso ;
; Prottipo em Linguagem C ;
; char* itoa( char val) ;
;===================================================================;
itoa
call h2d ;
movwf dig_low ; digito = w = val;
movwf dig_high ;
movlw 0x0f ;
andwf dig_low,f ;
movlw 0 ;
addwf dig_low,f ; dig_low +=0;
swapf dig_high,f ;
movlw 0x0f ;
andwf dig_high,f ;
movlw 0 ;
addwf dig_high,f ;
return ;
END ; directive end of program

167
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

5.3 Ponto 3
; Trabalho n 9 PARTE III
; Medio de distancias com sensor IV - SHARP
;
; Resumo:
; Medio de distncias com sensor valores entre [10...40] cm
;
;********************************************************************
; *
; Nome ficheiro: trab9.asm *
; Data: 1/Junho/2005 *
; Verso: 1.0 *
; *
; Autores: Jos Miguel Gaspar *
; Olmpia Rodrigues *
; Orientador: Prof. Jos Lus Azevedo *
; *
; Universidade de Aveiro *
; Seminrio EEI 2004/2005 *
; *
;********************************************************************
; *
; Ficheiro necessrio: P16F876.INC *
; *
;********************************************************************
list p=16f876 ; list directive to define
radix decimal ; processor
#include "p16f876.inc" ; processor specific variable
; definitions
errorlevel -302 ; Turn off banking message
; known tested (good) code
;--------------------------------------------------------------------
; Constantes
;--------------------------------------------------------------------
RA0 EQU 0
RA1 EQU 1
RA2 EQU 2
RA3 EQU 3
RA4 EQU 4
RA5 EQU 5
RB0 EQU 0
RB1 EQU 1
RB2 EQU 2
RB3 EQU 3
RB4 EQU 4
RB5 EQU 5
RB6 EQU 6
RB7 EQU 7
RC0 EQU 0
RC1 EQU 1
RC2 EQU 2
RC3 EQU 3
RC4 EQU 4
RC5 EQU 5
RC6 EQU 6
RC7 EQU 7
ANALOG_CHANNEL EQU 0 ; Analog Channel 0(AN0)
TMR0_HW_VAL1 EQU 255 ; 25us aproximadamente
TMR0_HW_VAL2 EQU 0 ; 6ms aproximadamen
N_SHIFTS EQU 5
;--------------------------------------------------------------------

168
www.mecatronicadegaragem.blogspot.com

TP9 - Conversor A/D do PIC

;Displays de 7 segementos -|gfedcba-|


;--------------------------------------------------------------------
seg7_0 EQU b01111110 ; Valor 0
seg7_1 EQU b00001100 ; Valor 1
seg7_2 EQU b10110110 ; Valor 2
seg7_3 EQU b10011110 ; Valor 3
seg7_4 EQU b11001100 ; Valor 4
seg7_5 EQU b11011010 ; Valor 5
seg7_6 EQU b11111000 ; Valor 6
seg7_7 EQU b00001110 ; Valor 7
seg7_8 EQU b11111110 ; Valor 8
seg7_9 EQU b11001110 ; Valor 9
seg7_A EQU b11101110 ; Valor A
seg7_B EQU b11111000 ; Valor B
seg7_C EQU b01110010 ; Valor C
seg7_D EQU b10111100 ; Valor D
seg7_E EQU b11110010 ; Valor E
seg7_F EQU b11100010 ; Valor F
seg7_n EQU b10101000 ; Valor n
seg7_null EQU b00000000 ; Valor Null
;----------------------------------------------------------------------
; Variveis (REGISTOS DE USO GERAL)
;----------------------------------------------------------------------
variaveis UDATA 0x20
seg70 RES 1 ; Valor 0 endereo
seg71 RES 1 ; Valor 1 endereo
seg72 RES 1 ; Valor 2 endereo
seg73 RES 1 ; Valor 3 endereo
seg74 RES 1 ; Valor 4 endereo
seg75 RES 1 ; Valor 5 endereo
seg76 RES 1 ; Valor 6 endereo
seg77 RES 1 ; Valor 7 endereo
seg78 RES 1 ; Valor 8 endereo
seg79 RES 1 ; Valor 9 endereo
seg7A RES 1 ; Valor A endereo
seg7B RES 1 ; Valor B endereo
seg7C RES 1 ; Valor C endereo
seg7D RES 1 ; Valor D endereo
seg7E RES 1 ; Valor E endereo
seg7F RES 1 ; Valor F endereo
seg7n RES 1 ; Valor n endereo
seg7null RES 1 ; Valor null endereo
aux RES 1
dig_high RES 1
dig_low RES 1
divdo RES 1
disp_7seg RES 1
bcd_in RES 1
i RES 1
j RES 1
value_low RES 1
value_high RES 1
val_adc RES 1
value_dist_hex RES 1
value_decimal RES 1
buffer_32 RES 32
;--------------------------------------------------------------------
; Macros to select the register Banks
;--------------------------------------------------------------------
Bank0 MACRO ; Macro to select data RAM Bank 0
bcf STATUS,RP0
bcf STATUS,RP1
ENDM
Bank1 MACRO ; Macro to select data RAM Bank 1
bsf STATUS,RP0

169
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

bcf STATUS,RP1
ENDM
Bank2 MACRO ; Macro to select data RAM Bank 2
bcf STATUS,RP0
bsf STATUS,RP1
ENDM
Bank3 MACRO ; Macro to select data RAM Bank 3
bsf STATUS,RP0
bsf STATUS,RP1
ENDM
;********************************************************************
ORG 0x0000 ; Processor reset vector
clrf PCLATH ; Ensure page bits are cleared
goto main ; Go to beginning of program
;--------------------------------------------------------------------
; Rotina Main
;--------------------------------------------------------------------
ORG 0x0005
adc_table ;table for adc values default val
addwf PCL,f
dt 126,116,108,100,94,88,83,79,75,71,67,63,61,58,56,54,51,5
main ;Aqui comea o programa principal
call InitCfg
while_1
movlw buffer_32 ; inicialize pointer
call write_buff_32; void write_buffer(char* buff)
movlw buffer_32 ; char media_32(char* buff)
call media_32 ;
call calc_dist ; char calc_dist(char val_adc)
movwf value_dist_hex
sublw 0x00
btfsc STATUS,Z
goto OFF_SCALE
movfw value_dist_hex
sublw 0x32
btfsc STATUS,Z
goto END_SCALE
movfw value_dist_hex
call h2d
movwf value_decimal
andlw 0x0f ; bcd_in = unidades de cm
call prt_disp7seg
swapf value_decimal,w
andlw 0x0f ; bcd_in = dezenas de cm
call prt_disp7seg
movlw 0x11 ; bcd_in = null
call prt_disp7seg
goto while_1
END_SCALE
movlw 0x0d
call prt_disp7seg
movlw 0x10
call prt_disp7seg
movlw 0x0E
call prt_disp7seg
goto while_1
OFF_SCALE

170
www.mecatronicadegaragem.blogspot.com

TP9 - Conversor A/D do PIC

movlw 0x0f
call prt_disp7seg
movlw 0x0f
call prt_disp7seg
movlw 0x00
call prt_disp7seg
goto while_1
;*******************************************************************

;************************** ROTINAS ********************************


;*******************************************************************
;*******************************************************************
;===================================================================;
; InitCfg ;
; Configurao inicial dos registros associados ;
; ao programa principal, PORTOS I/O, Timer0, ADC, ;
; ;
; ;
; Notas: ;
;===================================================================;
InitCfg
;--------------- Analog 2 Digital - Config -------------------------;
Bank1 ; DATA memory (RAM) Bank1
movlw b00001110 ; RA0 = input analgico
movwf ADCON1
Bank0 ; DATA memory (RAM) Bank0
movlw b10000001 ; FOSC / 32
movwf ADCON0
;---------------- I/O - Config -------------------------------------;
Bank1 ; DATA memory (RAM) Bank1
movlw b11110001 ; RA[3:1] outputs
movwf TRISA ; RA[7:4 & 0] inputs
movlw b00000001 ; RB[7:1] outputs
movwf TRISB ; RB[0] input
;----------------- TRM0 - Config ------------------------------------;
clrf OPTION_REG ; clear OPTION_REG
bsf OPTION_REG,INTEDG ; INTEDG = 1
bsf OPTION_REG,PS2 ;
bsf OPTION_REG,PS1 ; TMR0 Rate
bsf OPTION_REG,PS0 ; 1:256
Bank0 ; DATA memory (RAM) Bank0
movlw TMR0_HW_VAL1 ; Set Hardware timer0 Value
movwf TMR0 ; Set TMR0
;----------------- OTHER - Config ----------------------------------;
clrf PORTA ;
clrf PORTB ;
clrf disp_7seg ; clear registers
;-------------------------------------------------------------------;
; Inicializao dos registros associados aos displays 7seg ;
;-------------------------------------------------------------------;
movlw seg7_0 ; Set 7segment valor 0
movwf seg70 ; Save valor 0
movlw seg7_1 ; Set 7segment valor 1
movwf seg71 ; Save valor 1
movlw seg7_2 ; Set 7segment valor 2
movwf seg72 ; Save valor 2
movlw seg7_3 ; Set 7segment valor 3
movwf seg73 ; Save valor 3
movlw seg7_4 ; Set 7segment valor 4
movwf seg74 ; Save valor 4

171
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

movlw seg7_5 ; Set 7segment valor 5


movwf seg75 ; Save valor 5
movlw seg7_6 ; Set 7segment valor 6
movwf seg76 ; Save valor 6
movlw seg7_7 ; Set 7segment valor 7
movwf seg77 ; Save valor 7
movlw seg7_8 ; Set 7segment valor 8
movwf seg78 ; Save valor 8
movlw seg7_9 ; Set 7segment valor 9
movwf seg79 ; Save valor 9
movlw seg7_A ; Set 7segment valor A
movwf seg7A ; Save valor A
movlw seg7_B ; Set 7segment valor B
movwf seg7B ; Save valor B
movlw seg7_C ; Set 7segment valor C
movwf seg7C ; Save valor C
movlw seg7_D ; Set 7segment valor D
movwf seg7D ; Save valor D
movlw seg7_E ; Set 7segment valor E
movwf seg7E ; Save valor E
movlw seg7_F ; Set 7segment valor F
movwf seg7F ; Save valor F
movlw seg7_n ; Set 7segment pattern N
movwf seg7n ; Save pattern N
movlw seg7_null ; Set 7segment pattern NULL
movwf seg7null ; Save pattern N
return
;===================================================================;
; Input: W(reg) - ponteito para o endereo de buffer_32 ;
; Output: - no tm parametro de sada ;
; Resumo: ;
; Recolhe 32 valores da ADC[0..255], escrevendo os mesmos em 32 ;
; posies consecutivas de memria RAM ;
; ;
; Prottipo em Linguagem C ;
; void write_buff_32(char* buffer_32) ;
;===================================================================;
write_buff_32
movwf FSR ; initialize pointer
write_again movlw ANALOG_CHANNEL ; w(reg) = analog_channel
call analog2digital ; analog2digital(char W(reg))
movwf INDF ; write INDF register
incf FSR,f ; inc pointer
btfss FSR,5 ; all done?
goto write_again ; no write again
; yes return
return
;===================================================================;
; Input: W(reg) - Canal de entrada AN<X> em que X[0:7] ;
; Output: W(reg) - valor de sada convertido pela ADC ;
; (formato digital) escala (0..255) em que 0 = gnd ;
; e 255 = VREF+ = 5V ;
; Resumo: ;
; Devolve em W(reg) valor digital convertido pela ADC. ;
; ;
; Prottipo em Linguagem C ;
; char analog2digital(unsigned char canal_ADC) ;
;===================================================================;
analog2digital
andlw 0x07 ;
movwf aux ; aux = 0x07 & w
bcf STATUS,C ;
rlf aux,f ;
rlf aux,f ;
rlf aux,f ;
movlw 0xC7 ;
andwf ADCON0,w ;

172
www.mecatronicadegaragem.blogspot.com

TP9 - Conversor A/D do PIC

iorwf aux,w ;
movwf ADCON0 ;
btfss INTCON,T0IF ; while(TOIF == 0) {}
goto $-1 ;
bcf INTCON,T0IF ; T0IF = 0;
movlw TMR0_HW_VAL1 ; Set Hardware timer0 Value
movwf TMR0 ; Set TMR0
bsf ADCON0,GO ; incio da converso
btfsc ADCON0,GO ;
goto $-1 ;
movfw ADRESH ;
;
return ;
;===================================================================;
; Input: W(reg) - ponteiro para o buffer ;
; Output: W(reg) - mdia aritmtica das 32 amostras ;
; ;
; Resumo: ;
; Soma os 32 resultados de converso da ADC, presentes no buffer de ;
; de 32 posies, devolvendo a sua mdia aritmtica. ;
; ;
; Prottipo em Linguagem C ;
; char media_32(char* buffer_32) ;
;===================================================================;
media_32 clrf value_low ; initialize register
clrf value_high ; initialize register
movwf FSR ; initialize pointer
read_again movfw INDF ; read INDF register to W(reg)
call soma ; soma(char W(reg))
incf FSR,f ; inc pointer
btfss FSR,5 ; all done?
goto read_again ; no read again
; yes continue
movlw N_SHIFTS ;
movwf aux ;
divide_again bcf STATUS,C ; next - > Carry = flag = 0
rrf value_high,f ; msb_value_high = 0
rrf value_low,f ;
decfsz aux,f ; all done?
goto divide_again ; no divide again
movfw value_low ; yes return (value_low in W)
return
;===================================================================;
; Input: W(reg) - valor de 8 bits a somar com os 8 bits menos ;
; significativos de value low ;
; Output: no tm parmetro de sada ;
; Resumo: ;
; Soma o valor actual com o anterior se existir CARRY, incrementa ;
; o valor de value_high de uma unidade. ;
; ;
; Prottipo em Linguagem C ;
; void soma(unsigned char val_buffer_32) ;
;===================================================================;
soma
addwf value_low,f ; value_low + W(reg)
btfsc STATUS,C ; exist CARRY?
incf value_high,f ; yes, inc value_high
return ; no, return
;===================================================================;
; Input: W(reg) - valor de 8 bits em hexadecimal 0x?? ;
; Output: W(reg) - valor de 8 bits equivalente em decimal ;
; Resumo: ;

173
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

; ;
; Equivalente em Linguagem C ;
; char h2d (char value_low) ;
; { ;
; return((value_low/10 << 4) + (value_low % 10); ;
; } ;
;===================================================================;
h2d movwf divdo ; temp = w = value_low ;
clrf j ; j = 0;
movlw 10 ; while( divdo >= 10)
next_sub subwf divdo,f ; se o subtraendo >= ao subtractor => CY
; se o subtraendo < ao subtractor => CY
btfss STATUS,C ; divdo -=divdo;
goto fwd ; }
incf j,f ;
goto next_sub ;
fwd
addwf divdo,f ;
swapf j,w
addwf divdo,w
; w = temp + count w => valor
; decimal correspondente a
return ; value_low(hex)
;===================================================================;
; Input: W(reg) - Valor da ADC - 0..255 em Hexadecimal ;
; Output: W(reg) - VALOR DECIMAL convertido para cm ;
; ;
; ;
; Resumo: ;
; ;
; ;
;===================================================================;
; unsigned char calc_dist(unsigned char val_adc) ;
;{ ;
; if (val_adc > adc_table[0]) ;
; return(0); // Obst. muito perto ;
; ;
; if (val_adc =< adc[31]) ;
; return(0xff); // Obst. muito longe ;
; ;
; for(val_adc <= adc_table[i] && val_adc > adc_table[i+1]){ ;
; return (i+10); ;
; } ;
;} ;
;-------------------------------------------------------------------;
calc_dist
movwf val_adc ; val_adc = w;
movlw 127 ;
andwf val_adc,f ; 0 =< val_adc =< 127
movlw HIGH adc_table
movwf PCLATH
movlw 0 ; adc_table[0]
call adc_table ; retrieve, w = adc_table[0]
subwf val_adc,w ; val_adc - adc_table[0];
btfsc STATUS,C ; if (val_adc > adc_table[0])
goto ret_0x00 ; return (0x00);
movlw HIGH adc_table ;
movwf PCLATH ;
movlw 31 ; adc_table[31]
call adc_table ; retrieve adc_table[31]
subwf val_adc,w ;
btfss STATUS,C ; if (val_adc =< adc_table[31])
goto ret_0xff ; return (0xff)
clrf i ; i = 0;
next_value movlw HIGH adc_table
movwf PCLATH ;
movfw i ;
call adc_table ;
subwf val_adc,w ; if(val_adc =< adc_table[i])
btfss STATUS,C ;

174
www.mecatronicadegaragem.blogspot.com

TP9 - Conversor A/D do PIC

goto if_false ;
movlw HIGH adc_table ;
movwf PCLATH ;
incf i,w ;
call adc_table ;
subwf val_adc,w ; if (val_adc > adc_table[i+1])
btfss STATUS,C ;
goto if_false ;
goto ret_dist ; return (i+10);
if_false incf i,f ;
goto next_value ;
ret_0x00 movlw 0x00
return
ret_0xff movlw 0x32
return
ret_dist movlw 10
addwf i,w
return
;===================================================================;
; Input: W(reg) - valor BCD de entrada ;
; Input: DISP_7SEG - seleo do display a ser refrescado ;
; Output: no tm parmetro de sada ;
; ;
; Resumo: Subroutina de Controlo dos displays ;
; Prottipo em Linguagem C ;
; void display(unsigned char bcd_in, unsigned char disp_7seg) ;
;===================================================================;
display
movwf bcd_in ;
movf PORTA,w ; w = PORTA
andlw 0xF1 ;
movwf aux ; aux = w & 0xf1
disp_0 movfw disp_7seg ; switch(disp_7seg)
sublw 0x00 ;
btfss STATUS,Z ;
goto disp_1 ;
movfw aux ; case_0
iorlw 0x08 ; w = aux | 0x08
goto break ; break
disp_1 movfw disp_7seg ; switch(dis_7seg)
sublw 0x01 ;
btfss STATUS,Z ;
goto disp_2 ;
movfw aux ; case_1
iorlw 0x04 ; w = aux | 0x04
goto break ; break
disp_2 movfw aux ; case_2
iorlw 0x02 ; w = aux | 0x02
break movwf PORTA ; escrita na porta
call bcd_7seg ; bcd_7seg(bcd_in);
return
;===================================================================;
; Input: bcd_in - valor BCD de entrada ;
; Output: no tm parmetro de sada ;
; ;
; Resumo: Subroutina => BCD to 7segment display, envia o valor ;
; passado em bcd_in para a PORTB ;
;===================================================================;
bcd_7seg
movlw seg70 ; Incio da tabela de valores

175
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

addwf bcd_in,w ; & do val a mostrar da tabela


movwf FSR ; Set do endereo da tabela
movf INDF,w ; leitura do valor de 7seg
movwf PORTB ; envio do valor para o PORTB
return
;===================================================================;
; Input: W(reg) = BCD_IN - valor BCD de entrada ;
; Output: ;
; ;
; Resumo: ;
;===================================================================;
prt_disp7seg
call display ; display(bcd_in,disp_7seg);
btfss INTCON,T0IF ; while(TOIF == 0) {}
goto $-1 ;
bcf INTCON,T0IF ; T0IF = 0;
movlw TMR0_HW_VAL2 ; Set Hardware timer0 Value
movwf TMR0 ; Set TMR0
btfss disp_7seg,1 ; if(disp_7seg == 2)
goto $+3
clrf disp_7seg ; disp_7seg = 0;
return
incf disp_7seg,f ; else disp_7seg ++;
return
END ; directive end of program

176
www.mecatronicadegaragem.blogspot.com

Apendix A

Figura 43: Mapa de memria RAM, registos do PIC e registos de uso geral

177
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

178
www.mecatronicadegaragem.blogspot.com

Apendix B

; Ttulo :
; MPLAB IDE programa de demonstrao
;
; Resumo:
; Led pisca-pisca (DUTTY CYCLE varivel)
;
; ___________
; | |
; | PIC16F876 |
; | |
; | | /-----\ RES
; | |->-- RB0 ------| LED |------\/\/\/---- 0V
; | | \-----/
; |___________|
;
; figura 1. esquema de ligao PIC.
;
; ON (T1)| OFF (T2) | ON (T1)
; _______ _______
; | | | |
; led _______| |_____________| |__________________
;
;
; figura 2. diagrama temporal da sada.
;
;********************************************************************
; *
; Nome ficheiro: exemplo.asm *
; ltima alterao: 24/Junho/2005 *
; *
; Autor: Prof. Jos Lus Azevedo *
; *
; Modificado por: Jos Miguel Oliveira Gaspar *
; Olmpia Rodrigues *
; *
; Universidade de Aveiro *
; Seminrio EEI 2004/2005 *
; *
;********************************************************************
; *

179
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

; Ficheiro necessrio: 16f876.lkr *


; *
;********************************************************************

list p=16f876 ; - directiva list, define


; o processor a usar
radix decimal ; - directiva radix especifica
; definio das variveis
#include "p16f876.inc" ; - directiva include inclui
; ficheiro adicional

errorlevel -302 ; Turn off banking message


; known tested (good) code
;--------------------------------------------------------------------
; Constantes
;--------------------------------------------------------------------
RA0 EQU 0
RA1 EQU 1
RA2 EQU 2
RA3 EQU 3
RA4 EQU 4
RA5 EQU 5
RB0 EQU 0
RB1 EQU 1
RB2 EQU 2
RB3 EQU 3
RB4 EQU 4
RB5 EQU 5
RB6 EQU 6
RB7 EQU 7
RC0 EQU 0
RC1 EQU 1
RC2 EQU 2
RC3 EQU 3
RC4 EQU 4
RC5 EQU 5
RC6 EQU 6
RC7 EQU 7
T1 EQU 50 ; Gama [1..255] = [10ms..2,5s]
T2 EQU 100 ;
;----------------------------------------------------------------------
; Variveis (REGISTOS DE USO GERAL) Bank0
;----------------------------------------------------------------------
group1 iDATA ; dados inicializados
delay_mult RES 1 ; Variaveis de controlo
delay_k50 RES 1 ; dos loops da rotina Delay
delay_k200 RES 1 ;

;--------------------------------------------------------------------

180
www.mecatronicadegaragem.blogspot.com

Apendix B

; Macros to select the register Banks


;--------------------------------------------------------------------
Bank0 MACRO ; Macro to select data RAM Bank 0
bcf STATUS,RP0
bcf STATUS,RP1
ENDM

Bank1 MACRO ; Macro to select data RAM Bank 1


bsf STATUS,RP0
bcf STATUS,RP1
ENDM

Bank2 MACRO ; Macro to select data RAM Bank 2


bcf STATUS,RP0
bsf STATUS,RP1
ENDM

Bank3 MACRO ; Macro to select data RAM Bank 3


bsf STATUS,RP0
bsf STATUS,RP1
ENDM

;********************************************************************
Reset_vector ORG 0x0000 ; - directiva "ORG" origem do
; programa "ORG 0x0000" vector
; de reset
clrf PCLATH ; - instruo "clrf PCLATH" apaga
; todos os bits do registo garante
; que a memria do programa
; iniciada na pgina 0
goto main ; - instruo "goto main" salta para
; o endereo de memria do programa
; principal
;--------------------------------------------------------------------
; Rotina Main
;--------------------------------------------------------------------
ORG 0x0005 ; Program Memory PAGE 0
main ; Programa principal.
Bank1 ; DATA memory (RAM) Bank1
movlw b11111110 ; RB[0] output
movwf TRISB ; RB[7:1] inputs
;
Bank0 ; DATA memory (RAM) Bank0
clrf PORTB ; Inicializao PORTB.
loop ; while(1) {
bsf PORTB,RB0 ; Set (ON) LED in RB0 ON

movlw T1 ; W(reg) = 50
call Delay ; delay( 0,5 seg )

181
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

bcf PORTB,RB0 ; Set (OFF) LED in RB0


movlw T2 ; W(reg) = 100
call Delay ; delay( 1 seg )
goto loop ; }

;********************************************************************

;************************** ROTINAS *********************************


;********************************************************************
;********************************************************************
;===================================================================;
; Delay ;
; Pode gerar delays entre 10 mS e 2,5 S ;
; O valor de entrada e passado em W (1..255) ;
; Retorna em Bank0 ;
; ;
; Notas: o loop base e de 1 uS (T=200 nS <=> 4*1/20MHz) ;
; ;
;===================================================================;
Delay
movwf delay_mult ; Carrega o valor multiplo
Del_m10 movlw 50 ; de 10 mS
movwf delay_k50 ; 50 => 10 mS
Del_50 movlw 200 ; 200 => 200 uS
movwf delay_k200 ; Carrega o valor
Del_200 nop ; correspondente a 200 uS
nop
decfsz delay_k200,f ; Decrementa "delay_k200".
; O resultado colocadao em
; "delay_k200"
goto Del_200 ; while( delay_k200 > 0 )
decfsz delay_k50,f ;
goto Del_50 ; while( delay_k50 > 0 )
decfsz delay_mult,f ; Decrementa "delay_mult".
; O resultado colocadao
; em "delay_mult"
goto Del_m10 ; while( delay_mult > 0 )

return ;

;********************************************************************

END ; directive end of program

182
www.mecatronicadegaragem.blogspot.com

Apendix B

; Trabalho n 1
; Implementao de um led pisca-pisca, em RB1
; com boto on/off por INTERRUPO
;
; Objectivos:
; Introduo s Interrupes EXEMPLO
;
; Observaes:
;
;********************************************************************
; *
; Nome ficheiro: trab1Int.asm *
; Data: 1/Junho/2005 *
; Verso: 1.0 *
; *
; Autores: Jos Miguel Gaspar *
; Olmpia Rodrigues *
; Orientador: Prof. Jos Lus Azevedo *
; *
; Universidade de Aveiro *
; Seminrio EEI 2004/2005 *
; *
;********************************************************************
; *
; Ficheiro necessrio: P16F876.LKR *
; *
;********************************************************************

list p=16f876 ; list directive to define


radix decimal ; processor

#include "p16f876.inc" ; processor specific variable


; definitions
errorlevel -302 ; Turn off banking message
; known tested (good) code

;------------------------------------------------------------------------------
; Constantes
;------------------------------------------------------------------------------

RA0 EQU 0
RA1 EQU 1
RA2 EQU 2
RA3 EQU 3
RA4 EQU 4
RA5 EQU 5

RB0 EQU 0
RB1 EQU 1

183
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

RB2 EQU 2
RB3 EQU 3
RB4 EQU 4
RB5 EQU 5
RB6 EQU 6
RB7 EQU 7

RC0 EQU 0
RC1 EQU 1
RC2 EQU 2
RC3 EQU 3
RC4 EQU 4
RC5 EQU 5
RC6 EQU 6
RC7 EQU 7

;----------------------------------------------------------------------
; Variveis (REGISTOS DE USO GERAL)
;----------------------------------------------------------------------
variaveis UDATA 0x20
delay_mult RES 1 ; Variaveis de controlo dos loops
delay_k50 RES 1 ; da rotina Delay
delay_k200 RES 1 ;

start_stop RES 1

w_save RES 1 ; SAVE W


status_save RES 1 ; SAVE STATUS REG
pclath_save RES 1 ; SAVE PCLATH REG

;--------------------------------------------------------------------
; Macros to select the register Banks
;--------------------------------------------------------------------

Bank0 MACRO ; Macro to select data RAM Bank 0


bcf STATUS,RP0
bcf STATUS,RP1
ENDM

Bank1 MACRO ; Macro to select data RAM Bank 1


bsf STATUS,RP0
bcf STATUS,RP1
ENDM

Bank2 MACRO ; Macro to select data RAM Bank 2


bcf STATUS,RP0
bsf STATUS,RP1
ENDM

184
www.mecatronicadegaragem.blogspot.com

Apendix B

Bank3 MACRO ; Macro to select data RAM Bank 3


bsf STATUS,RP0
bsf STATUS,RP1
ENDM

;********************************************************************

ORG 0x0000 ; Processor reset vector


clrf PCLATH ; Ensure page bits are cleared
goto main ; Go to beginning of program
ORG 0x0004 ; Processor Interrupt Vector
goto interrupt_start; Go to interrupt service
; rotine
;--------------------------------------------------------------------
; Rotina Main
;--------------------------------------------------------------------
ORG 0x0005
main ;Aqui comea o programa principal
call InitCfg
while_1 ; while(1) {
btfsc start_stop,0 ; while (start_stop == 1) {}
goto $-1 ;

bsf PORTB,RB1 ; Set RB1 ON


movlw 25 ;
call Delay ; delay( 0,25 seg )

bcf PORTB,RB1 ; Set RB1 OFF


movlw 25 ;
call Delay ; delay( 0,25 seg )

goto while_1 ; }

;********************************************************************

;************************** ROTINAS *********************************


;********************************************************************
;********************************************************************
;===================================================================;
; InitCfg ;
; Configurao inicial dos registros associados ;
; ao programa principal, PORTOS I/O, Timer0, INTERRUPTS. ;
; ;
; Retorna em Bank0 ;
; ;
; Notas: ;
;===================================================================;
InitCfg

185
www.mecatronicadegaragem.blogspot.com

Guia prtico sobre microcontroladores PIC

;----------------- I/O - InitCfg -----------------------------------;


Bank1 ; DATA memory (RAM) Bank1
movlw 0x01 ; RB[1] output
movwf TRISB ; RB[7:2 & 0] inputs

;----------------- Interrupts enable bits --------------------------;


Bank0 ; DATA memory (RAM) Bank0
bsf INTCON,GIE ; Global Int. Enable bit
bsf INTCON,INTE ; External Int. enable bit

;-------------------------------------------------------------------;
clrf PORTB ; Inicializao PORTB.
clrf start_stop ;

return

;===================================================================;
; Delay ;
; Pode gerar delays entre 10 mS e 2,5 S ;
; O valor de entrada e passado em W (1..255) ;
; ;
; Notas: o loop base e de 1 uS (T=200 nS <=> 4*1/20MHz) ;
; ;
;===================================================================;
Delay
movwf delay_mult ; Carrega o valor multiplo
Del_m10 movlw 50 ; de 10 mS
movwf delay_k50 ; 50 => 10 mS
Del_50 movlw 200 ; 200 => 200 uS
movwf delay_k200 ; Carrega o valor
Del_200 nop ; correspondente a 200 uS
nop
decfsz delay_k200,f ; Decrementa "delay_k200".
; O resultado colocadao em
; "delay_k200"
goto Del_200 ; while( delay_k200 > 0 )
decfsz delay_k50,f ;
goto Del_50 ; while( delay_k50 > 0 )
decfsz delay_mult,f ; Decrementa "delay_mult".
; O resultado colocadao
; em "delay_mult"
goto Del_m10 ; while( delay_mult > 0 )

return

;********************************************************************

;************************** ISR *************************************

186
www.mecatronicadegaragem.blogspot.com

Apendix B

;********************************************************************
;********************************************************************
interrupt_start
movwf w_save ; salvaguarda do W reg.
swapf STATUS,W ;
clrf STATUS ; DATA memory (RAM) Bank0
movwf status_save ; salvaguarda do STATUS reg.
movf PCLATH,W ;
movwf pclath_save ; salvaguarda do PCLATH reg.
clrf PCLATH ; pgina 0, de memria de
; programa
bcf INTCON,INTF ; reset, do bit INTF
incf start_stop,w ;
andlw 0x01 ;
movwf start_stop ; toggle do start_stop (0/1)
;
interrupt_end movf pclath_save,w; restauro do PCLATH reg.
movwf PCLATH ;
swapf status_save,w; restauro da DATA memory (RAM)
; Bank? inicial
movwf STATUS ;
swapf w_save,f ; restauro do W reg.
swapf w_save,w ;

retfie

END

187

Вам также может понравиться