ferrugem em transistores

Circuitos eletrônicos, topologias, diagramas elétricos, etc...

Moderadores: 51, Renie, gpenga

Re: ferrugem em transistores

Mensagempor ze » 03 Jun 2016 16:09

(ops!.. dê uma olhada na página anterior... as duas mensagens minhas não foram mescladas!)

Só um desabafo...
Código: Selecionar todos
unsigned char cb=0x0f;
...
SEGMENTOS=tab[dig[i]]|cb;//padrão
ACOM=~k;//anodo comum
k<<=1;
i++; if(i>4) {cb^=0xff;i=0;k=4;}

segmentos e acom são ports do mc. acom aplicado na base de um bc807
Com resitor de 680R + o algoritimo acima, estimei em 21mA aplicado em 4 pinos do mc quando display mostra 8. Brilho (2me & no meu lab) está aceitável. Verei com cliente.
Desta forma, acendendo 3 e depois 4 segmentos, deu tempo do mc ler a linha I2C entre interrupts e mostra corretamente a temperatura

Mas (sempre tem um) nem tudo está tão bom que não possa ser melhorado. Ainda estou de olho num algoritimo pra acender 1 led por vez.
Neste caso sim, posso dispensar o transistor driver além de usar 1 resistor só pra todo mundo...
Imagem
O dilema inquietante (gostei deste termo) é coordenar a leitura I2C com tempos tão pequenos e... puts..! um agravante.. vou ter que ler um sinal analógico..

Adrenalina...

Só um desabafo... mas pode não ser totalmente inútil pra algum errante navegante do futuro (que pode até ser eu mesmo... eu tenho memória fraca... eu tenho memória fraca)
Avatar do usuário
ze
Dword
 
Mensagens: 1655
Registrado em: 05 Jun 2007 14:32

Re: ferrugem em transistores

Mensagempor KrafT » 03 Jun 2016 21:29

Zé, eu fiz um projeto assim e postei aqui nos primórdios do Asm51, lá em 2003. Lembro que na época um colega com nick de Professor Francisco, não concordava de jeito nenhum nos benefícios de usar só um resistor por display. No meu caso era um termômetro de três dígitos, que ficou funcionando até o ano passado, quando desativei o trem.

Não dava para tirar foto nem filmar o dsiplay :?
"..."Come to the edge," he said. And so they came. And he pushed them. And they flew."― Guillaume Apollinaire
Avatar do usuário
KrafT
Dword
 
Mensagens: 2228
Registrado em: 11 Out 2006 14:15
Localização: Blumenau -SC

Re: ferrugem em transistores

Mensagempor msamsoniuk » 04 Jun 2016 02:29

entao, eu trabalho bastante com sistemas realtime no dia a dia e tem N formas de fazer isso, algumas mais sofridas, outras mais simples.

daih vem uma pergunta: o microcontrolador tem um interface I2C dedicada ou vc faz via GPIO? qual a taxa de amostragem que vc precisa? nada critico acho eu, eh apenas para balizar o raciocinio a seguir... independente do caso, suponho que consiste em algo atomico como:

REPLY = i2c_request(REQUEST);

se for um I2C dedicado, provavelmente eh algo como colocar REQUEST em um buffer de transmissao, setar um bit e entao ficar lendo um flag de status enquanto o hardware serializa aquela mensagem e espera o periferico serializar a resposta, algo como:

Código: Selecionar todos
int i2c_request(int REQUEST)
{
  I2C_XFIFO = REQUEST;
  I2C_CTRL.XMIT = 1;
  while(I2C_STAT.BUSY); // espera o HW enviar e receber os dados serializados naquela cadencia lerda do I2C
  return I2C_RFIFO;
}


um processo demorado em que ele fica esperando a resposta (vc comentou em torno de 2ms). no caso de GPIO, nao sei se o microcontrolador nao eh rapido demais para gerar um I2C diretamente, entao acredito que seja algo como:

Código: Selecionar todos
switch(i2c_state)
  case 0:
    GPIO.PTB0 = 0; // CLK = 0
    GPIO.PTB1 = REQUEST&1; // DAT = bit0
    usleep(DELAY); // delay para nao exceder a velocidade maximo do periferico
    GPIO.PTB0 = 1; // CLK = 1
    break;
  case 1:
    GPIO.PTB0 = 0; // CLK = 0
    GPIO.PTB1 = REQUEST&2; // DAT = bit1
    usleep(DELAY); // delay para nao exceder a velocidade maximo do periferico
    GPIO.PTB0 = 1; // CLK = 1
    break;

    ...


