miércoles, 13 de agosto de 2008

Guia de extraordinario control

1.- Dibuja una Señal PWM con frecuencia de trabajo 2 Hz, porcentaje de encendido 25%.


2.- Explica el funcionamiento y sintaxis de la función ó método para recibir datos desde el puerto serial en el lenguaje que utilizaste para programar la comunicación RS232.

3.- Explica el funcionamiento y sintaxis de la función ó método para transmitir datos desde el puerto serial en el lenguaje que utilizaste para programar la comunicación RS232.


1.- Describe el funcionamiento de los siguientes PINS en microcontroladores.

RESET, VCC, GND, PA1, PD5.

2.- Dibuja el diagrama eléctrico de interconexión entre una PC, un puente H a traves de un microcontrolador AVR, utilizando comunicación por protocolo RS232. Sólo es necesario anotar nombre de PINS.

3.- Describe el funcionamiento del siguiente programa:

.include "8515def.inc"

.def temp = r16 ;temporary data
.def temp2= r17

.org $0000
ldi temp,low(RAMEND)
out SPL,temp
ldi temp,high(RAMEND)
out SPH,temp ;init Stack Pointer

ser temp2
out DDRB,temp2 ; Inicializamos el puerto B como salida

rjmp start ;reset handler

.org URXCaddr ;definition in the
rjmp UART_RX_interrupt ;8515 include file

;receive complete interrupt
UART_RX_interrupt:
in temp ,UDR
dec temp
out PORTB,temp
inc temp
rcall transmit
reti

;initialize UART
initialize:
out UBRR, temp ;init baudrate

;enable receiver, transmitter and TXCint
ldi temp, (1<out UCR, temp
sei ;global interrupt enable
ret

;transmit a byte
transmit:
sbis USR,UDRE ;ready to send?
rjmp transmit
out UDR, temp
ret

start:
ldi temp, 11 ;19.200bps@3.686MHz
rcall initialize
forever:
rjmp forever ;eternal loop


miércoles, 6 de agosto de 2008

Programa de PWM con ADC

Es necesario quitar la parde del ADC para utilizar solo control en lazo abierto

.nolist
.include "8535def.inc"
.list

.equ PWM10_TOPVAL = 0x03FF
.equ PWM10_50VAL = 0x01FF
.equ PWM_RLDVAL = 184 ; 20ms with CK/1024
.equ INCR_VAL = 2

.def ZERO = r2
.def INCR = r3
.def PWM_RLD = r4
.def KEY_SCAN= r5
.def TEMP6 = r6
.def TEMP7 = r7
.def canal1 = r8
.def canal2 = r9
.def TEMP = r16
.def PWM10H = r17
.def PWM10L = r18
.def PWM9H = r19
.def PWM9L = r20
.def dato = r21
.def aux = r22
.def TEMP2 = r23
.def RAMTEMP = r24
.def i = r25

.cseg

.org 0x0000
rjmp init

.org INT0addr ; External Interrupt Request 0
reti

.org INT1addr ; External Interrupt Request 1
reti

.org ICP1addr ; Timer/Counter Capture Event
reti

.org OC1Aaddr ; Timer/Counter1 Compare Match A
reti

.org OC1Baddr ; Timer/Counter1 Compare Match B
reti

.org OVF1addr ; Timer/Counter1 Overflow
reti

.org OVF0addr ; Timer/Counter0 Overflow
rjmp T0_OVF

.org SPIaddr ; Serial Transfer Complete
reti

.org URXCaddr ; UART, Rx Complete
rjmp UART_RX_interrupt ;8515 include file

.org UDREaddr ; UART Data Register Empty
reti
.org UTXCaddr ; UART, Tx Complete
reti
.org ADCCaddr ; ADC
reti
.org ACIaddr ; Analog Comparator
reti


UART_RX_interrupt:
in dato ,UDR
cpi i,0
brne salto1
mov canal1,dato
out PORTC,canal1
inc i
; rjmp transmit1
reti
salto1:
mov canal2,dato
out PORTB,canal2
dec i
; rjmp transmit1
reti



init:
; Test for A/D conversion
; ADMUX bit's' 0-2 select a/d channel
; ADCSR (7)enable a/d-1 (6)Start Conv-1 (5)free run-1 (4)interrupt flag
; (3)Do interrupts, (2-0) Prescaler N, ADC clock div=1/2^N
; ADCL/ADCH Low,hi A/D results
; ADCSR is set in RESET
ldi TEMP,0xff
out DDRB,TEMP
ldi TEMP,0xff
out DDRC,TEMP
ldi TEMP,0x00
out PORTB,TEMP
ldi TEMP,0xff
out DDRA,TEMP
out PORTA,TEMP

ldi TEMP, 0b10000111 ;go for slowest most accurate A/D conv "vaya a la velocidad mas lenta del A/D para mejor presicion"
out ADCSR, temp
ser aux
out DDRB,aux ; Set PORTB to output



ldi i,0


ldi temp, 11 ;19.200bps@3.686MHz
out UBRR, temp ;init baudrate
;enable receiver, transmitter and TXCint
ldi temp, (1< out UCR, temp


; init SP
ldi TEMP, LOW(RAMEND)
out SPL, TEMP
ldi TEMP, HIGH(RAMEND)
out SPH, TEMP

; set vars
; ldi PWM10L, LOW(PWM10_50VAL) ; PWM10 start val 50%
; ldi PWM10H, HIGH(PWM10_50VAL)

ldi TEMP, PWM_RLDVAL ; Timer reload value var
mov PWM_RLD, TEMP

ldi TEMP, INCR_VAL
mov INCR, TEMP
clr ZERO

; enable sleep mode
ldi TEMP, (1< out MCUCR, TEMP

; PD5 as output OC1A and PD4 as output OC1B
ldi TEMP, (1< out DDRD, TEMP


; PA0/PA1 as input with pull-up for switches (PWM up/down 0..100%)
; ldi TEMP, (1<; out PORTA, TEMP

; intall 10-bit pwm mode on T/C1
; OC1A non-inverted and OC1B inverted PWM, prescale CK/8
ldi TEMP, (1< out TCCR1A, TEMP
ldi TEMP, (1< out TCCR1B, TEMP

; install interrupt for switch PWMing on T/C0
ldi TEMP, (1< out TIMSK, TEMP
ldi TEMP, (1< 3.686MHz/1024 = 278us
;ldi TEMP, (1< out TCCR0, TEMP
out TCNT0, PWM_RLD ; reload für 20ms

; pwm 50%, load top values
ldi TEMP, HIGH(PWM10_50VAL)
out OCR1AH, TEMP
ldi TEMP, LOW(PWM10_50VAL)
out OCR1AL, TEMP

ldi TEMP, HIGH(PWM10_50VAL)
out OCR1BH, TEMP
ldi TEMP, LOW(PWM10_50VAL)
out OCR1BL, TEMP

sei

main:

rcall pwm_keys
rjmp main

; **** sub routines ****

; -- eval switch scan codes --
; Note, the STK500 keys are low active
; SW0 -> down
; SW1 -> up
pwm_keys:

; for SIMULATOR TEST ONLY
; ldi TEMP, 0x02
; mov KEY_SCAN, TEMP

; check on sw0/PA0
; sbrs KEY_SCAN, PA0
; rcall pwm_dec

; check on sw1/PA1
; sbrs KEY_SCAN, PA1
; rcall pwm_inc

pwm_keys_exit:

ldi TEMP, 0x03
or KEY_SCAN, TEMP ; clear pwm key scan

DO_AD0:
ldi TEMP,0 ;Subtract 65 to get 0<=TEMP<=7
out ADMUX, TEMP ;Select the wanted channel
sbi ADCSR,ADSC
DLOOP0:
sbis ADCSR,ADIF
rjmp DLOOP0

in RAMTEMP,ADCL ;get a/d low byte
in TEMP2,ADCH

lsl TEMP2
lsl TEMP2
lsl TEMP2
lsl TEMP2
lsl TEMP2
lsl TEMP2
lsr RAMTEMP
lsr RAMTEMP
or TEMP2,RAMTEMP

mov PWM9L,canal1

ldi PWM9H,0
clr TEMP
out ADCL,TEMP
clr TEMP
out ADCH,TEMP

DO_AD1:
ldi TEMP,1 ;Subtract 65 to get 0<=TEMP<=7
out ADMUX, TEMP ;Select the wanted channel
sbi ADCSR,ADSC
DLOOP1:
sbis ADCSR,ADIF
rjmp DLOOP1

in TEMP6,ADCL ;get a/d low byte
in TEMP7,ADCH

lsl TEMP7
lsl TEMP7
lsl TEMP7
lsl TEMP7
lsl TEMP7
lsl TEMP7
lsr TEMP6
lsr TEMP6
or TEMP6,TEMP7

mov PWM10L,canal2

ldi PWM10H,0
clr TEMP
out ADCL,TEMP
clr TEMP
out ADCH,TEMP


; set the PWM values
out OCR1AH, PWM9H
out OCR1AL, PWM9L

out OCR1BH, PWM10H
out OCR1BL, PWM10L

rjmp transmit1

ret

; -- decrement PWM --
pwm_dec:

; sub PWM10L, INCR
; sbc PWM10H, ZERO

brmi pwm_dec_limit ; if PWM10 value less than zero, limit it

ret

pwm_dec_limit:

; clr PWM10L
; clr PWM10H

ret

; -- increment PWM --
pwm_inc:

; add PWM10L, INCR
; adc PWM10H, ZERO

; test on PWM TOPVAL
mov TEMP, PWM10L
subi TEMP, LOW(PWM10_TOPVAL + 1)
mov TEMP, PWM10H
sbci TEMP, HIGH(PWM10_TOPVAL + 1)

breq pwm_inc_limit ; if PWM10 value greater than TOPVAL, limit

ret

pwm_inc_limit:

; ldi PWM10L, LOW(PWM10_TOPVAL)
; ldi PWM10H, HIGH(PWM10_TOPVAL)

ret

; ********* ISR *********

T0_OVF:
cli

push TEMP ; save register
in TEMP, SREG
push TEMP

; in KEY_SCAN, PINA ; scan switches on PD

out TCNT0, PWM_RLD ; reload timer

pop TEMP ; restore register
out SREG, TEMP
pop TEMP

sei

reti

transmit1:
sbis USR,UDRE ;ready to send?
rjmp transmit1

out UDR,TEMP2
;transmit2:
; sbis USR,UDRE ;ready to send?
; rjmp transmit2
; out UDR,TEMP6
ret