Introducción al SDCC.
Introducción a SDCC (Small Device C Compiler).
Introducción.
Dispositivos soportados:
Añadir nuevos dispositivos.
Comenzar a trabajar con SDCC y Piklab.
Variables y constantes.
Lectura y escritura de los registros.
Insertar código en ensamblator.
Introducción.
SDCC es un compilador ANSI - C de código libre y abierto, distribuido bajo licencia GPL y adaptable a distintos microcontroladores, para programar Intel 8051, Maxim 80DS390, Zilog Z80, Motorola 68HC08 y PIC16 y PIC18.Los usuarios de Ubuntu pueden instalarlo directamente de los repositorios.
Principales características:
- Corre bajo Linux, Windows y Mac.
- Maneja todo tipo de variables:
- bool
- char
- short
- int
- long
- float
- pointer
- Permite la inclusión de código ASM.
- Incluye un conjunto de optimizaciones de código standard.
Dispositivos soportados:
PIC 14:
12F: 629, 635, 675, 68316C: 432, 433
16C: 554, 557, 558
16C: 62, 620, 620a, 621, 621a, 622, 622a, 63a, 65b
16C: 71, 710, 711, 715, 717, 72, 73b, 745, 74b, 765, 770, 771, 773, 774, 781, 782
16C: 925, 926
16CR: 620a, 73, 74, 76, 77
16F: 616, 627, 627a, 628, 628a, 630, 636, 639, 648, 648a, 676, 684, 685, 687, 688, 689, 690
16F: 716, 72, 73, 737, 74, 747, 76, 767, 77, 777, 785
16F: 818, 819, 84, 84a, 87, 870, 871, 872, 873, 873a, 874, 874a, 876, 876a, 877, 877a, 88, 886, 887
16F: 913, 914, 916, 917, 946
26HV: 626, 785
PIC16:
18F: 242, 248, 252, 258, 442, 448, 452, 45818F: 1220, 1320, 13k50, 14k50
18F: 2220, 2221, 2320, 2321, 2331, 23k20
18F: 2410, 2420, 2423, 2431, 2450, 2455, 2480, 24j10, 24j50, 24k20
18F: 2510, 2515, 2520, 2523, 2525, 2550, 2580, 2585, 25j10, 25j50, 25k20
18F: 2610, 2620, 2680, 2682, 2685, 26j50, 26k20
18F: 4220, 4221, 4320, 4321, 4331, 43k20
18F: 4410, 4420, 4423, 4431, 4450, 4455, 4480, 44j10, 44j50, 44k20
18F: 4510, 4515, 4520, 4523, 4525, 4550, 4580, 4585, 45j10, 45j50, 45k20
18F: 4610, 4620, 4680, 4682, 4685, 46j50, 46k20
18F: 6520, 6527, 6585, 65j50
18F: 6620, 6622, 6627, 6680, 66j50, 66j55, 66j60, 66j65
18F: 6720, 6722, 67j50, 67j60
18F: 8520, 8527, 8585, 85j50
18F: 8620, 8622, 8627, 8680, 86j50, 86j55, 86j60, 86j65
18F: 8720, 8722, 87j50, 87j60
18F: 96j60, 96j65, 97j60
Está bastante desarrollado, incluyendo librerías para:
-
delay.
-
ADC.
-
Usart.
-
I2C.
-
funciones matemáticas.
-
etc.
Se pueden ver los include en la carpeta (Ubuntu): /usr/share/sdcc/include/pic16 (pic16=16 bit).
Añadir nuevos dispositivos.
También se pueden añadir nuevos dispositivos, generando los pic16*.h y pic16*.c necesarios a partir de los archivos de características de GPasm ya instalados, para eso hay que usar el script (Ubuntu): /usr/share/sdcc/scripts/inc2h.plCopiar el pic16*.h generado a la carpeta include correspondiente y adjuntar el archivo pic16*.c generado al proyecto o recompilar las librerías. También hay que editar el archivo pic*devices.txt que se encuentra en la carpeta include correspondiente y añadir una entrada para el nuevo PIC, con el formato:
processor 16f877, 16f877a
program 8K
data 368
eeprom 256
io 22
maxram 0x1ff
bankmsk 0x180
confsiz 1
regmap 0x180 0x00 0x02 0x03 0x04 0x0a 0x0b
regmap 0x100 0x01 0x81 0x06 0x86
memmap 0x0020 0x006f 0x000
memmap 0x0070 0x007f 0x180
memmap 0x00a0 0x00ef 0x000
memmap 0x0110 0x016f 0x000
memmap 0x0190 0x01ef 0x000
De esta forma, teniendo Gputis instalado y el datasheet del PIC, en un rato podemos dar soporte a otros dispositivos todavía no incluidos.
Comenzar a trabajar con SDCC y Piklab.
Para trabajar con SDCC lo mejor es utilizar Piklab, que es un entorno integrado de desarroyo (IDE) para aplicaciones basadas en microcontroladores de Microchip, similar a MPLAB.
Lo primero es seleccionar el compilador que queremos utilizar, en nuestro caso SDCC, el microcontrolador que queremos utilizar y el grabador. (si utilizamos un bootloader seleccionaremos Programador ICD2). Para esto vamos a Preferencias->Configuración Piklab->Archivo único y Seleccionar programador. También se pueden seleccionar el programador y el compilador en la barra inferior del entorno.
Cuando creamos un proyecto con Piklab también se puede seleccionar el compilador y el PIC que queramos utilizar, y si le decimos que nos cree una plantilla, nos genera una esqueleto básico de programa, incluyendo definición del micro y bits de configuración:
/* ----------------------------------------------------------------------- */
/* Plantilla generada por Piklab */
#include <pic16f877a.h>
/* ----------------------------------------------------------------------- */
/* Bits de configuración: adapte los parámetros a su necesidad */
typedef unsigned int word;
word at 0x2007 CONFIG = _RC_OSC & _WDT_ON & _PWRTE_OFF & _BODEN_ON & _LVP_ON & _CPD_OFF & _WRT_OFF & _DEBUG_OFF & _CP_OFF;
void isr() interrupt 0 { /* rutina de servicio de interrupciones */
/* << agregue el código de interrupción >> */
}
void main() {
/* << agregue el código >> */
}
Los bits de configuración los podemos generar, también, en Herramientas -> Generador de configuración, copiarlos al portapapeles y pegarlo en nuestro archivo fuente.
A partir de aquí podemos escribir nuestro programa.
Variables y constantes.
Los tipos de variables y sus tamaños son los siguientes:Tipo |
Tamaño |
Por defecto |
Rango con signo |
Rango sin signo |
||||||||||||||||||||||||||
bool |
1 bit |
unsigned |
- |
0, 1 |
||||||||||||||||||||||||||
char | 8 bits, 1 byte | signed |
-128, +127 |
0, +255 | ||||||||||||||||||||||||||
short | 16 bits, 2 bytes | signed | -32.768, +32.767 | 0, +65.535 | ||||||||||||||||||||||||||
int | 16 bits, 2 bytes | signed | -32.768, +32.767 | 0, +65.535 | ||||||||||||||||||||||||||
long | 32 bits, 4 bytes | signed | -2.147.483.648, +2.147.483.647 | 0, +4.294.967.295 | ||||||||||||||||||||||||||
float | 4 bytes IEEE 754 | signed | 1.175494351E-38, 3.402823466E+38 | |||||||||||||||||||||||||||
pointer | 1, 2, 3 or 4 bytes | generic |
Las constantes simbólicas funcionan como en ANSI-C, con la directiva #define, pero se puede hacer uso de los cualificadores const y code para que los datos que declaremos se almacenen en la zona de código del PIC como constantes y de esta forma podemos trabajar con con constantes de cualquier tipo de los expuestos antes, incluidos arrays y cadenas. Por ejemplo:
const int dato=5;
const char palabra[]="Hola";
O bien:
code int dato=5;
code char palabra[]="Hola";
En los dos casos dato y palabra[] se almacenan en la zona de memoria código del PIC.
El cualificador const me parece más standard.
También tenemos el cualificador volatile:
volatile char at 0x20 dato;
En este caso se indica al compilador que esa variable va a ser modificada por factores externos Por ejemplo una IRQ del sistema, otro proceso... En estos casos, el compilador asume que el valor de esa variable puede cambiar aunque el programa no lo cambia, y por tanto toma precauciones adicionales con ella (no se optimiza metiéndolo en registros, se guarda y restaura en la pila con más frecuencia, ...).
Lectura y escritura de los registros.
la sintaxis para manejar los registros del PIC consiste básicamente en referirse a ellos con su nombre en mayúsculas de la siguiente manera:
- A nivel de Byte:
- PORTB = 0x0F; PORTB= 15; PORTB = 0b00001111; PORTB = variable_char; PORTB &= v_char << x; variable_char=PORTA; ADCON0 = 0; ADCON1 = 0b10000001; ADCON0 = (fosc & 0x03) << 6; etc.
- A nivel de bit:
- RB0 = 1; RB5 = 0; ADIF = 0; ADIE = 1; PEIE = 1; etc.
Insertar código en ensamblator.
Una imagen vale más que mil palabras:
_asm
bucle:
addlw 1
btfss STATUS,0
goto bucle
_endasm;