Microcontroladores pic ling c unicamp

48
Microcontroladores PIC Linguagem C Linguagem C Prof. Francisco Fambrini Unicamp – Limeira - 2015

Transcript of Microcontroladores pic ling c unicamp

Page 1: Microcontroladores pic ling c unicamp

Microcontroladores PIC

Linguagem CLinguagem C

Prof. Francisco Fambrini

Unicamp – Limeira - 2015

Page 2: Microcontroladores pic ling c unicamp

Livro recomendado para esta Aula

Page 3: Microcontroladores pic ling c unicamp

Disposição dos pinos PIC16F877

Page 4: Microcontroladores pic ling c unicamp

Estrutura básica interna de um micocontrolador

Page 5: Microcontroladores pic ling c unicamp

Estrutura de um programa em C

Page 6: Microcontroladores pic ling c unicamp
Page 7: Microcontroladores pic ling c unicamp

Resumo sobre declaração de variáveis e

operadores

Page 8: Microcontroladores pic ling c unicamp

Algumas configurações de fuse bits

Page 9: Microcontroladores pic ling c unicamp

Tipos de Variáveis em C

Page 10: Microcontroladores pic ling c unicamp

Modificadores signed e unsigned

Page 11: Microcontroladores pic ling c unicamp

Variáveis Globais

Page 12: Microcontroladores pic ling c unicamp

Exercícios de fixação

Page 13: Microcontroladores pic ling c unicamp

Operadores em C

Page 14: Microcontroladores pic ling c unicamp

Operadores relacionais em C

Page 15: Microcontroladores pic ling c unicamp

Operadores Lógicos

Page 16: Microcontroladores pic ling c unicamp

Operadores de atribuição

Page 17: Microcontroladores pic ling c unicamp

Operadores bit a bit

Page 18: Microcontroladores pic ling c unicamp

Adicionando botões na entrada do

microcontrolador

Page 19: Microcontroladores pic ling c unicamp

Lendo um botão em C

Page 20: Microcontroladores pic ling c unicamp

Nosso primeiro programa em C

// BOTAO E PISCA-LED

#include <16f877.h>

#use delay (clock=4000000)

#fuses XT, NOWDT,PUT,NOBROWNOUT,NOLVP, NOPROTECT

main( ){

While(TRUE){

IF (! INPUT (PIN_B0 )) { OUTPUT_LOW(PIN_B7);

DELAY_MS(300);

OUTPUT_LOW(PIN_B7);

DELAY_MS(300);

}

ELSE { OUTPUT_LOW(PIN_B7); }

}

}

Page 21: Microcontroladores pic ling c unicamp

Problema

Fazer o Projeto, para o controle da Bomba d’água B1, sendo que o nível

sempre estará entre S1 e S2 (sensores da bóia).

Quando o nível atinge o sensor S1 o seu contato fecha ligando a bomba dágua

para encher o tanque;Quando o nível atinge S2 a bomba deve ser

desligada para evitar que a água transborde.

Page 22: Microcontroladores pic ling c unicamp

Esquema do hardware proposto

Page 23: Microcontroladores pic ling c unicamp

Questões

Page 24: Microcontroladores pic ling c unicamp
Page 25: Microcontroladores pic ling c unicamp

Exemplo 2

• Dado o circuito do slide anterior, proponha para este

hardware um sequencial em firmware, capaz de

acender os leds um de cada vez, sendo que apenas

um led fica aceso a cada vez.

Page 26: Microcontroladores pic ling c unicamp

Quando o sensor S5 detecta a presença de uma pessoa a porta abrirá

rapidamente até que o sensor S3 seja atingido, onde a velocidade diminui

Quando chega a S4 o portão para, espera 15 segundos e a seguir, o portão

fecha. Chegando a S2 a velocidade diminui e em S1 o portão para. Considera

a velocidade lenta como uma saída VL e a rápida como VR. Faça o Projeto do

hardware e o esquema elétrico.

Page 27: Microcontroladores pic ling c unicamp

Pressionando o botão S1 o guindaste vai para a esquerda até o fim de curso S5

onde pára, só o botão S3 faz ao guindaste retornar até a posição S6. O botão S2

envia o guindaste para a direita até S7 e para retornar aperta-se o botão S4 fazendo o guindaste

retornar até S6.

Page 28: Microcontroladores pic ling c unicamp

Interrupções em C

1 - Dependem do Compilador.

2- Duas formas para o tratamento de interrupções no compilador PCHW da CCS:

