Página 1 de 2
[Resolvido] Otimizar rotina em C18

Enviado:
16 Mar 2012 10:15
por FabioSom12
Olá.
Eu programo em assembler e quero migrar pro c18.
Fiz um trecho da interrupção e ficou meio estranho, não sei se isso é da linguagem mesmo ou caquinha minha.
//Soma TMR1 com 0x063c7 (c18) 29 ciclos
ax1 = (TMR1L|TMR1H<< 8) + 0x063c7; //14
TMR1H = (ax1>>8); // 9
TMR1L = (ax1&0xff); // 6
//Soma TMR1 com 0x063c7 (asm) 8 ciclos
movff TMR1L, TMR1L_temp
movlw 0c7h ;
addwf TMR1L_temp
movlw 063h ;
addwfc TMR1H ;
movff TMR1L_temp, TMR1L
Dá pra otimizar isso ou essa diferença de ciclos é do c18 mesmo?

Enviado:
16 Mar 2012 22:27
por tcpipchip
Disassembla para o pessoal o codigo gerado pelo C18

Enviado:
17 Mar 2012 08:06
por FabioSom12
Tentei bastante aqui e acho que essa diferença é normal.
Vou misturar o C com asm, senão não vai dar certo.
C18
- Código: Selecionar todos
004A 50CF MOVF 0xfcf, W, ACCESS
004C 0E00 MOVLW 0
004E 50F3 MOVF 0xff3, W, ACCESS
0050 10CE IORWF 0xfce, W, ACCESS
0052 6E02 MOVWF 0x2, ACCESS
0054 6A03 CLRF 0x3, ACCESS
0056 0EC7 MOVLW 0xc7
0058 2602 ADDWF 0x2, F, ACCESS
005A 0E63 MOVLW 0x63
005C 2203 ADDWFC 0x3, F, ACCESS
005E C002 MOVFF 0x2, 0xfde
0060 FFDE NOP
0062 C003 MOVFF 0x3, 0xfdd
0064 FFDD NOP
45: TMR1H = (ax1>>8);
0066 CFDE MOVFF 0xfde, 0x2
0068 F002 NOP
006A CFDD MOVFF 0xfdd, 0x3
006C F003 NOP
006E C003 MOVFF 0x3, 0x2
0070 F002 NOP
0072 6A03 CLRF 0x3, ACCESS
0074 5002 MOVF 0x2, W, ACCESS
0076 6ECF MOVWF 0xfcf, ACCESS
46: TMR1L = (ax1&0xff);
0078 CFDE MOVFF 0xfde, 0x2
007A F002 NOP
007C CFDD MOVFF 0xfdd, 0x3
007E F003 NOP
0080 5002 MOVF 0x2, W, ACCESS
0082 6ECE MOVWF 0xfce, ACCESS
Asm- Código: Selecionar todos
47: _asm movff TMR1L, ax1
00E8 CFCE MOVFF 0xfce, 0
00EA F000 NOP
48: movlw 0x0c7
00EC 0EC7 MOVLW 0xc7
49: addwf ax1, 1, 0
00EE 2600 ADDWF 0, F, ACCESS
50: movlw 0x063
00F0 0E63 MOVLW 0x63
51: addwfc TMR1H, 1, 0
00F2 22CF ADDWFC 0xfcf, F, ACCESS
52: movff ax1, TMR1L _endasm
Caraca, alguem consegue entender isso?

Enviado:
17 Mar 2012 09:04
por marcelo campos
Caro FabioSom12
Por acaso alguém te disse que C é mais eficiente que Assembly ?
pois se te falaram é mentira...
Tem uma particularidade do C18 também à considerar: ele tem o modo student e o registrado que otimiza "um pouco mais" mas isto não quer dizer que vá ficar aquela maravilha de código pequeno; qual você está usando ?
abraço,
Marcelo

Enviado:
17 Mar 2012 12:35
por Djalma Toledo Rodrigues
marcelo campos escreveu:Caro FabioSom12
Por acaso alguém te disse que C é mais eficiente que Assembly ?
pois se te falaram é mentira...
abraço,
Marcelo
Claro, lógico
Se o C, após compilado, se transforma em Instruções do Microcontrolador seria absurdo
cogitar em ser mais eficiente o código gerado, já que em Asm é 'montado' com as próprias Instruções
Sei, um Programa grande em Asm fica bem complicado
O C disponibiliza Bibliotécas, se por um lado facilita (e muito) por outro se torna uma coisa
abstrata e isso não é de meu agrado.
------------------
Algumas dicas para os "montadores":
Datasheet e Esquemas em mãos
Copiar e colar o Set de Instruções na parter inferior do editor de Texto
elas ficarão ali disponíveis mas, após o
End
logo nem se faz necessário deleta-las
ao concluir
DJ

