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

PIC16F1503

Ср июн 28, 2017 11:52:13

Доброго всем времени суток! Очень нужна ваша помощь. С пиками работаю впервые да и вообще такую задачу решаю впервые. Есть данный контроллер ножки 3,7,8,9,10,11,12,13 сделаны как входы аналогового сигнала (на выводах 3,5В) от светодиодов. На каждую ножку подведено 2 светодиода. Задача состоит в том, что бы определить высокий уровень на данных входах, что бы сделать определенное действие. Небольшое исследование - закоротив 4 светодиода получили на всех входах 4.1В.

Re: PIC16F1503

Ср июн 28, 2017 12:26:00

входы аналогового сигнала (на выводах 3,5В) от светодиодов. На каждую ножку подведено 2 светодиода
Можете схемку изобразить, а то что-то вообще ничего не понятно? :dont_know:

Re: PIC16F1503

Ср июн 28, 2017 17:44:24

...сделаны как входы аналогового сигнала...

Схему сюда.

Re: PIC16F1503

Ср июн 28, 2017 21:56:01

Доброго всем времени суток! Очень нужна ваша помощь. С пиками работаю впервые да и вообще такую задачу решаю впервые. Есть данный контроллер ножки 3,7,8,9,10,11,12,13 сделаны как входы аналогового сигнала (на выводах 3,5В) от светодиодов. На каждую ножку подведено 2 светодиода. Задача состоит в том, что бы определить высокий уровень на данных входах, что бы сделать определенное действие. Небольшое исследование - закоротив 4 светодиода получили на всех входах 4.1В.

Что-то не стыкуется, схема нужна!

Re: PIC16F1503

Ср июн 28, 2017 22:14:33

Похоже, вопрос "как работать с ADC PIC16F1503".....

Re: PIC16F1503

Чт июн 29, 2017 10:23:43

И как что то сделать не читая datasheet.

Re: PIC16F1503

Чт июн 29, 2017 13:40:55

вот схема Изображение

Да, я понял что с ADC работа. План действий таков:

1) Устанавливаю выводы как аналоговые входы
2) Через АЦП меряю какое напряжение и сравниваю его с нужным пределом.

Просто не знал что в пиках любой порт можно перевести как аналоговый, думал что с аналоговыми сигналами работает только порт A АЦП.

Буду благодарен в помощи настройки таймера. Даже в даташите не понимаю..

необходимо сформировать одиночный прямоугольный сигнал на ноге А5. При подаче питания высокий уровень длительностью 75мс, затем низкий уровень длительностью 25мс.

Re: PIC16F1503

Чт июн 29, 2017 15:42:15

По таймеру: Как вариант, настройте TMR2 на 1mS и считайте время программно по прерыванию с TMR2.
Для настройки таймера надо знать частоту FOSC.
----
P.S.
А pdf на PIC16F1503, всё-таки, читать придётся...

Re: PIC16F1503

Пт июн 30, 2017 04:41:19

Для PIC16F84A будет так:

Изображение
Для PIC16F1503 нужно учесть наличие регистров ADCONx.

Re: PIC16F1503

Пт июн 30, 2017 19:54:11

Если на контроллер подается 24В, то измерять не придется. Схема отвратительного качества. Контроллер очень непростой, это не 84а

Re: PIC16F1503

Сб июл 01, 2017 03:47:15

anatol378 писал(а):...отвратительного качества...

Курсовой надо полагать.
...очень непростой...

Не боги горшки обжигают.

Re: PIC16F1503

Сб июл 01, 2017 08:07:59

anatol378 писал(а):Контроллер очень непростой
Если не читать документацию - все контроллеры не простые. :)))

Re: PIC16F1503

Сб июл 01, 2017 10:18:26

..все контроллеры не простые. :)))

Оно ж понятно - человек просто набивает себе цену.

Re: PIC16F1503

Пн июл 03, 2017 09:12:58

Насчет "Контроллер очень непростой" вероятно имелось ввиду, что для начала не помешало бы с обычными "среднемладшими" познакомиться, затем 18-ю серию проштудировать - а потом уже к этой разновидности приступать.
8)

Re: PIC16F1503

Пн июл 03, 2017 18:23:34

..для начала не помешало бы с обычными "среднемладшими"...

Как замечательно сказал. Даже если не применять всего что заложено (типа конфигурируемых логических ячеек или цифрового генератора), необходимо правильно сконфигурировать его, а для этого читать доки. Другого пути нет. Там немного в основном ДШ - 340 страниц. :beer:

Re: PIC16F1503

Ср авг 02, 2017 10:12:39

Уважаемые знатоки! Укажите куда копать.. не могу получить устойчивую работу ADC на PIC16F1503.

Вот текущий код:
void main(void)
{
// set up oscillator control register
OSCCONbits.IRCF = 0x0F; //set OSCCON IRCF bits to select OSC frequency=16Mhz
OSCCONbits.SCS = 0x02; //set the SCS bits to select internal oscillator block
LATA = 0x00; // turn all outputs off
LATC = 0x00;
// set timer
// PR2 = 0xFF;
// PIR1bits.TMR2IF = 0; // clear TMR2 interrupt flag
// T2CONbits.T2CKPS = 0x02; // TMR2 prescalar bits are both high; prescalar = 64
// T2CONbits.TMR2ON = 1; // TMR2 on

OPTION_REGbits.nWPUEN = 1; // all weak pullups are disabled

// PORT A5 - ВЫХОД, остальные ВХОДЫ
TRISAbits.TRISA0 = 1; // RA0 = nc (SPDAT)
TRISAbits.TRISA1 = 1; // RA0 = nc (SPCLK)
TRISAbits.TRISA2 = 1; // RA2 = Blue LED
//TRISAbits.TRISA3 = 1; // RA0 = nc (MLCR)
TRISAbits.TRISA4 = 1; // RA4 = nc
TRISAbits.TRISA5 = 0; // RA5 = nc


PORTA = 0x20; // Порт A5 устанавливаем 1.

ANSELA = 0x1F; // Все порты кроме A3 аналоговые


// Все порты С входы
TRISCbits.TRISC0 = 1; // RC0 =привет пишем комент на русском
TRISCbits.TRISC1 = 1; // RC1 =
TRISCbits.TRISC2 = 1; // RC2 =
TRISCbits.TRISC3 = 1; // RC3 =
TRISCbits.TRISC4 = 0;
TRISCbits.TRISC5 = 0;

PORTC = 0x00; //На всех входах 0

ANSELC = 0x0F; // С0 - С3 аналоговые

// Выбираем канал внутренего опорного напряжения
//Бит - 7 - Не используется, читается как 0
//Бит - 6-2- Выбор канала (11111 внутрение опорное напряжение)
//Бит 1- 1 - статус преобразования
//Бит 0 - 0 - включение преобразования
/// работаем с первым каналом

ADCON0 = 0b00000000;
ADCON1 = 0xb01110000;

ADCON0bits.ADON = 1;
__delay_us(5);
ADCON0bits.GO = 1;
while (ADCON0bits.GO);
{
result = ((ADRESH * 205) + ADRESL);
}

if (result >= 4)
{
countChanel++;
}

__delay_us(5);
// Второй канал
ADCON0 = 0b00000100;
ADCON0bits.ADON = 1;
__delay_us(5);
ADCON0bits.GO = 1;
while (ADCON0bits.GO);
{
result = ((ADRESH * 205) + ADRESL);
}
if (result >= 4)
{
countChanel++;
}

__delay_us(5);
// 3 канал
ADCON0 = 0b00001000;
ADCON0bits.ADON = 1;
__delay_us(5);
ADCON0bits.GO = 1;
while (ADCON0bits.GO);
{
result = ((ADRESH * 205) + ADRESL);
}
if (result >= 4)
{
countChanel++;
}


__delay_us(5);
//Работаем с 4 каналом
ADCON0 = 0b00010000;
ADCON0bits.ADON = 1;
__delay_us(5);
ADCON0bits.GO = 1;
while (ADCON0bits.GO);
{
result = ((ADRESH * 205) + ADRESL);
}
if (result >= 4)
{
countChanel++;
}

__delay_us(5);
// 5 канал
ADCON0 = 0b00010100;
ADCON0bits.ADON = 1;
__delay_us(5);
ADCON0bits.GO = 1;
while (ADCON0bits.GO);
{
result = ((ADRESH * 205) + ADRESL);
}
if (result >= 4)
{
countChanel++;
}

__delay_us(5);
// 6 канал
ADCON0 = 0b00011000;
ADCON0bits.ADON = 1;
__delay_us(5);
ADCON0bits.GO = 1;
while (ADCON0bits.GO);
{
result = ((ADRESH * 205) + ADRESL);
}
if (result >= 4)
{
countChanel++;
}

__delay_us(5);
// Седьмой канал
ADCON0 = 0b00011100;
ADCON0bits.ADON = 1;
__delay_us(5);
ADCON0bits.GO = 1;
while (ADCON0bits.GO);
{
result = ((ADRESH * 205) + ADRESL);
}
if (result >= 4)
{
countChanel++;
}


if (countChanel <= 2 )
{
PORTA = 0x20; // Порт A5 устанавливаем 1.
mydelay_ms(87);
PORTA = 0; // Порт A5 устанавливаем 1.
mydelay_ms(25);
PORTA = 0x20; // Порт A5 устанавливаем 1.
}

while(1)
{

}

}

