1 | /*
|
2 | * FloppyMusik.c
|
3 | *
|
4 | * Created: 11.07.2014 08:09:28
|
5 | * Author: chaoskind
|
6 | * Programm zur Steuerung von 3,5" Floppy Laufwerken, um Töne zu erzeugen
|
7 | *
|
8 | *
|
9 | * Pinbelegung(Active Low) 0/1
|
10 | *
|
11 | * PD1 = Floppy An/Aus
|
12 | * PD2 = Diskmotor An/Aus
|
13 | * PD3 = Richtung Lesekopf Vor/Zurück
|
14 | * PD4 = Schritt
|
15 | */
|
16 |
|
17 | #define F_CPU 8000000UL
|
18 |
|
19 | #define Floppy 1
|
20 | #define Motor 2
|
21 | #define Richtung 3
|
22 | #define Schritt 4
|
23 |
|
24 | #define Rueckwaerts (1<<Richtung)
|
25 |
|
26 | #define FloppyAn PORTD &= ~(1 << Floppy);
|
27 | #define FloppyAus PORTD |= (1 << Floppy);
|
28 |
|
29 | #define MotorAn PORTD &= ~(1 << Motor);
|
30 | #define MotorAus PORTD |= (1 << Motor);
|
31 |
|
32 | #define KopfVor PORTD &= ~(1 << Richtung);
|
33 | #define KopfRueck PORTD |= (1 << Richtung);
|
34 |
|
35 | #define SchrittLow PORTD &= ~(1 << Schritt); //einmal Low High um einen Schritt auszuführen
|
36 | #define SchrittHigh PORTD |= (1 << Schritt);
|
37 |
|
38 | #define TonAus TCCR1B &= ~(1<<CS01);
|
39 | #define TonAn TCCR1B |= (1<<CS01);
|
40 |
|
41 | #define STEP_TIME 1 // Pulsbreie für Schritt /us
|
42 |
|
43 | #define Grundstellung DDRD = 0b00011110;
|
44 |
|
45 | #include <avr/io.h>
|
46 | #include <avr/interrupt.h>
|
47 | #include <util/delay.h>
|
48 |
|
49 | void Init (void);
|
50 | void Startposition (void);
|
51 | void WildeTonfolge (void);
|
52 |
|
53 | volatile uint8_t Schrittzaehler = 0;
|
54 | volatile uint8_t Minutenzaehler = 0;
|
55 |
|
56 | volatile uint16_t SysTick_ms = 0;
|
57 |
|
58 | ISR(TIMER1_COMPA_vect)
|
59 | {
|
60 |
|
61 | if (PORTD & Rueckwaerts) // Aktuellen Zustand einlesen und prüfen in welche Richtung der letzte Schritt ging
|
62 | {
|
63 | Schrittzaehler ++;
|
64 | if (Schrittzaehler >=60) // um nicht in den Anschlag zu fahren, nach 60 Schritten Richtung wechseln (von Anschlag zu Anschlag etwa 85)
|
65 | {
|
66 | KopfVor
|
67 | Schrittzaehler = 0;
|
68 | }
|
69 | else{}
|
70 | }
|
71 |
|
72 | else
|
73 | {
|
74 | Schrittzaehler ++;
|
75 | if (Schrittzaehler >=60)
|
76 | {
|
77 | KopfRueck
|
78 | Schrittzaehler = 0;
|
79 | }
|
80 | else{}
|
81 | }
|
82 |
|
83 | SchrittLow
|
84 | _delay_ms(STEP_TIME);
|
85 | SchrittHigh
|
86 | }
|
87 |
|
88 | ISR (TIMER0_COMP_vect)
|
89 | {
|
90 | SysTick_ms ++;
|
91 | if (SysTick_ms == 60000)
|
92 | {
|
93 | Minutenzaehler++;
|
94 | SysTick_ms = 0;
|
95 | }
|
96 | }
|
97 |
|
98 |
|
99 |
|
100 | int main(void)
|
101 | {
|
102 | Init();
|
103 |
|
104 | while(1)
|
105 | {
|
106 | WildeTonfolge();
|
107 | }
|
108 | }
|
109 |
|
110 |
|
111 |
|
112 | void Init(void)
|
113 | {
|
114 | Grundstellung
|
115 | FloppyAn
|
116 |
|
117 | OCR1A = 2000;
|
118 | OCR0 = 125;
|
119 | TCCR0 = (1 << WGM01) | (1 << CS01) | (1 << CS00); //Timer0 CTC Vorteiler 64, für Systick 125Ticks = 1ms
|
120 | TIMSK = (1 << OCIE1A) | (1 << OCIE0);
|
121 |
|
122 | sei();
|
123 | Startposition();
|
124 | cli();
|
125 | TCCR1B = (1 << CS11) | (1 << WGM12); //Timer1 im CTC-Modus(Clear Timer on Compare match) Vorteiler 8
|
126 | sei();
|
127 | }
|
128 |
|
129 |
|
130 |
|
131 | void Startposition (void)
|
132 | {
|
133 | uint8_t i = 0;
|
134 | uint8_t SysTick_alt = 0;
|
135 |
|
136 | KopfRueck
|
137 |
|
138 | for(i=0; i<100; i++) //100 Schritte, um sicher an den Endanschlag zu fahren
|
139 | {
|
140 | SysTick_alt = SysTick_ms;
|
141 | while (SysTick_ms == SysTick_alt); //wenn eine ms vergangen ist, nächsten Schritt machen
|
142 |
|
143 | SchrittLow
|
144 | _delay_ms(STEP_TIME);
|
145 | SchrittHigh
|
146 | }
|
147 |
|
148 | KopfVor
|
149 |
|
150 | for(i=0; i<15; i++) //weitere 15 Schritte auf definierte Startposition zu kommen.
|
151 | {
|
152 | SysTick_alt = SysTick_ms;
|
153 | while (SysTick_ms == SysTick_alt); //wenn eine ms vergangen ist, nächsten Schritt machen
|
154 |
|
155 | SchrittLow
|
156 | _delay_ms(STEP_TIME);
|
157 | SchrittHigh
|
158 | }
|
159 | }
|
160 |
|
161 | void WildeTonfolge (void)
|
162 | {
|
163 | switch (SysTick_ms)
|
164 | {
|
165 | case 200: OCR1A = 10000; break;
|
166 | case 488: OCR1A = 8000; break;
|
167 | case 732: OCR1A = 6000; break;
|
168 | case 1038: OCR1A = 4000; break;
|
169 | case 1453: OCR1A = 2000; break;
|
170 | case 2145: OCR1A = 1000; break;
|
171 | case 2256: OCR1A = 15555; break;
|
172 | case 2565: OCR1A = 13555; break;
|
173 | case 2900: OCR1A = 6443; break;
|
174 | case 3131: OCR1A = 3452; break;
|
175 | case 3333: OCR1A = 13431; break;
|
176 | case 3676: OCR1A = 33333; break;
|
177 | case 4000: OCR1A = 45000; break;
|
178 | case 4943: OCR1A = 28000; break;
|
179 | case 5924: OCR1A = 4245; break;
|
180 | case 8424: OCR1A = 1200; break;
|
181 | case 8600: TonAus break;
|
182 | case 8800: TonAn break;
|
183 | case 9000: OCR1A = 980; break;
|
184 | case 9200: OCR1A = 960; break;
|
185 | case 9400: TonAus break;
|
186 | case 9600: TonAn break;
|
187 | case 9800: OCR1A = 900; break;
|
188 | case 10000: OCR1A = 890; break;
|
189 | case 10500: TonAus break;
|
190 | case 10800: TonAn break;
|
191 | case 12000: OCR1A = 860; break;
|
192 | case 12500: OCR1A = 850; break;
|
193 | case 13000: OCR1A = 840; break;
|
194 | case 13500: OCR1A = 830; break;
|
195 | }
|
196 |
|
197 | if (SysTick_ms >= 14000)
|
198 | {
|
199 | SysTick_ms = 0;
|
200 | }
|
201 | }
|