Помогите разобраться со скоростью передачи данных от Atmega8 на порт ПК (Rs-232). Запрограммировал АЦП в данном МК. Все работает, только данные передаются очень медленно . Мне нужно оцифровать частоту 50 герц с как можно большим количеством точек. У меня работает со скоростью около 1000 точек за секунду. Мне нужно около 10000 точек - в этом и собственно проблема. Программу писал в CodeVisionAVR.
Вот сама программа. Код:
#include <mega8>
#include <delay>
#include <stdio>
#define ADC_VREF_TYPE & 0xff;
interrupt [ADC_INT] void adc_isr(void){
printf("%d ",ADCW); // печатаем в УАРТ значение регистра ADCW
putchar(0x0D); // на новую строку УАРТА
}
void init(void){
// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud Rate: 57600
UCSRA=0x00;
UCSRB=0x18;
UCSRC="0x86;"
UBRRH=0x00;
UBRRL=0x0C;
ADMUX=0x0b00000000; // вибираем 0-й канал АЦП
ADCSRA=0x0b10001011; // конфигурация АЦП
#asm ("sei"); // разрешить все переривания
}
void main(void)
{
init(); // визов функции int (инициализация всего)
while(1){
ADCSRA=0b11001011; // включаем непреривное АЦП преобразование
}
}
В проекте использовал скорость 57600 бод поскольку это максимальная скорость симуляции RS-232 в Proteus. На практике хочу использовать 115200 бод. Даныє буду слать на расстояние 1-0,5 метра (максимум на 2,5 м).
Вполне достаточно и скорости 1000 точек/сек. Но моя задача посложнее. Нужно считать форму сигнала 50 гц максимально точно, вплоть до точного перехода через ноль.
То есть мне нужно считать несколько периодов (не больше 3-5) с максимальным количеством точек (чтобы увидеть наименьшие импульсы).
В будущем можно сделать цифровой осциллограф.
В прерывании отправлять данные это плохо -
Накапливай в буфер сколько надо значений, потом отправляй пачкой на уарт:
#include <mega8>
#include <delay>
#include <stdio>
#define ADC_VREF_TYPE & 0xff;
#define BUF_SIZE 512 // необходимое число точек
unsigned char buff[BUF_SIZE];
unsigned int buf_cnt=0;
unsigned char owf_flag =0;
interrupt [ADC_INT] void adc_isr(void){
if(!owf_flag){
buff[buf_cnt]=ADCW;
buf_cnt++;
if(buf_cnt == BUF_SIZE)owf_flag=1;
}
}
void init(void){
// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud Rate: 57600
UCSRA=0x00;
UCSRB=0x18;
UCSRC="0x86;"
UBRRH=0x00;
UBRRL=0x0C;
ADMUX=0x0b00000000; // вибираем 0-й канал АЦП
ADCSRA=0x0b10001011; // конфигурация АЦП
#asm ("sei"); // разрешить все переривания
}
void main(void)
{
init(); // визов функции int (инициализация всего)
while(1){
ADCSRA=0b11001011; // включаем непреривное АЦП преобразование
if(owf_flag)
{
while(buf_cnt){
buf_cnt--;
printf("%d ",buff[buf_cnt]); // печатаем в УАРТ значение
putchar(0x0D); // на новую строку УАРТА
}
owf_flag = 0;
}
}
}
но учти - он будет молотить с максимальной скоростью, буфера может не хватить - по идее надо завести таймер на нужную скорость оцифровки- а в прерывании от таймера запускать преобразование ацп...
Да не заметил - если ацп в режиме 10бит то нужно буфер объявить как unsigned int buff[]
и число точек уменьшить, а то не хватит памяти озу
хотя оцифровывать сеть 8бит заглаза