Enviado:
17 Mar 2012 12:53
por tcpipchip
Sei, um Programa grande em Asm fica bem complicado
Se voce nao documentar...

Enviado:
17 Mar 2012 14:06
por fabim
Fábio, aconselho que você não troque de linguagem.
Continue em ASM mesmo, larga a mão de tentar entrar no mundo de programação em alto nível.
Pique que tem apenas alguns KB de flash, fica complicado programar em C ou CPP fique como esta mesmo.
Nos que aconselhamos a utilização de C. é porque não nos falta FLASH, e se faltar colocamos uma RAM externa, ou uma FLASH externa e fazemos o mapeamento. Sobre o que falou de velocidade, nos pics é complicado mesmo, alguns Mega MIPS, a diferença na quantidade de instruções faz toda a diferença do mundo, no nosso caso, é Centenas de Mega MIPS, e até GIGA MIPI.
Até porque querer comparar linguagem quase de máquina, com sintaxe humana, é uma coisa bem complicada pra engolir.
Resumindo, FIQUE COMO ESTA.
Re: Diferença entre C18 e assembler

Enviado:
17 Mar 2012 14:19
por Djalma Toledo Rodrigues
FabioSom12 escreveu:Olá.
Eu programo em assembler e quero migrar pro c18. ...
Mas, PIC?
e logo PIC18F um Microcontrolador tão complicado.
Porque não Atmel?
Bem mais simples, veloz, e ainda leva os 32 General Purpuse Register
onde qualquer deles pode ser o Acumulador
DJ

Enviado:
19 Mar 2012 08:24
por FabioSom12
Bom dia amigos,
Acabei trazendo comparações de "C x asm" de um jeito ruim, vou mudar o titulo.
Sei que o C não é mais eficiente que Assembly, mas preciso de mais velocidade e legibilidade na programação.
Só que essa parte do timer eu enrosquei mesmo, a coisa não tava saindo de jeito nenhum.
Pra mim que estou aprendendo fica difícil saber se a falha é minha ou limitação da linguagem C.
Eu penso que ainda tem outro comando ou algum macete, tipo fazer uma union e somar em 16b.
Eu até tentei mas ainda sou ruim com struct e union e o PIC tem uma limitação na escrita e leitura do "TMR1H". Não consegui muita coisa.
As vezes olho e código e fico imaginando que estou programando em C, mas ainda pensando em assembly. É coisa do capeta, não da pra explicar.
Escolhi o PIC por já ter a placa e gravador.
Acho que errei nisso, eu acabo fazendo muita comparação entre as linguagens.
Depois vou tentar os ATmegas.
Nesse trechinho do programa o problema é a velocidade. É um timer de 63uS e o pic 18f é bem limitado em velocidade

.
Abraços...

Enviado:
19 Mar 2012 08:53
por fabim
Fábio, você esta começando a pensar da forma correta.
Não existe milagre.
Eu programava somente em ASM, depois aprendi o ANSI C.
Eu afirmo com todas as letras, que ANSI C= ASM alto nível.
Desde que não seja com aquele monte de makros prontas igual o CCS, ou etc. Ai que você esta phodido mesmo que não sabe o que acontece atrás das chamas de makro.
A uns anos eu tentei uma mágica, "tinha a mente pequena ainda", fazer um true RMS da rede com pic, escrevendo no display e tudo mais. O pic rodava a 48mhz, até com ASM eu não consegui...
Anos depois com um LPC2148, funcionou lindamente perfeito, e ainda tinha que colocar uma porrada de delays.
Hoje o mercado te oferece processadores que rodam a 100mhz em 32 bits com 1.25Dmips com preço de 18F4550...
Se quer um conselho de um inútil, não passe de algo pequeno para algo um pouco menos pequeno.
Um atmel rodando com um cristal de 20mhz, roda a 20mhz na CPU.
Um pic rodando com cristal de 20mhz, roda a 5mhz na CPU.
Agora compare a performance dos dois, pelo set de instruções!!!
A diferença do atmel mesmo com clock 4X maior, é muito pouca...
Escolha um fabricante de processador de 32bits com barramento ARM ou 68000 que seja, compre um kit baratinho do ebay e cresça junto com a tecnologia.

