В корень SD-карты положить файл "cybernoi.rom". Если карта не обнаружена, то подаётся сигнал 200Гц/100мс, если не обнаружен файл, то сигнал 200Гц/300мс.
Код:
/*
* SD-картридер подключяется к выводам ардуино:
** MOSI - D11
** MISO - D12
** CLK - D13
** CS - D10
*
* Выход - D3
*/
#include <SD.h>
File romFile;
// Заголовок
byte SB[27] = {
0x4E, 0x4F, 0x44, 0x49, 0x53, 0x43, 0x30, 0x30, // NODISK00
0x31, 0x39, 0x30, 0x31, 0x31, 0x38, // дата: 190118
0x74, 0x65, 0x73, 0x74, 0x74, 0x70, 0x20, 0x20, // testtp.....
0x20, 0x20, 0x20, 0x00, 0x00 };
int p = 3; // номер пина, на который будет вывод сигнала
void setup() //процедура setup
{
pinMode(p, OUTPUT); //объявляем пин как выход
pinMode(10, OUTPUT);
while (!SD.begin(10)){ // SD-карта готова?
tone(p, 200, 100); // нет -- включаем на 200 Гц на 100 мс
delay(3000); // ждем 3 с
}
}
void loop() //процедура loop
{
tone(p, 500, 100); //включаем на 500 Гц на 100 мс
delay(1000); //ждем 1 с
romFile = SD.open("cybernoi.rom"); // открываем файл
if (romFile) { // открылся?
byte BLs = 0x01; // начальный блок
unsigned int Nbt = romFile.size(); // всего байтов
byte BLe = Nbt/256; // всего блоков
byte BLt; // осталось блоков
byte Nst; // номер строки
byte St; // выводимый байт
byte CSz = 0x00; // контрольная сумма заголовка
byte CSs = 0x00; // контрольная сумма строки
byte i;
byte j;
if (Nbt%256 != 0){ // корректировка количества блоков, если размер файла не кратен 256
BLe++;
}
// Начинаем вывод
for (i=0; i<=3; i++){ // преамбула (4*(00H*25+55H*25))
for (j=0; j<=24; j++){
SendByte(0x00);
}
for (j=0; j<=24; j++){
SendByte(0x55);
}
}
for (BLt=BLe; BLt>=1; BLt--){ // Вывод блоков данных
CSz = BLs;
CSz += BLe;
CSz += BLt;
for (j=0; j<=15; j++){ // 00h*16
SendByte(0x00);
}
for (j=0; j<=3; j++){ // 55h*4
SendByte(0x55);
}
SendByte(0xE6); // E6h*1
for (j=0; j<=3; j++){ // 00h*4
SendByte(0x00);
}
for (j=0; j<=26; j++){ // заголовок блока
CSz += SB[j];
SendByte(SB[j]);
}
SendByte(BLs); // начальный блок
SendByte(BLe); // конечный блок
SendByte(BLt); // осталось блоков
SendByte(CSz); // контр.сумма заголовка
for (Nst=0x80; Nst<=0x87; Nst++){ // вывод строк (8 шт.)
for (j=0; j<=3; j++){ // 00h*4
SendByte(0x00);
}
SendByte(0xE6); // E6h*1
CSs = Nst;
SendByte(Nst); // номер строки
CSs += CSz;
SendByte(CSz); // контр.сумма заголовка
for (j=0; j<=31; j++){ // собственно, строка данных
if (Nbt > 0){ // ещё есть данные?
St = romFile.read(); // читаем очередной байт из файла
Nbt--;
}
else { // нет -- дополняем нулями
St = 0x00;
}
CSs += St;
SendByte(St);
}
SendByte(CSs); // контр.сумма строки
}
}
for (j=0; j<=15; j++){ // 00h*16 -- завершение вывода программы (?)
SendByte(0x00);
}
// close the file:
romFile.close();
}
else {
tone(p, 200, 300); // нет файла -- включаем на 200 Гц на 300 мс
}
delay(15000); // ждем 15 с
}
void SendByte(byte SBt){ // Подпрограмма вывода байта
byte Pd=PORTD;
byte i=8;
do{ // Выводим биты начиная со старшего
i--;
if ((bitRead(Pd, p))^(bitRead(SBt, i))){ // Если состояние порта и выводимый бит разные
Pd ^= (1 << p); // инвертируем бит в позиции p=3
PORTD = Pd; // вывод в порт p
}
else{
delayMicroseconds(16); // Задержка для выравнивания длительности сигнала
}
delayMicroseconds(256); // Задержка первого полупериода сигнала
Pd ^= (1 << p); // инвертируем бит в позиции p
PORTD = Pd; // вывод в порт p
delayMicroseconds(256); // Задержка второго полупериода сигнала
}
while (i>0);
}