ПРоблемка у меня...Скорее всего с АЦП. Контроллер - ATMega32, частота кварца 16 МГц
Задача такая - по оптическому каналу (лазер и фотодиод) передается байт. В этом же устройстве он принятый байт сравнивается с переданным и если байты одинаковы, возвращается 1.
вот код
Код
#define MUX_STATE (0 << REFS1)|(0 << REFS0)
#define ADC_STATE (1 << ADEN)|(0 << ADPS2)|(1 << ADPS1)|(1 <<ADPS0)
int ReadADC(unsigned char ChannelNum)
{
ADMUX = ChannelNum | MUX_STATE;
ADCSRA = (1 << ADSC) | ADC_STATE;
while ( (ADCSRA & ( 1 << ADIF))==0);
return ADCW;
}
send_pack(unsigned char byte)
{
char *text;
int i,x;
unsigned char _bit, recieved_byte;
for (i=0;i<8;i++) // разбираем байт по битам
{
_bit=(byte >> i) & 0x01; //присваиваем переменной _bit значение очередного бита переменной byte
if (_bit==1)
{
PORTD |= _BV(PD0); // бит равен 1, включаем лазер
glcdFillRect(10,10+i*18,20,20+i*18,RED);
}
if (_bit==0)
{
PORTD &= ~_BV(PD0); // 0, бит равен 0, выключаем лазер
glcdFillRect(10,10+i*18,20,20+i*18,WHITE);
}
glcdWait(1000); //ждем-с...
x=ReadADC(0); запускаем АЦП и измеряем освещенность фотодиода.
sprintf(text," %i ",x);
glcdMoveTo(60,10+i*18);
glcdPrint(text, 0);
if (x<50) // если освещенность низка - bit=0
{
glcdFillRect(30,10+i*18,40,20+i*18,WHITE);
_bit=0;
}
if (x>50) // если освещенность достаточна- bit=1
{
glcdFillRect(30,10+i*18,40,20+i*18,RED);
_bit=1;
}
recieved_byte |= _bit << i; // склеиваем из полученных битов байт
}
if (recieved_byte==byte) return 1;
return 0;
}
Но вот проблема... если в байте чередуются 1 и 0, то данные принимаются с точностью до наоборот.
вот вам пример того, что выводится на экран:
T- посылаемый бит
R- принятый бит
L- значение полученное с АЦП
Код
Для байта 0xFF: Для байта 0xAF: Для байта 0xAF: Для байта 0xFA:
T R L T R L T R L T R L
1 1 512 1 1 514 0 0 11 0 0 11
1 1 511 1 1 513 1 0 11 1 0 11
1 1 509 1 1 512 0 1 515 0 1 508
1 1 510 1 1 512 1 0 11 1 0 11
1 1 512 0 1 512 0 1 515 1 1 508
1 1 511 1 0 12 1 0 12 1 1 507
1 1 511 0 1 537 0 1 512 1 1 506
1 1 511 1 0 13 1 0 13 1 1 508
Небольшой анализ:
1.Подряд идущие биты анализируются нормально.
2.При переключении бита с 1 на 0 или обратно происходит как бы сдвиг, почему-то выводится все наоборот.
3. Первый неправильный "результат" (то есть когда после кучи единиц вдруг оказывается ноль или наоборот) всегда содержит предыдущее значение АЦП.
4. Два одинаковых бита подряд возвращат АЦП к нормальной работе.
Комбинации с частотой работы АЦП ничего не дали. VCC, AVCC и AREF соединены одним проводником.
P.S. Самое главное - я пишу в WinAVR. До этого аналогичный код был написан мной для CodeVision за полчаса и прекрасно работал...