Uživatel:Clarknat

Z MAM wiki

Přejít na: navigace, hledání

Obsah

[editovat] Introduction

Welcome to my Microprocessesors and Microcomputers Wiki Page. Here I will post some basic things about the course and some important general links that may be useful for many of the exercises and projects.

[editovat] Manuals

[editovat] Exercise 1

Exercise 1 (2.23.2012) was relatively simple and straightforward. We simply switched and LED on and off. Here is the link for that day: FirstAVR Experiment

[editovat] Exercise 2

For exercise 2 (1.3.2012) we played around with inputs and outputs. We used an external keyboard to change the color of the light. Some things to remember from this weeks exercise:

  • Use Simulator 2
  • Press F11 to step through the code after it is built
  • Use a pull-up resistor with DDRx (A,B,C,D) with PORTX(A, B, C ,D) set to 1.
    • Unconnected inputs have higher power consumption and can take random values that may cause unwanted problems
  • The maximum current output from a source is 40mA.
    • Use an external resistor to stay on the conservative side to not break the chip

The code can be seen below:

.EQU DDRB = $17		; DDRB address
	.EQU PORTB = $18	; PORTB address

	.EQU DDRD = $11
	.EQU PIND = $10
	.EQU PORTD = $12
	.EQU KEY_IN = 5	    ; Check the 5th bit on register D


	.EQU LED_X = 0      ; LED_X is on PB0, pin 12 of ATtiny2313
	.EQU LED_Y = 1		; LED_Y is on PB1 pin 13 of ATtiny2313
	

	SBI	DDRB, LED_X	    ; SBI - Set Bit in I/O Register
	SBI DDRB, LED_Y

	CBI DDRD, KEY_IN	;Input
	SBI PORTD, KEY_IN	;with a pull-up resistor


HOP:
	SBIS PIND, KEY_IN 	; IF ITS NOT SET SKIP TO THE 2ND LINE PAST
	RJMP A
	RCALL GREEN
	;..
	RJMP B

A:
	RCALL RED
	;...
B:
	RJMP HOP 	; WILL GO BACK TO THE BEGINNING

RED:
	SBI PORTB, LED_X	;SETS X HIGH
	CBI PORTB, LED_Y	;CLEARS Y
	RET

GREEN:
	SBI PORTB, LED_Y	;SETS Y HIGH
	CBI PORTB, LED_X	;CLEARS X
	RET


[editovat] Exercise 5

Today we worked with C code and how to compile it using the command prompt. We wrote a very basic C code in the AVR studo

main(){
	int i = 5;
	i++;
}

Going into the command prumpt we must run the following to make the Assembly Code:

avr-gcc -S X.c
cat X.s

The first line needs the S to be capitalized! X.c represents the file name. Then cat forms the following assembly code:


	.file	"ClarkExercise5.c"
__SREG__ = 0x3f
__SP_H__ = 0x3e
__SP_L__ = 0x3d
__CCP__  = 0x34
__tmp_reg__ = 0
__zero_reg__ = 1
	.text
.global	main
	.type	main, @function
main:
	push r29
	push r28
	rcall .
	rcall .
	in r28,__SP_L__
	in r29,__SP_H__
/* prologue: function */
/* frame size = 4 */
	ldi r24,lo8(5)
	ldi r25,hi8(5)
	std Y+2,r25
	std Y+1,r24
	ldd r24,Y+1
	ldd r25,Y+2
	adiw r24,1
	std Y+2,r25
	std Y+1,r24
/* epilogue start */
	pop __tmp_reg__
	pop __tmp_reg__
	pop __tmp_reg__
	pop __tmp_reg__
	pop r28
	pop r29
	ret
	.size	main, .-main

Some of this code is cryptic most likely because it was fining a location of our "i". We can remove many of these lines manually, as many of them are redundant Or we can try to make our code with the -03 option to optimize it. It does nothing, if we printed the value of i then we might see more action in our code. This is just happening inside the computer. Instead of adding our compiler decided to use

