floppysound.c


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
}