Пишу пробный вариант программы для работы с АЦП (1) Настройка последовательно порта для вывода результатов преобразования (2) Настройка регистров АЦП (3) Произвести преобразование (4) Вывести результат на UART
Вроде все просто, скачал исходники с кейловского сайта для того, что бы разобраться... Вот мой код:
| Код | #include <ADUC814.H> #include <stdio.h>
void main() { unsigned char chan_2_convert; unsigned int conv_val;
/*----------------------------------------------- Configure the serial port to run at 9600 Baud. Yeah, this is really slow! -----------------------------------------------*/ SCON = 0x50; TMOD |= 0x20; TH1 = 0xA0; TR1 = 1; TI = 1; /*----------------------------------------------- Configure the A/D to sequentially convert each input channel. -----------------------------------------------*/ ADCCON1 = 0x8C; // 0000 1100 ADCCON2 = 0x10; // simple conversion /* ADCI = 0; ADCSPI = 0; CCONV = 0; SCONV = 1; CS3 = CS2 = CS1 = CS0 = 0; */ printf ("ADCCON1 = 0x%4.4X\r\n", ADCCON1); printf ("ADCCON2 = 0x%4.4X\r\n", ADCCON2);
/*----------------------------------------------- Start a conversion and wait for it to complete. -----------------------------------------------*/ chan_2_convert = 0; // (chan_2_convert + 1) % 6; while (1) { ADCCON1 = 0x8C; // 1000 1100 START CONVERSION SCONV = 1; // printf ("ADCCON1 = 0x%4.4X\r\n", ADCCON1); // printf ("ADCCON2 = 0x%4.4X\r\n", ADCCON2); while ((ADCCON3 & (1 << 7)) == 1) // ADCCON3 & 0x80 printf ("Befor conversion: ADC is BUSY\n"); // printf ("After conversion: ADCCON3 = 0x%4.4X\r\n", ADCCON3); /*----------------------------------------------- Read A/D data and print it out. -----------------------------------------------*/ conv_val = ADCDATAL | ((ADCDATAH & 0x0F) << 8); printf ("ADC Channel %bu = 0x%4.4X\r\n", chan_2_convert, conv_val); SCONV = 0; ADCCON1 = 0x0C; } }
|
Теперь о замеченных чудесах: (1) В регистр ADCCON2 почему-то записывается значение 0х80, вместо 0х10, пытался записать всеми доступными способами. Выводит 0х80 и при таком варианте
| Код | ADCCON2 = 0x10; // simple conversion
|
И при побитовой адресации
| Код | ADCI = 0; ADCSPI = 0; CCONV = 0; SCONV = 1; CS3 = CS2 = CS1 = CS0 = 0;
|
Дальше вторая беда в цикле, когда выполняется само преобразование. В таком варианте все работает, но стоит только мне убрать из цикла
| Код | ADCCON1 = 0x8C; // 1000 1100 START CONVERSION SCONV = 1;
.......
SCONV = 0; ADCCON1 = 0x0C;
|
Как программа работать перестает, т.е. результат преобразования 0х0000, даже если я выше стоящие строки возвращаю наместо, что для меня очень странно Оо Как думаете в чем может быть проблема??? Я больше всего склоняюсь в сторону некорректной записи в регистр ADCCON2, мне кажется от сюда все беды...
ЗЫ для симуляции работы использую ини файл, взятый с кейловского сайта и немного урезанный, он подает входное напряжение
| Код | /*------------------------------------------------------------- This file set the analog inputs for the A/D to different values depending on the button clicked -------------------------------------------------------------*/ define float my_VREF; my_VREF = 2.5
/*------------------------------------------------------------- Create buttons -to set the analog inputs to 0. -to set the analog inputs to VREF. -to set different analog inputs. -------------------------------------------------------------*/
define button "Inputs = 0V" , "Set_Inputs(0.0);" define button "Inputs = High" , "Set_Inputs(my_VREF);" define button "Different A/D Inputs" , "Different_Inputs();"
/*------------------------------------------------------------- The following functions will set the imputs of the analog converter to 0, limit, or differnt values -------------------------------------------------------------*/ func void Set_Inputs (float volt) { AIN0 = AIN1 = AIN2 = AIN3 = AIN4 = AIN5 = volt; }
func void Different_Inputs () { AIN0 = 0.2; AIN1 = 0.6; AIN2 = 1.0; AIN3 = 1.3; AIN4 = 1.7; AIN5 = 2.1; }
|
|