Iniciamos aquí otra serie de posteos, que espero sea larga y fructífera,
con la sana intención de facilitarle el camino a nuestros amables visitantes
Picmaníacos.
La titúlo Mis Funciones favoritas en CCS C ya que pretendo ir subiendo
aquellas funciones que me van haciendo falta en mi otra serie de
Ejemplitos 16F876A: Indice de contenidos y tambien aquellas funciones que detecte que son muy
buscadas y necesitadas por los amigos principiantes.
Empezamos pues con una de la mas famosas ...
Titulo: ASCII Hex to Int=================
Descripción:
Convierte un carácter ASCII Hex (0..9 A..F) al valor
entero (0..15) correspondiente (4 bits)
Declaración:
#include <stdlib.h>
int aschex2int(char d);Función y ejemplo de uso:
<span class="texto_mini">Codigo:</span>
[
BR]int aschex2int(char d){ // Convierte un caracter ascii hex a int
int r=0; // Declaro e inicializo a cero el resultado
if(isxdigit(d)){ // Si es un digito hexadecimal ...
if(isdigit(d)){ // si es un digito decimal ...
r=d-'0'; // devuelvo su diferencia con el valor ascii del caracter "0"
}
if(isalpha(d)){ // si es alfanumerico ...
d=toupper(d); // lo paso a mayusculas y ...
r=10+(d-'A'); // devuelvo 10 mas su diferencia con el valor ascii de la letra "A"
}
}
return(r);
}
// Ejemplo de uso con 1 caracter
int x;
x = aschex2int('F'); // x toma el valor 15
// Ejemplo de uso con dos caracteres
char *ptr;
strcopy(ptr,"ff" );
int x;
x =(16*aschex2int(ptr[0])); // Convierto el dígito mas significativo
x+=(aschex2int(ptr[1])); // Convierto el dígito menos significativo
// y lo sumo a lo anterior, x toma el valor 255
Y ahora vamos con una función muy util a la hora de manejar los Displays
de 7 segmentos; sobre todo para su uso con los Drivers estilo <a href="
http://picmania.garcia-cuervo.com/recursos/74LS48.pdf" target="_blank">74LS48[/url]
Esta función es facilmente adaptable a su uso con solo dos dígitos ...
Titulo: Int to BCD==============
Descripción:
Convierte un entero a su representación BCD (Binary Code Decimal)
Declaración:
int h_digit, m_digit, l_digit;
void int2bcd(int valor);Función y ejemplo de uso:
<span class="texto_mini">Codigo:</span>
[
BR]void int2bcd(int valor){ // Funcion que convierte de Entero a 3 x BCD
h_digit = (int) valor / 100; // 1er Dígito o Centenas
valor -= h_digit * 100; // y se lo resto al valor
m_digit = (int) valor / 10; // 2do Dígito o Decenas
valor -= m_digit * 10; // y también se lo resto
l_digit = valor; // y por último solo me quedan las unidades
}
int x=255;
int2bcd(x);
printf("
Test %u %u %u
",h_digit,m_digit,l_digit);
Titulo : Funciones Date y Time=====================
Y ahora en otro orden de cosas vamos a tratar una serie de funciones
bajo el denominador común de Date y Time.
Estas funciones no son mías, son una traducción de lo originalmente publicado
en el <a href="
http://www.ccsinfo.com/forum/viewtopic.php?t=25611" target="_blank">Foro CCS Library[/url] y su autor es <a href="mailto:nicksubzero@yahoo.com ">Aurelian Nichita[/url]
Yo me he limitado a traducirlas al español y probar que funcionan.
Incluye las funciones:
esAgnoBisiesto(int y)
diasDesdeAgno1(int y, int m, int d)
segundosDesdeHora0(int h, int m, int s)
segundosDesdeAgno1(int yr, mo, dy, hr, mi, se)
segundosEntre(int yr1, mo1, dy1, hr1, mi1, se1, yr2, mo2, dy2, hr2, mi2, se2)
ISODiaDeLaSemana(int YY, int MM, int DD)
ISONumeroDeLaSemana(int YY, int MM, int DD, int& weekOfYear, int& actualYear)
<span class="texto_mini">Codigo:</span>
[
BR]
// Definiciones y Funciones de Date Time ////////////////////////////////////////////////
// Números ISO de los dias de la semana
#define LUNES 1
#define MARTES 2
#define MIERCOLES 3
#define JUEVES 4
#define VIERNES 5
#define SABADO 6
#define DOMINGO 7
const int Dias_de_cada_Mes[2][13] = { {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} };
const int Orden_Dias_Semana[7] = {6, 7, 1, 2, 3, 4, 5};
#define SEGUNDOS_EN_UN_DIA 86400
#define SEGUNDOS_EN_UNA_HORA 3600
#define SEGUNDOS_EN_UN_MINUTO 60
#define MINUTOS_EN_UN_DIA 1440
#define MINUTOS_EN_UNA_HORA 60
#define HORAS_EN_UN_DIA 24
// Algunas funciones que seran usadas mas adelante
#inline
short esAgnoBisiesto(int y) {
return (y % 4 == 0);
}
#separate
int32 diasDesdeAgno1(int y, int m, int d) {
int32 dias = 0;
int i;
short es_bisiesto;
es_bisiesto = esAgnoBisiesto(y);
for (i=1; i<y; i++) {
if (esAgnoBisiesto(i))
dias += 366;
else
dias += 365;
}
for (i=1; i<m; i++)
dias += Dias_de_cada_Mes[es_bisiesto][ i ];
dias += d;
return dias;
}
#separate
int32 segundosDesdeHora0(int h, int m, int s) {
int32 segundos;
segundos = (int32)h * SEGUNDOS_EN_UNA_HORA;
segundos += (int32)m * SEGUNDOS_EN_UN_MINUTO;
segundos += s;
return segundos;
}
#separate
int32 segundosDesdeAgno1(int yr, mo, dy, hr, mi, se) {
int32 segundos;
segundos = diasDesdeAgno1(yr, mo, dy) * SEGUNDOS_EN_UN_DIA;
segundos += segundosDesdeHora0(hr, mi, se);
return segundos;
}
// Calcula el numero de segundos entre dos fechas y horas
// Adaptado para años entre 2001 y 2135 (limitado por el tamaño de los int32)
#separate
int32 segundosEntre(int yr1, mo1, dy1, hr1, mi1, se1, yr2, mo2, dy2, hr2, mi2, se2) {
int32 inicio;
int32 final;
inicio = segundosDesdeAgno1(yr1, mo1, dy1, hr1, mi1, se1);
final = segundosDesdeAgno1(yr2, mo2, dy2, hr2, mi2, se2);
if (inicio > final)
return inicio-final;
else
return final-inicio;
}
// Calculo del dia de la semana. Adaptado SOLO para años del 2000 al 2099
#separate
int ISODiaDeLaSemana(int YY, int MM, int DD) {
signed long diaDeLaSemana;
int cent = 20; // YYYY / 100
// Algoritmo de congruencia de Zeller
if (MM < 3) {
MM = MM + 12;
if (YY > 0)
YY--;
else {
YY = 99;
cent--;
}
}
diaDeLaSemana = DD;
diaDeLaSemana += (((signed long)MM + 1) * 26) / 10;
diaDeLaSemana += YY;
diaDeLaSemana += YY / 4;
diaDeLaSemana += cent / 4;
diaDeLaSemana -= cent * 2;
while (diaDeLaSemana < 0)
diaDeLaSemana += 7;
diaDeLaSemana %= 7;
return Orden_Dias_Semana[(int)diaDeLaSemana]; // Ahora tenemos el número ISO del dia de la semana
}
// Calculo de número ISO de la semana. Adaptado SOLO para años del 2001 al 2098
#separate
void ISONumeroDeLaSemana(int YY, int MM, int DD, int& weekOfYear, int& actualYear)
{
signed long diaDelAgno;
int DiaDeLaSemanaInicial;
int DiaDeLaSemanaFinal;
short bisiesto;
signed int i;
do {
bisiesto = esAgnoBisiesto(YY);
diaDelAgno = 0;
for (i=1; i<=MM; i++) {
if (i < MM)
diaDelAgno += Dias_de_cada_Mes[bisiesto][ i ];
else
diaDelAgno += DD;
}
actualYear = YY;
DiaDeLaSemanaInicial = ISODiaDeLaSemana(actualYear, 1, 1);
if (DiaDeLaSemanaInicial > JUEVES)
diaDelAgno -= 8 - DiaDeLaSemanaInicial;
else
diaDelAgno += DiaDeLaSemanaInicial - 1;
if (diaDelAgno <= 0)
weekOfYear = 0xFF;
else {
weekOfYear = diaDelAgno / 7;
if (diaDelAgno % 7 != 0)
weekOfYear++;
if (weekOfYear > 52) {
DiaDeLaSemanaFinal = DiaDeLaSemanaInicial;
if (bisiesto) {
if (DiaDeLaSemanaFinal == DOMINGO)
DiaDeLaSemanaFinal = LUNES;
else
DiaDeLaSemanaFinal++;
}
if (DiaDeLaSemanaFinal < JUEVES) {
actualYear++;
weekOfYear = 1;
}
}
}
if (weekOfYear == 0xFF) {
if ((--DD)==0) {
if ((--MM)==0) {
YY--;
MM = 12;
}
DD = Dias_de_cada_Mes[esAgnoBisiesto(YY)][MM];
}
}
} while (weekOfYear == 0xFF);
}