na pratica, ele fica a maior parte do tempo em um while(1) fazendo hora para dar o delay ali. de fato, em ambos os casos, daria para dizer que o microcontrolador fica a maior parte do tempo em idle, esperando. eh normal, eu vejo no meu dia a dia processadores cavalares multicore na mesma situacao: em idle esperando. a ideia eh aproveitar melhor esse tempo e vc consegue isso colocando prioridades. e no caso, temos I2C e refresh do display. eu diria que colocar o refresh do display como maior prioridade eh legal, pq eh facil de granular a tarefa. granular o I2C eh possivel, mas eh um pouco mais complicado... como soh tem dois processos, eh mais facil seguir o caminho mais facil.

assim, permitir a interrupcao de refresh do display em cima desses processos nao deve causar problemas, desde que a interrupcao de refresh do display seja jogo rapido. se vc codificar o I2C via GPIO, o que vai perceber eh um pequeno jitter nos sinais, justamente referente a execucao da interrupcao de refresh de display. escapar desse jitter, soh mesmo em uma FPGA, onde eh possivel ter o hardware todo em paralelo... e olhe lah! mesmo um sistema todo paralelizado e pipelinezado acaba tendo seus interlocks no meio da logica! se fosse tudo assim facil, eu jah estaria trilionario e estaria construindo uma estacao espacial para conquistar a galaxia! \o/ hahaha

no seu caso, eu faria o seguinte: calcularia um "tic" para o sistema, digamos, de 3kHz, como vc comentou. a vantagem de trabalhar com um numero inteiro eh que vc consegue derivar "soft timers" a partir desse "tic". nessa interrupcao do "tic" eu faria um unico passo de refresh do display, ou seja, desligaria um segmento e ativaria o proximo segmento. tem que ser um negocio bem montado e bem otimizado, mas acho que como vc jah pescou como fazer o refresh de 2 partes, fazer parte por parte nao deve ser complexo. seria tipo uma funcao em que cada vez q vc entra, ela desliga o segmento atual e ativa o proximo, algo assim:

Código: Selecionar todos
void refresh_display()
{
  static int count_display = 0;
  static int count_segment = 0;

  turn_off(count_display,count_segment);

  count_segment++;
  if(count_segment == 8)
  {
    count_segment = 0;
    count_display++;
    if(count_display == 6)
    {
      count_display=0;
    }
  }
 
  turn_on(count_display,count_segment);
}


as funcoes turn_off() e turn_on(), no caso apenas desativam e ativam exatamente 1 segmento, indicado na chamada da funcao, onde eh passado tb o display em uso. dah para otimizar esse codigo bem! fiz as contas ali para 7 segmentos x 5 displays. como eh o processo mais rapido (3kHz), ficaria na interrupcao e ficaria bem deterministico. tambem na mesma interrupcao eu decrementaria um contador, que divide os 3kHz, digamos, por 30 (contando de 29 a 0), resultando em uma sub-contagem de 100Hz. digamos que essa contagem de 100Hz eh usava para coletar dados do I2c:

Código: Selecionar todos
int i2c_timer_req;
int i2c_timer_cnt;

interrupt tic()
{
  refresh_display();
  if(!i2c_timer_cnt--)
  {
    i2c_timer_cnt=29;
    i2c_timer_req++;
  }
  return;
}


note que soh tem o refresh do segmento do display como processamento. no caso do i2c, apenas incremento uma variavel, mas nao perco tempo fazendo o i2c aqui para nao lockar na interrupcao pelos 2ms que vc comentou. para ter uma contagem, digamos de 1 segundo, vc faria na mesma interrupcao algo similar, mas nesse caso a contagem eh de 2999 a 0:

Código: Selecionar todos
int 1sec_timer_req;
int 1sec_timer_cnt;

interrupt tic()
{

...

  if(!1sec_timer_cnt--)
  {
    1sec_timer_cnt=2999;
    1sec_timer_req++;
  }
  ...


soh como exemplo mesmo, depois uso lah no outro loop para mostrar como encadear essas coisas... novamente, apenas incremento uma variavel. a ideia eh que o codigo na interrupcao eh bem rapido. na pratica, ele faz o minimo possivel. soh faco o refresh do display aqui pq esta EH a tarefa em realtime: se vc fizer de outra forma, vai ter um grande jitter. e jitter nesse caso implica em maior corrente/brilho para um segmento do que para outro. para eles ficarem perfeitamente homogeneos, eu diria que tem que ser feito esse refresh aqui na interrupcao! mas acho que jah escrevi sobre isso acima hehehe

lah no processo principal eu teria tarefas que nao sao realtime:

Código: Selecionar todos
main()
{
  GPIO.PTA0 = 1; // red led on
  startup_sequence(); // funcao que inicializa todas as tranqueiras
  GPIO.PTA0  = 0; // red led off
  interrupt_enable();
  GPIO.PTA1 = 1; // green led on
  while(1)
  {
    if(i2c_timer_req)
    {
      REPLY = i2c_send(REQUEST);
      uart_send_data(REPLY);
      i2c_timer_req--;
    }
    // else <- se eu colocar esse else, eu priorizo a tarefa de cima sobre a debaixo! :O
    if(1sec_timer_req)
    {
       GPIO.PTA1 ^= 1; // green led blink = good! :D

      if(1sec_timer_req!=1) // more than 1 credit! :O
         GPIO.PTA0 = 1; // red led on! panic! :O
      if(GPIO.PTA2==1)
        GPIO.PTA0 = 0; // alarm override! :'(

      1sec_timer_req--;
    }
  }
}


eu estou meio enferrujado nessas coisas, mas enfim, eh um sistema de "creditos": quando a interrupcao ocorre lah em cima, os timers incrementam variaveis que dao creditos para o codigo aqui embaixo. quando ocorrem 30 contagens do tic, a variavel de i2c eh incrementada. aqui embaixo, se houver credito na variavel, a tarefa do i2c roda e gasta o credito (decrementa a variavel). eh tipo um master/slave: a interrupcao dah creditos, o loop principal gasta eles. se vc ativar um GPIO cada vez que a tarefa de i2c roda, vc vai ver que ela roda a 100Hz. a outra tarefa roda a cada 1 segundo e analisa dados de performance. no caso, espera-se que existe apenas 1 credito disponivel sempre. se houver mais de 1, eh pq o processador ficou mais de 1 segundo ocupado e essa tarefa nao rodou no tempo dela! se tudo estiver normal, um led verde pisca, do contrario, um led vermelho de alarme ativa para permitir que o operador veja a falha e aperte um botao para desligar o alarme!

caraca! isso ficou tao profissa que merecia um "selo dollynho de excelencia corporativa"! huahuahua

ze escreveu:Nem vi que moderador tinha migrado pra cá. Título nada a ver pode ser alterado de acordo com o desenrolar ou sua vontade

MOR_AL escreveu:Zé.
Tudo bem.
MOR_AL

Moris, tudo bem se eu considerar isso como "perdão. realmente a intenção foi te ajudar" E "seu devaneio noturno tem sentido" ? ok.. considerado

Por uma destas raras boas coincidências do destino, um comprador nosso veio até mim com um display 7seg pra ser homologado. Testei no projeto novo, ele tem um brilho bom com 330R @ 5V com 5 sendo multiplexados a 400Hz, cada um oscila a 80Hz. Mesmo assim penso que ao acender 8 ele abusa um pouco da capacidade de corrente do mc. O que me remonta à ideia do Marcelo San...

M.San... acho que vou testar sua ideia de acender um por vez. Tudo a ver a ideia de dar exclusividade de corrente ao pino. Mas o meu desafio é:
-tenho que fazer uma interrupção de uns 3Khz pros 35 segmentos, ou seja , a cada 330uS o sistema seria interrompido pra tratar dos segmentos. Apesar do mc estar a 16Mhz, pretende-se ter pouca tarefas na interrupt.
-o mc tem que ler o sensor de temperatura em I2C e este leva um tempo de ~2mS. Este tempo "parado" deve comprometer a demonstração do display. De fato, não sei como o hw do I2C se comportaria sendo interrompido

Se vc (ou vc) tiver alguma ideia, por gentileza não te acanhes em expô-la. Algo como menos freq de interrupt, ao invés de 1, acender 2 ou 3 segmentos, ou algo do gênero

Agradeço!
Avatar do usuário
msamsoniuk
Dword
 
Mensagens: 2935
Registrado em: 13 Out 2006 18:04

Re: ferrugem em transistores

Mensagempor msamsoniuk » 04 Jun 2016 02:37

genial! :O

Imagem

KrafT escreveu:Zé, eu fiz um projeto assim e postei aqui nos primórdios do Asm51, lá em 2003. Lembro que na época um colega com nick de Professor Francisco, não concordava de jeito nenhum nos benefícios de usar só um resistor por display. No meu caso era um termômetro de três dígitos, que ficou funcionando até o ano passado, quando desativei o trem.

Não dava para tirar foto nem filmar o dsiplay :?
Avatar do usuário
msamsoniuk
Dword
 
Mensagens: 2935
Registrado em: 13 Out 2006 18:04

Re: ferrugem em transistores

Mensagempor xultz » 04 Jun 2016 11:57

Eu não sei como é no STM32 que o Zé vai usar, mas no caso dos PICs uma transmissão de I2C tem três etapas que demoram: mandar um Start, mandar o byte, e mandar um Stop. Esses três eventos podem gerar interrupção, então eu acabei fazendo uma máquina de estados na ISR (porque os PICs de 8 bits têm um único vetor de interrupção), que fazia toda a comunicação por I2C. Assim, o loop principal marcava num flag que queria começar a comunicar, mandava um Start e setava o flag prá gerar interrupção. Na ISR, mandava o byte e setava prá gerar interrupção, e depois a ISR mandava o stop ou próximo byte ou desistia da ideia e ia vender coco na praia, conforme o caso, e desse jeito o resto meio que coexistia sem stress.
98% das vezes estou certo, e não estou nem aí pros outros 3%.
Avatar do usuário
xultz
Dword
 
Mensagens: 3001
Registrado em: 13 Out 2006 18:41
Localização: Curitiba

Re: ferrugem em transistores

Mensagempor msamsoniuk » 04 Jun 2016 14:15

xultz escreveu:Eu não sei como é no STM32 que o Zé vai usar, mas no caso dos PICs uma transmissão de I2C tem três etapas que demoram: mandar um Start, mandar o byte, e mandar um Stop. Esses três eventos podem gerar interrupção, então eu acabei fazendo uma máquina de estados na ISR (porque os PICs de 8 bits têm um único vetor de interrupção), que fazia toda a comunicação por I2C. Assim, o loop principal marcava num flag que queria começar a comunicar, mandava um Start e setava o flag prá gerar interrupção. Na ISR, mandava o byte e setava prá gerar interrupção, e depois a ISR mandava o stop ou próximo byte ou desistia da ideia e ia vender coco na praia, conforme o caso, e desse jeito o resto meio que coexistia sem stress.


pois eh, depende muito do hardware... por exemplo, tem um DSP que projetamos na firma para fazer processamento de voz em realtime, mas ele nao suporta interrupcoes, pq foi projetado para ser compacto, de modo que conseguimos colocar 16 deles rodando a 125MHz em uma FPGA LX25 da xilinx! pow! ser que tem mercado para um curso "projete seu proprio DSP"? :v hahaha

bom, dada as limitacoes, fizemos algo assim:

Código: Selecionar todos
int lastsync = 0;
while(1)
{
  int sync = *SYNC;
  if(sync!=lastsync)
  {
    lastsync = sync;
    *PCM0 = process(*PCM0);
    *PCM1 = process(*PCM1);
    ...
  }
}


basicamente, o existe um registro SYNC que eh incrementado de forma sincronizada pelo hardware TDM externo a taxa de 8kHz. entao o DSP fica em loop testando se esse cara muda. se ele mudar, ele le, processa e escreve os registros de audio PCM, que eh um double-buffer do audio que entra e sai do DSP. o DSP tem uma janela de 125us para processar TODOS os canais, do contrario o double-buffer faz o swap e ele perde as amostras de audio. o processamento pode ser variado: cancelamento de eco, geracao de tons, deteccao de tons, etc. o codigo tem que ser bem deterministico, quer dizer, digamos que vc tem 25us para o pior caso. entao 125/25 = 5. mas fica meio na tampa, entao pode ser bom processar apenas 4 canais e deixar uma margem de 25us livres para eventuais variacoes de processamento.

apesar de ser sem interrupcoes, funciona bem. medindo com o osciloscopio, a partir do pulso de sincronismo externo de 125us, dah para ver bem o comportamento: o inicio das funcoes ocorre com um pequeno jitter, conforme o loop principal se sincroniza com a mudanca de frame, entao ele chama as funcoes e elas consomem uma certa fatia de tempo, que varia conforme o dado de entrada. deixando com persistencia infinita por um bom tempo com audio randomico, confirmamos que o processamento nao se aproxima de consumir a janela inteira de 125us. eh dificil convencer os desenvolvedores de que eles tem que fazer tudo em um tempo limitado. o primeiro contato do cara eh sempre mais dificil, pq ele pensa daquela forma tipo "stream" em C, por exemplo, um filtro:

Código: Selecionar todos
process()
{
  while((c = getchar() != EOF)
  {
    d = (c+d)/2;
    putchar(c);
  }
}


tem que ser reescrito de forma generica para multiplos canais, onde ele recupera, processa e armazena:

Código: Selecionar todos
int process(int ch, int c)
{
  static int d[MAXCH];

  return d[ch] = (c+d[ch])/2
}


eventualmente, uma variacao do loop principal poderia incluir uma avaliacao de performance:

Código: Selecionar todos
int lastsync = 0, idle=0;
while(1)
{
  int sync = *SYNC;
  if(sync!=lastsync)
  {
    lastsync = sync;
    if(idle==0) overload(idle);
    idle=0;
    *PCM0 = process(0,*PCM0);
    *PCM1 = process(1,*PCM1);
    ...
  }
  else idle++;
}


ou seja, quando ele estah em idle esperando o proximo sincronismo, ele nao processa nada e fica incrementando a variavel idle. conforme o processamento aumenta, idle diminui e conforme o processamento diminui, idle aumenta. se a rotina for maior que 125us, idle nem vai incrementar uma rotina de tratamento de overload eh ativada, avisando que houve problema no processamento.

se tiver interrupcao, claro, fica mais simples:

hw -> interrupcao -> buffer -> loop principal -> processo

em um HC908 eu implementei algo assim e foi bem bacana: no loop principal, eu testava um buffer de mensagens. conforme havia mensagem, no header da mensagem havia tb o id da respectiva task. assim, quando havia alguma mensagem no buffer, ele ativava a respectiva task, do contrario apenas ficava em idle, incrementando o contador para testar performance tal. quem colocava mensagens no buffer eram as interrupcoes. entao quando uma interrupcao ocorria, ela naturalmente inseria mensagens no buffer. por ex, uma interrupcao de UART RX recebia um byte e colocava nesse buffer central. com isso, o atendimento de interrupcao ficava bem rapido, de modo que um burst de recebimento de dados ia direto para o buffer. quando sobrava tempo, o loop principal escalava as tasks na ordem das mensagens do buffer, no ex, a task de uart_rx. o objetivo de deixar o processamento fora da interrupcao eh justamente permitir que o microcontrolador consiga um volume alto de interrupcoes, diminuindo a latencia no atendimento e evitando perda de dados. pow! sera q tem mercado para um curso "projete seu proprio RTOS"? :v hahaha
Avatar do usuário
msamsoniuk
Dword
 
Mensagens: 2935
Registrado em: 13 Out 2006 18:04

Re: ferrugem em transistores

Mensagempor xultz » 04 Jun 2016 16:26

Marcelo, não sei se tem mercado pros cursos que você disse, mas quando criar, pode preencher meu nome nos dois! :)

Esse DSP que você inventou parece aquelas PRU (Programmable Real Time Unit) dos processadores da Texas (OMAP), que são uns microcontroladores bem simprinhos ficam dentro do core do processador, que não têm interrupção e servem prá ficar num loop infinito fazendo uma única coisa, bem feita, rápida e determinística.
98% das vezes estou certo, e não estou nem aí pros outros 3%.
Avatar do usuário
xultz
Dword
 
Mensagens: 3001
Registrado em: 13 Out 2006 18:41
Localização: Curitiba

Re: ferrugem em transistores

Mensagempor ze » 04 Jun 2016 18:43

M.San ... a qualquer momento vou dar mais algumas relidas pra tentar digerir isso que vc digitou. Sou 1/2 2old4this

o i2c é por hw mesmo com a tradicional sequencia. O pseudo código que digito online (não tenho o fonte atualizado cá em casa)

Código: Selecionar todos
unsigned int i2cread(unsigned char adress)
{
unsigned int dado;
start(); //só seta 1 bit
endereco_fisico(); //só escreve num registro com ultimo bit em 0
stop();//só seta 1 bit
start();//só seta 1 bit
endereco_interno(addres);//só escreve num registro com último bit em 1
dado=REGISTRO_do_I2C;
dado<<=8;
dado|=REGISTRO_do_I2C;
stop();//só seta 1 bit
return dado;
}

entre cada evento acima tenho que esperar um flag do hw, por isso os aproximados 2mS.
Pra este projeto, uma medição por segundo tá bonde+. Ja pra um outro são 8 termopares, portano 125mS cada 1
Vou focar neste por hora e fazer uma interrupt 3Khz e ver o comportamento do hw do i2c mesmo sendo interrompido. De fato, com os atuais 800Hz eu espero a interrupção liberar um flag pra ler o i2c. Algo como
Código: Selecionar todos
interrupt_timer2()
{
...
flag=1;
...
)

e no loop principal
Código: Selecionar todos
if (flag) {temperatura=i2cread(xxxx);flag=0;}

(ou algo do gênero. Já disse que não tenho fonte aqui pow!!. Puts.. minha memória tá funcionando!)
a ideia é garantir que a leitura é sempre feita entre interrupts. Mas como disse não vou dar mais bola pra isso, aumentar a freq e ler i i2c pra ver que merdadá. Em último caso, como a freq i2c é 50Khz, penso que posso criar algo assim pra cada evento da função i2c_read()... sei lá.

Xults, realmente vil algum exemplo na net pra este mc rodando via interrupção mesmo. No entando tive dificuldade em dominar isso

Kraft, procura o proejto aí no seu baú mofado pra gente fazer troca troca .. de conhecimento!
Avatar do usuário
ze
Dword
 
Mensagens: 1655
Registrado em: 05 Jun 2007 14:32

Re: ferrugem em transistores

Mensagempor KrafT » 04 Jun 2016 18:58

ze escreveu: Kraft, procura o proejto aí no seu baú mofado pra gente fazer troca troca .. de conhecimento!


Então... Não tenho mais o código, mas liguei todos os segmentos e ponto decimal num port inteiro e o comum via um resistor (em cada pino) em outras três IOs, totalizando 11 IOs para display.

Aí no timer eu varria os sete LEDs de cada segmento um a um. Como os comuns dos displays estavam em IOs diferentes, a velocidade tinha que ser apenas 8x a que seria necessário se eu utilizasse 8 resistores.

Foi só um preciosismo, porque era para fazer um Ar Condicionado comum virar "digital". Como aluguei a casa, eu arranquei a automação e deixei o modo eletromecânico para o inquilino.

Mas... Viajado um pouco, talvez dê para ligar todos os segmentos simultaneamente, se calcular o tempo que os mesmos devem ficar ligados para compensar o "compartilhamento de corrente" dos segmentos acesos. Mas a cada alteração nos LEDs, esses tempos teriam que ser recalculados e recarregados. :oops:

@Marcelo Sam, tais com o modo verbose ativado, heh :mrgreen: :mrgreen: :mrgreen: Gosto das aulas do Sam e do MOR_AL.
"..."Come to the edge," he said. And so they came. And he pushed them. And they flew."― Guillaume Apollinaire
Avatar do usuário
KrafT
Dword
 
Mensagens: 2228
Registrado em: 11 Out 2006 14:15
Localização: Blumenau -SC

Re: ferrugem em transistores

Mensagempor msamsoniuk » 05 Jun 2016 00:40

bom, eu conheco o conceito das PRUs da texas bem superficialmente... a motorola usou bastante um conceito similar na decada de 90 nas TPUs (co-processadores RISC para automacao) e QUICCs (co-processadores RISC para telecom). acho que no fim das contas, os conceitos convergem para uma solucao comum: um processador RISC rapido e simples capaz de simular operacoes de IO... conheco bem o conceito. e usar algo do genero em uma FPGA sempre foi uma "carta na manga", aquele recurso para usar em caso de panico e tal... mas normalmente eu sempre resolvi os problemas usando hardware diretamente. de fato, a minha experiencia em projetos complexos mostrou que em 9 entre 10 casos, uma solucao por hardware eh mais simples, rapida e barata do que por software! o bernardi, que tambem habita neste forum, nao me deixa mentir sozinho! :v hahaha

mas neh, tinha aquele gap no curriculo: nunca havia projetado um processador. o impulso definitivo, no entanto, veio quando vi esse cara:

http://hackaday.com/2010/12/01/j1-a-sma ... -for-fpga/

na real achei o conceito meio ruim (baseado em stack), mas comprovava que era possivel projetar um processador de 16-bits rodando na faixa dos 100MHz em uma FPGA de baixo custo. mais importante, era compacto o suficiente para colocar varios deles na mesma FPGA, o que rapidamente desperta ideias mirabolantes...

daih, em um daqueles feriados chuvosos de curitiba, acabei implementando um primeiro prototipo de processador de 16-bits rodando a 80MHz, com 1 clock por instrucao e 16 registros de 16 bits. e era tao compacto que dava para colocar dois deles em uma FPGA de 5 dolares, fornecendo 160 MIPS e ao mesmo tempo permitindo uma gama assombrosa de perifericos, gracas a flexibilidade de estar em uma FPGA! mostrei a ideia a outro colega e comecamos a fazer as contas... talvez desse para colocar 48 processadores deste em uma FPGA, cada um rodando um conjunto de codigo para fazer codec de voz e cancelamento de eco. na epoca estavamos em vias de contratar uma empresa externa para fazer isso e acabamos optando pela solucao baseada em FPGA. comecamos entao a refinar o conceito para o processador de 16-bits suportar uma unidade MAC de 48-bits e rodar com um clock maior. o resultado final foi um DSP de 16-bits com unidade MAC de 48-bits rodando a 125MHz e com capacidade de executar 9 operacoes na mesma instrucao. criamos ateh um assembler baseado em um grande script em awk! conseguimos espremer 16 cores destes em uma FPGA barata e comecamos entao a trabalhar no codigo. como o objetivo era 48 canais, cada DPS processava 3 canais em sequencia. de inicio, o processamento de um um unico canal consumia 70us, ou seja, rodava um canal por core! mas o pessoal do firmware do DSP conseguiu otimizar o codigo, tirando proveito da capacidade de paralelizar as operacoes, ateh atingir 4 canais processados em apenas 100us, ou seja, seguramente dentro da janela de 125us. como resultado conseguimos, atingir 64 canais por FPGA. claro, essa magia soh eh possivel se a FPGA fornece as interfaces adequadas! no meu caso, cada DSP possui integrado um conjunto de interfaces PCM que convergem para uma highway PCM de 8Mbps e passam por um TDM switch para se integrar nas interfaces de voz do sistema, sem falar em um elegante conceito de FIFO para interface com o sistema, onde eh possivel trocar mensagens com o cluster de DSPs em unicast ou broadcast... enfim, ficou joia! :v

foi uma experiencia legal: a FPGA te permite fazer qualquer coisa, mas esse qualquer coisa eh em tempo de desenvolvimento. uma vez desenvolvido, vc nao mexe no projeto, pq mexer em um unico flip-flop eh como puxar uma carta aleatoria em um castelo de cartas. no caso do cluster de DSPs, a flexibilidade eh incrivel: eu posso projetar virtualmente qualquer capacidade de IO na FPGA em volta do DSP. uma vez pronto e funcionando, eu consigo mexer em aspectos operacionais apenas alterando o software do DSP, que nao causa absolutamente nenhum impacto no resto da FPGA. repensando em projetos antigos que eram hardware puro, se eu tivesse esse DSP na epoca, poderia ter usado FPGAs muito mais compactas e ao mesmo tempo ganhar muito mais flexibilidade.

se tiver curiosidade em dar uma olhada no processador RISC original que projetei, estah disponivel aqui:

https://darklife.org/pics/xilinx/

eh bem simples e conceitual, provavelmente tem bugs ainda nao determinados, mas ateh que funciona e eh uma boa base para comecar a projetar algo maior! :)