• Automática:

O compilador gera todo o código do tratamento da interrupçãoO compilador gera todo o código do tratamento da interrupção

(flags, configuração de registradores , contexto, etc.)

A única tarefa do programador é a construção das funções de tratamento dos eventos individuais de cada interrupção.

• Manual:

O programador deverá se incumbir de tudo: verificar flags de interrupção, chamadas específicas para tratamento de cada evento, configuração dos registradores, salvar e recuperar contexto, etc.

Page 29: Microcontroladores pic ling c unicamp

O que são interrupções?

Interrupções, como o nome sugere, interrompem a execução normal e pedem atenção

urgente de CPU.

Interrupções são situações que a CPU não pode prever quando vai acontecer, elas podem

acontecer a qualquer momento, de modo que o CPU não pode esperar por elas.

Assim, a CPU continua fazendo seu trabalho normal a menos que interrupção ocorra.

Por exemplo, quando o USART (Hardware Comunicação Serial) receberá dados é

desconhecida, pode receber dados a qualquer momento.desconhecida, pode receber dados a qualquer momento.

Assim, a CPU continua a fazer o seu trabalho normal, que pode ser por exemplo ler a

temperatura de um sensor LM35 e mostrar no LCD.

A CPU continua a fazer o trabalho "normal", mas assim que a USART receber dados

informa a CPU usando uma interrupção. A CPU salva seu estado atual (para que ele

possa retornar a ele), e pula para a rotina de serviço de interrupção) ISR

imediatamente.

A Rotina ISR é geralmente muito pequena e rápida.

Assim que a ISR termina, a CPU restaura seu estado que foi salvo e retoma do ponto onde

ocorreu a interrupção.

Page 30: Microcontroladores pic ling c unicamp

Interrupções com tratamento Automático

e Manual

Interrupção Automática

• Vantagens: Simplicidade

• Desvantagens: Gera programas maiores.

Gera tempo extra no tratamento das interrupções,ou seja, o tempo entre aocorrência do evento de interrupção propriamente dito e o tratamento da mesma.

• Uso: Aplicações simples onde o tempo não é um fator crítico.• Uso: Aplicações simples onde o tempo não é um fator crítico.

Interrupção Manual

• Vantagens:

Adequado quando a aplicação demanda precisão de contagem.

• Desvantagens: Gera programas menores.

Mais trabalho para o programador. (contexto, flags,registradores, etc.)

• Uso: Aplicações de tempo real e/ou onde pequenos atrasos são indesejáveis.

• Observação!! Demanda inclusão de código assembler (diretiva específica)

Page 31: Microcontroladores pic ling c unicamp

Periféricos que geram interrupção no

PIC16F877

• Interrupção por overflow do Timer0;

• Interrupção RB (mudança de estado das portas B);

• Interrupção externa;

• Interrupção de conversão analógico/digital;

• Interrupção de transmissão de dados da porta serial (RS232);

• Interrupção de recepção de dados da porta serial (RS232);• Interrupção de recepção de dados da porta serial (RS232);

• Interrupção por overflow do Timer1;

• Interrupção por comparação do Timer2;

• Interrupção do módulo CCP1 e CCP2;

• Interrupção de atividade da comunicação SPI ou I2C;

• Interrupção de colisão de dados do barramento;

• Interrupção de escrita da EEPROM;

• Interrupção de evento do comparador.

Page 32: Microcontroladores pic ling c unicamp

INTCON: o registrador principal que

controla as interrupções

Page 33: Microcontroladores pic ling c unicamp

Algumas interrupções que serão

importantes para o Projeto Final

Page 34: Microcontroladores pic ling c unicamp

Hardware interno do microcontrolador

Page 35: Microcontroladores pic ling c unicamp

Exemplo: Configurar o TMR0 para que gere interrupções a cada 1 segundo.

//Após 125 estouros do TMR0 (125 interrupções), teremos chegado ao tempo de 1 segundo (1Hz).

#include <16F877A.h>

#use delay ( clock=4000000 )

#fuses HS,NOWDT,PUT,NOLVP

#int_timer0