subi r25, lo8(-(1))

This subtracts a negative 1 so it is adding it. This will work with R16-R32 since it is using a constant. Note this changes the Carry Flag while the "inc" also adds one but doesn't change the carry flag. Be cautious when using this in loops if you are expecting to test the value of the carry bit as inc will not change that! To optimize and see it try this magic:

 volatile unsigned char i = 5

[editovat] Semester Work

For my semester work, I am going to demonstrate some tasks with Seven-Segment Displays (from here on abbreviated SSD). A SSD is contains 7 LED segments and a decimal. SSDs have many uses such as digital clocks. They may be used to display basic numbers and even simple characteristics may be coded. As you can see, SSDs are potentially very useful many projects involving microcontrollers. A typical SSD looks like this (from http://en.wikipedia.org/wiki/Seven-segment_display):

More basic information may also be found in that Wikipedia link.

[editovat] Equipment

Here is a list of the components (or similar ones) which should be used:

  • ATtiny2313 (potentially any microcontroller with 10+ output pins will also work) along with the AVR Dragon
  • Choice of Seven-Segment Display, here we use a common anode
  • ULN2003, 7-channel Darlington Array
  • PNP transistor for each SSD
  • Resistors (7 x 330 and 2.2k for each SSD)
  • Connecting wires

[editovat] Setup

In this section, I will present the necessary setup and discuss the proposed design. Lets begin with the very basics, feel free to skip over this paragraph is you have some experience with using AVR microcontrollers. We will need to connect the AVR Dragon to the ATtiny2313 in the following fashion, as we have done throughout the semester:

Soubor:DW-Dragon-ATtiny2313.png

More details on this can be found from our first exercise: http://noel.feld.cvut.cz/vyu/a2m99mam/index.php/First_AVR_experiment. The AVR Dragon is connected to the PC via a USB cable which also provides power to the ATtiny2313. To refresh your memory and provide reference, I will also display the pin diagram of the ATtiny2313 chip:

Soubor:ATtiny2313.png

The full datasheet for the ATtiny 2313 may be found here and will be useful: ATtiny2313 Datasheet.

We used a ULN2003 (datasheet here http://www.datasheetcatalog.org/datasheets/120/489337_DS.pdf) as it allows for the connection of higher voltage loads. Its hand because it has 7 pins and will allow us to control the 7 segments of the display (excluding the decimal place). Therefore we will connect the 7 inputs to the 7 outputs of the ATtiny2313 and the outputs of this chip will feed the SSDs. The chip may be seen below:

Soubor: Clark-ULN2003.png

In this section we can observe the schematic. Here we have displayed just one SSD, but there are options for more, pins are labeled there as SSD0, SSD1, SSD2, but it was simply easier to display only one. Also the A, B, C, etc. should be connected to all of the SSDs. Lastly, each SSD needs a transistor to drive it.

Soubor: Clark_Schematic.png

[editovat] Code

In this section, I will provide some illustrative examples in C language to control SSDs. Before diving into the actual code, it is useful to make a table to decode what needs to happen to make desired numbers appear (easily extended for basic letters):

Displayed Number Dot G F E D C B A Hex To Send
0 0 0 1 1 1 1 1 1 3F
1 0 0 0 0 0 1 1 0 06
2 0 1 0 1 1 0 1 1 5B
3 0 1 0 0 1 1 1 1 4F
4 0 1 1 0 0 1 1 0 66
5 0 1 1 0 1 1 1 0 6D
6 0 1 1 1 1 1 0 1 7D
7 0 0 0 0 0 1 1 1 07
8 0 1 1 1 1 1 1 1 7F
9 0 1 1 0 0 1 1 1 67

Because we will use PORTD for controlling values on the SSDs, we need to make sure this is configured properly. As we will use PORTB similarly to control which SSD we want to currently write to we also need to set that up initially as well. As we need the 7 least significant bits we will right those high on DDRD, and for this example we have 3 SSDs, so we need to set the 3 least significant bits on DDRB as well. This code goes in the main loop:

//Initialize our SSD outputs on Port D
DDRD = 0x7F; //0111 1111
//We will use PB0, PB1, and PB2 for selection of the SSD
DDRB = 0x07; // 0000 0111; Used to Select or SSD

The next thing we must also setup in the main loop is the timers and interrupts, and it is important to enable global interrupts!

TIMSK |= (1 << TOIE0); // Timer 0 Overflow Interrupt
TCCR1B |= (1 << WGM12); // Configure for CTC mode
TIMSK |= (1 << OCIE1A); // CTC interrupt
OCR1A = 15625; // With prescaler of 64, this results in 1 Hz @ 1 MHz

// Don't forget to enable global interrupts
sei(); 

//Start the timers
TCCR0B |= (1 << CS01); // Prescale factor of 8
TCCR1B |= (1 << CS11)+(1 << CS10); // Prescale factor of 64

A-G and Dot represent the location on the segment. From this example, it would be easy to create some basic characters as well, using the same logic. To implement this in C, I have created a function which is controlled by a switch case and writes the proper bits on PORTD to make the desired display:

void display_Number(n) //uint8_t 
{
	switch(n){
	//Display the integer 0:
	case 0: PORTD = 0x3F;
	break;

	//Display the integer 1:
	case 1: PORTD = 0x06;
	break;

	//Display the integer 2:
	case 2: PORTD = 0x5B;
	break;

	//Display the integer 3:
	case 3:PORTD = 0x4F;
	break;

	//Display the integer 4:
	case 4: PORTD = 0x66;
	break;

	//Display the integer 5:
	case 5: PORTD = 0x6D;
	break;

	//Display the integer 6:
	case 6: PORTD = 0x7D;
	break;

	//Display the integer 7:
	case 7: PORTD = 0x07;
	break;

	//Display the integer 8:
	case 8: PORTD = 0x7F;
	break;

	//Display the integer 9:
	case 9: PORTD = 0x67;
	break;
	}	
}

This code to control which display we are writing to, and is also in the ISR. If you would like to have more values than you can change i = 2 to a higher value for more SSDs:

static uint8_t i=0;
if(i == 2)
   {
      //Loops back to the first display
      i=0;
   }
   else
   {
      //Continue to the next display
      i++;
   }

Here is the code which also controls the display of numbers by incrementing a variable j. Please note this is also in the ISR for Timer 0. In order to make sure we display a proper value on the display we control j to make sure it doesn't exceed these values, thus when j = 9, the next time we set it back to 0. This acts in the way of a loop.

static uint8_t j=0;
if(j == 9)
   {
	   j = 0;
   }
   else
   {
	   j++;
   }

[editovat] Conclusion

In this section, I will draw an end to my semester work, highlighting the successes and downfalls, provide useful advice, and lessons learned from this work.

One thing to keep in mind is the refresh rate of changing the SSDs. You have to ensure that it is high enough to go unnoticed. A good idea is to keep the refresh rate above 60 Hz. This can be controlled by the speed of the microcontoller, the timer prescaler, etc. as we have learned about in the lectures of this course.

This example should be able to extended for more (or less) SSDs. Of course this will require more pins on the microcontroller which might require you to use something different than the ATtiny2313. Be aware the registers for counters and such might have slightly different names for different microcontrollers in the AVR series. You could also extend to control the decimal point (perhaps better with PORTB), and it could also be extended to include basic charactersitcs which can be controlled by only 7 segments.

SSDs may be used to make basic timers or counters which can be incorporated with external devices like sensors. This project hopefully you learn the basics about Seven-Segment Displays and how many of them may be controlled by one microcontroller.

Osobní nástroje