Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Кто собирал цифровое устройство записи речи на AVR+DataFlash?
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
prog
Здравствуйте!!!

Люди раскажите каким компилятором собирали прилагаемый код.
Пробывал CVAVR наткнулся на грабли присутствия ina90.h
потом IAR Embedded Workbench там при компиляции высыпалась масса ошибок.

С уважением, Владимир.
bodja74
А где код?

Вообще ina90.h есть в комплекте WinAVR.
prog
Цитата(bodja74 @ Aug 13 2006, 18:15) *
А где код?

Вообще ina90.h есть в комплекте WinAVR.


Вот и код
//------------------
#include "io8535.h"
#include "stdlib.h"
#include "dataflash.h"

// прототипы
void setup (void);
void erasing (void);
void recording (void);
void interrupt[ADC_vect] sample_ready (void);
void write_to_flash (unsigned char ad_data);
void playback (void);
void next_page_to_next_buffer (unsigned char active_buffer, unsigned int page_counter);
void interrupt[TIMER1_OVF1_vect] out_now(void);
void active_buffer_to_speaker (unsigned char active_buffer);

// глобальные переменные
volatile unsigned char wait = 0;


void setup(void)
{
DDRB = 0xBD;// Инициализация порта SPI
// SCK, MISO, MOSI, CS, LED, WP , RDYBSY, RST
// PB7, PB6, PB5, PB4, PB3, PB2 , PB1, PB0
// O I O O O O I O
// 1 0 1 1 1 1 0 1
PORTB = 0xFF;// все выходы в высоком состоянии, на входах нагрузочные резисторы (LED погашен)
DDRA = 0x00; // Port A определяется как вход
PORTA = 0x00;
DDRD = 0x10; // Port D определяется как вход (D4: выход)

_SEI(); // прерывания разрешены
}


void erasing(void)
{
unsigned int block_counter = 0;
unsigned char temp = 0x80;
ACSR |= 0x02; // установка флага, показывающего, что следующим этапом должна быть запись данных

// прерывания запрещены, порт SPI включён, «ведущий» режим, первый MSB, 3 режим SPI, Fcl/4
SPCR = 0x5C;

while (block_counter < 512)
{
PORTB &= ~DF_CHIP_SELECT; // включение DataFlash
SPDR = BLOCK_ERASE;
while (!(SPSR & temp)); // ожидание завершения передачи
SPDR = (char)(block_counter>>3);
while (!(SPSR & temp)); // ожидание завершения передачи
SPDR = (char)(block_counter<<5);
while (!(SPSR & temp)); // ожидание завершения передачи
SPDR = 0x00; // не важно
while (!(SPSR & temp)); // ожидание завершения передачи
PORTB |= DF_CHIP_SELECT; // выключение DataFlash

block_counter++;
while(!(PINB & 0x02)); // ожидание очистки блока
}
SPCR = 0x00; //отключение SPI
}


void recording(void)
{
// прерывания запрещены, порт SPI включён, «ведущий» режим, первый MSB, 3 режим SPI, Fcl/4

SPCR = 0x5C;
ADMUX = 0x00; // номер входного вывода АЦП = 0
ADCSR = 0xDD; // одиночное АЦ преобразование, fCK/32, старт преобразования
while (!(PIND & 8)); // цикл продолжается пока нажата кнопка записи (кнопка 3)

ADCSR = 0x00; // выключение АЦП
SPCR = 0x00; // выключение SPI
}


void interrupt[ADC_vect] sample_ready(void)
{
unsigned char count = 0;

while (count < 6) count++; // ожидание в течение нескольких циклов
ADCSR |= 0x40; // старт нового АЦ преобразования
write_to_flash(ADC-0x1D5); // чтение данных, преобразование 8 бит и сохранение во флэш
}


