Curso de programación en C para microcontroladores PIC

De todas formas, cuando se mezclan assembler y C, hay que tener en cuenta el estado de los registros al momento de llamar a una función en assembler desde C, porque tal vez el código en C utilizaba algunos registros. Eso dependerá del uC y tal vez del compilador, pero hay que tenerlo en cuenta.
 
Una pregunta, estoy usando XC8, me gusta la programación más universal y siempre he tenido mis momentos de discusión con los PIC y el acceso a sus registros de una forma que no es tan estándar, cosa que obliga a reescribir medio programa si pasas a otro.

Mi problema es que quería ejecutar una simple instrucción PORT ^= PIN para hacer destellar el LED, esto funciona en MSP430, AVR y ARM, pero por algún motivo, no lo hace en el PIC, no se si es cosa del compilador o que, siento que no traduce la instrucción. ¿hay algo que haga mal? básicamente solo es eso en bucle while(1) y un delay. ¿no se puede usar bitwise directamente en los puertos?
 
A mi me pasó lo mismo, y he visto que los compiladores no siempre interpretan las instrucciones de la misma forma.

En XC8 un bit toggle, me funcionó con las siguientes instrucciones:
Ejemplo para el bit RB4.
PORTBbits.RB4 ^= 1;
Y esta otra forma también funciona:
PORTBbits.RB4 = PORTBbits.RB4 ^ 1;
 

Dr. Zoidberg

Well-known-Papá Pitufo
No se en XC8, pero en CCS el modo de operacion por defecto de los puertos es algo medio raro, y para que funcione "como uno espera que lo haga" hay que cambiar el modo de operacion con la directiva #fast_io (o algo parecido)
 
creo que tiene que ver mucho con el modo de operación de los PIC, eso de tener que mover todo a W, así está el programa, en GP5 si destella, pero en GP4 no lo hace

Código:
/* 
 * File:   Main.c
 * Author: nuyel
 *
 * Created on 21 de febrero de 2017, 11:08 PM
 */

#include <stdio.h>
#include <stdlib.h>
#include <xc.h>

// PIC12F675 Configuration Bit Settings

// 'C' source line config statements

// CONFIG
#pragma config FOSC = INTRCIO   // Oscillator Selection bits (INTOSC oscillator: I/O function on GP4/OSC2/CLKOUT pin, I/O function on GP5/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF      // Power-Up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = OFF      // GP3/MCLR pin function select (GP3/MCLR pin function is digital I/O, MCLR internally tied to VDD)
#pragma config BOREN = OFF      // Brown-out Detect Enable bit (BOD disabled)
#pragma config CP = OFF         // Code Protection bit (Program Memory code protection is disabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.


/*
 * 
 */
#define LEDBIT _GPIO_GPIO4_MASK
#define _XTAL_FREQ 4000000

//__CONFIG(MCLRE_OFF & CP_OFF & BOREN_OFF & WDTE_OFF & FOSC_INTRCIO & PWRTE_ON);

void main() {
    TRISIO = 0;
    GPIO = 0;
    while(1){
        GPIObits.GP4 ^= 1;
        GP5 = 1;
        __delay_ms(500);
        GP5 = 0;
        __delay_ms(500);
    }
}
Supongo que no podré escribir un código más universal sin tener que agregar toda una HAL para manejar esas peculiaridades de los PIC, ahora recuerdo el por qué nunca quise aprender de ellos realmente.

Agrego, es un PIC12F675.
 
Cada ves mas problemáticos, normalmente cuando algo no se usa en otro microcontrolador se inicia desactivado como predeterminado, supongo que el error viene por que el PIC opera con Read-Modify-Write, con ANSEL sin configurar los pines devolvían 0 por lo que el bitwise operaba en 0 siempre.

Ahora ya funciona el PORT ^= PIN;
 
