Академический Документы
Профессиональный Документы
Культура Документы
ISO 9001:2008
SEMANA 22 AL 25 DE ABRIL
TEMA: PROGRAMACIN MICROCONTROLADORES MICROCHIP
1 MATERIALES NECESARIOS
2 TEMAS
Abril 22
-
Abril 23
-
Abril 24
-
Abril 25
-
Preparado por:
Luis Guillermo Montoya Diaz
Asesor Profesional
SUCONEL S.A
Lo primero que vamos a realizar, luego de instalar el software necesario, ser aprender a
manejar la nueva plataforma de MICROCHIP llamada MPLABX, para eso, debemos
seguir el paso a paso que se presenta a partir de la siguiente pgina.
Adicional a esto se iniciar el curso con 2 programas bsicos en el manejo de entradas y
salidas, tanto en lenguaje ensamblador como en lenguaje C, para as poder continuar con
propiedad el resto del curso.
Sale el primer paso que es elegir el tipo de proyecto a realizar se elige Microchip
Embedded y Standalone Project click en Next.
Inicio el cdigo y al finalizar lo compilo del icono Clean and Build (Escoba y
martillo). Si no hay errores debe aparecer la frase Loading Completed.
Ahora se procede con la programacin. Si el programador est conectado, como
en este caso que tenemos seleccionado y conectado a nuestra aplicacin el
PICKIT3, se debe habilitar la alimentacin a travs del puerto USB donde est
conectado el PICKIT3, esto se hace si la aplicacin no tiene alimentacin
independiente. Si alimentamos a travs del PICKIT3, se debe verificar que el
consumo de corriente de la aplicacin no supere los 500 mA para no poner en
riesgo el puerto USB del PC.
Al finalizar la programacin
Programming/Verify complete
en
forma
correcta,
aparece
el
aviso
En este caso se elige el compilador para lenguaje C llamado XC8. La versin 1.12
es la ltima al momento de realizar este ejercicio. Click en Next.
Con el proyecto listo a la izquierda de tu PC, se selecciona Source File luego New
y finalmente
C source file si est presente, sino es as, se selecciona Other y se busca C
Source File.
decide si los pines del puerto sern entrada o salida, se llaman TRIS as: TRISA,
TRISB, TRISC, TRISD y TRISE.
Recuerde que a diferencia de otros microcontroladores como los ATMEL AVR y
los FREESCALE, en los PIC de MICROCHIP las entradas se configuran con unos
y las salidas con ceros, por ejemplo si se configura el registro TRISA como
01001011, el microcontrolador tendr los pines RA0, RA1, RA3 Y RA6 con la
impedancia respectiva para el trabajo como entradas y los dems pines podrn
trabajarse como salidas.
Como se ve en el diagrama de pines, las lneas que se utilizan para convertir
seales anlogas a digitales son 14 y estn ubicadas en los puertos A, B y E,
denotados como AN0, AN1AN13, los registros encargados de configurar los
canales anlogos se llaman ANSEL y ANSELH, stos vienen preparados de
fbrica para recibir seales anlogas, por lo tanto, se deben limpiar (Cargar con
cero) si no se va a realizar ninguna conversin A/D, as se podrn trabajar todos
los pines como entrada o salida digital. En el captulo dedicado a la conversin
anlogo a digital se tratar ms a fondo el trabajo de estos registros.
Con estos conceptos bsicos se da comienzo al primer ejemplo que simplemente,
permite contar de 0 a 9 los pulsos generados desde el pin RD4 del puerto D,
visualizando en el puerto A, a travs de leds y en el puerto C, mediante un display
de siete segmentos de ctodo comn conectado a un decodificador BCD a 7
segmentos. Ver plano electrnico.
La cuenta solo se incrementar con flanco de subida, as aseguramos que se
incremente solo en uno cada que se presiona el pulsador.
R2
220
R3
220
R4
220
R5
220
D1
U1
1
LED-RED
D2
LED-RED
D3
LED-RED
D4
LED-RED
2
3
4
5
6
7
14
13
33
34
35
36
37
38
39
40
RE3/MCLR/VPP
RC0/T1OSO/T1CKI
RC1/T1OSI/CCP2
RA0/AN0/ULPWU/C12IN0RC2/P1A/CCP1
RA1/AN1/C12IN1RC3/SCK/SCL
RA2/AN2/VREF-/CVREF/C2IN+ RC4/SDI/SDA
RA3/AN3/VREF+/C1IN+
RC5/SDO
RA4/T0CKI/C1OUT
RC6/TX/CK
RA5/AN4/SS/C2OUT
RC7/RX/DT
RA6/OSC2/CLKOUT
RA7/OSC1/CLKIN
RD0
RD1
RB0/AN12/INT
RD2
RB1/AN10/C12IN3RD3
RB2/AN8
RD4
RB3/AN9/PGM/C12IN2RD5/P1B
RB4/AN11
RD6/P1C
RB5/AN13/T1G
RD7/P1D
RB6/ICSPCLK
RB7/ICSPDAT
RE0/AN5
RE1/AN6
RE2/AN7
PIC16F887
U2
15
16
17
18
23
24
25
26
7
1
2
6
4
5
3
A
B
C
D
BI/RBO
RBI
LT
QA
QB
QC
QD
QE
QF
QG
13
12
11
10
9
15
14
7448
19
20
21
22
27
28
29
30
R6
Q1
2N2222
2.7K
8
9
10
R1
10k
ENDC
;*********************************************************************************************
ORG 00
; Primera posicin de la memoria de programa
GOTO
ORG
INICIO
05
;*********************************************************************************************
; Subrutina de retardo para milisegundos
;*********************************************************************************************
RETARDO ; el literal que viene en W es el nmero de milisegundos del retard o
MOVWF REG1
DOS
MOVLW .110
MOVWF REG2
UNO
NOP
NOP
NOP
NOP
NOP
NOP
DECFSZ REG2
GOTO
UNO
DECFSZ REG1
GOTO
DOS
RETURN
;*********************************************************************************************
; Programa principal
;*********************************************************************************************
INICIO
LIMPIAR
PREG
BANKSEL TRISA
CLRF
TRISA
CLRF
TRISC
MOVLW B'00010000'
MOVWF TRISD
BANKSEL ANSEL
CLRF
ANSEL
CLRF
ANSELH
BANKSEL PORTD
; Regreso al banco 0
BSF
PORTD,0
CLRF
CONT
; Limpio contador
MOVF
CONT,W
; Paso contador a W
MOVWF PORTC
MOVWF PORTA
BTFSC PORTD,4
GOTO
$-1
MOVLW .200
CALL
RETARDO
BTFSS PORTD,4
GOTO
$-1
; preguntando
INCF
CONT
MOVLW 0X0A
XORWF CONT,0
BTFSC STATUS,2
GOTO
LIMPIAR
CONT,W
MOVWF PORTC
MOVWF PORTA
GOTO
PREG
END
//*********************************************************************************************
Programa en lenguaje C
//*********************************************************************************************
#include <xc.h>
//*********************************************************************************************
// Palabras de configuracin de bits generadas automticamente por el compilador
// ********************************************************************************************
// CONFIG1
#pragma config FOSC = XT
#pragma config WDTE = OFF
#pragma config PWRTE = OFF
#pragma config MCLRE = ON
#pragma config CP = OFF
#pragma config CPD = OFF
#pragma config BOREN = ON
#pragma config IESO = ON
#pragma config FCMEN = ON
#pragma config LVP = OFF
// CONFIG2
#pragma config BOR4V = BOR40V // Brown-out Reset Reset set to 4.0V
#pragma config WRT = OFF
//*********************************************************************************************
// Definicin de la velocidad del oscilador
// ********************************************************************************************
#define _XTAL_FREQ 4000000
// ********************************************************************************************
// Declaracin de variables
// ********************************************************************************************
char cont = 0; // Declaro variable cont como un char y la inicio en 0
// ********************************************************************************************
void main()
{
TRISA=0;
TRISC=0;
TRISD=0X10;
ANSEL=0;
ANSELH=0;
PORTA=0;
// Limpio puerto A
PORTC=0;
// Limpio puerto C
RD0=1;
while(1)
{
if(cont<10)
{
if (!RD4)
// Pregunto si RD4=0
{
__delay_ms(200); // Retardo para evitar rebote de contacto
while(!RD4)
continue;
cont=cont+1;
PORTC=cont;
PORTA=cont;
}
}
else
{
cont=0;
}
}
}
1 Definir las entradas y salidas con nombres diferentes a los pines y los puertos
as:
#define suiche RD4
#define leds
PORTA
#define Q1
RD0
cont=cont+1;
display=cont;
leds=cont;
}
Unsigned int
// CONFIG2
#pragma config BOR4V = BOR40V // Brown-out Reset Reset set to 4.0V
#pragma config WRT = OFF
//*********************************************************************************************
// Definicin de la velocidad del oscilador
//*********************************************************************************************
#define _XTAL_FREQ 4000000
//*********************************************************************************************
Definicin de nombres para las variables
//*********************************************************************************************
#define suiche RD4
#define leds
PORTA
#define Q1
RD0
//*********************************************************************************************
// Declaracin de variables
//*********************************************************************************************
char cont=0; // Declaro variable cont como char y la inicio en 0
//*********************************************************************************************
// Declaracin de funciones
//*********************************************************************************************
void incremente (void) // Declaro y realizo la funcin incremente
{
cont=cont+1;
// Incremento el contador
display=cont;
leds=cont;
}
//*********************************************************************************************
void main()
{
TRISA=0;
TRISC=0;
TRISD=0X10;
ANSEL=0;
ANSELH=0;
leds=0;
// Limpio puerto A
display=0;
// Limpio puerto C
Q1=1;
while(1)
{
if(cont<10)
{
if (!suiche) // Pregunto si suiche est presionado, en este caso = 0
{
__delay_ms(200);// Retardo para evitar rebote de contacto
while(!suiche) // Mientras suiche est en cero no haga nada
continue; // Si pasa a uno incrementa contador por flanco de subida
incremente(); // Llamo la funcin incrementar
}
}
else
{
cont=0; // Si cont no es menor que 0, entonces lo limpio.
}
}
}
Puede comparar ambos programas e ir notando las diferencias entre un
compilador y otro. Aunque soy gran amigo del lenguaje ensamblador, el hecho de
no tener que direccionar bancos de memoria de datos, ni tener en cuenta en qu
posicin de memoria comienzan los registros de propsito general, porque en C
simplemente se declaran las variables, adems de la facilidad del procesamiento
matemtico, hace que generalmente me decida por el lenguaje C para realizar mis
aplicaciones.
Materiales necesarios
-
D1
R1
220
U1
D2
GP0
GP1
GP2/T0CKI/FOSC4
GP3/MCLR
R2
220
D3
PIC10F200
R3
220
R4
10k
Plano Electrnico
Programa en lenguaje C
// Se incluye la librera principal con los bits y registros especiales del micro
//********************************************************************************************
#include <xc.h>
//********************************************************************************************
// Palabra de configuracin creada automticamente
//*********************************************************************************************
#include <xc.h>
// CONFIG
#pragma config WDTE = OFF
#pragma config CP = OFF
GPIO=0;
{
if (GP3==1) // Pregunto por el estado del pin GP3
{
GPIO=7;
}
else
{
GPIO=0;
}
}
}
00
GOTO
MAIN
ORG
05
MOVLW
B'1000'
TRIS
GPIO
; como salidas
MOVLW
B'0000'
MAIN
OPTION
PREG
OFF
; pin GP2
BTFSS
GPIO,3
GOTO
OFF
MOVLW
B'111'
MOVWF
GPIO
GOTO
PREG
CLRF
GPIO
GOTO
PREG
END
LCD1
D0
D1
D2
D3
D4
D5
D6
D7
7
8
9
10
11
12
13
14
RS
RW
E
4
5
6
1
2
3
VSS
VDD
VEE
LM016L
este caso el bit 5, porque es quien permite al microcontrolador del LCD ubicarse
en la columna correspondiente. El dato en decimal es 56, este nmero no puede
estar en ninguna de las otras filas de la matriz, por la diagonal de unos obligatoria
que est presente en ella.
Ahora viene el programa en lenguaje C para el primer ejercicio de escribir
mensajes fijos en el LCD.
// Programa para escribir un mensaje fijo en un LCD de 2 lneas x 16 caracteres
//*********************************************************************************************
// Se incluye librera xc.h y palabras de configuracin de bits, todo esto generado
// automticamente por el compilador XC8
//*********************************************************************************************
#include <xc.h>
__CONFIG(FOSC_XT & WDTE_OFF & PWRTE_OFF & MCLRE_ON & CP_OFF
& CPD_OFF & BOREN_ON & IESO_ON & FCMEN_ON & LVP_OFF);
__CONFIG(BOR4V_BOR40V & WRT_OFF);
//*********************************************************************************************
// Defino la velocidad del oscilador necesaria para el clculo de los delay
//*********************************************************************************************
#define _XTAL_FREQ 4000000
//*********************************************************************************************
// Defino nombres propios para pines y puerto del PIC usados para RS, E y el dato
//*********************************************************************************************
#define
LCD_RS
RD6
#define
LCD_EN
RD7
#define
LCD_DATA PORTB
//*********************************************************************************************
// Declaro funciones para el LCD
//*********************************************************************************************
void lcd_init (void);
// Direcciones en el LCD
void main()
{
TRISD=0;
TRISB=0;
PORTB=0;
// Limpio Puerto B
lcd_init();
while(1)
{
lcd_goto(0); // selecciono primera lnea
lcd_puts(" BIENVENIDOS
lcd_goto(0x40);
lcd_puts("
LIBRO PIC
continue;
}
}
void lcd_init (void) // funcin de inicializacin del LCD
{
LCD_DATA=2;
set_lcd();
LCD_DATA=56;
set_lcd();
LCD_DATA=15;
set_lcd();
LCD_DATA=6;
set_lcd();
LCD_DATA=1;
set_lcd();
}
LCD_EN=1;
// Habilito la operacin
// Termina la operacin
// Funcin de direcciones
{
LCD_RS = 0;
// RS en 0 para configuracin
lcd_write(0x80+pos);
}
void lcd_write(unsigned char c)
{
LCD_EN=1;
// Habilito la operacin
LCD_DATA = ( c );
__delay_ms(2);
LCD_EN=0;
// Termina la operacin
}
/* Escribo una cadena de caracteres en el LCD */
void lcd_puts(const char * s)
{
LCD_RS = 1;
// Habilito la operacin
while(*s)
lcd_write(*s++);
// Pase al siguiente
}
Todas las funciones utilizadas pueden formar un archivo de cabecera .h para
anexar al proyecto y dejar el programa principal ms corto.
LCD1
LM016L
D0
D1
D2
D3
D4
D5
D6
D7
7
8
9
10
11
12
13
14
RS
RW
E
4
5
6
1
2
3
VSS
VDD
VEE
U1
1
2
3
4
5
6
7
14
13
33
34
35
36
37
38
39
40
RE3/MCLR/VPP
RC0/T1OSO/T1CKI
RC1/T1OSI/CCP2
RA0/AN0/ULPWU/C12IN0RC2/P1A/CCP1
RA1/AN1/C12IN1RC3/SCK/SCL
RA2/AN2/VREF-/CVREF/C2IN+ RC4/SDI/SDA
RA3/AN3/VREF+/C1IN+
RC5/SDO
RA4/T0CKI/C1OUT
RC6/TX/CK
RA5/AN4/SS/C2OUT
RC7/RX/DT
RA6/OSC2/CLKOUT
RA7/OSC1/CLKIN
RD0
RD1
RB0/AN12/INT
RD2
RB1/AN10/C12IN3RD3
RB2/AN8
RD4
RB3/AN9/PGM/C12IN2RD5/P1B
RB4/AN11
RD6/P1C
RB5/AN13/T1G
RD7/P1D
RB6/ICSPCLK
RB7/ICSPDAT
RE0/AN5
RE1/AN6
RE2/AN7
15
16
17
18
23
24
25
26
19
20
21
22
27
28
29
30
8
9
10
PIC16F887
//*********************************************************************************************
#define
LCD_RS RD6
lcd_init();
while(1)
{
lcd_goto(0); // selecciono primera lnea
lcd_puts("
CONTADOR
lcd_goto(0x40);
");
lcd_puts(" IGUAL A:
while(cont<999)
");
{
cont++;
bin_bcd();
lcd_goto(0x4C);
lcd_putch(decenas+48);
lcd_goto(0x4E);
void lcd_init(void)
{
LCD_DATA=2;
set_lcd();
LCD_DATA=56;
set_lcd();
LCD_DATA=15;
set_lcd();
LCD_DATA=6;
set_lcd();
LCD_DATA=1;
set_lcd();
}
/*
* Voy a una posicin especfica
*/
void lcd_goto(unsigned char pos)
{
LCD_RS = 0;
lcd_write(0x80+pos);
}
LCD_EN=1;
LCD_DATA = ( c );
__delay_ms(2);
LCD_EN=0;
}
void lcd_putch(char c)
{
LCD_RS = 1;
lcd_write( c );
}
// write characters
LCD1
LM016L
D0
D1
D2
D3
D4
D5
D6
D7
7
8
9
10
11
12
13
14
RS
RW
E
4
5
6
1
2
3
VSS
VDD
VEE
U1
1
2
3
4
5
6
7
14
13
33
34
35
36
37
38
39
40
RE3/MCLR/VPP
RC0/T1OSO/T1CKI
RC1/T1OSI/CCP2
RA0/AN0/ULPWU/C12IN0RC2/P1A/CCP1
RA1/AN1/C12IN1RC3/SCK/SCL
RA2/AN2/VREF-/CVREF/C2IN+ RC4/SDI/SDA
RA3/AN3/VREF+/C1IN+
RC5/SDO
RA4/T0CKI/C1OUT
RC6/TX/CK
RA5/AN4/SS/C2OUT
RC7/RX/DT
RA6/OSC2/CLKOUT
RA7/OSC1/CLKIN
RD0
RD1
RB0/AN12/INT
RD2
RB1/AN10/C12IN3RD3
RB2/AN8
RD4
RB3/AN9/PGM/C12IN2RD5/P1B
RB4/AN11
RD6/P1C
RB5/AN13/T1G
RD7/P1D
RB6/ICSPCLK
RB7/ICSPDAT
RE0/AN5
RE1/AN6
RE2/AN7
PIC16F887
15
16
17
18
23
24
25
26
19
20
21
22
27
28
29
30
8
9
10
Registro ADCON0
Para el ejercicio, si queremos velocidad Fosc/8, canal 5 y habilitar el mdulo de
conversin, el ADCON0 queda as:
ADCON0 = 0B01010101;
Por ltimo el ADCON1
Registro ADCON1
Si el voltaje de referencia es el de alimentacin y se quiere alinear el resultado a la
derecha, el registro ADCON1 queda as:
ADCON1 = 0B10000000;
Programa de conversin anlogo a digital
//*********************************************************************************************
// Se incluye archivo de cabecera xc.h y las palabras de configuracin
//*********************************************************************************************
#include <xc.h>
__CONFIG(FOSC_XT & WDTE_OFF & PWRTE_OFF & MCLRE_ON & CP_OFF
& CPD_OFF & BOREN_ON & IESO_ON & FCMEN_ON & LVP_OFF);
__CONFIG(BOR4V_BOR40V & WRT_OFF);
//*********************************************************************************************
// Se define al velocidad del oscilador
//*********************************************************************************************
#define _XTAL_FREQ 4000000
//*********************************************************************************************
void main()
{
TRISE=0X01;
TRISB=0;
TRISC=0;
ANSELH=0;
PORTB=0;
// Limpio Puerto B
PORTC=0;
// Limpio Puerto B
while(1)
{
GO=1;
}
}
PORTB=ADRESL;
PORTC=ADRESH;
__delay_ms(200);
D1
LED-RED
D2
R1
LED-RED
D4
U1
1
220
R2
2
3
4
5
6
7
14
13
220
R3
220
LED-RED
D5
R4
220
R5
LED-RED
D6
LED-RED
D7
33
34
35
36
37
38
39
40
220
R6
220
R7
220
LED-RED
D8
R8
LED-RED
D10
R9
RC0/T1OSO/T1CKI
RC1/T1OSI/CCP2
RA0/AN0/ULPWU/C12IN0RC2/P1A/CCP1
RA1/AN1/C12IN1RC3/SCK/SCL
RA2/AN2/VREF-/CVREF/C2IN+ RC4/SDI/SDA
RA3/AN3/VREF+/C1IN+
RC5/SDO
RA4/T0CKI/C1OUT
RC6/TX/CK
RA5/AN4/SS/C2OUT
RC7/RX/DT
RA6/OSC2/CLKOUT
RA7/OSC1/CLKIN
RD0
RD1
RB0/AN12/INT
RD2
RB1/AN10/C12IN3RD3
RB2/AN8
RD4
RB3/AN9/PGM/C12IN2RD5/P1B
RB4/AN11
RD6/P1C
RB5/AN13/T1G
RD7/P1D
RB6/ICSPCLK
RB7/ICSPDAT
RE0/AN5
RE1/AN6
RE2/AN7
15
16
17
18
23
24
25
26
C0
C1
19
20
21
22
27
28
29
30
U1(RE0/AN5)
V=4.45
8
9
10
PIC16F887
220
LED-RED
D9
RE3/MCLR/VPP
C0
220
R10
RV1
C1
220
LED-RED
89%
LED-RED
D3
1k
LCD_RS
#define
LCD_EN
#define
//*******************************************************************************
// Declaracin de variables
//*******************************************************************************
Unsigned int voltaje, digital,temp; // Declaro variables enteras sin signo
// Declaracin de funciones
//*******************************************************************************
void main()
{
TRISD=0;
TRISB=0;
PORTB=0;
// Limpio Puerto B
PORTD=0;
// Limpio Puerto D
TRISE=0X01;
ADCON0=0X55;
ADCON1=0X80;
ANSEL=0X20;
ANSELH=0;
lcd_init();
while(1)
{
lcd_goto(0);
while(GO==1)
continue;
// Si pasa a 0 continuo
binbcd();
lcd_goto(0x4C);
lcd_putch(diezmil+48);
lcd_goto(0x4E);
lcd_putch(miles+48);
lcd_goto(0x4F);
lcd_putch(centenas+48);
__delay_ms(500);
}
}
void lcd_init(void)
{
LCD_DATA=2;
set_lcd();
LCD_DATA=56;
set_lcd();
LCD_DATA=15;
set_lcd();
LCD_DATA=6;
set_lcd();
LCD_DATA=1;
set_lcd();
}
void set_lcd (void)
{
LCD_RS=0;
LCD_EN=1;
__delay_ms(2);
LCD_EN=0;
}
LCD_EN=1;
LCD_DATA = ( c );
__delay_ms(2);
LCD_EN=0;
}
/* Escribo una cadena de caracteres en el LCD */
void lcd_puts(const char * s)
{
LCD_RS = 1;
while(*s)
lcd_write(*s++);
}
/* Escribo un caracter en el LCD */
void lcd_putch(char c)
{
LCD_RS = 1;
// write characters
lcd_write( c );
}
void binbcd (void)
{
temp=voltaje;
diezmil=0;
// Inicializo variables en 0
miles=0;
centenas=0;
decenas=0;
unidades=0;
while(temp>10000)
{
temp=temp-10000;
diezmil=diezmil+1;
}
while(temp>1000)
{
temp=temp-1000;
miles=miles+1;
}
while(temp>100)
{
temp=temp-100;
centenas=centenas+1;
}
while(temp>10)
{
temp=temp-10;
decenas=decenas+1;
}
unidades=temp;
}
Simulacin
SPBRG = 25 ;
TRISC=0;
TXSTA=0X24;
SPBRG=25;
SPEN=1;
while(1)
{
TXREG=65;
while(TRMT==0)
continue;
__delay_ms(500);
}
}
Simulacin
Cuando deseamos enviar cadenas de caracteres existe la instruccin printf que
hace parte de la librera stdio.h.
{
TRISC=0;
SPEN=1;
SPBRG=25;
TXSTA=0X20;
while(1)
{
for(cont=0;cont<10;cont++) // for para el conteo de uno a 10
{
printf("\r Contador = %d\n",cont); // Envo del mensaje y la variable cont
__delay_ms(1000);
}
}
}
void putch (unsigned char byte) // Funcin para envo con printf
{
while(!TRMT)
continue;
TXREG=byte;
}
Simulacin
Por ltimo, vamos a utilizar la comunicacin para monitorear una variable anloga
y enviarla al PC
// Programa de monitoreo de temperatura en el PC
//*********************************************************************************************
// Se incluyen las libreras necesarias y las palabras de configuracin de bits
//*********************************************************************************************
#include <xc.h>
#include <stdio.h>
__CONFIG(FOSC_XT & WDTE_OFF & PWRTE_OFF & MCLRE_ON & CP_OFF
& CPD_OFF & BOREN_ON & IESO_ON & FCMEN_ON & LVP_OFF);
__CONFIG(BOR4V_BOR40V & WRT_OFF);
//*********************************************************************************************
// Definicin de la velocidad del oscilador
//*********************************************************************************************
TRISC=0;
// Canal 6 anlogo
ANSELH=0;
TXSTA=0X26;
SPBRG=25;
RCSTA=0X80;
while(1)
{
GO=1;
// Cada 200 ms
}
}
void putch (unsigned char byte)
{
while(!TRMT)
continue;
TXREG=byte;
}
Simulacin
En la simulacin superior se puede ver que la lectura del puerto A es 3, ya que los
pulsadores ubicados en RA0 y RA1 no estn presionados y la polarizacin de
estos es a 5V, por lo tanto se leen unos, el pulsador RA2 est presionado, es decir
que entra un 0. La lectura es 3, es menor a 4 y por eso se activa RA1.
En la simulacin inferior se puede ver que la lectura del puerto A es 7, ya que los 3
pulsadores no estn presionados y la polarizacin de estos es a 5V, por lo tanto se
leen unos. La lectura es 7, es mayor a 4 y por eso se activa RA0.
Mientras no haya interrupcin por recepcin del dato, el PIC permanece activando
y desactivando la salida RA2.
Programa de transmisin
//*********************************************************************************************
// Se incluye la librera xc.h con bits y registros especiales del micro
//*********************************************************************************************
#include <xc.h>
//*********************************************************************************************
// Palabras de configuracin de bits
//*********************************************************************************************
// CONFIG1
#pragma config FOSC = XT
#pragma config WDTE = OFF
#pragma config PWRTE = OFF
#pragma config MCLRE = ON
#pragma config CP = OFF
#pragma config CPD = OFF
#pragma config BOREN = ON
#pragma config IESO = ON
#pragma config FCMEN = ON
#pragma config LVP = OFF
// XT oscillator
// Watchdog Timer Disable
// Power-up Timer Enable bit (PWRT disabled)
// pin function is MCLR
// Program memory code protection is disabled
// Data memory code protection is disabled
// BOR enabled
// Internal External Switchover
// Fail-Safe Clock Monitor Enabled bit
// HV on MCLR must be used for programming
// CONFIG2
#pragma config BOR4V = BOR21V // Brown-out Reset set to 2.1V
#pragma config WRT = OFF
//*********************************************************************************************
// Definicin de la velocidad del oscilador
//*********************************************************************************************
#define _XTAL_FREQ 4000000
//*********************************************************************************************
// Declaracin de variables
//*********************************************************************************************
char aux=0;
//*********************************************************************************************
void main()
{
TRISC=0X00;
TRISA=0XFF;
TXSTA=0X26;
SPBRG=25;
SPEN=1;
ANSEL=0;
ANSELH=0;
while(1)
{
aux=PORTA; // Leo el puerto A y lo llevo al registro aux
TXREG=aux; // Llevo el dato al registro de transmisin
while(TRMT==0)
continue;
__delay_ms(5000);
}
}
Programa de recepcin
//*********************************************************************************************
// Se incluye librera con bits y registros especiales
//*********************************************************************************************
#include <xc.h>
//*********************************************************************************************
// XT oscillator
// Watchdog Timer Disable
// Power-up Timer Enable bit (PWRT disabled)
// pin function is MCLR
// Program memory code protection is disabled
// Data memory code protection is disabled
// BOR enabled
// Internal External Switchover
// Fail-Safe Clock Monitor Enabled bit
// HV on MCLR must be used for programming
// CONFIG2
#pragma config BOR4V = BOR21V // Brown-out Reset set to 2.1V
#pragma config WRT = OFF
//*********************************************************************************************
// Definicin de la velocidad del oscilador
//*********************************************************************************************
#define _XTAL_FREQ 4000000
//*********************************************************************************************
// Declaracin de variables
//*********************************************************************************************
char temp=4;
char aux;
//*********************************************************************************************
void main()
{
TRISC=0X80;
TRISA=0;
TRISD=0;
TXSTA=0X26;
SPBRG=25;
RCSTA=0X90;
ANSEL=0;
ANSELH=0;
PORTA=0;
// Limpio Puerto A
PORTD=0;
// Limpio Puerto D
PORTC=0;
// Limpio puerto C
RD0=1;
while(1)
{
RA2=~RA2;
__delay_ms(200);
}
}
void interrupt isr()
{
// Funcin de interrupcin
PORTC=RCREG;
aux=RCREG;
if(aux>temp)
{
RA0=1;
__delay_ms(1000);
RA0=0;
}
else
{
RA1=1;
__delay_ms(1000);
RA1=0;
}
RCIF=0;
__delay_ms(100);
}
Podemos ver en el diagrama de pines que el mdulo CCP1 tiene salida por los
pines RB0 por el pin RB3. Se selecciona en el registro APFCON.
#include <xc.h>
// CONFIG1
#pragma config FOSC = HS
// Internal/External Switchover
// CONFIG2
#pragma config WRT = OFF
PR2=255;
CCPTMRS=0;
CCPR1L= 128;
while(1)
{
TMR2=0;
for (i=0;i<250;i++)
{
TMR2ON=1; // bit 2 del T2CON se activa TMR2
while (TMR2IF==0)
continue;
TMR2IF=0;
}
}
}
Las frmulas para hallar los diferentes parmetros son las siguientes:
1 Perodo PWM = (PRx + 1) * 4 * Tosc * Preescala del TIMER
2 Ancho de pulso = CCPRxL:CCPxCON(4:5) * Tosc * Preescala del TIMER
3 Duty Cycle = {CCPRxL:CCPxCON(4:5) } / { 4(PRx + 1)}
4 Resolucin = log {4 (PRx + 1)} / log (2)
CCPTMRS=0;
while(1)
{
TMR2=0;
for (i=0;i<250;i++)
{
TMR2ON=1; // bit 2 del T2CON se activa TMR2
while (TMR2IF==0)
continue;
TMR2IF=0;
}
CCPR1L = CCPR1L +1; Se incrementa ancho de pulso en uno
}
}
Materiales necesarios
As las cosas:
12TAD x 154 ns = 1,848us (Cuantificacin y codificacin)
1TAD x 154 ns = 15nss = 0,154us (Adquisicin)
Total = 1,848 + 0,154 = 2,002us (Cumple perfectamente con el requerimiento de
velocidad del conversor A/D, o sea, 500 Ksps)
Ejemplo: Una seal de audio cuya frecuencia de muestreo es de 44100 HZ se debe tratar
en un DSP 30F4012 a una velocidad de 500Ksps. La frecuencia de oscilacin en el DSP
es de 80MHZ.
Hallar los tiempos de adquisicin y muestreo y el parmetro para los bits ADCS del
registro de control ADCON3.
Solucin:
Tiempo de muestreo es 1/44,1KHZ = 0,0226 ms, = 22,6 us
TAD = 154 ns
TCY = 50 ns
ADCS = 2 (TAD / TCY) 1 = 2 (154/50) - 1= 5,16 se aproxima hacia arriba ADCS = 6
TAD real de trabajo = [(ADCS + 1) * TCY] / 2 = (7 * 50 ns) / 2 = 175 ns
Tiempo de conversin (Cuantificacin y Codificacin) = 12 x 175 = 2,1 us
Tiempo de adquisicin = 22,6 us 2,1 us = 20,5 us
Los registros que tienen que ver con el mdulo de conversin A/D de los DSP 33F
son:
ADCON1
ADCON2
ADCON3
ADPCFG
ADCSSL
ADCHS
ADCBUF0 A ADCBUFF (16 registros que almacenan el resultado de la conversin
A/D, se pueden almacenar hasta 16 resultados de 16 muestras)
ADPCFG es quien dice cuales son entradas anlogas (ceros) y cuales son
entradas o salidas digitales (unos). En nuestro ejemplo necesitamos solamente
RB0 como anloga, por lo tanto, el registro ADPCFG quedar en el programa as:
ADPCFG = 0xFFFE;
As mismo el TRISB debe configurarse para que el pin RB0 del puerto B sea
entrada
TRISB = 0x0001;
ADCHS simplemente, se configura con el nmero del canal anlogo a utilizar, en
este caso cero.
ADCHS = 0;
ADCSSL se utiliza para configurar los canales A/D a escanear, si se van a utilizar
varios, si es solo uno, se configura con cero.
ADCSSL = 0;
Ahora veamos los registros de control:
1 ADCON1
2 - ADCON2
ADCON2 = 0
Por las siguientes razones:
Como no vamos a tratar una seal con una frecuencia muy exigente, entonces el
parmetro que me permite configurar los tiempos de adquisicin y conversin
puede estar al mximo, es decir los 6 bits ADCS = 3F, como el mtodo de
conversin es manual, o sea poniendo a 1 el bit SAMP iniciar el muestreo y luego
de un retardo, poniendo este mismo bit a cero, finalizar el muestreo e iniciar la
conversin, los bits de tiempo para el mtodo automtico no los voy a utilizar,
entonces SAMC = 0, el reloj base para la conversin ser derivado de la
frecuencia de oscilacin principal, por lo tanto ADRC = 0,
"p30f4012.h"
(void)
{
TRISB=0X0001;
PORTB=0;
ADPCFG=0XFFFE;
ADCON1=0X2000;
ADCON2=0;
ADCON3=0X003F;
ADCHS=0X0000;
ADCSSL=0;
while(1)
{
ADCON1bits.ADON=1;
ADCON1bits.SAMP=1;
delay();
ADCON1bits.SAMP=0;
while(ADCON1bits.DONE==0)
continue;
PORTB=ADCBUF0;
ADCON1bits.DONE==0;
}
}
void delay(void)
{
unsigned long i;
for(i=50;i>0;i--);
}
Materiales necesarios
-
Ejemplos bsicos
1. Manejo de entradas y salidas
void main()
{
// 0. initialization
DDPCONbits.JTAGEN = 0; // disable JTAGport, libre PORTA
TRISA = 0x0000;
TRISB = 0xffff;
T1CON = 0x8030;
PR1 = 0xFFFF;
AD1PCFG =0XFFFF;
// 1. Loop principal
while( 1)
{
if (PORTBbits.RB2==0)
{
//1.1 todos los LED ON
PORTA = 0xff;
}
else
{
// 1.2 todos los LED OFF
PORTA = 0;
}}}
#include <p32xxxx.h>
// 256ms delay
// reduced delay for simulation
main()
{
// 0. initialization
DDPCONbits.JTAGEN = 0; // disable JTAGport, free up PORTA
TRISA = 0xff00;
T1CON = 0x8030;
PR1 = 0xFFFF;
// 1. main loop
while( 1)
{
//1.1 turn all LED ON
PORTA = 0xff;
TMR1 = 0;
while ( TMR1 < DELAY)
{
// just wait here
}