void write_to_flash(unsigned char flash_data)
{
static unsigned int buffer_counter;
static unsigned int page_counter;
unsigned char temp = 0x80;

if((ACSR & 0x02)) // если флаг установлен, то новые данные должны быть установлены
{
buffer_counter = 0;
page_counter = 0; // сброс счётчика если должны быть записаны новые данные
ACSR &= 0xFD; // очистка флага сигнала
}

while(!(PINB & 0x02)); // проверка занятости флэша

PORTB &= ~DF_CHIP_SELECT; // включение DataFlash

SPDR = BUFFER_1_WRITE;
while (!(SPSR & temp)); // ожидание завершения передачи
SPDR = 0x00; // не важно
while (!(SPSR & temp)); // ожидание завершения передачи

SPDR = (char)(buffer_counter>>8); // не важно + первые два бита буфера адреса
while (!(SPSR & temp)); // ожидание завершения передачи

SPDR = (char)buffer_counter; // буфер адреса (макс. 2^8 = 256 страниц)
while (!(SPSR & temp)); // ожидание завершения передачи
SPDR = flash_data; // запись данных в регистр данных SPI
while (!(SPSR & temp)); // ожидание завершения передачи


PORTB |= DF_CHIP_SELECT; // выключение DataFlash

buffer_counter++;

if (buffer_counter > 528) // если буфер заполнен, то его содержимое записывается в страницу памяти
{
buffer_counter = 0;
if (page_counter < 4096) // если память не заполнена
{
PORTB &= ~DF_CHIP_SELECT; // включить DataFlash

SPDR = B1_TO_MM_PAGE_PROG_WITHOUT_ERASE; // записать данные из буфера 1 в страницу
while (!(SPSR & temp)); // ожидание завершения передачи
SPDR = (char)(page_counter>>6);
while (!(SPSR & temp)); // ожидание завершения передачи
SPDR = (char)(page_counter<<2);
while (!(SPSR & temp)); // ожидание завершения передачи
SPDR = 0x00; // не важно
while (!(SPSR & temp)); // ожидание завершения передачи

PORTB |= DF_CHIP_SELECT; // выключение DataFlash

page_counter++;
}
else
{
PORTB |= 0x08; // погасить LED
while (!(PIND & 8)); // ждать пока кнопка записи не отпущена (кнопка 3)
}
}
}


void playback(void)
{
unsigned int page_counter = 0;
unsigned int buffer_counter = 0;
unsigned char active_buffer = 1; // активный буфер = буфер 1
unsigned char temp = 0x80;

TCCR1A = 0x21; // 8 бит ШИМ, используется COM1B
TCNT1 = 0x00; // обнуление счётчика 1
TIFR = 0x04; // сброс флага превышения счётчика 1
TIMSK = 0x04; // разрешение прерывания переполнения счётчика 1
TCCR1B = 0x01; // коэф. Пересчёта счётчика 1 = 1
OCR1B = 0x00;// обнуление выходного регистра сравнения B
// прерывания запрещены, порт SPI включён, «ведущий» режим, первый MSB, 3 режим SPI, Fcl/4

SPCR = 0x5C;

next_page_to_next_buffer (active_buffer, page_counter); // чтение страницы 0 в буфер 1

while (!(PINB & 0x02)); // ожидание завершения передачи данных из страницы 0 в буфер 1
while ((page_counter < 4095)&(!(PIND & 2))) // пока кнопка воспроизведения (кнопка 1) нажата
{
page_counter++; // теперь берём следующую страницу

next_page_to_next_buffer (active_buffer, page_counter);
active_buffer_to_speaker (active_buffer);

if (active_buffer == 1) // если буфер 1 является активным буфером
{
active_buffer++; // то устанавливаем буфер 2 в качестве активного
}
else // иначе
{
active_buffer--; // устанавливаем буфер 1 в качестве активного
}
}
TIMSK = 0x00; // запрещаем все прерывания
TCCR1B = 0x00; // останавливаем счётчик 1
SPCR = 0x00; // отключаем SPI
}