суть кода: анализирую напряжение на каналах, если напряжение больше 4 вольт то прибавляю счетчик. В итоге если счетчик меньше 2, то генерирую одиночный импульс. Правильно ли я перевожу полученные значения регистров в вольты. Небходимо с точностью хотя бы 1 знак после запятой..

Re: PIC16F1503

Ср авг 02, 2017 12:03:47

После окончания преобразования сделайте вызов функции:
Код:
unsigned int calc_v(void)
{
    unsigned int result_adc;
    unsigned long result_v;

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

Только предварительно через #define Vdd_mV определите напряжение питания в мВ.
А откуда вы взяли 205 я так и не понял.

Для расчета удобно было бы подать напряжение питания 5.12 В, тогда result_v = 5 * result_adc - готовый результат в мВ.
Можно еще сделать привязку Vdd через внутреннее опорное 1.024 В, тогда еще с формулами поколдовать придется. В общем, варианты разные.

Re: PIC16F1503

Ср авг 02, 2017 13:19:28

Сделал как вы написали:

объявил #define Vdd_mV 4750

unsigned int ADC = 0;

и затем для каждого канала

ADRESH = 0;
ADRESL = 0;
ADCON0bits.ADON = 1;
__delay_us(10);
ADCON0bits.GO = 1;
while (ADCON0bits.GO);
{
ADC = calc_v();
}

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

почему то в результате countChanel = 7 т.е считает что каждый канал соответствует условию. на деле же только 2 канала 4,7 вольта, остальные 4

Re: PIC16F1503

Ср авг 02, 2017 14:08:52

Куда выводите результат? В смысле устройство отображения имеется?
Если есть возможность, для начала выводите голые значения result_adc для каждого канала, чтобы оценить правильность измерений.
А дальше видно будет.

Re: PIC16F1503

Ср авг 02, 2017 14:34:43

к сожалению устройства отображения нету.

проверяю в условии:

if (countChanel >= 2 )
{
PORTA = 0x20; // Порт A5 устанавливаем 1.
mydelay_ms(87);
PORTA = 0; // Порт A5 устанавливаем 1.
mydelay_ms(25);
PORTA = 0x20; // Порт A5 устанавливаем 1.
}

в итоге условие выполняется при countChanel = 7. А это значит что выполняется условие
if (ADC >= 4700)
{
countChanel++;
}
для каждого канала

Добавлено after 19 minutes 53 seconds:
в изначальной функции
unsigned int calc_v(void)
{
unsigned int result_adc;
unsigned long result_v;

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

присвоил result_adc = 0;

в итоге все верно. На выходе все каналы выдают 0;
Ответить