Cada ves mas problemáticos, normalmente cuando algo no se usa en otro microcontrolador se inicia desactivado como predeterminado, supongo que el error viene por que el PIC opera con Read-Modify-Write, con ANSEL sin configurar los pines devolvían 0 por lo que el bitwise operaba en 0 siempre.
Pues no es así.
En los compiladores en donde puedes manipular los registros, cómo el caso de XC Compiler, hay que tener eso en cuenta al inicializar los registros.
Mira la hoja de datos y verás cómo se inicia el registro ANSEL en un Power On Reset (POR) y en el Brown Out Detect (BOD)
12F675 - Special Function Registers (ANSEL).jpg
Entonces sin configurar ANSEL, se tendrá: 0b00001111 = 0x15, por defecto.
Lo que establece a GP4 (ANS3) como entrada análoga.
12F675 - ANSEL Register.jpg

En cambio, el compilador PCWHD de CCS, establece todo digital por defecto.
Y por lógica, al ser de alto nivel, establece muchas cosas más para una inicialización adecuada.
Sin embargo, tenemos la opción de declarar los registros y configurarlos cómo uno quiera. ;)
 
Última edición:
saben anteriormente eh trabajado con el BASIC la cual contiene la funcion SERIN la cual me permite obtener un dato serial LA CUAL LO ESPERO CIERTO TIEMPO pero en el caso del ccs no sè si tiene una funcion parecida,por que con la funcion GETCH se me queda indefinidamente esperando el dato y no me permite continuar con las tareas o saber si el pic sigue en funcionamiento
 
Si se puede, pero lo debes especificar en la configuración de #USE RS232 (Usando timeout = xxx en ms)
Lee la ayuda y busca: getc_timeout. No es una instrucción, pero encontrarás un ejemplo.
 
ahh cuando hablas de esos registros en los mensajes anteriores el ccs tiene funciones que acceden a los registros ya sea de interrupciones o flags sin embargo no creo que contenga todos los que dispone un pic ,por ello mi pregunta en el caso del ansel como puedo acceder a este registro y a los demás por que en el ccs no me deja declararlo como el programa de NUYEL el cual esta en otro compilador ,pienso que al declararlo ¿deberia estar en forma de assembler? bueno por que sino no me pueden funcionar bien los pines analógicos si los quiero utilizar como digitales ,de antemano gracias por su respuesta
 
Eso es raro, por que xc.h solo es un link al correspondiente picxxx.h de microchip y esas generalmente siempre son iguales, ANSEL es un puntero, lo que si me es incomodo es el como se declaran los valores en las cabeceras y luego no funcionan a como uno está acostumbrado, prácticamente los PIC usan un C muy diferente, de hecho he pensado en hacer mi propia cabecera para usar un C más normalizado al programar.

En mi cabecera viene como:
Código:
extern volatile unsigned char           ANSEL               @ 0x09F;
#ifndef _LIB_BUILD
asm("ANSEL equ 09Fh");
#endif
 
Cuando hablas de esos registros en los mensajes anteriores, el CCS tiene funciones que acceden a los registros ya sea de interrupciones o flags, sin embargo no creo que contenga todos los que dispone un PIC, por ello mi pregunta en el caso del ANSEL.
¿Cómo puedo acceder a este registro y a los demás?
Declarándolo de esta forma que es más sencillo que buscar su dirección:
#byte ANSEL = getenv ("SFR:ANSEL") // Nombre del registro.
Y sus bits correspondientes se pueden declarar a partir del mismo:
#bit BITX = ANSEL.X
Porque en el CCS no me deja declararlo como el programa de NUYEL, el cual está en otro compilador.
Pienso que al declararlo ¿Debería estar en forma de ensamblador?
Bueno, porque sí no, no me pueden funcionar bien los pines analógicos si los quiero utilizar como digitales.
La forma de declaración que mostré, es válida.
Pero también se pueden declarar los registros de ésta forma:
#byte PORTA = 0x05 // Dirección del registro
Y por defecto, el compilador de CCS (PCWHD) configura todo como digital al compilar.
 
ahh bien me han funcionado tus aportes, sin embargo al manipular usb-cdc solo veo ejemplos por polling
y trato de poner la #int_usb pero no me compila e investigado y hay una libreria para eso,pero al final no se como usarlo(es para comunicarme al labview por puerto serial para adquirir datos ) un ejemplo de referencia por fa