20. 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); }
}
}
21. 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.
25. 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.
26. 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.
27. 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.
28. 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.
29. 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.
30. 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)
31. 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.
37. 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);
}
38. 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);
}
39. 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
42. Quais são os problemas com esse projeto de
hardware ?
43. 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 !)
}
44. 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);
45. 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.
46. 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)
48. 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);
}