Create sdig2_exame_2011-07-06.c

Resolucao do exame de 6 de Julho de 2011

Baseado num ATmega128@1MHz, pretende-se controlar a velocidade e o sentido de rotação de um motor DC utilizando um potenciómetro ligado ao canal 3 do ADC. A relação entre o valor lido pelo ADC e o valor do PWM (OCR2) e sentido de rotação está representada na figura abaixo (lado esquerdo). De notar a existência de uma zona neutra onde o valor de OCR2 deve ser 0.

Funcionamento:
- Após a inicialização do sistema o motor encontra-se parado. Mesmo que o potenciómetro seja accionado o motor deve manter-se parado (modo de funcionamento OFF).
- Para colocar o sistema no modo de funcionamento ON é necessário premir S1. Este modo de funcionamento só é iniciado se a leitura do ADC estiver na zona neutra (461<Leitura_AD<562). Se isto acontecer é activado o LED.
- A partir deste momento, qualquer alteração no potenciómetro vai provocar uma variação da velocidade e do sentido de rotação do motor. O valor de OCR2 e o sentido de rotação são dados pelas seguintes fórmulas:
Se Leitura_AD >= 562: OCR2 = (Leitura_AD – 562) * 256 / 462  PA4=1, PA5=0 (sentido directo)
Se Leitura_AD <= 461: OCR2 = (461 – Leitura_AD) * 256 / 462	PA4=0, PA5=1 (sentido retrógrado)

- O modo de funcionamento ON é desligado se for premido S2. Também neste caso a leitura do ADC deverá estar na zona neutra. Se isto acontecer, o LED é desactivado e o sistema entra em modo de funcionamento OFF.
- A detecção da tecla STOP (emergência) provoca a paragem imediata do motor e a consequente saída do modo de funcionamento ON, desactivando também neste caso o LED.
- Se o sistema se encontrar em modo de funcionamento ON, de 1 em 1s deve ser enviado pela USART o valor actual do sentido de rotação e do OCR2.

Escreva o software necessário à implementação do sistema descrito, de acordo com as seguintes alíneas:
1. Nesta alínea do exercício serão declaradas todas as variáveis globais que utilizar no software e, se necessário, protótipos das funções.

2. Rotina Inic() para a inicialização do sistema:
a. Inicialização dos portos;
b. Inicialização do TIMER0 de modo a permitir gerar uma interrupção de, aproximadamente, 100 em 100 ms (@1MHz);
c. Inicialização do TIMER2, em modo Phase Correct PWM, para gerar em OC2 um PWM com uma frequência de aproximadamente 250Hz (@1MHz);
d. Inicialização do ADC;
e. Inicialização da USART0 para 4800 bps, 8 bits de dados, s/ paridade, 1 stop bit;
f. Inicialização do sistema de interrupções: TIMER0, ADC e enable global.

3. Rotina de serviço da interrupção do TIMER0 (COMP). Esta rotina deve gerar o “start” da conversão do ADC (canal 3) e gerar a temporização de 1s activando a flag_TX no final desta temporização. Esta rotina deve ser escrita em linguagem Assembly.

4. Rotina de serviço da interrupção do ADC (fim de conversão) que faz a leitura dos 10 bits do ADC e calcula o valor da variável Leitura_AD. Deve também activar a flag Fim_conversao.

5. Função Calcula_PWM() que, de acordo com o valor de Leitura_AD, calcula o valor do PWM a aplicar ao motor (OCR2) e o sentido de rotação do motor (PA4 e PA5).

6. Função Print() que envia pela USART uma mensagem com o actual sentido de rotação seguido do valor actual de OCR2. Ex: "D128", "R64"

7. Função main(), programa principal que implementa as seguintes tarefas:
- Inicialização do sistema;
- Leitura e processamento dos interruptores S1, S2 e S3;
- Verificar a flag Fim_conversao. Se o sistema estiver ON, deve ser chamada a função Calcula_PWM();
- Verificação de flag_TX. Se o sistema estiver ON, deve ser enviada uma mensagem utilizando a função Print().

notas:  http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=50106&start=all&postdays=0&postorder=asc