Escrito originalmente por pocher
El que lo desee que habrá un Microcursillo en C.
Codigo:
/////////////////////////////////////////////////////////////////////////
//// PARPADEO ////
//// ////
//// Ejemplo de parpadeo de todos los leds colocados en el PORTB ////
//// ////
//// Realizado por Manuel Jiménez (nocturno) para el foro TODOPIC ////
//// ////
//// 4/8/2004 ////
//// ////
/////////////////////////////////////////////////////////////////////////
#include <16F84.h>
#fuses HS,NOWDT,NOPROTECT
#use delay(clock=4000000)
#byte port_b=6
void main() {
int contador;
set_tris_b(0); //// declaramos el puerto B como salidas
port_b=0;
while (true) { //// bucle infinito
contador=200; //// retraso, 200 ciclos de 1000 microsegundos, o sea, 2 milisengundos
while(--contador!=0)
delay_us(1000);
port_b=0xff; //// activa todos los pins del puerto B
contador=200;
while(--contador!=0) //// retraso, 200 ciclos de 1000 microsegundos, o sea, 2 milisengundos
delay_us(1000);
port_b=0x00;}; //// apaga todos los pins del puerto B
}
Codigo:
////////////////////////////////////// PREPROCESADO ///////////////////////////////////
#include <16F84.h>
#use delay(clock=4000000)
#fuses XT,NOWDT,NOPUT,NOPROTECT
#use fast_io(B)
#byte PORTB = 0x06
/////////////////////////////////////// PRINCIPAL /////////////////////////////////////
void main()
{
set_tris_b(0b00000000); // Puerto B al completo configurado como salida
PORTB = 1; // Encendemos el primer led
for(;;) // Bucle infinito
{
while(PORTB != 128) // Avanzamos en una dirección
{
PORTB = PORTB * 2; // Apagamos el led que esté encendido y encendemos el siguiente
delay_ms(200); // Retardo de 200 ms
}
while(PORTB != 1) // Avanzamos en la otra dirección
{
PORTB = PORTB / 2; // Apagamos el led encendido y encendemos el anterior
delay_ms(200);
}
}
}
Codigo:
#include <16F84.h>
#fuses XT,NOWDT,NOPROTECT
#use delay(clock=4000000)
#use fast_io(B)
void main()
{
set_tris_b(0x00);
while (1)
{
output_b(0xff);
delay_ms(200);
output_b(0x00);
delay_ms(200);
}
}
Codigo:
/////////////////////////////////////////////////////////////////////////
//// PARPADEO v.2 ////
//// ////
//// Ejemplo de parpadeo de todos los leds colocados en el PORTB ////
//// ////
//// Realizado por Manuel Jiménez (nocturno) para el foro TODOPIC ////
//// ////
//// 4/8/2004 ////
//// ////
/////////////////////////////////////////////////////////////////////////
#include <16F84.h>
#fuses XT,NOWDT,NOPROTECT
#use delay(clock=4000000)
#use fast_io(B)
void main() {
int i;
while (true) { //// bucle infinito
//// en esta primera parte va encendiendo la mitad alta del puerto B y apagando la mitad baja
for (i=1;i<=24;++i) { //// va cambiando el retraso, de 1 a 24 ms
output_b(0xF0); //// encendemos la mitad del puerto B
delay_ms (i); //// hacemos una parte de la espera
output_b(0x0F); //// encendemos la otra mitad del puerto B
delay_ms ((25-i)); //// realizamos la espera complementaria
};
//// en esta segunda parte va encendiendo la mitad baja del puerto B y apagando la mitad alta
for (i=1;i<=24;++i) { //// va cambiando el retraso, de 1 a 24 ms
output_b(0x0F); //// encendemos la mitad del puerto B
delay_ms (i); //// hacemos una parte de la espera
output_b(0xF0); //// encendemos la otra mitad del puerto B
delay_ms ((25-i)); //// realizamos la espera complementaria
};
};
}
Codigo:
while (1)
{
delay_ms(200);
PORTB= ~ PORTB;
}
Escrito originalmente por pocher
Así es nocturno, además usando la directiva #use fast_io(B) el código generado en ensamblador cada vez que se encuentra con un input o un output es más corto.
Conviene que uses en fuses XT (4MHz) aunque con HS también debe funcionar.
Codigo:
set_tris_b(0);
Codigo:
port_b=0xff;
Codigo:
set_tris_b(0b00000000);
Codigo:
output_b(0xF0);
Codigo:
///////////////////////////// DIRECTIVAS DE PREPROCESADO /////////////////////////////
#include <16F876.h> // Dispositivo a utilizar
#device adc=8 // Resolución de 8 bits para el conversor ADC
#fuses HS,NOWDT,NOPROTECT,NOLVP,NOBROWNOUT // Fusibles
#use delay(clock=10000000) // Velocidad del cristal
#include "lcd.c" // Librería para el manejo del lcd.En mi caso está configurada para
// manejar el lcd desde el puerto B
// Con la siguiente directiva,se optimiza código,ya que el compilador asume que en cada momento que accedemos al puerto B,
// este está configurado adecuadamente(como entrada ó como salida) para la acción que vamos a ejercer sobre él
// Si no añadimos esta directiva,cada vez que accedamos al puerto,el compilador generará código para
// asegurar que el puerto esté configurado como salida si lo que vamos a hacer es escribir en él y viceversa
#use fast_io(B)
////////////////////////////////////// GLOBALES //////////////////////////////////////
// Estos parámetros son visibles desde todo el código,por eso se les llama globales.
// Al ser constantes,lo más práctico es declararlas aquí.
const int escala = 255; // Escala del conversor ADC (8 bits)
const float v_max = 25.2; // Voltaje máximo que entrega mi fuente
////////////////////////////////////// RUTINAS ////////////////////////////////////////
void borra_lcd()
{
lcd_putc("f"); // Con esta instrucción borramos el lcd
}
// Como se observa en la cabecera,los nombres de los parámetros no tienen por qué ser iguales
// que los de la llamada ( calcula_voltaje(valor,voltaje) ),pero sí deben estar en el mismo
// orden.
// "voltaje",al ser de entrada-salida,debe llevar el símbolo "&" delante
void calcula_voltaje(int val,float &voltaje)
{
// "escala" y "v_max" son parámetros globales,por eso son visibles dentro
// de esta rutina(y en todo el código).Si no lo fueran,al no estar declarados dentro de ella ni
// ser parámetros de entrada ó entrada-salida como los de la cabecera,se produciría
// error al compilar
voltaje = (val*v_max)/escala;
}
/////////////////////////////////////// PRINCIPAL //////////////////////////////////////
void main()
{
int valor,; // La declaración de variables SIEMPRE debe ir lo primero
float voltaje; //
set_tris_B(0b00000000); // Puerto B configurado como salida
port_b_pullups(FALSE); // Desactivamos pull-ups del puerto B
setup_adc_ports(RA0_RA1_RA3_ANALOG); //Configura A0,A1 y A3 como entradas analógicas y Vdd como voltaje de referencia
setup_adc(ADC_CLOCK_INTERNAL); // Reloj para el conversor
set_adc_channel(0); // Seleccionamos el canal 0 (RA0)
lcd_init(); // Antes de usar el lcd,hay que inicializarlo
for(;;) // Bucle infinito,que se ejecuta de forma indefinida
{
valor = read_adc(); // Capturamos señal analógica que entra por el canal previamente seleccionado (RA0)
// Esta rutina tiene a "valor" como parámetro de entrada y a "voltaje" como parámetro de entrada-salida.
// "valor",al ser de entrada,podrá ser utilizado por la rutina pero NO podrá ser modificado.
// "voltaje",al ser de entrada-salida,si puede ser modificado dentro de la rutina
calcula_voltaje(valor,voltaje); // Le mandamos el parámetro "valor" y nos devuelve "voltaje"
borra_lcd(); // Llamada a rutina que borra el lcd
printf(lcd_putc,"%f",voltaje) // Mostramos en el lcd el contenido de la variable "voltaje"
delay_ms(10); // Retardo de un 10 ms
}
}
Codigo:
#include <16F877A.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=19200, xmit=PIN_C6, rcv=PIN_C7) // Jumpers: 8 to 11, 7 to 1
void main() {
printf("Press any key to begin
"
getc();
printf("1 khz signal activated
"
while (TRUE) {
output_high(PIN_B0);
delay_us(500);
output_low(PIN_B0);
delay_us(500);
}
}
Codigo:
#include <16F877A.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#include "lcd.c"
int numero1; // Esta variable es global,por lo que ocupará 1 byte durante
// toda la ejecución
void suma()
{
// numero2 está localizada en este procedimiento,por lo que su ámbito es
// exclusivamente este procedimiento y no será visible desde ningún otro sitio.
// ¿Qué ganamos con ello? Pues es sencillo,cuando suma() es llamado desde el main,
// lo primero que ocurre es que se crea la variable numero2,que ocupará 1 byte
// en algún lugar de la memoria.Cuando suma() termina de ejecutarse,ese byte
// quedará liberado para que otro dato pueda usarlo si fuera necesario.
// Conclusión: se optimiza memoria
int numero2;
numero2 = 15;
numero1 = numero1 + numero2; // Modificamos el valor de nuestra variable global
}
void main()
{
lcd_init();
numero1 = 10; // La vemos porque es global
suma(); // Llamada al procedimiento suma()
printf(lcd_putc,"%u",numero1); // La mostramos en el lcd
for(;;) {}
}
Codigo:
#include <16F877A.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#include "lcd.c"
void suma(int num1,int num2,long int &res)
{
// "num1" y "num2" son parámetros de entrada.
// "res" es de entrada-salida.
// "num1" es un parámetro de entrada por valor.Al ser un parámetro de entrada,cuando se produce
// la llamada al procedimiento,se crea una copia de dicho valor y el procedimiento
// trabaja con dicha copia,y no con el original como cabe pensar.
// "num2" es otro parámetro pasado por valor.Al ser sólo de entrada,también se crea una copia en
// memoria con la que trabajaremos y que será destruída,al igual que "num1",cuando
// acabe la ejecución de la rutina.
// Por último nuestro parámetro de entrada-salida.Ni que decir tiene que un parámetro
// de entrada-salida JAMAS DE LOS JAMASES es pasado por valor,siempre lo es por referencia y
// deberá tener SIEMPRE como origen una variable.
// Esta vez,al ser un parámetro de entrada-salida,susceptible de ser modificado,el
// el procedimiento no hace copia ninguna y trabaja con el original de forma dinámica
// ¿qué quiere decir eso? Pues que se crea un puntero que apuntará al dato de origen y la
// rutina trabajará con ese puntero en vez de hacerlo directamente con el dato.
res = num1 + num2; // Asiganmos a "res" la suma de los otros 2 parámetros
}
void main()
{
// Declarar variables en el programa principal es casi como declararlas globales,
// por lo que tampoco es lo más óptimo.
int numero;
long int resultado;
lcd_init();
resultado = 0; // Esta acción es superflua ya que vamos a modificar su valor en breve.
// suma() lleva 3 parámetros: uno por valor y dos por referencia.
suma(numero,23,resultado); // Llamada al procedimiento suma()
// "resultado" ha sido modificado y devuelto por el procedimiento suma()
printf(lcd_putc,"%lu",resultado); // La mostramos en el lcd
for(;;) {}
}
Codigo:
#include <16F877A.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#include "lcd.c"
void suma(int num1,int num2,long int *res)
{
// "num1" y "num2" son parámetros de entrada.
// "res" es de entrada-salida.
// "num1" es un parámetro de entrada por referencia,ya tiene como referencia
// a una variable ("numero" del main).Al ser un parámetro de entrada,cuando se produce
// la llamada al procedimiento,se crea una copia de dicho parámetro y el procedimiento
// trabaja con dicha copia,y no con el original como cabe pensar.
// "num2" es un parámetro pasado por valor,ya que tiene como origen un valor
// constante(23),y no una variable.Al ser sólo de entrada,también se crea una copia en
// memoria con la que trabajaremos y que será destruída,al igual que "num1",cuando
// acabe la ejecución de la rutina.
// Por último nuestro parámetro de entrada-salida.Ni que decir tiene que un parámetro
// de entrada-salida JAMAS DE LOS JAMASES puede ser pasado por valor.
// Deberá tener SIEMPRE como origen una variable.
// Esta vez,al ser un parámetro de entrada-salida,susceptible de ser modificado,el
// el procedimiento no hace copia ninguna y trabaja con el original.
*res = num1 + num2; // Asiganmos a "res" la suma de los otros 2 parámetros
}
void main()
{
// Declarar variables en el programa principal es casi como declararlas globales,
// por lo que tampoco es lo más óptimo.
int numero;
long int resultado;
lcd_init();
resultado = 0; // Esta acción es superflua ya que vamos a modificar su valor en breve.
// suma() lleva 3 parámetros: uno por valor y dos por referencia.
suma(numero,23,&resultado); // Llamada al procedimiento suma()
// "resultado" ha sido modificado y devuelto por el procedimiento suma()
printf(lcd_putc,"%lu",resultado); // La mostramos en el lcd
for(;
{}
}
Codigo:
struct lcd_pin_map {
BOOLEAN unused; // RB0 (sin conectar a nada)
BOOLEAN rs; // RB1
BOOLEAN rw; // RB2
BOOLEAN enable; // RB3
int data : 4; // RB4 a RB7
} lcd;
Codigo:
////////////////////////////////////// PREPROCESADO ///////////////////////////////////
#include <16F876.h>
#use delay(clock=20000000)
#fuses HS,NOWDT,NOPUT,NOLVP,NOBROWNOUT,NOWRT
#include "lcd.c"
#use fast_io(B)
#use fast_io(C)
////////////////////////////////////// RUTINAS ///////////////////////////////////////
int entrada_activa()
{
if(input(PIN_C0))
{
// Esto se ejecuta si RC0 está a 1
return(0); // Devolvemos un 0
}else if(input(PIN_C1)) {
// Esto se ejecuta si RC1 está a 1
return(1); // Devolvemos un 1
}else if(input(PIN_C2)) {
// RC2 está a 1
return(2); // Devolvemos un 2
}else if(input(PIN_C3)) {
// RC3 está a 1
return(3);
}else if(input(PIN_C4)) {
// RC4 está a 1
return(4);
}else if(input(PIN_C5)) {
// RC5 está a 1
return(5);
}else if(input(PIN_C6)) {
// RC6 está a 1
return(6);
}else if(input(PIN_C7)){
// RC7 está a uno
return(7);
}else {
// Si entramos aquí es que no se dió ninguno de los casos anteriores (todas a 0)
return(8);
}
}
////////////////////////////////////// PRINCIPAL //////////////////////////////////////
void main()
{
int pin_activo;
set_tris_c(0xff); // Puerto C configurado como entrada
lcd_init();
pin_activo = entrada_activa(); // Asiganmos a "pin" el valor que devuelve entrada_activa()
while(TRUE) // Bucle infinito
{
if(entrada_activa() > 7) // Usamos directamente el valor que nos retorne la función
{
// entrada_activa() devolvió el valor 8
printf(lcd_putc,"No hay entradas activas");
}else {
// En otro caso...
printf(lcd_putc,"El pin %u está a 1",entrada_activa()); // Mostramos qué pin está a 1
}
}
}
Codigo:
////////////////////////////////////// PREPROCESADO ///////////////////////////////////
#include <16F876.h>
#use delay(clock=20000000)
#fuses HS,NOWDT,NOPUT,NOLVP,NOBROWNOUT,NOWRT
#include "lcd.c"
#use fast_io(B)
////////////////////////////////////// RUTINAS ///////////////////////////////////////
BOOLEAN a_mayor_que_b(int a,int b)
{
BOOLEAN mayor; // Esta es la variable que vamos a devolver
mayor = FALSE; // Las variables booleanas es bueno inicializarlas con algún valor
if(a >= b)
{
// "a" es mayor o igual que "b"
mayor = TRUE;
}else {
// "a" es menor que "b"
// Aquí no necesitamos hacer mayor=FALSE ya que hemos inicializado "mayor" a FALSE
}
return(mayor);
}
////////////////////////////////////// PRINCIPAL //////////////////////////////////////
void main()
{
int a,b;
a = 50;
b = 30;
if(a_mayor_que_b(a,b))
{
// La función ha devuelto TRUE
output_high(PIN_B1); // Por ejemplo :)
}else if(!a_mayor_que_b(a,b)) {
// La función ha devuelto FALSE
output_high(PIN_B2);
}
}
Codigo:
///////////////////////////////////// PREPROCESADO ////////////////////////////////////
#include <16F876.h>
#use delay(clock=20000000)
#fuses HS,NOWDT,NOPUT,NOLVP,NOBROWNOUT,NOWRT
#include "lcd.c"
#use fast_io(B)
////////////////////////////////////// GLOBALES ///////////////////////////////////////
int (*funcion) (int,int); // Puntero a una función que lleva dos parámetros enteros
// y que devuelve un entero
////////////////////////////////////// RUTINAS ///////////////////////////////////////
int suma(int a,int b)
{
return(a+b);
}
int resta(int a,int b)
{
return(a-b);
}
//////////////////////////////////// PRINCIPAL //////////////////////////////////////
void main()
{
int resultado;
lcd_init();
funcion = suma; // Hacemos que el puntero apunte a la función "suma"
resultado = funcion(10,2); // Asignamos a "resultado" el valor que devuelve la función
// apuntada por el puntero "funcion"
printf(lcd_putc,"La suma es: %u",resultado); // Al lcd
funcion = resta; // Ahora el puntero apunta a "resta"
resultado = funcion(10,2); // Asignamos
lcd_gotoxy(1,2); // Segunda línea del lcd
printf(lcd_putc,"La resta es: %u",resultado); // Al lcd
for(;;) {}
}
Codigo:
enum tasks {taskA, taskB, taskC};
run_task(tasks task_to_run) {
switch(task_to_run) {
case taskA : taskA_main(); break;
case taskB : taskB_main(); break;
case taskC : taskC_main(); break;
}
}
Codigo:
///////////////////////////////////// PREPROCESADO ////////////////////////////////////
#include <16F876.h>
#use delay(clock=10000000)
#fuses HS,NOWDT,NOPUT,NOLVP,NOBROWNOUT,NOWRT
#include "lcd.c"
#use fast_io(B)
////////////////////////////////////// CABECERAS ////////////////////////////////////
// Aquí declaramos todos los procedimientos a excepción del "main"
// Cuando el código comienza a adquirir unas dimensiones considerables,una ventaja
// que esto tiene es poder ordenar las rutinas por orden alfabético para poder
// localizarlas con facilidad.
// Las cabeceras también las ordenamos por orden alfabético
void fulanito(int var);
float manolito(int a,int b);
void pepito(); // OJO! No olvidar el ";"
////////////////////////////////////// GLOBALES ///////////////////////////////////////
int var_global;
////////////////////////////////////// RUTINAS ///////////////////////////////////////
void fulanito(int var)
{
// "pepito()" está implementada después del algoritmo llamante,pero
// al estar ya declarado,será visible aunque esté después.
pepito();
}
float manolito(int a,int b)
{
return(a/b);
}
void pepito()
{
printf(lcd_putc,"bla bla bla");
}
//////////////////////////////////// PRINCIPAL //////////////////////////////////////
void main()
{
// ¿Cual puede ser el motivo por el cúal el "main" está siempre lo último? :)
}
Codigo:
///////////////////////////////////// PREPROCESADO ////////////////////////////////////
#include <16F876.h>
#use delay(clock=10000000)
#fuses HS,NOWDT,NOPUT,NOLVP,NOBROWNOUT,NOWRT
#define use_portb_lcd TRUE
#include "lcd.c"
////////////////////////////////////// CONSTANTES /////////////////////////////////////
const unsigned int NUM_SENSORES = 5;
//////////////////////////////////////// TIPOS ////////////////////////////////////////
typedef int Tsensores[NUM_SENSORES];
// Esto es un array de 5 enteros(int es el tipo base).Puede albergar,pues eso,5 valores
// individuales comprendidos entre 0-255.
// Tsensores es el nombre que le hemos puesto al tipo,la T se suele poner para
// tener constancia,por si lo vemos en alguna parte del código,de que se trata de un
// tipo definido de usuario.
///////////////////////////////////// CABECERAS ///////////////////////////////////////
int temperatura(int canal);
/////////////////////////////////////// RUTINAS ///////////////////////////////////////
int temperatura(int canal)
{
// Esta rutina se supone que captura un valor en el canal adc que indique el
// parámetro canal (0,1,2,3 ó 4),lo procesa y devuelve un valor de temperatura.
int valor;
// blablabla...
return(valor);
}
////////////////////////////////////// PRINCIPAL //////////////////////////////////////
void main()
{
int j;
Tsensores sensores; // Array de 5 posiciones,cada posición es un entero.
// La forma de acceder a cada uno de los elementos del array es usando su número de
// orden (índice) dentro de él.
// No olvidar que el primer elemento de un array tiene SIEMPRE índice 0.
// Si el array tiene dimensión 5 -> primer elemento,índice 0
// -> último elemento,índice 4
for(j = 0; j <= 4; j++) // Vamos a poner todos los valores a 0
{
sensores[j] = 0; // Así se accede al elemento de un array,mediante su índice.
}
j = 0; // Después del for,el valor de j es indeterminado,así que
// la ponemos a 0 para afrontar el siguiente bucle.
while(j < 5) // Bucle infinito
{
// Capturamos la temperatura de todos los sensores continuamente,con un intervalo
// de tiempo de un segundo entre sensor y sensor.
// Se ve la correspondencia entre el número del canal y la posición dentro del array.
sensores[j] = temperatura(j);
delay_ms(1000);
j++;
if(j==5) // Cuando j=5,la ponemos otra vez a 0 para no salir del bucle y empezar de nuevo
{
j = 0;
}
}
}
Codigo:
///////////////////////////////////// PREPROCESADO ////////////////////////////////////
#include <16F876.h>
#use delay(clock=10000000)
#fuses HS,NOWDT,NOPUT,NOLVP,NOBROWNOUT,NOWRT
#define use_portb_lcd TRUE
#include "lcd.c"
//////////////////////////////////////// TIPOS ////////////////////////////////////////
struct Tregistro {
int edad;
float estatura;
boolean casado;
};
// Nuestro registro contiene tres campos,una variable booleana llamada "casado",
// una entera llamada "edad" y una real llamada "estatura".
////////////////////////////////////// PRINCIPAL //////////////////////////////////////
void main()
{
struct Tregistro juan,antonio; // Creamos 2 variables tipo registro.
// Para acceder a un campo de un registro,se pone el nombre de la variable
// registro seguido de un punto y el nombre del campo.
juan.edad = 28; // Llenamos los registros con datos
juan.estatura = 1.75; //
juan.casado = TRUE; //
antonio.edad = juan.edad; //
antonio.estatura = 1.81; //
antonio.casado = FALSE; //
for(;;) {}
}
Codigo:
///////////////////////////////////// PREPROCESADO ////////////////////////////////////
#include <18F258.h>
#use delay(clock=10000000)
#fuses HS,NOWDT,NOPUT,NOLVP,NOBROWNOUT,NOWRT
#define use_portb_lcd TRUE
#include "lcd.c"
//////////////////////////////////////// TIPOS ////////////////////////////////////////
struct Tregistro { // Este es el más pequeño
int edad;
float estatura;
boolean casado;
};
typedef struct Tregistro TmatrizRegistros[5][5]; // Matriz de 25 registros
// Este es el mediano
struct TregistroMatrices { // Este es el que los contiene a todos
TmatrizRegistros hombres;
TmatrizRegistros mujeres;
};
////////////////////////////////////// PRINCIPAL //////////////////////////////////////
void main()
{
struct TregistroMatrices poblacion;
poblacion.mujeres[1][3].edad = 18;
for(;;) {}
}
Codigo:
#include <16F877A.h>
#use delay(clock=20000000)
#fuses HS,NOWDT,NOPUT,NOLVP,NOBROWNOUT,NOWRT
#define use_portb_lcd TRUE
#include "lcd.c"
#include "string.h"
// Esta función la he tenido que incluir aquí porque si hacía un include de su librería y la llamaba me fallaba. Pegándola aquí funciona bien.
unsigned int32 _Randseed = 1;
long rand(void)
{
_Randseed = _Randseed * 1103515245 + 12345;
return ((unsigned long)(_Randseed >> 16) % 93);
}
// Esta función recibe dos cadenas de caracteres y sus longitudes, y las representa en un LCD 2x16 con un efecto parecido a Matrix
void matrix (char *cadena1, char *cadena2, int largo1, int largo2)
{
int i,j;
// durante 15 ciclos mostramos caracteres aleatorios
for (i=0;i<=15;i++) {
for (j=1;j<=16;j++) { // va pasando por cada columna del LCD
lcd_gotoxy (j,1); // pone el cursor en la primera fila y la columna j
printf (lcd_putc,"%C",rand()+161); // escribe un caracter aleatorio comprendido entre el 161 y el 253
lcd_gotoxy (j,2); // pone el cursor en la segunda fila y la columna j
printf (lcd_putc,"%C",rand()+161); // escribe un caracter aleatorio comprendido entre el 161 y el 253
};
delay_ms (100); // y esperamos una décima de segundo para que dé tiempo a verlo
};
// en los siguientes 16 ciclos vamos desvelando los caracteres correctos en posición par
for (i=1;i<=16;++i) { // repetimos 16 veces para acompañar el efecto Matrix
for (j=0;j<=15;++j) { // pero ya vamos cumplimentando los 16 caracteres, del 0 al 15
if (j<=i & bit_test (j,0)) { // sólo escribiremos el carácter si el bucle principal ha pasado por aquí y está en posición par
lcd_gotoxy (j+1,1); // vamos allí, en la primera fila
if (j<largo1) // si no hemos sobrepasado el tamaño de la cadena
printf (lcd_putc,"%C",cadena1[j]); // escribimos la letra que corresponda
else // y si no
printf (lcd_putc," " // un espacio en blanco
lcd_gotoxy (j+1,2); // vamos allí, en la segunda fila
if (j<largo2) // si no hemos sobrepasado el tamaño de la cadena
printf (lcd_putc,"%C",cadena2[j]); // escribimos la letra que corresponda
else // y si no
printf (lcd_putc," " // un espacio en blanco
} else { // si aún no hemos llegado o se trata de una posición impar
lcd_gotoxy (j+1,1); // en la primera fila
printf (lcd_putc,"%C",rand()+161); // escribimos carácter matrix aleatorio
lcd_gotoxy (j+1,2); // y en la segunda fila
printf (lcd_putc,"%C",rand()+161); // escribimos carácter matrix aleatorio
};
};
delay_ms(100); // y esperamos una décima de segundo para que dé tiempo a verlo
};
// y en los siguientes 16 ciclos vamos desvelando los caracteres correctos en cualquier posición
// aunque para el espectador sólo son nuevos los impares
// no comento esta rutina porque es igual que la anterior, exceptuando la condición de la paridad
for (i=1;i<=16;++i) {
for (j=0;j<=15;++j) {
if (j<=i) {
lcd_gotoxy (j+1,1);
if (j<largo1)
printf (lcd_putc,"%C",cadena1[j]);
else
printf (lcd_putc," "
lcd_gotoxy (j+1,2);
if (j<largo2)
printf (lcd_putc,"%C",cadena2[j]);
else
printf (lcd_putc," "
} else {
lcd_gotoxy (j+1,1);
printf (lcd_putc,"%C",rand()+161);
lcd_gotoxy (j+1,2);
printf (lcd_putc,"%C",rand()+161);
};
};
delay_ms (100);
};
}
void main()
{
char cad1[16],cad2[16];
output_high (PIN_B0); // es un led que se enciende al arrancar, y me sirve para señalar si ha habido un reset
delay_ms (300); // lo mantengo encendido 3 décimas de segundo
output_low (PIN_B0); // y lo apago
lcd_init(); // inicializamos la pantalla
strcpy (cad1,"EFECTO MATRIX" // preparamos las strings a mostrar
strcpy (cad2,"(por Nocturno)"
matrix (cad1,cad2,strlen(cad1),strlen(cad2)); // e invocamos a la función
// no he conseguido calcular las longitudes de las strings en la función, por eso hago el cálculo en la llamada
sleep(); // ponemos el bichito a dormir la siesta
}
Codigo:
#define RAND_MAX 255
#define LONG_CADENA 14
unsigned int32 semilla = 1;
long rand(unsigned int maximo)
{
semilla = semilla * 1103515245 + 12345;
return ((unsigned long)(semilla >> 16) % maximo);
}
void srand(unsigned int32 seed)
{
semilla = seed;
}
Escrito originalmente por pocher
Muy sencillo, cogeros un libro con ejercicios en ensamblador (el de Angulo podría servir) y empezais por los primeros pasándolos a C.
Podeis plantear aquí el enunciado y su resolución.
Escrito originalmente por MGLSOFT
En la pagina de Angulo encontraran los ejemplos en C, los mismos que hay en assembler...
Codigo:
#include <16F877A.h>
#use delay(clock=20000000)
#fuses HS,NOWDT,NOPUT,NOLVP,NOBROWNOUT,NOWRT
#define use_portb_lcd TRUE
#include "lcd.c"
#include "math.h"
float lee_acelerometro (int Eje, int Decimales) { // Según Eje sea 0 o 1 se lee el pin D0 o D1
// Decimales indica la resolución del resultado
// El resultado siempre será un porcentaje
int32 alto=0, bajo=0, j;
float Resultado;
int i;
for (i=0;i<10;++i) { // se lee 10 veces, para evitar márgenes de error (se puede modificar)
// si es necesaria mayor frecuencia
if (Eje) {
while( input(PIN_D0)); // esperamos a que baje la señal de entrada
while( !input(PIN_D0)); // esperamos a que suba la señal de entrada
while( input(PIN_D0)) { // mientras esté arriba vamos contando en alto
alto++;
} ;
while( !input(PIN_D0)) { // y mientras esté abajo vamos contando en bajo
bajo++;
};
} else {
while( input(PIN_D1) );
while( !input(PIN_D1) );
while( input(PIN_D1) ) {
alto++;
} ;
while( !input(PIN_D1) ) {
bajo++;
};
};
};
Resultado = (((float)alto/((float)alto+(float)bajo))-0.43)*10000/9; // el resultado es alto/(alto+bajo),
// las constantes son ajustes de escala y calibración del acelerómetro
Resultado = floor(Resultado*pow(10,Decimales))/pow(10,Decimales); // Formateamos el resultado con nº decimales
return (Resultado); // no he podido hacer toda la operación aquí porque me decía "Expression too complex"
}
void main()
{
lcd_init();
output_high (PIN_B0); // es un led que se enciende al arrancar, y me sirve para señalar si ha habido un reset
delay_ms (300); // lo mantengo encendido 3 décimas de segundo
output_low (PIN_B0); // y lo apago
while (TRUE) {
printf (lcd_putc,"fLectura: %f%%",lee_acelerometro(0,2)); // muestra el resultado de la lectura del eje 0
lcd_gotoxy (1,2);
printf (lcd_putc,"Lectura: %f%%",lee_acelerometro(1,2)); // muestra el resultado de la lectura del eje 1
output_high (PIN_B0);
delay_ms (100); // parpadea para saber que ha pasado por el bucle
output_low (PIN_B0);
};
}
Escrito originalmente por nocturno66Escrito originalmente por MGLSOFT
En la pagina de Angulo encontraran los ejemplos en C, los mismos que hay en assembler...
Marcos, ¿cuál es la página de Angulo?
Codigo:
#include <16f84a.h>
#fuses XT, NOWDT, NOPROTECT
#use delay(clock=4000000)
#use rs232(baud=2400, xmit=PIN_A1, rcv=PIN_A0)
#use fast_io (a)
#use fast_io (b)
SET_TRIS_A(0b00000001);
SET_TRIS_B(0x00);
int dato,conteo;
void main(void)
{
output_b(0x00);
output_a(0x00);
while(1)
{
for(conteo=0x61;conteo<=0x7a;conteo++)
{
dato=conteo;
putc(dato);
delay_ms(1000);
}
}
}
Pero queda bien ponerlo y es un buen h bito de programaci¢n. Las maneras, el protocolo, el procedimiento, ... ya sabes.





Lo malo es que no he bajado la última versión de Proteus y no me lo corre 



Escrito originalmente por pic-chi
Hola
la funcion main() puede llevar main(void) o void main(), pues asi lo he visto
Kien me puede aclarar esto, por qué se usa void, para que sirve, y por qué a veces simplemente no se usa??
Gracias

Escrito originalmente por MGLSOFT
Segun creo si declaras VOID Funcion (VOID) o Funcion () es exactamente lo mismo, en apariencia el modificador VOID es el tomado por default cuando no existe otro modificador declarado.


.
{}



;
;Escrito originalmente por pocher
Son estas:
RAND()
Syntax:
re=rand()
Parameters:
None
Returns:
A pseudo-random integer.
Function:
The rand function returns a sequence of pseudo-random integers in the range of 0 to RAND_MAX.



Escrito originalmente por Modulay
Nocturno,no conocía ese método.Probaremos a ver que tal va.
migsantiago,he simulado tu archivo y no se iluminan los led.
A ver si alguien más lo puede probar:
http://personal.auna.com/asencio5/Ejemplos%20C/I2C/
A propósito ¿como funciona eso del archivo bin? me interesa el tema
David,si no me equivoco,para calcular el tiempo de interrupción del timer 0 (8 bits),sería una cosa así:
Frecuencia interrupción timer 0 = Fosc / [4 x preescaler x (256 - valor de carga)]
Siendo:
Fosc = frecuencia del cristal
preescaler = valor del preescaler
valor de carga = valor con el que cargas el timer tras cada interrupción
He colgado un ejemplo en el enlace que te puede venir bien:
http://personal.auna.com/asencio5/Ejemplos%20C/TIMER/
)


cuando estaba contento que entendia algo de asm encontre la posibilidad de hacerlo con c .De programacion c c++ se alguito nomas
me baje el HI-TECH DEMO y el PCW (PIC C compiler DEMO) y encontre que es mas completo el primero en cuanto a librerias para cosas como calculos y manejo de strings pero poco para cosas como LCD .en cambio el segundo tiene lo contrario .se podria encontrar librerias para el primero ? 
Escrito originalmente por carlyvalente
Alguno me puede recomendar un buen link online para aprender C de micros?
Si es en ingles da igual.
Gracias.
, aunque por ahi hay bastantes ejemplos con HiTech usando dispositivos poco usados(de ahi obtendrias la libreria)


, por favor dime cual es el que te falla.
//Bucle infinito

.

,migsantiago,aunque creo q te lo podrán explicar mejor Lager o manex.
//Bucle infinito
*/
*/
Codigo:
.................... output_b(150);
001F: MOVLW 96
0020: MOVWF 06
....................
.................... PORTB=120;
0021: MOVLW 78
0022: MOVWF 06


solo queria participar. Es que me expreso de una manera que releida da la sensacion 
.
.

;
;Codigo:
/////////////////////////////////////////////////////////////////////////
//// EX_STWT.C ////
//// ////
//// This program uses the RTCC (timer0) and interrupts to keep a ////
//// real time seconds counter. A simple stop watch function is ////
//// then implemented. ////
//// ////
//// Configure the CCS prototype card as described below. ////
//// ////
//// This example will work with the PCM and PCH compilers. The ////
//// following conditional compilation lines are used to include a ////
//// valid device for each compiler. Change the device, clock and ////
//// RS232 pins for your hardware if needed. ////
/////////////////////////////////////////////////////////////////////////
//// (C) Copyright 1996,2003 Custom Computer Services ////
//// This source code may only be used by licensed users of the CCS ////
//// C compiler. This source code may only be distributed to other ////
//// licensed users of the CCS C compiler. No other use, ////
//// reproduction or distribution is permitted without written ////
//// permission. Derivative programs created using this software ////
//// in object code form are not restricted in any way. ////
/////////////////////////////////////////////////////////////////////////
#if defined(__PCM__)
#include <16F877.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7) // Jumpers: 8 to 11, 7 to 12
#elif defined(__PCH__)
#include <18F452.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7) // Jumpers: 8 to 11, 7 to 12
#endif
#define INTS_PER_SECOND 76 // (20000000/(4*256*256))
BYTE seconds; // A running seconds counter
BYTE int_count; // Number of interrupts left before a second has elapsed
#int_rtcc // This function is called every time
void clock_isr() { // the RTCC (timer0) overflows (255->0).
// For this program this is apx 76 times
if(--int_count==0) { // per second.
++seconds;
int_count=INTS_PER_SECOND;
}
}
void main() {
BYTE start;
int_count=INTS_PER_SECOND;
set_timer0(0);
setup_counters( RTCC_INTERNAL, RTCC_DIV_256 | RTCC_8_BIT);
enable_interrupts(INT_RTCC);
enable_interrupts(GLOBAL);
do {
printf("Press any key to begin.
"
getc();
start=seconds;
printf("Press any key to stop.
"
getc();
printf("%u seconds.
",seconds-start);
} while (TRUE);
}
Codigo:
/// Descripcion
/// 1. Comunica con DAC, saca un valor (400) y enciende led correspondiente
/// 2. Espera dos minutos
/// 3. Comunica con DAC, saca un valor (340) y enciende led correspondiente
/// 4. Espera a las entradas: conmutador de tres posiciones (arriba, inicial, abajo)
/// 5. Arriba: Comunica con DAC, saca un valor superior y enciende led correspondiente
/// Abajo: Comunica con DAC, saca un valor inferior y enciende led correspondiente
/// Configuracion ///
#include <16F87.h> // Libreria del pic
#fuses HS,NOPUT,NOWDT,NOWRT,NOPROTECT,NOLVP,NOBROWNOUT // Fusibles ???
#use delay(clock=20000000) // Velocidad reloj
#use I2C(MASTER,SDA=PIN_B1,SCL=PIN_B4,SLOW,RESTART_WDT) // Comunicacion serie ???
#use fast_io(B) // Da por buena la configuaracion del puerto B
#use fast_io(A) // Da por buena la configuaracion del puerto A
#byte port_a=5 // ???
#byte port_b=6 // ???
port_a_pullups(FALSE); // Desactiva pull-ups del puerto A
port_b_pullups(FALSE); // Desactiva pull-ups del puerto B
/// Programa Principal ///
void main()
{
// Declaracion de Variables
int nivel;
int const dac_alta[6]={0x38,0x39,0x39,0x3A,0x3B,0x3C};
int const dac_baja[6]={0x00,0x6A,0xFD,0xAB,0x6E,0x4F};
// Configura puertos
set_tris_b(0x00); // Puerto B configurado como salida
output_b(0x00); // Limpia B
set_tris_a(0x02); // Puerto A configurado RA6 y RA7 como entrada y el resto como salida
output_a(0x00); // Limpia A
// Inicio
nivel=0x00;
output_low(PIN_B0); // Comunica con DAC
i2c_start();
i2c_write(dac_baja[nivel]);
i2c_write(dac_alta[nivel]); // Saca el valor para 400V
i2c_stop();
port_a=nivel; // Enciende el led rojo de RA0
nivel++;
delay_ms(120000); // Espera 2 minutos
output_low(PIN_B0); // Comunica con DAC
i2c_start();
i2c_write(dac_baja[nivel]);
i2c_write(dac_alta[nivel]); // Saca el valor para 340V
i2c_stop();
port_a=nivel; // Enciende el led amarillo de RB1
while(input(PIN_A6) || input(PIN_A7)); // Espera si el conmutador no está en posición inicial
while(TRUE) // Bucle infinito
{
if((nivel>1) && (input(PIN_A6))) // Si no esta dando el máximo y el conmutador arriba
{
nivel++;
output_low(PIN_B0); // Comunica con DAC
i2c_start();
i2c_write(dac_baja[nivel]);
i2c_write(dac_alta[nivel]);
i2c_stop();
port_a=nivel; // Enciende el led amarillo del nivel correspondiente
while(input(PIN_A6)); // Espera a que el conmutador pase a posición inicial
}
if((nivel<5) && (input(PIN_A7))) // Si no esta dando el minimo y el conmutador abajo
{
nivel--;
output_low(PIN_B0); // Comunica con DAC
i2c_start();
i2c_write(dac_baja[nivel]);
i2c_write(dac_alta[nivel]);
i2c_stop();
port_a=nivel; // Enciende el led amarillo del nivel correspondiente
while(input(PIN_A7)); // Espera a que el conmutador pase a posición inicial
}
}
}
Codigo:
/// Descripcion del programa
/// 1. Comunica con DAC, saca un valor (400) y enciende led correspondiente
/// 2. Espera dos minutos
/// 3. Comunica con DAC, saca un valor (340) y enciende led correspondiente
/// 4. Espera a las entradas: conmutador de tres posiciones (arriba, inicial, abajo)
/// 5. Arriba: Comunica con DAC, saca un valor superior y enciende led correspondiente
/// Abajo: Comunica con DAC, saca un valor inferior y enciende led correspondiente
/// Configuracion ///
#include <16F87.h> // Libreria del pic
#fuses HS,NOPUT,NOWRT,NOPROTECT,NOLVP,NOBROWNOUT // Fusibles
#use delay(clock=20000000) // Velocidad reloj
#use I2C(MASTER,SDA=PIN_B1,SCL=PIN_B4) // Comunicacion serie
#use fast_io(B) // Da por buena la configuaracion del puerto B
#use fast_io(A) // Da por buena la configuaracion del puerto A
/// Programa Principal ///
void main()
{
// Declaracion de Variables
int nivel;
int const tension[6]={0x1800,0x196A,0x19FD,0x1AAB,0x1B6E,0x1C4F};
// Configura puertos
set_tris_b(0x00); // Puerto B configurado como salida
output_b(0x00); // Limpia B
set_tris_a(0x02); // Puerto A configurado RA6 y RA7 como entrada y el resto como salida
output_a(0x00); // Limpia A
// Inicio
nivel=0x00;
output_low(PIN_B0); // Comunica con DAC
i2c_start();
i2c_write(tension[nivel]>>8); // Escribe la parte alta del dato (400)
i2c_write(tension[nivel]); // Escribe la parte baja del dato (400)
i2c_stop();
output_a(nivel); // Enciende el led rojo de RA0
nivel++;
delay_ms(120000); // Espera 2 minutos
output_low(PIN_B0); // Comunica con DAC
i2c_start();
i2c_write(tension[nivel]>>8); // Escribe la parte alta del dato (340)
i2c_write(tension[nivel]); // Escribe la parte baja del dato (340)
i2c_stop();
output_a(nivel); // Enciende el led amarillo de RB1
while(input(PIN_A6) || input(PIN_A7)); // Espera si el conmutador no está en posición inicial
while(TRUE) // Bucle infinito
{
if((nivel>1) && (input(PIN_A6))) // Si no esta dando el máximo y el conmutador arriba
{
nivel++;
output_low(PIN_B0); // Comunica con DAC
i2c_start();
i2c_write(tension[nivel]>>8); // Escribe la parte alta del dato
i2c_write(tension[nivel]); // Escribe la parte baja del dato
i2c_stop();
output_a(nivel); // Enciende el led amarillo del nivel correspondiente
while(input(PIN_A6)); // Espera a que el conmutador pase a posición inicial
}
if((nivel<5) && (input(PIN_A7))) // Si no esta dando el minimo y el conmutador abajo
{
nivel--;
output_low(PIN_B0); // Comunica con DAC
i2c_start();
i2c_write(tension[nivel]>>8); // Escribe la parte alta del dato
i2c_write(tension[nivel]); // Escribe la parte baja del dato
i2c_stop();
output_a(nivel); // Enciende el led amarillo del nivel correspondiente
while(input(PIN_A7)); // Espera a que el conmutador pase a posición inicial
}
}
}
Hace poco que he empezado con esto de la programación de PIC"s y he programado una cosilla que alomejor os parece interesante, es mi primer aplicación realizada para un PIC y alomejor hay gente que le parece interesante. Os pego aquí el codigo. Es un pequeño ejemplo de utilización de EEPROM externas y cadenas de caracteres, el circuito esta probado con PROTEUS y funciona a la perfección.Codigo:
//*******************************************************************//
// Nombre : Strings.c
// Autor : Albert Fabregat Hernando (|RooT|)
// Descripción : Manejo de cadenas de caracteres (Strings) y
// su almacenamiento en EEPROM
//
//*******************************************************************//
#include <16F876.h> // Utilizaremos en PIC16F76
#fuses HS,NOWDT,NOPROTECT,NOLVP,NOBROWNOUT // Fusibles
#use delay(clock=10000000) // Velocidad del cristal
#define use_portb_lcd TRUE // Para usar el puerto B en este PIC ya que no tiene D
#include "lcd.c" // Librería para el manejo del lcd.
#include <2416.c> // Librería para el manejo de la EEPROM 24LC16B
// Se ha cambiado por
// #define EEPROM_SDA PIN_C4
// #define EEPROM_SCL PIN_C3
#use fast_io(B) //Para hacerlo FAST el port B
#define MAX_CADENA 32 //Una cadena de 32bytes como MAXIMO
//Rutinas para el LCD
void borra_lcd()
{
lcd_putc("f" // Con esta instrucción borramos el lcd
}
// Esto nos muestra en forma de LETRERO una cadena de caracteres (STRING)
void letrero(char *s)
{
delay_ms(100); // Retardo de un 100 ms
do{
printf(lcd_putc,"%c",*s);
delay_ms(50); // Retardo de un 50 ms para las letras
}
while(*s++);
}
// Rutinas para el manejo de la EEPROM
//Esto nos guarda una cadenad de caracteres empezando por una posición de memoria
void guarda_string_en_rom(char *s,int d)
{
borra_lcd();
printf(lcd_putc,"Guardando en %u",d);
do{
write_ext_eeprom(d++,(byte)*s);
}
while(*s++);
write_ext_eeprom(d,0); //OJO!! Ponemos un 0 al final de la cadena para
//que sepa cuando acaba la cadena.
borra_lcd();
}
//Esto nos devuelve la cadena que hay en la posición que pongamos
//OJO!! Las cadenas tienen que acabar en si no la reconocera y podria morir
char *lee_string_de_rom(int d)
{
char tmp[MAX_CADENA];
int i=0;
borra_lcd();
printf(lcd_putc,"Leyendo en %u",d);
do{
if(i==MAX_CADENA)break; //BUG_FIX: Solucionado para que no muera si
//no encuentra un antes de MAX_CADENA
tmp[ i ]=read_ext_eeprom(d++);
}while(tmp[i++]);
borra_lcd();
return tmp;
}
// El programa principal
void main()
{
char str[MAX_CADENA]; //Cadena que queremos GUARDAR
char rstr[MAX_CADENA]; //Cadena que vamos a LEER
set_tris_B(0b00000000); // Configuramos PORT_B como salida
port_b_pullups(FALSE); // Desactivamos pull-ups del puerto B
init_ext_eeprom(); //Iniciamos la EEPROM
lcd_init(); //Iniciamos el LCD
strcpy(str,"*** Fabre ***" //Copiamos la cadena a STR
guarda_string_en_rom(str,0); //Guarda la cadena en la EEPROM
strcpy(rstr,lee_string_de_rom(0)); //Leemos la CADENA de la EEPROM
//y la guardamos en RSTR
letrero(rstr);
for( ; ; ) // Esto se ejecuta de forma indefinida.
{
}
}

, y es muy didactico. Soy novato en el manejo de micros, aunque ya habia tenido algun contacto con el lenguaje C. Aqui van mis dudas:
; //Saca texto
; //Saca texto
; //Limpia pantalla
; //Saca texto
;
; //Limpia ese sector de pantalla

.
Codigo:
#include <16F877.H>
#fuses HS,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT,NOLVP
#use Delay(Clock=4000000)
#include <lcd-picdem.c>
#use fast_io(B)
#byte PORTB=6
const float escala = 255;
const float d_max = 2000;
void calcula_duty (int val, float &duty)
{
duty=(val*d_max)/escala;
}
main()
{
int valor;
float duty;
PORTB=0b00000010;
lcd_init();
lcd_gotoxy(1,1);
lcd_putc(" f=500Hz->T=2ms ");
lcd_gotoxy(1,2);
lcd_putc("duty = us");
setup_ccp1(CCP_PWM); // Configura CCP1 como PWM
setup_timer_2(T2_DIV_BY_16,124,1); // f=500Hz (T=2ms)
setup_adc(adc_clock_div_32); // Selecciona Reloj
setup_adc_ports(AN0); // RA0 analogico
set_adc_channel(0);
while(1)
{
valor=read_adc(); // Lee valor RA0
set_pwm1_duty(valor); // Establece duty como valor
calcula_duty(valor,duty); // Escala el duty
lcd_gotoxy(8,2);
printf(lcd_putc,"%3.2f",duty); // Muestra el resultado
}
}





Escrito originalmente por Fer_TACA
Con esto leo un pin del puerto B y pongo su valor en el puerto C. Pero si quiero leer todo el puerto B y pasarlo al puerto C como lo haria?
Gracias
Carmelo



Hola Amig@s!!!, HOY me meti con todo en "C"... 








(de eso se trata un lenguaje de alto nivel no?)




Codigo:
solo quiero uno en que me diga como van las teclas o algo asi...
;
;
) tambien lo he comprimido a rar y lo he colgado por si alguien mas esta interesado en poder repasarlo sin tener conexion, aqui lo dejo : minicursillo de C

Codigo:
Contador = Contador + incremento_variable;
Codigo:
if (((input(PIN_A0)==0)||(input(PIN_A1)==0)||(V2==1))&&(V1==1))
output_low(PIN_B7);
else
{
incremento_variable=1;
}
Codigo:
if (Contador==20000)
{
incremento_variable=0; // paramos los incrementos
output_high (PIN_B7);
}
//loop
Codigo:
#device adc=8
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES XT //Crystal osc <= 4mhz
#FUSES NOPROTECT //Code not protected from reading
#FUSES BROWNOUT_SW //Brownout controlled by configuration bit in special file register
#FUSES BROWNOUT //Reset when brownout detected
#FUSES BORV20 //Brownout reset at 2.0V
#FUSES NOPUT //No Power Up Timer
#FUSES NOCPD //No EE protection
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES NODEBUG //No Debug mode for ICD
#FUSES LVP //Low Voltage Programming on B3(PIC16) or B5(PIC18)
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES IESO //Internal External Switch Over mode enabled
#FUSES FCMEN //Fail-safe clock monitor enabled
#FUSES PBADEN //PORTB pins are configured as analog input channels on RESET
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOEBTRB //Boot block not protected from table reads
#FUSES NOCPB //No Boot Block code protection
#FUSES MCLR //Master Clear pin enabled
#FUSES LPT1OSC //Timer1 configured for low-power operation
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES PLL1 //No PLL PreScaler
Escrito originalmente por nocturno66
Parece que aún no soporta los PIC...
Primera pregunta: como estoy configurando el puerto B como entradas y salidas, y despues le envio un output_b(0b00000000); esto pone 0 en todas las salidas y entradas? que passa cunado pongo 0 en una entrada?En CCS hay básicamente dos formas de trabajar con los puertos, y dependerá de cómo lo tengas configurado.
Segunda pregunta: el puerto A tiene apenas 5 bits (RA0 hasta RA4), porque es necesario poner (0b00010000)(8 bits)? Si guardo en la memoria "write_eeprom(dir,port_a);", que datos voy a tener en los ultimos bits?
if(ap=1) if(ap==1)#include <16F84A.h>
#use delay(clock=4000000)
#use fast_io(B)
#fuses HS,NOWDT,NOPUT
//globales
int ap=1;
//Rutinas
void enciende(){
do{ // Hasta que pulsemos RB7
delay_ms(100); //rebote
output_low(PIN_B4); //zero en la salida, led encendido
}while(input(PIN_B7));
ap=0; // la proxima pulsacion se va a apaga
}
void apaga(){
do{ // Hasta que pulsemos RB7
delay_ms(100); // rebote
output_high(PIN_B4); //Uno en la salida, led apagado
}while(input(PIN_B7));
ap=1; //la proxima pulsacion se va a enciende
}
//Principal, deveria encender y apagar un led en RB4, con un pulsador en RB7
//Elpulsador cuando entra envia +5V al pin 13 (RB7)
//el LED esta con el anodo al + y el catodo al pin 10 (RB4) del 16F84A
void main(){
set_tris_B(0b10001111); // RB0,1,2,3 y 7 entradas RB4,5 y 6 salidas
output_high(PIN_B4); // zero la salida, led apagado
while(true){
if(input(PIN_B7)){
if(ap==1)
enciende();
else
apaga();
}
}
}
saludos,Hola a todos
Vuelvo con mas dudas...
Suponer que la funcion beep, emite un pitido en un altavoz.
Suponer que tengo un pulsador en RB7.
porque cuando ejecuto el siguinte codigo solo escucho un beep despues de pulsar el pulsador? Yo creia que durante la ejecucion del programa, siempre escucharia un beep, independiente si pulso o no el pulsador!
void main()
{
set_tris_B(0b10001111); // RB0,1,2,3 y 7 entradas RB4,5 y 6 salidas
while(true)
{
beep();
if(input(PIN_B7)){ //si pulsamos switch en RB7
hace_algo();
}
}
esto nó es un loop infinito?
for( ; ; ){....}
Hola Jose, prueba con este código:Código: [Seleccionar]#include <16F84A.h>saludos,
#use delay(clock=4000000)
#use fast_io(B)
#fuses HS,NOWDT,NOPUT
//globales
int ap=1;
//Rutinas
void enciende(){
do{ // Hasta que pulsemos RB7
delay_ms(100); //rebote
output_low(PIN_B4); //zero en la salida, led encendido
}while(input(PIN_B7));
ap=0; // la proxima pulsacion se va a apaga
}
void apaga(){
do{ // Hasta que pulsemos RB7
delay_ms(100); // rebote
output_high(PIN_B4); //Uno en la salida, led apagado
}while(input(PIN_B7));
ap=1; //la proxima pulsacion se va a enciende
}
//Principal, deveria encender y apagar un led en RB4, con un pulsador en RB7
//Elpulsador cuando entra envia +5V al pin 13 (RB7)
//el LED esta con el anodo al + y el catodo al pin 10 (RB4) del 16F84A
void main(){
set_tris_B(0b10001111); // RB0,1,2,3 y 7 entradas RB4,5 y 6 salidas
output_high(PIN_B4); // zero la salida, led apagado
while(true){
if(input(PIN_B7)){
if(ap==1)
enciende();
else
apaga();
}
}
}
Mario
Hola Jose, prueba con este código:Código: [Seleccionar]#include <16F84A.h>saludos,
#use delay(clock=4000000)
#use fast_io(B)
#fuses HS,NOWDT,NOPUT
//globales
int ap=1;
//Rutinas
void enciende(){
do{ // Hasta que pulsemos RB7
delay_ms(100); //rebote
output_low(PIN_B4); //zero en la salida, led encendido
}while(input(PIN_B7));
ap=0; // la proxima pulsacion se va a apaga
}
void apaga(){
do{ // Hasta que pulsemos RB7
delay_ms(100); // rebote
output_high(PIN_B4); //Uno en la salida, led apagado
}while(input(PIN_B7));
ap=1; //la proxima pulsacion se va a enciende
}
//Principal, deveria encender y apagar un led en RB4, con un pulsador en RB7
//Elpulsador cuando entra envia +5V al pin 13 (RB7)
//el LED esta con el anodo al + y el catodo al pin 10 (RB4) del 16F84A
void main(){
set_tris_B(0b10001111); // RB0,1,2,3 y 7 entradas RB4,5 y 6 salidas
output_high(PIN_B4); // zero la salida, led apagado
while(true){
if(input(PIN_B7)){
if(ap==1)
enciende();
else
apaga();
}
}
}
Mario
Saludos amigos de este microcursillo de c
bueno la verdad que yo soy nuevo en esto de la programacion en c, pero bueno estoy tratando de aprender de sus ejemplos y empesando a programar mis propias aplicasiones
tengo una duda... estuve leyendo las primeras notas d este curso.. hay unas notas de Nuestro amigo modulay.. que por cierto son muy explicativas.. pero algo que no entinedo ... por ejemplo en sus notas sobre las variables globales y localizadas .. mas especificamente en su codigo en la ultima linea
for(; :wink: {}
que significa esa linea... es acaso algun tipo bucle infinito como
while(true) {
puedo remplasarlo por este... esque saben.. cuando trato de compilar el codigo original, me bota un error en esa linea de codigo....
ojala puedan resolver mi duda... la verdad ya estoy un poco cabezon .. con esto.... gracias de antemano por su antencion..
for(; ; ) {}
Y realmente es un bucle infinito similar al While(true){}Modulay utuliza el for de esa forma y funciona pero pienso que de esa forma no se debe usar, ya que para eso no ha sido hecho el for sino para bucles finitos, para un bucle infinito sería while (1) o while (true).
Alguién podría responderme mi pregunta, nos vemos.
Hombre, si un pin está declarado como salida, de poco vale leer su estado, ya que por soft, el programador le indica el estado que debe estar, en cambio, si el pin está configurado como entrada, si es interesante, en un determinado tiempo, ver que estado tiene dicho pin.
Suerte!!! ;)
...
Yo cambiaría tu línea por esta:
if (input(PIN_B0)==1)
if (input(PIN_B0)) // pregunta si RB0 está a uno
if (!input(PIN_B0)) // pregunta si RB0 está a cero
.................... if (input(PIN_B0)==1);
0048: BSF F93.0
004A: BTFSS F81.0
004C: BRA 004E
....................
.................... if (input(PIN_B0));
004E: BSF F93.0
0050: BTFSS F81.0
0052: BRA 0054
....................
.................... if (input(PIN_B0)==1);
0054: BSF F93.0
0056: BTFSS F81.0
0058: BRA 005A
....................
.................... if (!input(PIN_B0));
005A: BSF F93.0
005C: BTFSC F81.0
005E: BRA 0060Sí, se puede cambiar por la que tú dices. Creo que es cuestión de gustos.
Mira cómo compila CCS las cuatro opciones siguientes:Código: [Seleccionar].................... if (input(PIN_B0)==1);
0048: BSF F93.0
004A: BTFSS F81.0
004C: BRA 004E
....................
.................... if (input(PIN_B0));
004E: BSF F93.0
0050: BTFSS F81.0
0052: BRA 0054
....................
.................... if (input(PIN_B0)==1);
0054: BSF F93.0
0056: BTFSS F81.0
0058: BRA 005A
....................
.................... if (!input(PIN_B0));
005A: BSF F93.0
005C: BTFSC F81.0
005E: BRA 0060
En definitiva, aunque lo pongamos como nos de la gana, siempre se compila en tres ciclos, así que no hay más simplificación posible.
.................... if ( bit_test( PORTB , 0 )){a=0;}
002C: BTFSC F81.0
002E: CLRF 05
Si maumix , hace cosa rara esto -> if (input(PIN_B0)==1);Código: [Seleccionar].................... if ( bit_test( PORTB , 0 )){a=0;}
002C: BTFSC F81.0
002E: CLRF 05
Si maumix , hace cosa rara esto -> if (input(PIN_B0)==1);Código: [Seleccionar].................... if ( bit_test( PORTB , 0 )){a=0;}
002C: BTFSC F81.0
002E: CLRF 05
Si, una vez ví leyendo velozmente el manual del CCS (el cual no uso) que usa un modo automático que acomoda el tris de un pin como entrada si es que se lee el registro o como salida si es que se lo escribe.
Y que si uno usa algo así como FAST_IO o similar, se evitaba eso.
tal vez justo en el ejemplo de manolo estaban activados. :)
Hola a todos,
Llevo algún tiempo intentando aprender esto del "C", pero resulta que me encuentro con algunos escaloncillos...
He intentado simular estos primeros ejercicios que indicais, pero no puedo compilarlos, el MPLAB, con el compilador de microchip, me dice que no es posible para el 16F84.
Es posible que sea por que no encuentra el archivo 16f84.h.
Aunque los programas los voy entendiendo, creo que se me quedan cosas en el tintero.
Por cierto, está claro que llevo algo de retraso..... vuestros mensajes son del 2004.