Поклонники продукции Microchip Technology Inc тусуются тут.
Ответить

Re: PIC16F1503

Ср авг 02, 2017 14:55:30

1. После изменением номера канала, необходимо выдерживать паузу.
2. По программе. У Вас имеются совершенно одинаковые куски кода. Зачем их плодить в такую огромную нечитаемую простыню, вместо создания одной функции и её вызова ?

Re: PIC16F1503

Ср авг 02, 2017 15:01:55

задержка имеется в 20 мкс
вот как выглядит для каждого канала

ADCON0 = 0b00000000; // выбор канала
__delay_us(20);
ADRESH = 0;
ADRESL = 0;
ADCON0bits.ADON = 1;
__delay_us(20);
ADCON0bits.GO = 1;
while (ADCON0bits.GO_nDONE)
{continue;}
ADC = calc_v();

if (ADC >= 4700)
{
countChanel++;
}

да, согласен код оставляет желать лучшего.. просто срочно надо рабочий код, а не красивый.. красоту позже наведу

Re: PIC16F1503

Ср авг 02, 2017 15:07:05

УАРТ можно задействовать, если он не занят, выводить в комп в терминальную программу.

Re: PIC16F1503

Ср авг 02, 2017 15:32:42

У этих ПИКов обслуживание прерываний весьма специфичное (в отличии от стандартной "среднемладшей" серии).
В обязательном порядке помимо стека задействуются "теневые хранилки".
Так что прежде, чем прерываниями воспользоваться внимательно даташит перечитать надо и помозговать над возможными "наложениями"
8)

Re: PIC16F1503

Ср авг 02, 2017 15:39:28

Теневые регистры используются в обязательном порядке только при СОХРАНЕНИИ контекста. А вот при восстановлении совсем нет. Совсем как в 18-х.
В зависимости от параметра команды retfie контекст будет или не будет восстановлен из теневых регистров. И тем обеспечена возможность вложенных прерываний.

Re: PIC16F1503

Ср авг 02, 2017 16:29:00

DarkWolf писал(а):задержка имеется в 20 мкс
Вы уверены, что этого достаточно ? Попробуйте поставить побольше. Для эксперимента, можно и миллисекунду воткнуть.

DarkWolf писал(а):просто срочно надо рабочий код, а не красивый.. красоту позже наведу
Красота тут не причём. Выведя код в функцию, Вы получаете быстрое изменение кода для всех каналов, меняя код только в одном месте. Разве это не быстрее ?

Re: PIC16F1503

Чт авг 03, 2017 10:05:53

переписал код в следующем виде

функция чтения ацп

Код:
unsigned int calc_v(void)
{
    unsigned int result_adc;
    unsigned long result_v;

    result_adc = (ADRESH | (ADRESL << 2));
    result_v = (unsigned long)Vdd_mV * result_adc;
    return (result_v / 1024);
}


функция с выбором каналов

Код:
unsigned char  read_adc( unsigned char ch)
{
    unsigned int ADC = 0;
   
    switch (ch)                                     
         {case 0:ADCON0=0b00000000; // Канал 0
                 break;
          case 1:ADCON0=0b00000100; // Канал 1
              break;
          case 2:ADCON0=0b00001000; // Канал 1
              break;
          case 3:ADCON0=0b00001100; // Канал 1
              break;
          case 4:ADCON0=0b00010000; // Канал 1
              break;
          case 5:ADCON0=0b00010100; // Канал 1
              break;
          case 6:ADCON0=0b00011000; // Канал 1
              break;
          case 7:ADCON0=0b00011100; // Канал 1
              break;
          }
  __delay_ms(1);//задержка в 1 мс
    // Обнуляем регистры
    ADRESH = 0;
    ADRESL = 0;
    // Разрешаем АЦП
    ADCON0bits.ADON = 1;
    __delay_us(20);
    // Запускаем измерение
    ADCON0bits.GO = 1;
    while (ADCON0bits.GO);
    {
        ADC = calc_v();
    }
    if (ADC >= 4700)
    {
        return 1;
    }
    else
        return 0; 
 } 


в основной функции проверяю
Код:
count = read_adc(0) + read_adc(1) + read_adc(2) + read_adc(3) + read_adc(4) + read_adc(5) + read_adc(6)+read_adc(7);
   
    if (count == 2)
    {
     PORTA = 0x20; // Порт A5 устанавливаем 1.
     mydelay_ms(87);
    PORTA = 0; // Порт A5 устанавливаем 1.
    mydelay_ms(25);
     PORTA = 0x20; // Порт A5 устанавливаем 1.
    }
    else
    {
        PORTA = 0x20; // Порт A5 устанавливаем 1.
    }


сейчас у меня два канала с напряжением 4.75 вольта. Но программа почему то не работает.
Прерывания не использую. Из отладочных средств только вольтметр и осцилограф. Может кто в протеусе проверить работоспособность кода?

Re: PIC16F1503

Чт авг 03, 2017 10:36:42

1.
Код:
    while (ADCON0bits.GO);
    {
        ADC = calc_v();
    }
Что то тут не то ... Вам не кажется ? :roll:
Зачем, пока идёт преобразование, постоянно читать его результат ? Его же (результата) пока ещё нет, он появится только после преобразования.

2. Для чего Вы преобразовываете в милливольты ? Пороги известны, а значит и значение "попугаев" тоже известны. Почему бы с ними и не сравнивать ? Вам же не на экран значения выводить. Только лишние преобразования, которые только увеличивают вероятность совершения ошибки.

Может кто в протеусе проверить работоспособность кода?
Почему бы Вам самому его не установить и не погонять свой код ? :roll:

Re: PIC16F1503

Пт авг 04, 2017 13:49:58

Всем принявшим участие в помощи, огроменное спасибо. Поставленная задача выполнена. Но не без костылей. Наблюдается следующая особенность поведения АЦП. Если подать напряжение питания на 3 и больше каналов, то в результате код выдает как будто напряжение питания подано на все 8 каналов. Если напряжение питания подать на 2 и меньше каналов то они успешно определяются программой.

Re: PIC16F1503

Ср апр 10, 2019 17:35:28

DarkWolf , не вы ли автор светoдиoдных фонaрей на кaмaзe?

Re: PIC16F1503

Чт апр 11, 2019 08:03:09

Если Вам нужен только высокий уровень, почему-бы компараторы не использовать?
Ответить