.....

Software e Hardware para linha ARM

Moderadores: 51, guest2003, Renie, gpenga

.....

Mensagempor fabim » 20 Ago 2009 16:21

[code]#include <math.h>
#include <LPC210X.h>


#define u16 unsigned int
#define u08 unsigned char

unsigned int const radiano = 360;
unsigned int const numero_pontos = 180;
unsigned int const grau_ponto = radiano/numero_pontos;
unsigned int const resolucao = 32767;
unsigned int const ponto_0 = resolucao / 2;
unsigned int const volume = 500; // minimo 10* (sum_p/4)

u16 raw_sample[180];

void aloca_valores(u16 *pontos){
u08 angulo;

for(angulo = 0; angulo < (numero_pontos/2); angulo++){
*pontos++ = (u16)ponto_0 + (sin((angulo*grau_ponto)*0.017453)*volume);
}

for(angulo = 0; angulo < (numero_pontos/2); angulo++){
*pontos++ = (u16)ponto_0 - (sin((angulo*grau_ponto)*0.017453)*volume);
}

}

////////////////////////////////////////////////////////////////////////////////
int main(void){
aloca_valores(&raw_sample[0]);
for(;;);
}[/code]

mimimi !! mimi...

miiiiiiiii!
fabim
Dword
 
Mensagens: 5001
Registrado em: 16 Out 2006 10:18
Localização: aqui uái!!!?

Mensagempor tcpipchip » 20 Ago 2009 16:27

Gyroscope ?
Avatar do usuário
tcpipchip
Dword
 
Mensagens: 6560
Registrado em: 11 Out 2006 22:32
Localização: TCPIPCHIPizinho!

Mensagempor fabim » 20 Ago 2009 16:34

[quote="tcpipchip"]Gyroscope ?[/quote]


mimi!!
Gerar senoide para DAC ou pwm..
Com amplitude controlavel...

Se precisar de uma amplitude menor, precisa de diminuir o numero de samples.

Um amigo nosso duvidou que eu dava conta, me chamou de mula véia e de zé mané.

o LPC2103 em 60mhz, demora 168mS pra gerar os calculos.

MIMI !!!
fabim
Dword
 
Mensagens: 5001
Registrado em: 16 Out 2006 10:18
Localização: aqui uái!!!?

Mensagempor Jorge_Francisco » 20 Ago 2009 17:01

Gerador senoidal com defasagem de 90º. Muito legal, e aí fabim o que está achando dos ARM's? Valem à pena no seu escopo? Está aprendendo por aprender ou acha que tem grande uso nos seus projetos?

Abraço.
Avatar do usuário
Jorge_Francisco
Dword
 
Mensagens: 1009
Registrado em: 12 Out 2006 09:53
Localização: Rio de Janeiro

Mensagempor Jorge_Francisco » 20 Ago 2009 17:04

Reduz 2 for's para 1 só pow!!!
Avatar do usuário
Jorge_Francisco
Dword
 
Mensagens: 1009
Registrado em: 12 Out 2006 09:53
Localização: Rio de Janeiro

Mensagempor proex » 20 Ago 2009 17:13

Fabin disse: Se precisar de uma amplitude menor, precisa de diminuir o numero de samples.

Proex disse: Isso não pode acontecer. O Sampling Rate tem que ficar fixo.

Faça assim com áudio digital e verá a porcaria que vai ficar seu controle de volume.

Controle de amplitude (ou volume) é uma função logaritmica, e deve atuar somente na amplitude da forma de onda e nada mais.

Estuda mais um pouquinho que vc consegue.

mi mi mi mi mi !!!!
Editado pela última vez por proex em 20 Ago 2009 17:14, em um total de 1 vez.
proex
Dword
 
Mensagens: 2101
Registrado em: 11 Out 2006 14:05
Localização: São Paulo

Mensagempor fabim » 20 Ago 2009 17:13

olha velho, vou ser sincero.
A unica coisa que encomoda é que não tem arm de 28 pinos e DIP.

Soldar isso é um parto, e esse monte de pino sobrando é druris.

No mais, ser sincero.

Estamos acostumado com pic, para projetos simples de alarmes, controladores simples, automação simples etc.
Logicamente, que existem aqueles que fazem um pic virar um jato e controlar tanta coisa que da até medo.
Não é correto menosprezar a linha uxip, mais no meu ver AGORA.
Levando em consideração numero de pinos, perifericos, consumo, velocidade, arquitetura bem flexivel e fazendo uma comparação com uxip tem sim a possibilidade de substituir um 18f4550 por um LPC1766, que são de mesmo custo mais com capacidades incomparaveis.
Tanto como um 16f877/18f452 por um LPC2103 por exemplo.

Unica coisa que me deixou muito animado, é que não preciso mais me preocupar com tempo de execução.
Por exemplo o DTS5000 que estou desenvolvendo.
18F4550 a 12 mips, fazendo 5860 amostras de um DAC externo por segundo, multiplexado. Entre amostras elevar ao quadrado as duas variaveis e depois de 1S/40 tirar o RMS, e sem parar de fazer amostragem. Meo precisei ficar um tempão debugando, enxugando e batenco a cabeça.
Ja no arm, hum..

Abraços

E sim, ARM7=> sim compensa substituir. Logico que não vai colocar um ARM7 pra piscar led, ou fazer um alarme ou central de portão, baita despercidio.

Abraços2


Fabim
fabim
Dword
 
Mensagens: 5001
Registrado em: 16 Out 2006 10:18
Localização: aqui uái!!!?

Mensagempor fabim » 20 Ago 2009 17:18

[quote="proex"]Fabin disse: Se precisar de uma amplitude menor, precisa de diminuir o numero de samples.

Proex disse: Isso não pode acontecer. O Sampling Rate tem que ficar fixo.

Faça assim com áudio digital e verá a porcaria que vai ficar seu controle de volume.

Controle de amplitude (ou volume) é uma função logaritmica, e deve atuar somente na amplitude da forma de onda e nada mais.

Estuda mais um pouquinho que vc consegue.

mi mi mi mi mi !!!![/quote]

Mula véia.
De 0 a 90° = 45 amostras.

estamos workando com valores inteiros.

coloca 45 por exemplo no calculo, ou coloca 25...veja a resultante.

mimii !!! eu ja sabia!! mimimi!! estou falando de calculo de seno pra gerar os valores para senoide, o calculo que eu fiz!!! mimimi

Abraços

mimi!!!
fabim
Dword
 
Mensagens: 5001
Registrado em: 16 Out 2006 10:18
Localização: aqui uái!!!?

Mensagempor B-EAGLE » 20 Ago 2009 21:40

esses dias modulei a amplitude de um sinal de 60hz em 12-45hz num ADuC7026 (arm7)...

tenho o código aqui ainda... ficou legal a parada, por interrupción! :D

ah! os semiciclos positivos em DAC0 e os negativos em DAC2...

Código: Selecionar todos
#include <ADuC7026.h>               // ADuC7026 definitions
#include <stdio.h>
#include <math.h>

//**************Protótipos das funções***************
void inicializa(void);
void configura_ad(void);
void configura_da(void);
unsigned short le_ad(unsigned char);
void configura_timer1(void);
void IRQ_Handler(void) __irq;
void portadora(double);
//***************************************************

//****************Variáveis globais******************
unsigned short res_ad;
unsigned int x, i;
float temp, t;
unsigned short valores_dac0[360];
unsigned short valores_dac1[360];
//***************************************************


void main(void){
   inicializa();
   configura_ad();
   configura_da();
   portadora(35);
   while(1);
}

void portadora(double freq){
   double periodo_port;
   for(t = 0; t < 360; t++){
      temp = sin(t*0.0174532925)*3276;            //fórmula seno
      if (t <= 180){                           //valores para senóide DAC0
         valores_dac0[t] = ((unsigned short)temp);
         valores_dac1[t] = 3276;
      }
      else{                                 //valores para senóide DAC2
         valores_dac0[t] = 0;
         valores_dac1[t] = ((unsigned short)temp);
      }         
   }
   //cálculo e configuração timer1 para interrupção e atualização da senóide
   periodo_port = 1/freq;                     //calcula período da portadora
   periodo_port /= 360;                     //divide pela qtd de pontos totais da senóide = periodo de interrupção
   T1LD = periodo_port/0.0000000239348970799426;   //divide periodo de interrupção   pelo período do clock do core (41.78MHz)
   T1LD -= 3;   
   T1CON = 0xC0;                           // Enabled,Periodic,Binary and CLK/16
   IRQEN = GP_TIMER_BIT;                     // Enable XIRQ0 and Timer1 IRQ
   i = 0;                                 //contador de ponto da senóide = 0
   return;
}
 
void inicializa(void){
   PLLKEY1 = 0xAA;      //sequência para habilitar escrita em PLLCON
   PLLCON = 0x21;      //registrador de seleção de fonte de clock
   PLLKEY2 = 0x55;      //PLLCON = 0x21 -> Internal 32KHz clock source

   POWKEY1 = 0x01;      //sequência para habilitar escrita em POWCON
   POWCON = 0x00;      //registrador de divisor do clock.
   POWKEY2 = 0xF4;      // POWCON = 0 -> CD = 0 / clock divider = 0 -> 41.78MHz;

   CMPCON = 0x400;      //comparador desabilitado

   GP4CON = 0x0000;   //todos pinos de P4 são GPIO
   GP4DAT = 0x04000000;

   return;
}

void configura_ad(void){
   unsigned int time_wakeup;
   time_wakeup = 50000;
   ADCCON = 0x20;                     //ADC on;
   while (time_wakeup > 0) time_wakeup--;   //wake-up time para o ADC   
   ADCCON = 0x0223;                  // fADC/1 - 8 clocks - single-ended mode - single sw conv //0000 0010 0010 0011   
   REFCON = 0x01;                     //referência interna de 2.5V conectada ao Vref
   return;
}

unsigned short le_ad(unsigned char canal){
    ADCCP = canal;               //seleciona canal
   ADCCON |= 0x083;            //inicia conversão   
   while(!ADCSTA);               //espera conversão finalizar
   return (ADCDAT >> 16) & 0x0FFF;   //retorna resultado em 12 bits
}
      