void trata_tmr0 ( ) {

static boolean LED;

static int contador;

set_timer0(131 + get_timer0()) ;

contador++;

if( contador == 125) {if( contador == 125) {

contador = 0;

LED = !LED;

output_bit(pin_b0, LED); } }

void main( ) {

// configura o TMR0 para clock interno e prescaler dividindo por 64

setup_timer_0 (RTCC_INTERNAL | RTCC_DIV_64);

set_timer0 (131); // inicia o timer 0 em 131

// habilita interrupções

enable_interrupts (global | int_timer0);

while (true); // espera pela interrupção

}

Page 36: Microcontroladores pic ling c unicamp

Usar interrupção de Timer para gerenciar máquinas

de estado

Page 37: Microcontroladores pic ling c unicamp

Analise o código abaixo e diga o que ele faz

#include <16F877.h>

#fuses HS,NOWDT,NOPROTECT,NOLVP

#use delay(clock=20000000)

BYTE blink = 0;

#int_rb

void button_isr() {

delay_ms (20); //debounce

if( !input(PIN_B4) && !blink )

blink = 1;

else

if( !input(PIN_B4) && blink ) blink = 0; }

void main( ) {

enable_interrupts(global);

enable_interrupts(int_rb);

ext_int_edge( H_TO_L );

do { if(blink){ output_high(PIN_D1);

delay_ms(500);

output_low(PIN_D1);

delay_ms(500); }

} while (TRUE);

}

Page 38: Microcontroladores pic ling c unicamp

Usando o Conversor AD em C#include<16f877a.h>

#Device ADC=8

#fuses HS,NOLVP,NOWDT,PUT

#use delay(clock=20000000)

#use rs232(baud=9600,xmit=PIN_C6,rcv=PIN_C7)

void main( ) {

int i, value, min, max;

printf("Sampling:");

setup_adc_ports( RA0_ANALOG );

setup_adc( ADC_CLOCK_INTERNAL );

set_adc_channel( 0 );

do { // Toma 30 amostras do conversor AD aplicadas no pino A0

min = 255; // e mostra os valores mínimos e máximo dentre as 30 amostras

max = 0; // valores tomados em intervalos de 100ms

for(i = 0; i <= 30; ++i) {

delay_ms(100);

value = read_adc();

if(value < min)

min = value;

if(value > max)

max = value;

}

printf("nrMin:%x MAX: %x", min, max);

} while (TRUE);

}

Page 39: Microcontroladores pic ling c unicamp

No arquivo cabeçalho 16F877A.h encontramos as constantes:

• // Constants used in SETUP_ADC_PORTS() are:

• #define NO_ANALOGS 7 // None

• #define ALL_ANALOG 0 // A0 A1 A2 A3 A5 E0 E1 E2 Ref=Vdd

• #define AN0_AN1_AN2_AN4_AN5_AN6_AN7_VSS_VREF 1 // A0 A1 A2 A5 E0 E1 E2 Ref=A3

• #define AN0_AN1_AN2_AN3_AN4 2 // A0 A1 A2 A3 A5 Ref=Vdd

• #define AN0_AN1_AN2_AN4_VSS_VREF 3 // A0 A1 A2 A5 Ref=A3

• #define AN0_AN1_AN3 4 // A0 A1 A3 Ref=Vdd

• #define AN0_AN1_VSS_VREF 5 // A0 A1 Ref=A3

• #define AN0_AN1_AN4_AN5_AN6_AN7_VREF_VREF 0x08 // A0 A1 A5 E0 E1 E2 Ref=A2,A3

• #define AN0_AN1_AN2_AN3_AN4_AN5 0x09 // A0 A1 A2 A3 A5 E0 Ref=Vdd

• #define AN0_AN1_AN2_AN4_AN5_VSS_VREF 0x0A // A0 A1 A2 A5 E0 Ref=A3

• #define AN0_AN1_AN4_AN5_VREF_VREF 0x0B // A0 A1 A5 E0 Ref=A2,A3

• #define AN0_AN1_AN4_VREF_VREF 0x0C // A0 A1 A5 Ref=A2,A3

• #define AN0_AN1_VREF_VREF 0x0D // A0 A1 Ref=A2,A3• #define AN0_AN1_VREF_VREF 0x0D // A0 A1 Ref=A2,A3

• #define AN0 0x0E // A0

• #define AN0_VREF_VREF 0x0F // A0 Ref=A2,A3

• #define ANALOG_RA3_REF 0x1 //!old only provided for compatibility

• #define A_ANALOG 0x2 //!old only provided for compatibility

• #define A_ANALOG_RA3_REF 0x3 //!old only provided for compatibility

• #define RA0_RA1_RA3_ANALOG 0x4 //!old only provided for compatibility

• #define RA0_RA1_ANALOG_RA3_REF 0x5 //!old only provided for compatibility

• #define ANALOG_RA3_RA2_REF 0x8 //!old only provided for compatibility

• #define ANALOG_NOT_RE1_RE2 0x9 //!old only provided for compatibility

• #define ANALOG_NOT_RE1_RE2_REF_RA3 0xA //!old only provided for compatibility

• #define ANALOG_NOT_RE1_RE2_REF_RA3_RA2 0xB //!old only provided for compatibility

• #define A_ANALOG_RA3_RA2_REF 0xC //!old only provided for compatibility

• #define RA0_RA1_ANALOG_RA3_RA2_REF 0xD //!old only provided for compatibility

• #define RA0_ANALOG 0xE //!old only provided for compatibility

• #define RA0_ANALOG_RA3_RA2_REF 0xF //!old only provided for compatibility

Page 40: Microcontroladores pic ling c unicamp

SETUP_ADC( )

Page 41: Microcontroladores pic ling c unicamp

Set_adc( ) e read_adc( )

Page 42: Microcontroladores pic ling c unicamp

Quais são os problemas com esse projeto de

hardware ?

Page 43: Microcontroladores pic ling c unicamp

Exemplo de configuração dos 2 canais de PWM

#include <16F877.h>

#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP

#use delay(clock = 4000000)

main( ) {

output_low(PIN_C1); // Set CCP2 output low

output_low(PIN_C2); // Set CCP1 output low

setup_ccp1(CCP_PWM); // Configure CCP1 as a PWM

setup_ccp2(CCP_PWM); // Configure CCP2 as a PWM

setup_timer_2(T2_DIV_BY_16, 124, 1); // 500 Hz

set_pwm1_duty(31); // 25% duty cycle on pin C2

set_pwm2_duty(62); // 50% duty cycle on pin C1

while(1); // Prevent PIC from going to sleep (Important !)

}

Page 44: Microcontroladores pic ling c unicamp

Equações usadas para ajustar os valores do

PWM no CCS

value = Fosc / (Fpwm * 4 * T2DIV) - 1

setup_timer_2(T2_DIV_BY_X, value, 1);

valor = (Desired_Duty_Cycle% * Fosc) / (Fpwm * 4 * T2DIV)

set_pwm1_duty(valor);

Page 45: Microcontroladores pic ling c unicamp

Exercício

A cada 2 segundos o microcontrolador deve adicionar à sua saída analógica 0,5

volt, até alcançar 5 volts. Isto será iniciado quando o operador pressionar o botão

start, e quando for pressionado o botão stop a rampa deverá ser decrescente

até o motor parar. Para este problema assuma que a saída analógica é a saida do

PWM 1.

Page 46: Microcontroladores pic ling c unicamp

Memória de dados não voláteis:

Eeprom

Para escrever na EEPROM

Write_eeprom ( end. , valor);

Para ler o conteúdo de um determinado endereço:Para ler o conteúdo de um determinado endereço:

x = read_eeprom (end.);

Obs: valor deve ser um inteiro de 8 bits ! ( int8)

Page 47: Microcontroladores pic ling c unicamp

Memória de dados não voláteis: Eeprom -

exemplo

#include <16F877A.h>

#fuses HS,NOWDT,NOPROTECT,NOLVP

#use delay(clock=20000000)

#rom 0x2100 = { 7, 39 } // Diretiva #ROM inicializa a EEPROM

#include <lcd2.c>

void main( ) {

int8 value, value1;int8 value, value1;

lcd_init( );

value = read_eeprom (0x2100);

value1= read_eeprom (0x2101);

delay_ms(6);

lcd_gotoxy(1,1);

printf(lcd_putc," Prof. Fambrini ");

lcd_gotoxy(1,2);

printf( lcd_putc,"D1=%u",value);

lcd_gotoxy(9,2);

printf(lcd_putc,"D2=%u",value1) ;

while(TRUE) { }

}

Page 48: Microcontroladores pic ling c unicamp

Como guardar um número Float ou um int32 na

Eeprom ?

//*********************** Gravando Float na EEPROM *****************************//

void WRITE_FLOAT_EEPROM (int8 n, float data){

int8 i;

for (i = 0; i < 4; i++)write_eeprom (i + n, *(&data + i) ) ;

}

//**************************** Lendo Float na EEPROM *************************//

float READ_FLOAT_EEPROM (int8 n){

int8 i ;float data;

for (i = 0; i < 4; i++)*(&data + i) = read_eeprom (i + n);

return(data);}