Curso en C para Pic Ccs
Curso en C para Pic Ccs
Curso en C para Pic Ccs
Los programas son editados y compilados a instrucciones mquina en el PC. El cdigo mquina es cargado del PC al sistema PIC mediante el ICD2. El cdigo es ejecutado en el PIC y puede ser depurado (puntos de ruptura, paso a paso, etc) desde el PC.
Directivas de preprocesado
Programas Bloques de programa. Siempre debe incluirse una llamada main(). Sentencias Instrucciones que definen lo que hace el programa y la secuencia de ejecucin del mismo. Comentarios Imprescindibles cdigo fuente. como documentacin del
p.e.:int i;
Los tipos de datos aceptados en C estndar son cinco: char (carcter) int (entero) float (coma flotante en 32 bits) double (coma flotante en 64 bits) void (sin valor) Las variables pueden ser locales o globales. Las variables locales slo pueden ser usadas en la funcin en que se declaran, mientras que las variables globales son compartidas por todas las funciones del programa (deben declararse fuera de cualquier funcin y antes de ser utilizadas).
Los tipos de variable short y long pueden tener detrs la palabra int sin efecto alguno.
Los nmeros negativos se codifican en complemento a 2. Cuando se opera con distintos grupos de datos en una misma expresin, se aplican una serie de reglas para resolver las diferencias. En general se produce una promocin hacia los tipos de datos de mayor longitud presentes en la expresin.
Argumentos de llamada
Los argumentos se pueden pasar a las funciones por valor o por referencia. La llamada por valor copia el argumento de llamada en el parmetro formal de la funcin (No modifica su valor en la funcin de partida). La llamada por referencia usa la direccin de la variable que se pasa a la funcin (se consigue usando punteros o arrays).
De asignacin
Aritmticos
10
Lgicos
De bits
11
Desplazamiento bit
Direccin/indireccin
En lenguaje C profesional es muy frecuente usar abreviaturas. As, por ejemplo, es ms habitual ver a += b; que a = a + b;
12
13
14
Sentencia if-else Se evala una expresin y, si es cierta, se ejecuta el primer bloque de cdigo (o sentencia 1). Si es falsa, se ejecuta el segundo.
if (expresin) sentencia 1; else sentencia 2;
15
16
17
18
19
20
21
22
23
Directivas de preprocesado ms habituales: #ASM #ENDASM #BIT id=x.y #BYTE id=x Las lneas entre estas dos directivas deben ser instrucciones ensamblador que se insertan tal y como aparecen. Se crea una variable tipo bit correspondiente al bit y del byte x en memoria. Se crea una variable y se sita en el byte x en memoria. Si ya exista esa variable, se coloca fsicamente en la posicin especificada.
24
#SEPARATE
La funcin que sigue a esta directiva se implementa de manera separada (no INLINE). De esta manera se ahorra ROM
25
#INT_xxxx #INT_GLOBAL
#PRIORITY ints
#USE DELAY (clock = frecuencia en Hz) Define la frecuencia del oscilador que se va a utilizar, que se emplea para realizar los clculos para funciones integradas de retardo.
26
27
28
29
Se puede Crear o abrir un fichero (FILE > NEW / OPEN) o crear un proyecto (conjunto de ficheros y opciones de compilacin que se utilizan en un programa). Los proyectos tienen la extensin PJT. Para crear un nuevo proyecto PROJECT > NEW > PIC WIZARD / MANUAL CREATE
30
31
32
Una vez definidas estas variables se pueden configurar y controlar los puertos mediante comandos de asignacin.A partir de este punto, estas variables permiten controlar los puertos y se pueden utilizar en sentencias de asignacin.
// 8 terminales de entrada // 8 terminales de salida // 4 pin de mayor peso OUT,4 pin de menor peso IN
33
34
bit_set (PORTC , 4); //saca un 1 por el terminal RC4 if (bit_test(PORTB,0)==1) bit_clear(PORTB,1); //si RB0 es 1 borra RB1 Tambin se puede declarar un bit de un registro con una variable mediante la directiva #BIT y trabajar directamente con la variable.
35
SW1 D1
LED-BLUE SW-SPST-MOM
R1
180
COMPILAR (F9)
MONTARLO
36
37
38
#USE FAST_IO (PUERTO) [PUERTO: A] Cada vez que se emplea una funcin output...() se saca el valor directamente al puerto, y cada vez que se emplea una funcin input...() se lee el puerto, pero no se modifican previamente el registro TRIS correspondiente. El usuario debe asegurarse de que los registros TRIS estn cargados adecuadamente antes de llamar a las funciones. Ej. #USE FAST_IO (B) #USE STANDARD_IO (PUERTO) [PUERTO: A] Cada vez que se emplea una funcin output...() se inserta cdigo previo para forzar a que el bit particular o el puerto completo sean de salida (mediante la carga del TRIS correspondiente). Si se trata de una funcin input...() se carga cdigo para definir bit o puerto completo como de entrada. sta es la opcin activa por defecto. Ej. #USE STANDARD_IO (C)
39
40
41
42
Para lee el valor del pin 7 del portB: If (*portb & 0b10000000) {..
43
44
45
46
47
48
49
50
51
52
53
54
55
56
Si se quiere trabajar con otro puerto, como por ejemplo el PORTC, se deben cambiar los datos en el fichero
57
RS RW E 4 5 6
1 2 3
U1
9 10 1 2 3 4 5 6 7 OSC1/CLKIN OSC2/CLKOUT MCLR/Vpp/THV RA0/AN0 RA1/AN1 RA2/AN2/VREFRA3/AN3/VREF+ RA4/T0CKI RA5/AN4/SS RB0/INT RB1 RB2 RB3/PGM RB4 RB5 RB6/PGC RB7/PGD RC0/T1OSO/T1CKI RC1/T1OSI/CCP2 RC2/CCP1 RC3/SCK/SCL RC4/SDI/SDA RC5/SDO RC6/TX/CK RC7/RX/DT 21 22 23 24 25 26 27 28 11 12 13 14 15 16 17 18
PIC16F876
7 8 9 10 11 12 13 14
D0 D1 D2 D3 D4 D5 D6 D7
58
RS RW E 4 5 6
1 2 3
U1
9 10 1 2 3 4 5 6 OSC1/CLKIN OSC2/CLKOUT MCLR/Vpp/THV RA0/AN0 RA1/AN1 RA2/AN2/VREFRA3/AN3/VREF+ RA4/T0CKI RA5/AN4/SS RC0/T1OSO/T1CKI RC1/T1OSI/CCP2 RC2/CCP1 RC3/SCK/SCL RC4/SDI/SDA RC5/SDO RC6/TX/CK RC7/RX/DT PIC16F876 RB0/INT RB1 RB2 RB3/PGM RB4 RB5 RB6/PGC RB7/PGD 21 22 23 24 25 26 27 28 11 12 13 14 15 16 17 18
R1
10k
7 8 9 10 11 12 13 14
D0 D1 D2 D3 D4 D5 D6 D7
59
kbd_get(); Devuelve el valor de la tecla pulsada en funcin de la tabla que tiene programada.
60
61
LCD2
LM016L
C0
1
C1 C2
VSS VDD VEE RS RW E 4 5 6 2 3
R0 R1
1 2 3
U1
9 10 1 2 3 4 5 6 7 OSC1/CLKIN OSC2/CLKOUT MCLR/Vpp/T HV RA0/AN0 RA1/AN1 RA2/AN2/VREFRA3/AN3/VREF+ RA4/T 0CKI RA5/AN4/SS RB0/INT RB1 RB2 RB3/PGM RB4 RB5 RB6/PGC RB7/PGD RC0/T 1OSO/T 1CKI RC1/T 1OSI/CCP2 21 22 23 24 25 26 27 28 11 12
4 7
5 8 0
6 9 #
62
R2
C
R3
7 8 9 10 11 12 13 14
D0 D1 D2 D3 D4 D5 D6 D7
RS RW E 4 5 6
1 2 3
U1
9 10 1 2 3 4 5 6 7 OSC1/CLKIN OSC2/CLKOUT MCLR/Vpp/T HV RA0/AN0 RA1/AN1 RA2/AN2/VREFRA3/AN3/VREF+ RA4/T 0CKI RA5/AN4/SS RB0/INT RB1 RB2 RB3/PGM RB4 RB5 RB6/PGC RB7/PGD RC0/T 1OSO/T 1CKI RC1/T 1OSI/CCP2 RC2/CCP1 RC3/SCK/SCL RC4/SDI/SDA RC5/SDO RC6/T X/CK RC7/RX/DT 21 22 23 24 25 26 27 28 11 12 13 14 15 16 17 18 C
4 7
5 8 0
6 9 #
PIC16F876
63
7 8 9 10 11 12 13 14
D0 D1 D2 D3 D4 D5 D6 D7
RS RW E 4 5 6
1 2 3
U1
9 10 1 2 3 4 5 6 7 OSC1/CLKIN OSC2/CLKOUT MCLR/Vpp/THV RA0/AN0 RA1/AN1 RA2/AN2/VREFRA3/AN3/VREF+ RA4/T0CKI RA5/AN4/SS RB0/INT RB1 RB2 RB3/PGM RB4 RB5 RB6/PGC RB7/PGD RC0/T1OSO/T1CKI RC1/T1OSI/CCP2 RC2/CCP1 RC3/SCK/SCL RC4/SDI/SDA RC5/SDO RC6/TX/CK RC7/RX/DT PIC16F876 21 22 23 24 25 26 27 28 11 12 13 14 15 16 17 18 D C
4 7
5 8 0
6 9 #
64
7 8 9 10 11 12 13 14
D0 D1 D2 D3 D4 D5 D6 D7
65
66
#INT_RTCC #INT_RB #INT_EXT #INT_AD #INT_TBE #INT_RDA #INT_TIMER1 #INT_TIMER2 #INT_CCP1 #INT_CCP2 #INT_SSP #INT_BUSCOL #INT_EEPROM
Desbordamiento de TMR0. Cambio en los pines RB<4:7>. Flanco en pin RB0. Fin de conversin A/D. Buffer de transmisin USART vaco. Dato recibido en USART. Desbordamiento de TMR1. Desbordamiento de TMR2. Captura / Comparacin en mdulo CCP1. Captura / Comparacin en mdulo CCP2. Envo / Recepcin de dato serie sncrono. Colisin de bus I2C. Escritura completa en EEPROM de datos.
(T0IF) (RBIF) (INTF) (ADIF) (TXIF) (RCIF) (TMR1IF) (TMR2IF) (CCP1IF) (CCP2IF) (SSPIF) (BCLIF) (EEIF)
67
La directiva #INT_GLOBAL. Indica que la funcin que va a continuacin sustituye todas las acciones que inserta el compilador al aceptarse una interrupcin. Slo se ejecuta lo que vaya en dicha funcin.
Ventajas de usar las directivas de interrupciones El compilador genera el cdigo necesario para saltar a la funcin que va tras esta directiva en el momento de la interrupcin. Tambin genera cdigo para salvar al principio y restituir al final el contexto, y borrar el flag que se activ con la interrupcin. El programador debe seguir encargndose de habilitar las interrupciones.
68
disable_interrupts (nivel); Hace la accin contraria a la funcin anterior, poniendo a 0 las mscaras relacionadas con la interrupcin indicada.
69
ext_int_edge (H_TO_L); Selecciona flanco de bajada para activar el flag INTF. ext_int_edge (L_TO_H); Selecciona flanco de subida para activar el flag INTF.
#INT_EXT ext_isr() { ......} enable_interrupts (INT_EXT); ext_int_edge (H_TO_L); enable_interrupts (GLOBAL); // Activa mscara INTE // Flag INTF si flanco de bajada. // Habilita mscara global de int.
/* Si entra una interrupcin por flanco de bajada en RB0, se ir a la funcin que aparece tras la directiva #INT_EXT */
disable_interrupts (INT_EXT); disable_interrupts (GLOBAL); // Desactiva interrupciones en RB0. // Desactiva todas las interrupciones.
70
SW1
SW-SPDT-MOM
D1
LED-GREEN
R1
180
COMPILAR (F9)
MONTARLO
71
72
Para que el temporizador WATCHDOG pueda llevar a cabo su misin es necesario indicarlo as con la directiva #fuses. #fuses [opciones], WDT [opciones] WDT activado #fuses [opciones], NOWDT [opciones] WDTdesactivado
73
74
(TMR0 valor)
(valor TMR0)
(equivale a CLRWDT)
75
Generar una seal cuadrada de 1KHz utilizando la interrupcin del Timer0. Con un semiperiodo de 500us 500us=4/Fosc(256-x) X=6 Con Fosc=4MHz y preescaler 1:2
#int_TIMER0 void TIMER0_isr(void) { var0++; if (var0==1) output_bit(PIN_B0,1); else output_bit(PIN_B0,0); set_timer0 (0x06); }
//se complementa la variable //para semiperiodo alto //para semiperiodo bajo //se recarga el timer0 //configuracin timer0 //carga del timer0 //habilita interrupcion timer0 //habilita interrupcin general //bucle infinito
76
77
bits 5-4 T1CKPS1:T1CKPS0: Seleccin del prescaler 00: Prescaler1:1. 10: Prescaler1:4. 01: Prescaler1:2. 11: Prescaler1:8. bit 3 T1OSCEN: Habilitacin del oscilador de TMR1 0: Apagado 1: Habilitado bit 1 TMR1CS: Reloj de TMR1 0: Reloj interno (fOSC/4). 1: Reloj externo ( en RC0). bit 2 T1SYNC: Control de la sincronizacin con el reloj externo Slo si TMR1CS=1 0: Sincronizar 1: No sincronizar bit 0 TMR1ON: Bit de encendido de TMR1 0: TMR1 apagado. 1: TMR1 encendido.
78
Configuracin del mdulo TMR1. setup_timer_1 (modo); modo: T1_DISABLED (T1CON 00h) T1_INTERNAL (T1CON 85h) T1_EXTERNAL (T1CON 87h) T1_EXTERNAL_SYNC (T1CON 83h) T1_CLK_OUT (T1CON 08h) T1_DIV_BY_1 (T1CON 00h) T1_DIV_BY_2 (T1CON 10h) T1_DIV_BY_4 (T1CON 20h) T1_DIV_BY_8 (T1CON 30h) Se pueden agrupar constantes de distintos grupos con |.
Lectura / Escritura en el mdulo TMR1. valor = get_timer1 (); set_timer1 (valor); valor: Entero de 16 bits.
79
Configurar el mdulo TMR1 para generar una temporizacin de 1s. (dos de 0,5)
0.5=4/Fosc(65536-x)P X = 3036 Con Fosc=4MHz y preescaler 1:8
while(1){ temp1s(); }
80
bits 6-3 TOUTPS3:TOUTPS0: Seleccin del postscaler 0000: Postscaler1:1 0001: Postscaler1:2 0010: Postscaler1:3 ..... 1111: Postscaler1:16 bit 2 TMR2ON: Bit de encendido de TMR2 0: Apagado 1: Habilitado bits 1:0 T2CKPS1:T2CKPS0: Seleccin del prescaler 00: Prescaler1 01: Prescaler4 1x: Prescaler16
81
82
int1 var0=0; //variable de cambio #int_TIMER2 void TIMER2_isr(void) { //Funcin Interrupcin var0++; //se complementa la variable if (var0==1) output_bit(PIN_B0,1); //para semiperiodo alto else output_bit(PIN_B0,0); //para semiperiodo bajo set_timer0 (0x7C); } //se recarga el timer0
void main() { setup_timer_2 (T2_DIV_BY_4 ,124,1); //configuracin timer2 enable_interrupts(INT_TIMER2); //habilita interrupcion timer0 enable_interrupts(global); //habilita interrupcin general while (1); //bucle infinito }
83
84
U1
9 10 1 2 3 4 5 6 7 OSC1/CLKIN OSC2/CLKOUT MCLR/Vpp/THV RA0/AN0 RA1/AN1 RA2/AN2/VREFRA3/AN3/VREF+ RA4/T0CKI RA5/AN4/SS RB0/INT RB1 RB2 RB3/PGM RB4 RB5 RB6/PGC RB7/PGD RC0/T1OSO/T1CKI RC1/T1OSI/CCP2 RC2/CCP1 RC3/SCK/SCL RC4/SDI/SDA RC5/SDO RC6/TX/CK RC7/RX/DT PIC16F876 21 22 23 24 25 26 27 28
D3
LED-GREEN
D1
D2
LED-GREEN LED-GREEN
R3
11 12 13 14 15 16 17 18 180
R1
180
R2
180
COMPILAR (F9)
MONTARLO
85
86
3. Se cambia la configuracin de la INTEXT por RB0 para detectar el siguiente Flanco de Bajada. 4. Cuando llegue el Flanco de Bajada se guarda de nuevo el valor de TIMER1.
5. Se vuelve a configurar la INTEXT por RB0 para detectar de nuevo un Flanco de Subida.
6. Con estos dos valores de TIMER1 se obtiene, expresados en PASOS de TIMER1, restando el segundo del primero, el tiempo que ha permanecido en alto el Pulso. Multiplicando dicho nmero de PASOS de TIMER1 por el tiempo que dura cada PASO (dependiente del cristal) se obtiene el Tiempo W. 7. El ancho de pulso mximo es de 65,536ms (un ciclo de TIMER1). El mnimo depender del tiempo que tarda en programa en gestionar la interrupcin y los clculos.
87
RS RW E 4 5 6
U1
1 2 3
9 10 1 2 3 4 5 6 7 OSC1/CLKIN OSC2/CLKOUT MCLR/Vpp/THV RA0/AN0 RA1/AN1 RA2/AN2/VREFRA3/AN3/VREF+ RA4/T0CKI RA5/AN4/SS RB0/INT RB1 RB2 RB3/PGM RB4 RB5 RB6/PGC RB7/PGD RC0/T1OSO/T1CKI RC1/T1OSI/CCP2 RC2/CCP1 RC3/SCK/SCL RC4/SDI/SDA RC5/SDO RC6/TX/CK RC7/RX/DT 21 22 23 24 25 26 27 28 11 12 13 14 15 16 17 18
PIC16F876
7 8 9 10 11 12 13 14
D0 D1 D2 D3 D4 D5 D6 D7
88
89
90
RS RW E 4 5 6
1 2 3
U1
9 10 1 2 3 4 5 6 7 OSC1/CLKIN OSC2/CLKOUT MCLR/Vpp/THV RA0/AN0 RA1/AN1 RA2/AN2/VREFRA3/AN3/VREF+ RA4/T0CKI RA5/AN4/SS RB0/INT RB1 RB2 RB3/PGM RB4 RB5 RB6/PGC RB7/PGD RC0/T1OSO/T1CKI RC1/T1OSI/CCP2 RC2/CCP1 RC3/SCK/SCL RC4/SDI/SDA RC5/SDO RC6/TX/CK RC7/RX/DT 21 22 23 24 25 26 27 28 11 12 13 14 15 16 17 18
PIC16F876
7 8 9 10 11 12 13 14
D0 D1 D2 D3 D4 D5 D6 D7
91