Commit 0913809d authored by spookysys's avatar spookysys
Browse files

lf dag 2

parent 0cbb0c29
Loading
Loading
Loading
Loading
+37 −7
Original line number Diff line number Diff line
@@ -28,7 +28,7 @@ int main(void)
	//Set LED pins as output
	PORTB.DIRSET = (1 << LED1) | (1 << LED2) | (1 << LED3);
	
	//Because the LEDs are active low, we invert the output
	//Because the LEDs are active low, we invert the output. This means high PWM value -> bright led
	PORTB.PIN0CTRL |= (1 << PORT_INVEN_bp);
	PORTB.PIN1CTRL |= (1 << PORT_INVEN_bp);
	PORTB.PIN4CTRL |= (1 << PORT_INVEN_bp);
@@ -38,19 +38,48 @@ int main(void)
	PORTA.PIN6CTRL |= (1 << PORT_PULLUPEN_bp);
	PORTA.PIN7CTRL |= (1 << PORT_PULLUPEN_bp);	
	
	//Set clock prescaler div256
	TCA0.SINGLE.CTRLA |= (TCA_SINGLE_ENABLE_bm); //Enable timer
	TCA0.SINGLE.CTRLB |= (0x05 << TCA_SINGLE_WGMODE0_bp); //Set mode to single slope
	/*We will be using timer 1 in single (not split) mode.
	  It is highly recommended that you read chapter 20.3.3.4 in the datasheet 
	  on timer compare channels.
	  There you will find a sub-capter on the single-slope PWM we will be using.
	*/
	
	//First, enable the timer
	TCA0.SINGLE.CTRLA |= (TCA_SINGLE_ENABLE_bm); 
	
	//Set the mode of the timer to single slope PWM
	TCA0.SINGLE.CTRLB |= (0x03 << TCA_SINGLE_WGMODE0_bp);
	
	TCA0.SINGLE.CTRLB |= (TCA_SINGLE_CMP0EN_bm) | (TCA_SINGLE_CMP1EN_bm); //Enable the compare channels
	//We have to override the normal pin opperation so the PWM is pushed directly to the pin
	//Hint: WO0 and WO1 are connected to leds. We need to override them to get the PWM out.
	TCA0.SINGLE.CTRLB |= (TCA_SINGLE_CMP0EN_bm) | (TCA_SINGLE_CMP1EN_bm);
	
	/*Timer A is a 16 bit timer. This will give us a frequency of 25Hz, we can see it flicker.
	  By lowering the period, (PER) we get higher frequency at the cost of lower resolution.
	*/
	
	//Set the period to 12 bit. (This results in a frequency of ~400Hz.)
	TCA0.SINGLE.PER = 0x0fff; //We set our top to have a sufficiently high frequency (Top at 16 bit (0xffff) ~25Hz, 12 bit (0x0fff) ~400Hz)
	TCA0.SINGLE.CMP0 = 0x0000;
	TCA0.SINGLE.CMP1 = 0x0fff;
	
	//We can now control the PWM duty cycle by simply writing values to the CMP0 and CMP1 registers.
	TCA0.SINGLE.CMP0 = 0x0000; //We have inverted the pin outputs so this is MIN
	TCA0.SINGLE.CMP1 = 0x0fff;	//We have inverted the pin outputs so this is MAX
	
	
    while(1){
		
		/*Have some fun with the leds. Examples:
		  Have them fade between max and min
		  Have them fade in a pattern (Heartbeat?) 
		  Change the brightness based on buttons

		*/
		
		//Here we use button pushes to shift the CMP register so we get brightness steps
		//adding and subtracting works just as well
		
		//It is largely up to the student to choose how the led brightness is changed.
		
		if (!(PORTA.IN & (1 << SW1))){
			if(!SW1_pressed){
				TCA0.SINGLE.CMP0 = (((TCA0.SINGLE.CMP0 << 1) + 1) & (0x0fff)); //Shift in a 1, and cut off excess to 12 bit
@@ -63,6 +92,7 @@ int main(void)
			SW1_pressed = false;
		}
		
		
		if (!(PORTA_IN & (1 << SW2))){
			if(!SW2_pressed){
				TCA0.SINGLE.CMP1 = (((TCA0.SINGLE.CMP1 << 1) + 1) & (0x0fff)); //Shift in a 1, and cut off excess to 12 bit
+20 −8
Original line number Diff line number Diff line
@@ -12,8 +12,8 @@
#include <util/delay.h>
#include <avr/interrupt.h>

#define LED1 0 // port B, connected to WO0
#define LED2 1 // port B, connected to WO1
#define LED1 0 // port B
#define LED2 1 // port B
#define LED3 4 // Port B


@@ -24,14 +24,24 @@ int main(void)
	*/

	PORTB.DIR = (1 << LED1) | (1 << LED2);
	PORTB.OUTTGL = (1 << LED1); //Only to start with LEDs off	
	PORTB.OUTTGL = (1 << LED1); //Starting with only 1 LED on	
	
	//We will be using a timer overflow interupt with timer A
	//We set the prescaler to clk=clk/256
	/*We will be using timer A that will trigger an overflow interupt.
	  This is a 16 bit timer that can run in 2 modes
		-single mode as 1 16-bit timer
		-dual/split mode as 2 8-bit timers
	  We will be using single mode in this exercise.
	  
	  Hint because the register names can be hard to understand:
	  TCA0.SINGLE.CTRLA addresses the control A register for timer A
	  
	  First we set the prescaler to clk=clk/256 and enable the timer. 
	  This is done by setting the right bits in the control A register.
	*/
	TCA0.SINGLE.CTRLA |= (TCA_SINGLE_CLKSEL_DIV256_gc) | (TCA_SINGLE_ENABLE_bm);
	

	//Next we Enable timer interupts on overflow 
	//Next we Enable timer interupts on overflow on timer A
	TCA0.SINGLE.INTCTRL |= (TCA_SINGLE_OVF_bm);
	
	//Finally we have to set the max value of the timer, the top. 
@@ -50,9 +60,11 @@ int main(void)
}

ISR(TCA0_OVF_vect){

	//Do something with the led(s), like toggle.
	PORTB.OUTTGL = (1 << LED1) | (1 << LED2);
	
	TCA0.SINGLE.INTFLAGS = ( TCA_SINGLE_OVF_bm); //Clear the interupt flag
	//Clear the interrupt flag.
	//If we do not clear the flag, we will instantly jump back into the ISR again
	TCA0.SINGLE.INTFLAGS = ( TCA_SINGLE_OVF_bm);
	
}
 No newline at end of file
+28 −8
Original line number Diff line number Diff line
@@ -12,42 +12,61 @@
#include <avr/interrupt.h>
#include <util/delay.h>

/*
In this exercise we will set up and use UART communication.
The embedded debugger has a virtual com port that we will use to communicate with the computer.

*/


void uart_init(unsigned long baud){
	
	//From chapter 24.3 in datasheet
	PORTB.OUTSET = (1 << PIN2_bp); 
	PORTB.DIRSET = (1 << PIN2_bp); 	//Setting up TX pin as output
	USART0.BAUDH = (baud >> 8); 	//Shift register right by 8 bits
	USART0.BAUDL = baud; 			//Set baud rate
	PORTB.OUTSET = (1 << PIN2_bp); 	//Setting the TX pin high
	
	USART0.BAUDH = (baud >> 8); 	//Shift register right by 8 bits to get the 8 high bits
	USART0.BAUDL = baud; 			//Set baud rate without shifting to get the 8 low bits
	
	//It turns out the compiler can handle this automatically, meaning this works just as well:
	//USART0.BAUD = baud;
	
	
	//USART.CTRLC CMODE bits default to async, 1 stop bit, 8 bit character size
	
	USART0.CTRLB |= (1 << USART_RXEN_bp) | (1 << USART_TXEN_bp);	//Enable RX and TX

	USART0.CTRLA |= (1 << USART_RXCIE_bp); //Enable interrupts on incomming data
	USART0.CTRLA |= (1 << USART_RXCIE_bp); //Enable interrupts on incoming data
}

// function to transmit data
void uart_transmit(unsigned char data){
	
	//In this function we will be send data.
	
	//First we should check that there isn't already data being sent
	//	if there is, we should probably wait for it to finish first
	while (!(USART0.STATUS & (1 << USART_DREIF_bp))){
		//wait for previous transmit to finish
	};
	
	//Put our new data into se sending register
	USART0.TXDATAL = data;
}


int main(void)
{
	//Initialize the UART with our function. 
	//We will be using a baudrate of 9600 (defined as BAUD_9600 at the top of the file)
	uart_init(BAUD_9600);
	
	uart_init(BAUD_9600); //start uart with baudrate of 9600
	
	sei(); //Important for anything here to work
	sei(); //Enable inerrupt, important for anything here to work
	
    while (1) 
    {
		//Do nothing, interrupts handle everything
		//We don't really need to do anything here.
		//the ISR will handle receiving. 
    }
}

@@ -55,6 +74,7 @@ int main(void)
//Interrupt service routine for the receiver.
ISR(USART0_RXC_vect){
	
	//Read out the received data to a variable
	uint8_t data = USART0_RXDATAL;
	//Do things with data:
	uart_transmit(data + 1); //Example: Shift all characters by one step A -> B, B -> C etc.
+3 −3
Original line number Diff line number Diff line
@@ -22,12 +22,12 @@ int main(void)
	
	/*We will be using timer A that will trigger an overflow interupt.
	  This is a 16 bit timer that can run in 2 modes
		-sigle mode as 1 16-bit timer
		-single mode as 1 16-bit timer
		-dual/split mode as 2 8-bit timers
	  We will be using single mode in this exercise.
	  
	  Hint because the register names can be hard to understand:
	  TCA0.SINGLE.CTRLA adresses the control A register for timer A
	  TCA0.SINGLE.CTRLA addresses the control A register for timer A
	  
	  First we set the prescaler to clk=clk/256 and enable the timer. 
	  This is done by setting the right bits in the control A register.
@@ -58,7 +58,7 @@ ISR(TCA0_OVF_vect){

	//Do something with the led(s), like toggle.
	
	//Clear the interupt flag.
	//Clear the interrupt flag.
	//If we do not clear the flag, we will instantly jump back into the ISR again
	
}
 No newline at end of file

Session2/UART/.gitignore

deleted100644 → 0
+0 −2
Original line number Diff line number Diff line
UART/Debug
.vs
Loading