Documente Academic
Documente Profesional
Documente Cultură
Proiect cu Procesoare
ncuietoare Electronic
(MCU - Atmega328P)
Coordonator:
(Echipa 4)
Studeni:
Alexandru Prv
ETC, Anul 4, EA2, Gr.
2.2
Sebastian Subu
ETC, Anul 4, EA2, Gr.
2.2
Roland Vlduescu
Timioara 11 Ianuarie 2016
An universitar 2015 2016
Cuprins
1.
Descrierea proiectului.......................................................................................... 2
2.
Cerine................................................................................................................. 3
2.1.
3.
Autocerine.................................................................................................... 3
Schema bloc......................................................................................................... 4
3.1.
Explicaii........................................................................................................ 5
5.
Proiectare Hardware........................................................................................... 11
4.1.
4.2.
Lista de componente................................................................................... 12
4.3.
Layout.......................................................................................................... 13
4.4.
Fiiere de fabricaie...................................................................................... 16
Proiectare Software............................................................................................ 17
5.1.
Organigrama proceselor.............................................................................. 17
5.2.
5.3.
5.4.
Bibliografie......................................................................................................... 34
1
1. Descrierea proiectului
Tema aleas presupune proiectarea unui echipament electronic care s
permit utilizatorului uman s comande un anumit proces mecanic relativ simplu
(ex.: deschiderea unui zvor electro-magnetic) prin introducerea unei parole de
acces de la o tastatur numeric. Din interfaa cu utilizatorul vor mai face parte i
un afiaj LCD (16 caractere x 2 rnduri), i un buzzer care vor informa utilizatorul
pe durata folosirii echipamentului, cu diverse mesaje sau instruciuni pentru buna
utilizare.
De asemenea echipamentul electronic va fi prevzut i cu o interfa serial
RS-232 prin care acesta va putea cumunica cu un PC i vor putea fi setai anumii
parametrii ai programului ncrcat n microcontroller.
Partea de acionare din proiect se rezum la comanda unui releu de tip SPDT la
momentele de timp stabilite prin programul microcontroller-ului. Releul SPDT poate
fi mai departe folosit ca ntreruptor comandat pentru orice aplicaie ce nu
depeste 4A / 30VDC, 10A / 230VAC sau pentru sarcini inductive (cos = 0.4) 5A /
230VAC. (ex.: electro-magnei, motoare,...).
Microcontrollerul folosit, ATmega328P, se bucur de o mare popularitate n
ceea ce privete utilizarea sa mpreun cu mediul de dezvoltare Arduino, dar i
resursele hardware consistente (32 KB memorie flash, 1KB EEPROM, 2KB SRAM, i
diverse periferice de comunicare, temporizare, analogice sau digitale).
2. Cerine
Pentru o implementare i verificare uoar a proiectului, microcontrollerul
folosit trebuie s ndeplineasc urmtoarele cerine:
Memoria de Program s fie de tip FLASH
Programarea lui s fie posibil i prin tehnica ISP/ICSP
S poat fi simulabil (cu o comportare relativ similar cu cea din
realitate)
Microcontrollerul Atmega328P corespunde cerinelor impuse, dup datele
urmtoare de catalog:
32KBytes of In-System Self-Programmable Flash program memory 1
In-System Programming by On-chip Boot Program 2
Mediul de simulare Proteus 8 Professional are suport pentru
Atmega328P
2.1. Autocerine
Microcontrollerul ales trebuie s poat fi programat printr-un limbaj de
nivel nalt ( ANSI C, C99), astfel proiectarea software va fi necesita un timp
redus avnd n vedere experiena mai mare n limbajul C dect experiena n
limbaj de asamblare.
Sub sistemul de operare WINDOWS, Atmel ofer suport pentru
programarea n limbaj C prin intermediul compilatorului AVR gcc, care poate
fi utilizat de diferite procesoare de cod scris (Eclipse C/C++, Proteus
Professional 8, MikroAVR...etc), servind totodat la generarea fiierelor cu
extensie .hex care se vor ncrca n microcontroller. AVR gcc face parte din
pachetul de software WinAVR care deine i librrii pentru dezvoltarea de
cod ct mai rapid i eficient.
Printre seriile de microcontrollere de la Atmel pentru care WinAVR are
suport se numr ATMega i ATTiny.
3. Schema bloc
3.1. Explicaii
3.1.1. Tastatura 4x4
Liniile KP5-KP8 vor fi intrari digitale cu rezistori de pull-up intern pentru MCU
(microcontroller) (PD2, PD4, PD6, PD7) care vor fi citite periodic.
Liniile KP1-KP4 vor fi linii de ieire pentru MCU (PB0-PB3), care practic
simuleaz un resitru de deplasare pe 4 bii care va avea periodic la ieire valorile
binare 0001, 0010, 0100, 1000.
Astfel prin citirea liniilor KP5-KP8 simultan cu generarea semnalelor pe liniile
KP1-KP4 se poate identifica tasta apasat.
Fig. 2 Tastatura
numeric n schema
electronic
n schema electronic
Sursa de
alimentare accept la
intrare tensiune alternativ sinusoidal 9V-12V sau tensiune continu 12V15V. Alimentarea n ambele moduri o face posibil puntea redresoare 2W10,
Fig. 4 Blocul sursei de alimentare
capabil de un curent mediu redresat de 2A 3.
Tranzistorul Q1 permite un curent de colector de 3 A 4 care este suficient pentru
consumul total al circuitului. Dioda zener D2 regleaz valoarea tensiunii din
emitorului lui Q1 la aprox. 12.4 V
Variaiile tensiunii +12V pentru o tensiune de alimentare sinusoidal de 12V
i o impedan de sarcin echivalent de 100 vor fi (dac circuitul consum aprox
124 mA):
3 Datasheet 2W10, pg. 1
4 Datasheet D313Y, pg. 1
6
v=
Vm
17.48V
=
=1.74 V
2 Z L C f 21000.00150
3.1.4. LCD
Modulul LCD 16x2 reprezint un afiaj cu cristale lichide cu matrice de puncte
(5x8) care va fi folosit pentru afiarea unor caractere de tip alfa-numeric.
Comanda s-a se va face pe 4 bii, impreun cu semnalele RS, i E, semnalul
R/W fiind legat la mas considernd ca nu va fi interogat de MCU starea LCD-ului.
Prin poteniometrul RV1 se regreaz contrastul dispozitivului optoelectronic.
Comanda digital va fi asigurat de PORTUL C (PC0 PC5) al MCU.
Modulul dispune i de iluminare de fundal.
3.1.6. Buzzer
Buzzer-ul folosit este unul de tip piezo-electric, ceea ce necesit legarea n
paralel la terminalele sale a unui rezistor de 1 k.
Comanda PWM este execut prin tranzistorul NPN T1, polarizat prin semnale
logice de la MCU.
10
Pinii de alimentare VCC, AVCC sunt decuplai fiecare printr-un condensator ceramic
de 100nF pentru a ndeprta zgomotul de la frecvene ridicate.
Jumperul JP1 face posibil deconectarea MCU de la bara de VCC atunci cnd se
programeaz prin ISP.
10 Datasheet ATmega328P pg. 30
10
Fig.
9 Conexiunile MCU cu celelalte module
11
4. Proiectare Hardware
4.1. Schema electronic final
12
13
14
4.3. Layout
Schema electronic i layout-ul s-au proiectat cu software-ul KiCAD.
Regulile de proiectare globale au fost:
15
16
17
18
5. Proiectare Software
5.1. Organigrama proceselor
19
20
#include
#include
#include
#include
#include
<inttypes.h>
<avr/io.h>
<avr/interrupt.h>
<avr/sleep.h>
<util/delay.h>
21
6 #include <string.h>
7 #include <stdio.h>
8 #include "lcd4bit.h"
9 #include "keypad4x4.h"
10 #include "timer2_8bit.h"
11 #include "timer1_16bit.h"
12 #include "menu.h"
13 #include "usart.h"
14
15 void menu_ID_01(void)
16 {
17 char *cod="1993";
18 char j=0,a=0,match=1;
19 char w[4]={0, 0, 0, 0};
20 START:
21 LCD_Clear(); // clear the LCD display
22 LCD_Goto(0,0);
23 LCD_Message("COD ACCES:");
24 USART0SendByte(0x0A);//new line
25 USART0SendByte(0x0D);//carriage return
26 USART_putstring("COD ACCES:");
27 USART0SendByte(' ');
28 LCD_Goto(1,0);
29
30 while(1)
31 {
32 match=1;
33 *w="0000";
34 USART0SendByte(0x0D);//carriage return
35 USART0SendByte(0x0A);//new line
36 for (j=0;j<4;j++)
37 {
38 a=getKeypadInput();
39 if (a=='C') goto START;
40 w[j]=a;
41 LCD_Goto(1,j);
42 USART0SendByte(a);
43 LCD_Char(a);
44 }
45
46 for (j=0;j<4;j++)
47 {
48 if (w[j]!=*(cod+j))
49 match=0;
50 }
51 if (match==1)
52 {
53 PORTD|=(1<<PIN5);
54 StartTimer2_8bit();
55 StartTimer1_16bit();
56 LCD_Clear(); // clear the LCD display
57 LCD_Goto(0,0); // cursor goes to first line first row
58 LCD_Message("ACCES PERMIS!");
59 USART0SendByte(0x0D);//carriage return
60 USART0SendByte(0x0A);//new line
61 USART_putstring("ACCES PERMIS!");
62 USART0SendByte(0x0D);//carriage return
22
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
USART0SendByte(0x0A);//new line
_delay_ms(5000);
_delay_ms(6000);
break;
}
else
{
LCD_Clear(); // clear the LCD display
LCD_Goto(0,0);
LCD_Message("COD GRESIT");
USART0SendByte(0x0D);//carriage return
USART0SendByte(0x0A);//new line
USART_putstring("COD GRESIT");
USART0SendByte(0x0D);//carriage return
USART0SendByte(0x0A);//new line
_delay_ms(2000);
goto START;
}
1 /*
2 * keypad4x4.c *************************************************************
3 *
4 * Created on: Sep 2, 2014
5 * Author: Roland
6 */
7
8 #include <avr/io.h>
9 #include <avr/interrupt.h>
10 #include <util/delay.h>
11 #include <string.h>
12 #include <math.h>
13
14 #include "keypad4x4.h"
15
16
17 char getKeypadInput()
18 {
19
20 #define KB_PORT_OUT PORTB
21 #define KB_PORT_IN PIND
22 //#define KB_PORT_DIR DDRD
23
24
25 DDRB |= 0x0f; //Key-board lower nibble - output
26 KB_PORT_OUT |= 0x0f; //lower nibble = "1111"
23
24
/LCD4BIT.C ***************************************************************
1 #include "lcd4bit.h"
2 #include "misc.h"
3
4 #include <avr/io.h>
5 #include <avr/interrupt.h>
6 #include <util/delay.h>
7 #include <string.h>
8 #include <stdio.h>
9
10
11 // ----------------------------------------------------------------------12 // MISC ROUTINES
13 void SetupPortsLCD()
14 {
15
16 DDRC = 0x3F; // 0011.1111; set B0-B5 as outputs
17 PORTC=0xC0;
18
19 }
20 void msDelay(int delay) // put into a routine
21 { // to remove code inlining
22 for (int i=0;i<delay;i++) // at cost of timing accuracy
23 _delay_ms(1);
25
24 }
25
26 //
--------------------------------------------------------------------------27 // HD44780-LCD DRIVER ROUTINES
28 //
29 // Routines:
30 // LCD_Init initializes the LCD controller
31 // LCD_Cmd sends LCD controller command
32 // LCD_Char sends single ascii character to display
33 // LCD_Clear clears the LCD display & homes cursor
34 // LCD_Home homes the LCD cursor
35 // LCD_Goto puts cursor at position (x,y)
36 // LCD_Line puts cursor at start of line (x)
37 // LCD_Hex displays a hexadecimal value
38 // LCD_Integer displays an integer value
39 // LCD_Message displays a string
40 //
41 // The LCD module requires 6 I/O pins: 2 control lines & 4 data lines.
42 // PORTC is used for data communications with the HD44780-controlled LCD.
43 // The following defines specify which port pins connect to the
controller:
44 #define LCD_RS 0 // pin for LCD R/S (eg PC0)
45 #define LCD_E 1 // pin for LCD enable
46 #define DAT4 2 // pin for d4
47 #define DAT5 3 // pin for d5
48 #define DAT6 4 // pin for d6
49 #define DAT7 5 // pin for d7
50 // The following defines are HD44780 controller commands
51 #define CLEARDISPLAY 0x01
52 #define SETCURSOR 0x80
53
54 void PulseEnableLine ()
55 {
56 PORTC |= (1<<LCD_E); // take LCD enable line high
57 _delay_us(40); // wait 40 microseconds
58 PORTC &=~(1<<LCD_E); // take LCD enable line low
59 }
60
61 void SendNibble(byte data)
62 {
63 PORTC &= 0xC3; // 1100.0011 = clear 4 data lines
64 PORTC |= (data<<2);
65 PulseEnableLine(); // clock 4 bits into controller
66 }
67
68 void SendByte (byte data)
69 {
70 SendNibble(data>>4); // send upper 4 bits
71 _delay_us(1);
72 SendNibble(data&0x0F); // send lower 4 bits
73 _delay_us(40);
74 }
75
76 void LCD_Cmd (byte cmd)
77 {
78 PORTC&=~(1<<LCD_RS); // R/S line 0 = command data
26
79 SendByte(cmd); // send it
80 }
81
82 void LCD_Char (byte ch)
83 {
84 PORTC|=(1<<LCD_RS); // R/S line 1 = character data
85 SendByte(ch); // send it
86 }
87
88 void LCD_Init()
89 {
90 LCD_Cmd(0x33); // initialize controller
91 LCD_Cmd(0x32); // set to 4-bit input mode
92 LCD_Cmd(0x28); // 2 line, 5x7 matrix
93 LCD_Cmd(0x0E); // turn cursor off (0x0E to enable)
94 LCD_Cmd(0x06); // cursor direction = right
95 LCD_Cmd(0x01); // start with clear display
96 msDelay(3); // wait for LCD to initialize
97 }
98
99
100
101 void LCD_Clear() // clear the LCD display
102 {
103 LCD_Cmd(CLEARDISPLAY);
104 msDelay(3); // wait for LCD to process command
105 }
106
107 void LCD_Home() // home LCD cursor (without clearing)
108 {
109 LCD_Cmd(SETCURSOR);
110 }
111
112 void LCD_Goto(byte x, byte y) // put LCD cursor on specified line, row
113 {
114 byte addr = 0; // line 0 begins at addr 0x00
115 switch (x)
116 {
117 case 0: addr = 0x80; break; // line 1 begins at addr 0x40
118 case 1: addr = 0xC0; break;
119 }
120 LCD_Cmd(addr+y); // update cursor with x,y position
121 }
122
123 void LCD_Line(byte row) // put cursor on specified line
124 {
125 LCD_Goto(0,row);
126 }
127
128 void LCD_Message(char *text) // display string on LCD
129 {
130 while (*text) // do until /0 character
131 LCD_Char(*text++); // send char & update char pointer
132 }
133
134 void LCD_Hex(int data)
135 // displays the hex value of DATA at current LCD cursor position
27
136 {
137 char st[8] = ""; // save enough space for result
138 itoa(data,st,16); // convert to ascii hex
139 //LCD_Message("0x"); // add prefix "0x" if desired
140 LCD_Message(st); // display it on LCD
141 }
142
143 void LCD_Integer(int data)
144 // displays the integer value of DATA at current LCD cursor position
145 {
146 char st[8] = ""; // save enough space for result
147 itoa(data,st,10); // convert to ascii
148 LCD_Message(st); // display in on LCD
149 }
150
151 void LCD_Float(float data, char length)
152 {
153 char buffer[6]={0,0,0,0,0,0};
154 FloatToStringNew(buffer, data, length);
155 LCD_Message(buffer);
156 }
157
158
159
160 //
--------------------------------------------------------------------------161 // DEMO FUNCTIONS
162 void UpdateCursor (byte count) // helper fn for FillScreen
163 {
164 switch(count)
165 {
166 case 0: LCD_Line(1); break;
167 case 16: LCD_Line(2); break;
168 }
169 }
170 char GetNextChar(char ch) // helper fn for FillScreen
171 {
172 if ((ch<0x20) | (ch>=0xFF))
173 return 0x20;
174 if ((ch>=0x7F) & (ch<0xA0))
175 return 0xA0;
176 return ++ch;
177 }
178 #define NUMCHARS 64 // number of characters per screen
179 void FillScreen ()
180 // fills LCD screen with ascii characters
181 // be sure to set NUMCHARS to 32 or 64 characters, depending on the size
of your display
182 // 32 looks good on 16x2 displays; 64 looks good on 20x4 displays.
183 // four line displays also show an incrementing 1-99 page counter.
184 {
185 char ch = 'A';
186 LCD_Clear();
187 for (byte count=1;count<100;count++)
188 {
189 LCD_Goto(18,0);
190 LCD_Integer(count); // show counter (vis on 4-liners only)
28
191
192
193
194
195
196
197
198
199
200
201
202
1 /*************************************************************************
2 * timer1_16bit.c
3 *
4 * Created on: Sep 2, 2014
5 * Author: Roland
6 */
7 #include <avr/io.h>
8 #include <avr/interrupt.h>
9 #include <util/delay.h>
10 #include <string.h>
11
12 #include "timer1_16bit.h"
13 #include "lcd4bit.h"
14 #include "timer2_8bit.h"
15 #include "keypad4x4.h"
16
17
18 volatile uint16_t tick;
19 uint16_t cnt=0;
20 unsigned int TIM16_ReadTCNT1( void )
21 {
22 unsigned char sreg;
23 unsigned int i;
24 /* Save global interrupt flag */
25 sreg = SREG;
26 /* Disable interrupts */
27 cli();
28 /* Read TCNT1 into i */
29 i = TCNT1;
30 /* Restore global interrupt flag */
31 SREG = sreg;
32 return i;
33 }
34
35 unsigned int TIM16_ReadICR1( void )
36 {
37 unsigned char sreg;
38 unsigned int i;
39 /* Save global interrupt flag */
40 sreg = SREG;
41 /* Disable interrupts */
42 cli();
29
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
30
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
OUT:;
cnt++;
}
/*************************************************************************
2 * timer2_8bit.c
3 *
4 * Created on: Sep 2, 2014
5 * Author: Roland
31
6 */
1 #include <avr/io.h>
2 #include <avr/interrupt.h>
3 #include <util/delay.h>
4 #include <string.h>
5 #include <math.h>
6
7 #include "timer2_8bit.h"
8
9 /*****BUZZER**************/
10
11 void InitTimer2_8bit(void)
12 {
13 OCR2B = 128;
14 // set PWM for 50% duty cycle
15 TCCR2A |= (1 << COM2B1);
16 // set none-inverting mode
17 TCCR2A |= (1 << WGM21) | (1 << WGM20);
18 // set fast PWM Mode
19 // TCCR2B |= (1 << CS21)|(1 << CS22)|(1 << CS20);
20 // set prescaler to 8 and starts PWM
21 }
22
23 void StartTimer2_8bit(void)
24 {
25 TCCR2B |= (1 << CS21)|(1 << CS20); // set prescaler to 8 and starts PWM
26 }
27
28 void StopTimer2_8bit(void)
29 {
30 TCCR2B &= ~((1 << CS21)|(1 << CS22)|(1 << CS20)); // set prescaler to 8
and starts PWM
31 }
32
33 void SetTimer2_8bit_TOP(char TOP)
34 {
35 OCR2B=TOP;
36 }
/*************************************************************************
2 * usart.c
3 *
4 * Created on: Sep 2, 2014
5 * Author: Roland
6 */
1 #include <avr/io.h>
2
3 #define F_CPU 8000000UL
4 #define USART_BAUDRATE 9600
5 #define UBRR_VALUE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
6 void USART0Init(void)
7 {
8 // Set baud rate
9 UBRR0H = (uint8_t)(UBRR_VALUE>>8);
10 UBRR0L = (uint8_t)UBRR_VALUE;
32
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
33
34
6. Bibliografie
36