Pages: [1]   Go Down
Author Topic: Manipulação de portas  (Read 277 times)
0 Members and 2 Guests are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Eu li um artigo no site do arduino muito interessante falando sobre manipulação de portas: http://playground.arduino.cc/Learning/PortManipulation
Minha pergunta é a seguinte: Porque não estão todas nesse artigo? Vi num tópico aqui no fórum que existem mais, como a TCCR0A, que pelo entendi, serve pra mudar a frequência do PWM.
Logged

Portugal
Offline Offline
God Member
*****
Karma: 33
Posts: 964
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Penso que não viu esta parte:
Quote
Generally speaking, doing this sort of thing is not a good idea.

Se quiser todas, pode sempre ler o datasheet:
http://www.atmel.com/Images/doc8161.pdf

Tem 448 páginas para procurar todo o tipo de "portas" smiley .

O objectivo desta plataforma é tornar o microcontroladores fáceis para que qualquer pessoa (como diz o lema hobbyists and artists) os possam utilizar sem que para isso seja necessário ter muitos conhecimentos de electrónica e/ou programação. Se fosse necessário utilizar os registos especiais do microcontrolador, isso deixava de ser assim. No entanto, se quiser (e principalmente se tiver conhecimentos para isso), pode sempre programar o Arduino utilizando um IDE diferente e mesmo uma linguagem de programação diferente (por exemplo Assembler), porque o hardware mantém-se o mesmo.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 9
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bom dia FabioCarpi.
Tenho passado pelos mesmos problemas que vc  para manipular registradores internos do Atmega. Aconselho que vc faça como eu fiz, baixe o datasheet do atmega que vc usa, e então baixe algum livro sobre AVR ou ARM, vai te ajudar e elucidar muita coisa. Baixei alguns livros, não lembro onde salvei no meu PC, quando achar eu posto aqui.
Sds.

Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Eu achei a lista de registradores. Mas esperava  que tivesse explicação de pra que serve cada um e de como usar.... smiley-sad
Logged

Portugal
Offline Offline
God Member
*****
Karma: 33
Posts: 964
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

No datasheet que eu postei está lá tudo explicado.
Se tiver um exemplo prático talvez haja alguém que o consiga ajudar. Volto a chamar a atenção para a parte de:
Quote
Generally speaking, doing this sort of thing is not a good idea.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Desculpe, eu não vi seu post
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Eu até entendo os riscos de mexer nos registradores. Eu só queria saber por curiosidade mesmo. Mas qual o perigo de eu ficar limitado só as portas descritas no site do http://playground.arduino.cc/Learning/PortManipulation?
Logged

Portugal
Offline Offline
God Member
*****
Karma: 33
Posts: 964
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Os perigos, são descritos também no artigo:
Quote
  •     The code is much more difficult for you to debug and maintain, and is a lot harder for other people to understand. It only takes a few microseconds for the processor to execute code, but it might take hours for you to figure out why it isn't working right and fix it! Your time is valuable, right? But the computer's time is very cheap, measured in the cost of the electricity you feed it. Usually it is much better to write code the most obvious way.
  •     The code is less portable. If you use digitalRead() and digitalWrite(), it is much easier to write code that will run on all of the Atmel microcontrollers, whereas the control and port registers can be different on each kind of microcontroller.
  •     It is a lot easier to cause unintentional malfunctions with direct port access. Notice how the line DDRD = B11111101; above mentions that it must leave pin 1 as an input pin. Pin 1 is the receive line on the serial port. It would be very easy to accidentally cause your serial port to stop working by changing pin 1 into an output pin! Now that would be very confusing when you suddenly are unable to receive serial data, wouldn't it?

Basicamente, usando o acesso directo aos registos de memória que controlam as portas (ou outra coisa qualquer), perdem-se as grandes vantagens deste sistema - a facilidade de programação e a portabilidade (este último ponto quer dizer o quê? Quer dizer que eu posso escrever um sketch para o Arduino UNO e descarregá-lo para o MEGA que ele vai funcionar igual, se eu usar o acesso directo pode não funcionar - certamente não vai funcionar, diria até)

A pergunta original estava relacionada com o registo TCCR0A. Procurando referencias sobre este registo no datasheet (que coloquei na primeira resposta), chega-se ao ponto 14.9.1 da página 106. Lendo-se isto, chega-se à conclusão que este registo não tem nada a ver com portas, mas sim com Temporizadores/Contadores. Como o artigo, apenas faz referencia aos registos dedicados às portas, este registo não está contemplado nesse artigo.

Se quer ver como as coisas funcionam "por dentro", pode deitar um olho aos ficheiros da pasta (por exemplo):
INSTALAÇÃO/hardware/arduino/avr/cores/arduino
Logged

'round the world...
Offline Offline
Faraday Member
**
Karma: 42
Posts: 3216
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Procura por AVR Application Notes.

http://www.atmel.com/products/microcontrollers/avr/megaavr.aspx?tab=documents

La tem exemplos sobre como mexer nos registos internos. Tem cuidado que registos nao sao portas... smiley-wink
Logged