void configura_da(void){
   DAC0CON = 0x12;      //core-clock dac update - referência interna de 2.5V   
   DAC2CON = 0x12;      //core-clock dac update - referência interna de 2.5V   
   return;
}   

void IRQ_Handler() __irq {                  // example with two IRQ
   if ((IRQSTA & GP_TIMER_BIT) != 0){
      T1CLRI = 0;                        // Clear Timer IRQ
      DAC0DAT = valores_dac0[i] << 16;
      DAC2DAT = valores_dac1[i] << 16;
      i++;
      if (i == 360) i = 0;
   }             
   return ;
}            
B-EAGLE
Word
 
Mensagens: 847
Registrado em: 19 Out 2006 14:12
Localização: Campo Grande - MS

Mensagempor fabim » 21 Ago 2009 08:16

poisé.
nada impede de usar um potenciometro digital de 255 niveis.

saindo do PWM, a cada 2* Sample/4, e controlando a amplitude novamente no potenciometro digital.

com essa rotina, tu faz a roda cortada em qualquer frequencia que o pwm e o core permita.
Por exemplo de 0,5hz a trocentos hz.

ia me esquecendo.

*pontos++ = (u16)ponto_0 + (sin((angulo*grau_ponto)*0.017453)*volume);
/***********************************************************
Ponto_0 = ponto de onde vai partir o 0 da senoide, o seu valor deve ser tal que a soma de volume não ultrapasse o ranger do PWM ou DAC.
/************************************************************
Volume = peso no qual o calculo vai gerar a senoide.
/************************************************************
sin((angulo*grau_ponto)*0.017453)*

sin() = calculo seno do keil, ele trabalha em radianos.

angulo*grau_ponto = angulo é o sample do momento que vai de 0 a 180.
grau_ponto = 360°/numero samples180 = 2°.
0.017453 =radianos, como estou calculando para 180°.. sendo 0 - 90 - 180, o radiano = PI/180.

EX.:
sin((45*2°)*0.017453)*5000 = 5000

para por exemplo o ponto_0 = 15000.
o VP+ em 90° = 15000 + 5000,

Para gerar o semi ciclo de 180 a 270, é so fazer o ponto_0 - as mesmas resultantes ou fazer direto.

Abraços
fabim
Dword
 
Mensagens: 5001
Registrado em: 16 Out 2006 10:18
Localização: aqui uái!!!?

Mensagempor tcpipchip » 21 Ago 2009 09:56

Por falar em PERFORMANCE...faz um teste ai...

Mude o tipo de dado de "angulo" para 32 bits sem sinal...assim...o compilador nao vai passar trabalho em gerar os ROL da vida para alinhamento (32 bits)

Enfim, evite usar tipos de dado u8

Testa ai Fabim...

TCPIPCHIP
Editado pela última vez por tcpipchip em 22 Ago 2009 22:03, em um total de 1 vez.
Avatar do usuário
tcpipchip
Dword
 
Mensagens: 6560
Registrado em: 11 Out 2006 22:32
Localização: TCPIPCHIPizinho!

Mensagempor fabim » 21 Ago 2009 12:31

[quote="tcpipchip"]Por falar em PERFORMANCE...faz um teste ai...talvez para pequenos loops nao faça diferença....

Mude o tipo de dado de "angulo" para 32 bits sem sinal...assim...o compilador nao vai passar trabalho em gerar os ROL da vida para alinhamento (32 bits)

Enfim, evite usar tipos de dado u8

Testa ai Fabim...

TCPIPCHIP[/quote]

CARACA...!!!!!!!!!!
De 165mS para preencher o raw.
Coloquei tudo como unsigned long.
caiu para "6.37352mS"
casetada. 6mS!!
fabim
Dword
 
Mensagens: 5001
Registrado em: 16 Out 2006 10:18
Localização: aqui uái!!!?

Mensagempor tcpipchip » 21 Ago 2009 16:48

Legal né Fabim !!!!

Fico feliz que baixou para 6ms...

Depois que se estuda o assembly do ARM, a gente vê alguns pontos fracos de alguns dos compiladores na geração de código do código assembly.

Que tal baixarmos para 3 ms ?

TCPIPCHIP
Avatar do usuário
tcpipchip
Dword
 
Mensagens: 6560
Registrado em: 11 Out 2006 22:32
Localização: TCPIPCHIPizinho!

Mensagempor fabim » 25 Ago 2009 12:51

[quote="tcpipchip"]Legal né Fabim !!!!

Fico feliz que baixou para 6ms...

Depois que se estuda o assembly do ARM, a gente vê alguns pontos fracos de alguns dos compiladores na geração de código do código assembly.

Que tal baixarmos para 3 ms ?

TCPIPCHIP[/quote]

TCP, desisto.
Fiz algumas modificações e mesmo assim, cheguei no minimo de 5.383mS.

Abraços

Fabim
fabim
Dword
 
Mensagens: 5001
Registrado em: 16 Out 2006 10:18
Localização: aqui uái!!!?


Voltar para ARM

Quem está online

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

x