#define PUTCH(c) {while (!txif); txreg = c; }
void ConvierteARomano(int16 Numero) {
int8 Num;
if (Numero>>8) {
while (Numero >= 1000) {
PUTCH('M');
Numero -= 1000;
}
if (Numero >= 900) {
PUTCH('C');
PUTCH('M');
Numero -= 900;
}
if (Numero >= 500) {
PUTCH('D');
Numero -= 500;
}
if (Numero >= 400) {
PUTCH('C');
PUTCH('D');
Numero -= 400;
}
while(Numero>>8) {
PUTCH('C');
Numero -= 100;
};
}
Num = Numero;
while(Num >= 100) {
PUTCH('C');
Numero -= 100;
};
if (Num >= 90) {
PUTCH('X');
PUTCH('C');
Num -= 90;
}
if (Num >= 50) {
PUTCH('L');
Num -= 50;
}
if (Num >= 40) {
PUTCH('X');
PUTCH('L');
Num -= 40;
}
while(Num >= 10) {
PUTCH('X');
Num -= 10;
};
if (Num >= 9) {
PUTCH('I');
PUTCH('X');
Num -= 90;
}
if (Num >= 5) {
PUTCH('V');
Num -= 5;
}
if (Num >= 4) {
PUTCH('I');
PUTCH('V');
Num -= 4;
}
while(Num > 0) {
PUTCH('I');
Num--;
}
}
void ConvierteARomano(int16 Numero) {
unsigned char Num;
if (Numero>>8) {
while (Numero >= 1000) {
PUTCH('M');
Numero -= 1000;
}
if (Numero >= 900) {
PUTCH('C');
PUTCH('M');
Numero -= 900;
}
if (Numero >= 500) {
PUTCH('D');
Numero -= 500;
}
if (Numero >= 400) {
PUTCH('C');
PUTCH('D');
Numero -= 400;
}
while(Numero>>8) {
PUTCH('C');
Numero -= 100;
};
}
Num = Numero;
while(Num >= 100) {
PUTCH('C');
Num -= 100;
};
if (Num >= 90) {
PUTCH('X');
PUTCH('C');
Num -= 90;
}
if (Num >= 50) {
PUTCH('L');
Num -= 50;
}
if (Num >= 40) {
PUTCH('X');
PUTCH('L');
Num -= 40;
}
while(Num >= 10) {
PUTCH('X');
Num -= 10;
};
if (Num >= 9) {
PUTCH('I');
PUTCH('X');
Num -= 9;
}
if (Num >= 5) {
PUTCH('V');
Num -= 5;
}
if (Num >= 4) {
PUTCH('I');
PUTCH('V');
Num -= 4;
}
while(Num > 0) {
PUTCH('I');
Num--;
}
}
#include <18F458.h>
#device adc=16
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES HS //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES OSCSEN //Oscillator switching is enabled
#FUSES PUT //Power Up Timer
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#use delay(clock=8000000)
#use rs232(baud=9600,XMIT=PIN_C6)
#include <string.h>
int16 ListaNumeros[10]={54,1238,41,2500,640,99,1,999,1001,2666};
int16 Contador=0;
#byte PIR1=0xF9E
#bit txif=PIR1.4
#byte txreg=0xFAD
#define PUTCH(c) { while(txif==0); txreg=c; }
void ConvierteARomano(int16 Numero) {
unsigned char Num;
if (Numero>>8) {
while (Numero >= 1000) {
PUTCH('M');
Numero -= 1000;
};
if (Numero >= 900) {
PUTCH('C');
PUTCH('M');
Numero -= 900;
}
if (Numero >= 500) {
PUTCH('D');
Numero -= 500;
}
if (Numero >= 400) {
PUTCH('C');
PUTCH('D');
Numero -= 400;
}
while(Numero>>8) {
PUTCH('C');
Numero -= 100;
};
}
Num = Numero;
while(Num >= 100) {
PUTCH('C');
Num -= 100;
};
if (Num >= 90) {
PUTCH('X');
PUTCH('C');
Num -= 90;
}
if (Num >= 50) {
PUTCH('L');
Num -= 50;
}
if (Num >= 40) {
PUTCH('X');
PUTCH('L');
Num -= 40;
}
while(Num >= 10) {
PUTCH('X');
Num -= 10;
};
if (Num >= 9) {
PUTCH('I');
PUTCH('X');
Num -= 9;
}
if (Num >= 5) {
PUTCH('V');
Num -= 5;
}
if (Num >= 4) {
PUTCH('I');
PUTCH('V');
Num -= 4;
}
while(Num > 0) {
PUTCH('I');
Num--;
};
}
#INT_TIMER1
void Incrementa_Contador() {
Contador++;
}
void main()
{
int i;
int16 Duracion;
setup_timer_1 ( T1_INTERNAL);
printf ("Primer concurso de programacion. NUMEROS ROMANOS\n\r");
printf ("www.micropic.es\n\r\n\r");
set_timer1(0);
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
txif = 1; // Reset de la USART
for (i=0;i<10;i++) {
printf ("%LU = ",ListaNumeros[i]);
ConvierteARomano(ListaNumeros[i]);
printf ("\n\r");
}
Duracion=get_timer1();
printf ("Ha tardado %LU ticks\n\r",make32(Contador,Duracion));
while(TRUE);
}
Actualizo. He probado el código de Picuino también con MPLAB SIM, del cual me fío bastante más que de Proteus, y también se queda enganchado en el mismo punto.
Intentando ver cómo funciona el putc(), este es el código ASM que genera. No entiendo ASM, pero no veo ninguna escritura en el registro TXREG (0xFAD) en todo ese trozo de código, así que no sé cómo furula, pero creo que ahí está la clave.Código: ASM
0122 9C94 BCF 0xf94, 0x6, ACCESS 0124 9C8B BCF 0xf8b, 0x6, ACCESS 0126 0E08 MOVLW 0x8 0128 6E01 MOVWF 0x1, ACCESS 012A D000 BRA 0x12c 012C 0000 NOP 012E 8E01 BSF 0x1, 0x7, ACCESS 0130 D00E BRA 0x14e 0132 9E01 BCF 0x1, 0x7, ACCESS 0134 3244 RRCF 0x44, F, ACCESS 0136 B0D8 BTFSC 0xfd8, 0, ACCESS 0138 8C8B BSF 0xf8b, 0x6, ACCESS 013A A0D8 BTFSS 0xfd8, 0, ACCESS 013C 9C8B BCF 0xf8b, 0x6, ACCESS 013E 8C01 BSF 0x1, 0x6, ACCESS 0140 D006 BRA 0x14e 0142 9C01 BCF 0x1, 0x6, ACCESS 0144 2E01 DECFSZ 0x1, F, ACCESS 0146 D7F6 BRA 0x134 0148 D000 BRA 0x14a 014A 0000 NOP 014C 8C8B BSF 0xf8b, 0x6, ACCESS 014E 0E3F MOVLW 0x3f 0150 6EE9 MOVWF 0xfe9, ACCESS 0152 2EE9 DECFSZ 0xfe9, F, ACCESS 0154 D7FE BRA 0x152 0156 0000 NOP 0158 BE01 BTFSC 0x1, 0x7, ACCESS 015A D7EB BRA 0x132 015C BC01 BTFSC 0x1, 0x6, ACCESS 015E D7F1 BRA 0x142 0160 0012 RETURN 0
void ConvierteARomano(int16 Numero) {
unsigned char Num;
unsigned int8 posicion = 0;
#define PUTCH(c) Resultado[posicion++]=c
if(Numero>>8){
//*********************Miles****************************************************
if(Numero>=1000){
while(Numero>=1000){
Numero-=1000;
PUTCH('M');
}
}
//*********************Cientos**************************************************
if(Numero>=100){
if(Numero>=500){
if(Numero>=900){PUTCH('C');PUTCH('M');Numero-=900;}
else{PUTCH('D');Numero-=500;}
}
if(Numero>=400){PUTCH('C');PUTCH('D');Numero-=400;}
while(Numero>>8){PUTCH('C');Numero-=100;}
}
}
Num=Numero;
while(Num>=100){PUTCH('C');Num-=100;}
//***********************Decenas************************************************
if(Num>=50){
if(Num>=90){PUTCH('X');PUTCH('C');Num-=90;}
else{PUTCH('L');Num-=50;}
}
if(Num>=40){PUTCH('X');PUTCH('L');Num-=40;}
while(Num>=10){PUTCH('X');Num-=10;}
//******************************Unidades****************************************
if(Num){
if(Num>5){
if(Num==9){PUTCH('I');PUTCH('X');Num-=9;}
else{PUTCH('V');Num-=5;}
}
if(Num==4){PUTCH('I');PUTCH('V');Num-=4;}
while(Num){PUTCH('I');Num-=1;}
}
//******************************************************************************
Resultado[posicion] = '\0';
}
(http://www.todopic.com.ar/foros/index.php?action=dlattach;topic=40865.0;attach=20695;image)