Enviado:
19 Mar 2012 09:34
por FabioSom12
Valeu Fabim.
heheheheheheh
Eu li sua resposta e lembro de um projeto que fiz ano passado.
Usei 3 PICs e foi um **** sacrificio fazer as rotinhas, tive que ficar revisando várias vezes pra tentar ganhar 1uS a mais. Varava noite programando e até sonhava com o projeto.
O final ate que funcionou bem melhor do que esperado, mas é a visão do inferno ver aquele monte de PIC trabalhando em sincronia.
Meu maior medo é um dia ter que dar um up ou recall nesse projeto.
Cara se vc é inutil, eu sou uma samandai.
Valeu pela dica, agora que você falou em mudar de 8bits pra 32b acho que entendi a diferença de centenas de MIPs pra milhares de MIPs.
Hoje a noite vou comprar um kitzinho. Vou de arm7, acho é o que tem mais documentação na net e é mais fácil de comprar no Brasil.
O LPC2148 da pra comprar até pelo mercado livre. heheh
Vou continuar com o C18 pra ter uma base melhor do C-ANSI e migrar os projetos em assembler que já estão prontos.
Abraços..

Enviado:
20 Mar 2012 09:26
por fabim
ARM7 não, ele esta morrendo tanto como os 16F estão sendo substituídos pelos 18F bem mais velozes e baratos!!!
Vá direto para o CorteX, seja M0,1,3,4.
Se você aprender a trabalhar com o M3, e precisar de algo pequeno, use um M0 e ou M1, não vai ter quaisquer dificuldades...
Feito isto, vai se sentir confortável para subir ainda mais para SO etc.
LPC1768, é uma boa pedida pra começar.
Tenho um amigo com um kitizinho desse na caixa com J-link e tudo mais.
Ele Vende por R$300,00.
Tem até o display 3.5", com interface touch.
Qualquer coisa CCT-le =
d.fantinato@yahoo.com.br Daniel.
O kit é excelente e até pode usar ele em locais com **** EMI/RFI.

Enviado:
20 Mar 2012 09:51
por ze
voltando a sua comparação dos ciclos, creio que não foi muito válida pois em asm voce carregou literalmente os regs e em c teve que fazer umas continhas. De qualquer forma veja o asm que o c gerou (como sugeriu o tcpip).
Cogite usar o hitech-c. Se o programador asm estiver entre amador e mediano, sim o tamanho do cod gerado tende a ser igual ou menor. Se for avançado, tende a ser igual. Mas se for um conhecido amigo nosso... esquece.
Fazendo coro com os véios daqui, esqueça pic.
abç

Enviado:
20 Mar 2012 13:06
por FabioSom12
Valeu de novo Fabim,
Por sorte um amigo comprou uma evolution board com o LPC11U14 (M0) e encostou, quando ele achar vai me emprestar.
Esse fds devo começar a brincar de "Hello word!".
Lelis
Meu maior problema é que não conheço a linguagem C.
Eu ainda acho que dá pra melhorar, mas fica pra outra hora.


Enviado:
23 Mar 2012 22:38
por Fábio Pereira
Boa noite Fabio,
Realmente os timers dos PICs não são um primor de tecnologia nem facilidade de uso, mas acho que é possível melhorar um pouco o seu código em C:
- Código: Selecionar todos
union
{
unsigned int word;
struct
{
unsigned char byte_low;
unsigned char byte_high;
};
} my_word;
...
my_word.byte_low = TMR1L;
my_word.byte_high = TMR1H;
my_word.word += 0x63C7;
TMR1H = my_word.byte_high;
TMR1L = my_word.byte_low;
Este código respeita o mecanismo de leitura de 16 bits do TMR1 e compila no seguinte código:
- Código: Selecionar todos
259: my_word.byte_low = TMR1L;
0C46 CFCE MOVFF 0xfce, 0xaa
0C48 F0AA NOP
260: my_word.byte_high = TMR1H;
0C4A CFCF MOVFF 0xfcf, 0xab
0C4C F0AB NOP
261: my_word.word += 0x63C7;
0C4E 0EC7 MOVLW 0xc7
0C50 0100 MOVLB 0
0C52 27AA ADDWF 0xaa, F, BANKED
0C54 0E63 MOVLW 0x63
0C56 23AB ADDWFC 0xab, F, BANKED
262: TMR1H = my_word.byte_high;
0C58 C0AB MOVFF 0xab, 0xfcf
0C5A FFCF NOP
263: TMR1L = my_word.byte_low;
0C5C C0AA MOVFF 0xaa, 0xfce
0C5E FFCE NOP
O trecho de código executa em 13 ciclos de máquina. Verifique e veja se realmente funciona!
T+