xultz escreveu:Marcelo, não sei se tem mercado pros cursos que você disse, mas quando criar, pode preencher meu nome nos dois! :)

Esse DSP que você inventou parece aquelas PRU (Programmable Real Time Unit) dos processadores da Texas (OMAP), que são uns microcontroladores bem simprinhos ficam dentro do core do processador, que não têm interrupção e servem prá ficar num loop infinito fazendo uma única coisa, bem feita, rápida e determinística.
Avatar do usuário
msamsoniuk
Dword
 
Mensagens: 2935
Registrado em: 13 Out 2006 18:04

Re: ferrugem em transistores

Mensagempor msamsoniuk » 05 Jun 2016 00:56

ah, mas se vc jah usa esse conceito para a interrupcao, jah eh meio caminho andado: a rotina de interrupcao fica curta e rapida, nao interferindo em outras interrupcoes de maior prioridade. e com o volume de dados que vc precisa ler da i2c, acho que fica tranquilo, pode ateh colocar um low-power-stop no loop para o processador dormir e economizar energia! :D

tipo:

Código: Selecionar todos
while(1)
{
  if(flag1) codigo1;
  if(flag2) codigo2;
  ...
  lpstop();
}


daih quando tiver uma interrupcao, ele acorda, processa a interrupcao, que seta um flagN para um codigoN rodar e daih dorme, economizando energia... rola ateh um "selo dollynho ISO14000 de iniciativa verde"! \o/ hehehe