Eu não sou o teu criado. Se respondo no fórum é para ajudar todos mediante a minha disponibilidade e disposição. Responder por mensagem pessoal iria contra o propósito do fórum e por isso evito-o.
Se realmente pretendes que eu te ajude por mensagem pessoal, então podemos chegar a um acordo e contrato onde me pagas pela ajuda que eu fornecer e poderás então definir os termos de confidencialidade do meu serviço. De forma contrária toda e qualquer ajuda que eu der tem de ser visível a todos os participantes do fórum (será boa ideia, veres o significado da palavra fórum).
Nota também que eu não me responsabilizo por parvoíces escritas neste espaço pelo que se vais seguir algo dito por mim, entende que o farás por tua conta e risco.

Dito isto, mensagens pessoais só se forem pessoais, ou seja, se já interagimos de alguma forma no passado ou se me pretendes convidar para uma churrascada com cerveja (paga por ti, obviamente).

São Paulo / Brasil
Offline Offline
Full Member
***
Karma: 1
Posts: 160
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Olá!

Veja se isto ajuda:

https://spreadsheets.google.com/spreadsheet/pub?key=0AtfNMvfWhA_ccnRId19SNmVWTDE0MEtTOV9HOEdQa0E&gid=0

Abraço.
Fernando Garcia
Logged

Conheça uma nova opção Open Source para controlar seu aquário: www.ferduino.com

Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Então me surgiu 2 duvidas:

1) Pelo texto dito:
Quote
It is a lot easier to cause unintentional malfunctions with direct port access. Notice how the line DDRD = B11111101; above mentions that it must leave pin 1 as an input pin. Pin 1 is the receive line on the serial port. It would be very easy to accidentally cause your serial port to stop working by changing pin 1 into an output pin! Now that would be very confusing when you suddenly are unable to receive serial data, wouldn't it?
Qual seria a diferença do exemplo dado, DDRD = B11111101 para o pinMode(1, INPUT)?

2) A descoberta desses registradores tinha me dado uma luz pro que eu queria fazer, que é enviar os estados de todos os pinos pelo I2C. Sem usar o registrador, como mandar os estados como um byte?
« Last Edit: July 22, 2014, 08:27:56 pm by FabioCarpi » Logged

Portugal
Offline Offline
God Member
*****
Karma: 33
Posts: 964
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Qual seria a diferença do exemplo dado, DDRD = B11111101 para o pinMode(1, INPUT)?

Do ponto de vista prático, nenhuma. As duas instruções iriam ter o mesmo efeito. No entanto não é isso que o texto diz. Por exemplo, se o a alteração a DDRD for feita utilizando o resultado de uma cálculo e se por algum motivo esse cálculo introduzir um bit " 1 " naquele espaço xxxxxx1x a placa deixa de receber dados utilizando a porta série.  Utilizando a função pinMode() isso tem muito menos probabilidades de acontecer.

A descoberta desses registradores tinha me dado uma luz pro que eu queria fazer. Que é enviar os estados de todos os pinos pelo I2C. Sem usar o registrador, como mandar os estados como um byte?

A parte boa da programação é que há sempre uma maneira de dar a volta à situação, seja ela fácil ou difícil.
A 1ª questão é: "enviar os estados" não é alterar os estados;
A 2ª questão é: "mandar os estados como um byte" para quê (estou a pensar num byte genérico, por exemplo o TCCR0A? para quê?) Quer fazer um debuger ou alguma coisa desse género por sua conta? Não acha que é demais?

A 3ª questão é: para saber o "estados de todos os pinos", não é necessário ir aos registos, basta usar a função digitalRead(). Faça um vector, com os números de todos os pinos que quer ler, depois com um ciclo for consegue percorrer todo esse vector e ler o estado dos pinos, conforme o estado dos pinos, pode activar (ou desactivar) um bit numa variável.


Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Acho que entendi a questão da serial...
Estou fazendo um sistema de automação e o slave tem que informar os estados dos pinos para o master.
Minha idéia era fazer tipo Wire.write(PIND)
Dessa forma, eu enviaria os estados dos pinos 0 a 7 num único byte.
Se eu fosse fazer via digitalRead, eu iria mandar um byte para cada pino (do jeito que eu sei)
Wire.write(digitalRead(0));
Wire.write(digitalRead(1));
Wire.write(digitalRead(2));
Iria enviar 3 bytes...
Se tiver uma maneira de fazer isso...
Logged

Portugal
Offline Offline
God Member
*****
Karma: 33
Posts: 964
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

O que eu estou a dizer, é uma coisa deste género:
Code:
const int pinos[] = {0, 1, 2, 3, 4, 5, 6, 7}; // porto D (por acaso bate certo com os números)

void setup() {
  for (int i = 0; i < 8; i++) {
    pinMode(pinos[i], INPUT);
  }
}

void loop() {
  byte byteEstado;
  byte bitEstado;
  for (int i = 7; i >=0; i++) {
    bitEstado = digitalRead(pinos[i]);
    byteEstado = (byteEstado<<1) | bitEstado;
  }
  Wire.write(byteEstado);
}

Não sei se está certo ou se tem algum problema, mas penso que dá para perceber a ideia. (também não fui ver se HIGH=1 e se LOW=0, mas estou a partir desse princípio; estou a partir do princípio que a board é a do UNO)
Logged

Pages: [1]   Go Up
Jump to: