Init0 Include "Include/buzzer S"

You might also like

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 5

#include <avr/io.

h> // Include register definitions

.section .init0 // Places code at the top of programme memory

.include "include/buzzer.S" // Configures TCA0 to drive buzzer

entry:

// Ex 3.0
//
// In Ex 3.1 we are going to enable PB5 as an output, which is
// connected to the DISP DP net and controls LED DS1-DP (active low).
//
// Write assembly code such that when we enable PB5 as an output,
// LED DS1-DP is off.

ldi r16, PIN5_bm //0b0010 0000


sts PORTB_OUTSET, r16

// Write your code for Ex 3.0 above this line.

// Ex 3.1
//
// Write assembly code to enable the pin connected to the DISP DP
// net as an output.

ldi r16, PIN5_bm //0b0010 0000


sts PORTB_DIR, r16

// Write your code for Ex 3.1 above this line.

// Ex 3.2
//
// In later exercises you will be required to read the state of
// pushbuttons BUTTON0...3. Write assembly code to enable the
// internal pull-up resistors for the pins connected to these
// pushbuttons.

ldi r16, PORT_PULLUPEN_bm // enable pull-up bitmask

sts PORTA_PIN4CTRL, r16


sts PORTA_PIN5CTRL, r16
sts PORTA_PIN6CTRL, r16
sts PORTA_PIN7CTRL, r16
// Write your code for Ex 3.2 above this line.

// Ex 3.3
//
// Write assembly code to turn on LED DS1-DP.

ldi r16, PIN5_bm


sts PORTB_OUTCLR, r16 // set low (turn LED on)

// Write your code for Ex 3.3 above this line.

// The code between the "loop_100ms" and "end_loop_100ms" labels


// will execute approximately 10 times per second.
loop_100ms:

// Ex 3.4
//
// Write assembly code to read the state of BUTTON0 and store the result in
R17.
// If BUTTON0 is pressed:
// R17 should contain the value 0x00.
// Else, if BUTTON0 is not pressed (released):
// R17 should contain a non-zero value.
//
// Hint: You can use a bitmask and bitwise logical operation to
// isolate the bit that corresponds to the relevant pushbutton
// after reading the port state.

//ldi r16, 0b00010000 ; Load binary value 00000001 into register r16
lds r17, PORTA_IN ; Check BUTTON0 and store the result in r17

andi r17,0b00010000 ; r17 = 0 if Button 0 Pressed

// Write your code for Ex 3.4 above this line.

// Ex 3.5
//
// The two instructions below will test the value in R17 to determine
// whether BUTTON0 is pressed.
//
// If BUTTON0 is NOT pressed (i.e., the value in R17 is not zero),
// any code between the "brne" instruction and the label "end_loop_100ms"
// will be skipped.
//
// Write assembly code in the space provided to toggle the state of LED DS1-
DP.

cpi r17, 0
brne end_loop_100ms

// Write your code for Ex 3.5 below this line.

ldi r16, PIN5_bm //0b00010000 ; Load binary value 00000010 into register
r16
sts PORTB_OUTTGL, r16

// Write your code for Ex 3.5 above this line.

end_loop_100ms:

// The code between the "loop_10ms" and "end_loop_10ms" labels


// will execute approximately 100 times per second.
loop_10ms:

// Ex 3.6
//
// At the start of this programme, some code was included that sets up
// the Timer Counter A 0 (TCA0) peripheral to synthesize a ~200 Hz tone
// that will drive the piezo buzzer connected to the BUZZER net.
//
// TCA0 will automatically override the output of the pin connected
// to the BUZZER net, however, the pin needs to be configured as an output
// for the timer signal to define the state of the BUZZER net.
//
// Write assembly code below such that the buzzer is driven
// (i.e., an audible tone is produced), when BUTTON3 is pressed,
// and not driven (i.e., silent), when BUTTON3 is released.
//
// To assist you, we have written some code below that will test R18:
// If R18 contains zero, then:
// any code between ex36_zero and "rjmp end_ex36" will execute.
// Else, if R18 is not zero, then:
// any code between ex36_nonzero and end_ex36 will execute.

// Write your code for Ex 3.6 anywhere below this line


cpi r18, 0
brne ex36_nonzero

ex36_zero:

rjmp end_ex36

ex36_nonzero:

end_ex36:

// Write your code for Ex 3.6 anywhere above this line

// END OF TUTORIAL03 EXERCISES //


// DO NOT EDIT BELOW THIS LINE //
end_loop_10ms:

// For sys_clk = 3.33 MHz, ~33k cycles in 10ms


//
// Let's implement a delay loop based on a 16-bit counter
//
// adiw takes 2 cycles to execute, we will also need at
// least one cycle for a test, so let's assume 4 cycles
// total, which we need to repeat ~8k times.
//
// 0x2000 = 8192, so we can just test bit 5 in high byte

delay_10ms:
adiw r30, 1 // 2 cycles
cpi r31, 0x20 // 1 cycle
brne delay_10ms // 1 cycle

// Reset high byte of delay loop counter


// (low byte should already be 0x00)
ldi r31, 0

// Every 10 of these cycles we need to execute the 100ms loop also


inc r29
cpi r29, 10
brne loop_10ms
// Reset 1s counter then jump to 1s loop
ldi r29, 0
rjmp loop_100ms

// We should never get here, but just in case


loop:
rjmp loop

You might also like