void next_page_to_next_buffer (unsigned char active_buffer, unsigned int page_counter)
{
unsigned char temp = 0x80;
while(!(PINB & 0x02)); // ждём, пока флэш не освободится

PORTB &= ~DF_CHIP_SELECT; // включаем DataFlash

if (active_buffer == 1) // если буфер 1 активный
{
SPDR = MM_PAGE_TO_B2_XFER; // то передаём следующую страницу в буфер 2
}
else // иначе
{
SPDR = MM_PAGE_TO_B1_XFER; // передаём следующую страницу в буфер 1
}
while (!(SPSR & temp)); // ожидаем завершения передачи
SPDR = (char)(page_counter >> 6);
while (!(SPSR & temp)); // ожидаем завершения передачи
SPDR = (char)(page_counter << 2);
while (!(SPSR & temp)); // ожидаем завершения передачи
SPDR = 0x00; // записываем не имеющий значения байт
while (!(SPSR & temp)); // ожидаем завершения передачи
PORTB |= DF_CHIP_SELECT;// выключаем DataFlash и начинаем передачу
}


void interrupt[TIMER1_OVF1_vect] out_now(void)
{
wait = 0; // возникновение прерывания
}


void active_buffer_to_speaker (unsigned char active_buffer)
{
// пока активный буфер не очистится воспроизводим его содержимое на динамике
unsigned int buffer_counter = 0;
unsigned char temp = 0x80;

PORTB &= ~DF_CHIP_SELECT; // включение DataFlash

if (active_buffer == 1) // если буфер 1 активный буфер
{
SPDR = BUFFER_1_READ; // то читаем из буфера 1
}
else // иначе
{
SPDR = BUFFER_2_READ; // читаем из буфера 2
}

while (!(SPSR & temp)); // ожидаем завершения передачи
SPDR = 0x00; // запись не имеющего значения байта
while (!(SPSR & temp)); // ожидаем завершения передачи
SPDR = 0x00; // запись не имеющего значения байта
while (!(SPSR & temp)); // ожидаем завершения передачи
SPDR = 0x00; // начать с адреса 0 буфера
while (!(SPSR & temp)); // ожидаем завершения передачи
SPDR = 0x00; // запись не имеющего значения байта
while (!(SPSR & temp)); // ожидаем завершения передачи

while (buffer_counter < 528)
{
SPDR = 0xFF; // записываем фиктивное значение в начало сдвигового регистра
while (!(SPSR & temp)); // ожидаем завершения передачи
while(wait); // ожидаем прерывание переполнения таймера 1
OCR1B = SPDR; // воспроизводим данные из сдвигового регистра
wait = 1; // сброс флага сигнала

buffer_counter++;
}

PORTB |= DF_CHIP_SELECT; // выключение DataFlash
}


void main(void)
{
setup();

for(;;)
{
if (!(PIND & 8)) // если кнопка записи нажата (кнопка 3)
{
PORTB &= 0xF7; // зажигаем LED
recording();
}
if (!(PIND & 4)) // если нажата кнопка очистки (кнопка 2)
{
PORTB &= 0xF7; // зажигаем LED
erasing();
while (!(PIND & 4)); // ждём пока кнопка очистки не отпущена (кнопка 2)
}
if (!(PIND & 2)) //если нажата кнопка воспроизведения(кнопка 1)
{
PORTB &= 0xF7; // зажигаем LED
playback();
while (!(PIND & 2)); // ждём пока кнопка воспроизведения не отпущена (кнопка 1)

}
PORTB |= 0x08; // гасим LED во время «холостой» работы
}
}
//--------------
ksv198
Цитата(prog @ Aug 13 2006, 17:54) *
Здравствуйте!!!

Люди раскажите каким компилятором собирали прилагаемый код.
Пробывал CVAVR наткнулся на грабли присутствия ina90.h
потом IAR Embedded Workbench там при компиляции высыпалась масса ошибок.

С уважением, Владимир.

Дык, этож изначально была лабораторная работа в каком-то вражеском (кажется индусском) институте. Её для нормальной работы надо слегка рихтовать напильником. Первоначальный проект был под ICC, под WinAVR легко доробатывается путем создания нового проекта под целевой контроллер (какой вы используете в железке) и вдумчевого переноса подпрограмм с их анализом и доработкой. Я сам весь проект не реализовывал, подсматривал только функции работы с DataFlash (и переписывал слегка), но в целом там все очень понятно и без наворотов написано.
Shurmas
я делал по http://roboclub1.narod.ru/z7.htm там исправленый код для CodeVisionAVR.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.