ze escreveu:M.San ... a qualquer momento vou dar mais algumas relidas pra tentar digerir isso que vc digitou. Sou 1/2 2old4this
Avatar do usuário
msamsoniuk
Dword
 
Mensagens: 2935
Registrado em: 13 Out 2006 18:04

Re: ferrugem em transistores

Mensagempor msamsoniuk » 05 Jun 2016 00:57

KrafT escreveu:@Marcelo Sam, tais com o modo verbose ativado, heh :mrgreen: :mrgreen: :mrgreen: Gosto das aulas do Sam e do MOR_AL.


as vezes eu gosto de contar historias... mas soh as vezes! :v
Avatar do usuário
msamsoniuk
Dword
 
Mensagens: 2935
Registrado em: 13 Out 2006 18:04

Re: ferrugem em transistores

Mensagempor MOR_AL » 05 Jun 2016 11:53

KrafT escreveu:
@Marcelo Sam, tais com o modo verbose ativado, heh :mrgreen: :mrgreen: :mrgreen: Gosto das aulas do Sam e do MOR_AL.


Valeu KrafT :)
MOR_AL
"Para o triunfo do mal só é preciso que os bons homens não façam nada." Edmund Burke.
"Nunca discutas com pessoas estúpidas. Elas irão te arrastar ao nível delas e vencê-lo por possuir mais experiência em ser ignorante". Mark Twain
Avatar do usuário
MOR_AL
Dword
 
Mensagens: 2934
Registrado em: 19 Out 2006 09:38
Localização: Mangaratiba - RJ

controle de display 7seg: dicas de otimização

Mensagempor ze » 06 Jun 2016 12:41

1/2 que concluindo...

o dispositivo em questão
http://www.microchip.com/mymicrochip/No ... -01WJJW313
opera a 100Khz de i2c. Vou fazer a 90; no layout: não muito longe do mc e não muito perto: o calor do mc vai zoar a medição - falando nisso, usar a boa dica do M.San fazendo ele dormir pra esquentar menos; reduzir a freq de interrupt ao mínimo pra não ver o display cintilar e alguns etc.

Se moderador achar que deve, pode trocar o título do tópico para display 7seg: controle de display 7seg: dicas de otimização ou algo do gênero
Se eu achar que devo, publico mais alguns resultados...
+1 vez grato a todos!!
Avatar do usuário
ze
Dword
 
Mensagens: 1655
Registrado em: 05 Jun 2007 14:32

Anterior

Voltar para Circuitos Diversos

Quem está online

Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante

x