Перейти к содержанию

crazz

Рекомендуемые сообщения

Английский надо подтягивать.

7-й бит определяет выравнивание данных из АЦП. Поскольку АЦП там 10 битный, а результат ложится в 16-битный регистр то есть два варианта выравнивания - с 6 нулями в старших разрядах или с 6 нулями в младших разрядах. Первый вариант хорош когда надо все 10 бит, а второй вариант когда тебе надо только 8 бит, можно считать только старший байт а младший проигнорировать иначе надо было бы сдвигать результат.

6-й бит это продолжение 3-го бита выбора частоты работы АЦП, там в верхнем регистре расписаны значения.

бит2 - состояние модуля АЦП - в процессе преобразования/закончил преобразование. Запись в этот бит "1" начинает процесс преобразования. т.е. надо записать туда "1" и ждать пока появится "0" и только тогда можно считывать измеренное значение.

бит0 - вкл/выкл модуля АЦП. Если его выключить то он не будет работать от слова совсем, как и потреблять лишнюю энергию.

И соответственно прежде чем что-то делать с АЦП необходимо его включить и подождать некоторое время пока он оклемается.

Учение - изучение правил. Опыт - изучение исключений.

Ссылка на комментарий
Поделиться на другие сайты

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

7-й бит определяет выравнивание данных из АЦП.

каково практическое применение?

И где врубить 8 битный или 10 битный ацп?

бит2 - состояние модуля АЦП

тоже не понимаю каково практическое применение.

Ссылка на комментарий
Поделиться на другие сайты

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

Zombie47, тщательней надо прочитать пост #2003 - всё описано.

Бит 7 определяет выравнивание результата т.е. правое - результат преобразования записывается (з- значение) 000000зз зззззззз,

левое выравнивание записывается зззззззз зз000000. Выравнивание применяют для простоты обработки результата. 8 битное

значение АЦП не включается, а берётся из 10 битного значения, при правом выравнивании выбирается младший байт или при

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

программы для этого надо установить бит 2 в единицу и контролировать когда он переключится в 0 - преобразование завершено.

Я не говорю панацеи - я предлагаю варианты

Ссылка на комментарий
Поделиться на другие сайты

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

при включении левого выравнивания результат АЦП запишется в ADRESH старшие 8бит и в 7:6 бит ADRESL младшие 2бита

при включении правого выравнивания результат АЦП запишется в 1:0 бит ADRESH старшие 2бита и в ADRESL младшие 8бит...

бит2 запускает преобразование АЦП программно и сбрасывается аппаратно после окончания преобразования

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

далее выдержав паузу для заряда конденсатора Сhold , бит GO/DONE устанавливается в лог1

после того как бит GO/DONE сбросится аппаратно в лог0 читаем значение АЦП в регистрах ADRESH, ADRESL

ЗЫ вам бы мануал на средние семейство пиков почитать... http://www.microchip.ru/lit/articles/ раздел23

Ссылка на комментарий
Поделиться на другие сайты

ЗЫ вам бы мануал на средние семейство пиков почитать

Не знаю где там раздел 23 но про АЦП я оба мануала прочел там. Вся проблема в том что там написано что делать но не очень понятно как это делать на языке СИ. Вот и ломаю голову. Вроде АЦП заработал. Может криво косо я не знаю. Позже выложу программу чтобы оценили поправили направили.

Теперь вот ломаю голову с тем как объяснить что делать если АЦП состояние не определенное.

Ну в том плане если там есть какое либо напряжение все хорошо он работает. а вот если нету виснет.

Ссылка на комментарий
Поделиться на другие сайты

и в протеусе и в жизни. в протеусе ошибки валяться а в жизни просто все пропадает и больше не реагирует. Ну он не виснет а программа криво написана которая приводит к какому то действию которое я в ней не прописал так сказать =)

Ссылка на комментарий
Поделиться на другие сайты

Ну вот народ пошел то... а почитать хотябы описание ошибки? Или там написано китайскими иероглифами династии которая канула в лету 1000 лет назад?

Как правило сообщение об ошибке - это осознание 90% способа решения проблемы. Протеус вроде бы не замечен за выкидыванием безликих ошибок. Каждая имеет человекочитаемый вид.

Учение - изучение правил. Опыт - изучение исключений.

Ссылка на комментарий
Поделиться на другие сайты

Вроде чето сделал и все заработало. С таймером немного разобрался. Да и вообще скидывать проект заставлять в нем разбираться по мелочам не хочеться лишний раз напрягать. Я лучше скину когда совсем тупик будет, или когда уже будет полностью доделанный чтобы оценили код и поправили как лучше было сделать и почему.

Ссылка на комментарий
Поделиться на другие сайты

Про эффект бабочки слышали? лучше поправить сейчас, чем потом горы переставлять местами.

Учение - изучение правил. Опыт - изучение исключений.

Ссылка на комментарий
Поделиться на другие сайты

Еще вопрос, у меня светодиод через резистор в схеме подрублен катодом (минусом) к RA1 а анодом (плюсом) к +5вольтам.

То-есть управляется он замыканием на землю.

TRISA это как я понимаю инициализация. У меня прописано TRISA = 0b01110011; тоесть RA2,3,7 выходы а остальные входы.

Если прописываю TRISA = 0b01110001; тем самым делая RA1 тоже выходом то тогда светодиод загорается.

Если в простой программе прописываю RA1=1 то он тухнет, если RA1=0 то загорается.

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

Ссылка на комментарий
Поделиться на другие сайты

Вообщем вот весь код программы, она опять почему то зависает если на выводе RA0 ничего нет. Но в протеусе работает.

/*

* File: newmain.c

* Author: Vlad

*

* Created on 16 ???????? 2015 ?., 0:37

'11-a RB5

'13-b RB7

'7-c RB1

'9-d RB3

'6-e RB0

'10-f RB4

'12-g RB6

'8-dp RB2

' RA3 dig1

' RA2 dig2

' RA7 dig3

*

* $82 - E, $08 -R

*

*/

#pragma config FOSC = INTOSCIO // Oscillator Selection bits (INTRC oscillator; port I/O function on both RA6/OSC2/CLKO pin and RA7/OSC1/CLKI pin)

#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT enabled)

#pragma config PWRTE = ON // Power-up Timer Enable bit (PWRT enabled)

#pragma config MCLRE = OFF // RA5/MCLR/VPP Pin Function Select bit (RA5/MCLR/VPP pin function is digital I/O, MCLR internally tied to VDD)

#pragma config BOREN = ON // Brown-out Reset Enable bit (BOR enabled)

#pragma config LVP = OFF // Low-Voltage Programming Enable bit (RB3/PGM pin has digital I/O function, HV on MCLR must be used for programming)

#pragma config CPD = OFF // Data EE Memory Code Protection bit (Code protection off)

#pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off)

#pragma config CCPMX = RB2 // CCP1 Pin Selection bit (CCP1 function on RB2)

#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)

#include <xc.h>

#include <pic.h>

#include <pic16f819.h>

#define LED PORTB

#define dig1 RA3 //индикатор 1

#define dig2 RA2 //индикатор 2

#define dig3 RA7 //индикатор 3

#define tochka RB2

#define warning RA1

#define _XTAL_FREQ 4000000

const unsigned char digits [13] = {0x44,0x7D,0x16,0x15,0x2D,0x85,0x84,0x5D,0x04,0x05,0xFF,0x86,0x0C}; //0,1,2,3,4,5,6,7,8,9,пусто, E,R

int adc;

int d1=0, d2=0, d1_1=0, d3=0, valueT=0, c=0;

char a=0;

void convert (){ // функция преобразования

if(ADCON0bits.GO == 0)

{

adc=ADRESH; //Для получения 8-ми битного результата необходимо применить левое выравнивание и считывать только регистр ADRESH

if (adc<255){

valueT = ((-0.714 * adc)+162.857);// формула для перевода АЦП в нужное число

ADCON0bits.GO = 1;

}

else {

valueT=1234;

ADCON0bits.GO = 1;

}

}

}

void interrupt Timer (void){ //прерывание по таймеру для динамической индикации

if(TMR0IF){

TMR0IF=0;

convert();

if(valueT<10){

d1=10;

d2=10;

d3=valueT;

}// если значение ValueT меньше 10 то подаем цифру пусто на 1 и 2 слева индикатор

if (valueT >= 10 && valueT < 100){

d1=10; // если значение ValueT меньше от 10 до 100 то на 1 индикатор подаем цифру пусто. Заметил что там почемуто еле светиться цифра.

d1_1=valueT%100;

d2=d1_1/10; // Получаем разряд

d3=d1_1%10; // Получаем разряд

}

if (valueT >= 99 ){

d1_1=valueT%100;

d1=valueT/100;// Получаем разряд

d2=d1_1/10;

d3=d1_1%10; // Получаем разряд

}

if (valueT == 1234 ){

d1=11; //отправляем в 1 индикатор букву E

d2=12; //отправляем в 2 индикатор букву R

d3=12; //отправляем в 3 индикатор букву R

}

//ниже продолжение тела прерывания

a++;

switch(a){ // Динамическая индикация.

case 1: dig1=0; dig2=0; dig3=1; LED=digits[d3]; break; // Первый разряд

case 2: dig1=0; dig3=0; dig2=1; LED=digits[d2]; break; // второй разряд

case 3: dig2=0; dig3=0; dig1=1; LED=digits[d1]; a=0; break; // третий

}

}

}

void main (void) {

TRISA = 0b01110011; //порты RA2, RA3, RA7, RA1 на выход а остальные на вход

TRISB = 0b00000000; // все порты RB на выход

ADCON0=0b01000001;//ADCON0 из даташита page 81 bit7-6=00 clock fosc/2 ,bit5-3=000 analog chanel RA0, bit2=0 status,bit1=1 EMPTY,bit0=1 ADON,

ADCON1=0b00000010; //из даташита page 82 bit7=0 ADFM result format, bit6=0 ADCS2 disable,bit5-4 EMPTY, bit3-0=0010

OSCCON = 0b01100100; //из даташита page 38 (2 бит вкл стабилизация частоты,с 4 по 6 бит значение 110 означает 4mhz

TMR0 = 0; //сбрасываем таймер в 0

INTCON = 0b10100000; //врубаем таймер page 18 bit7=1 GIE enable all interrupts,bit6=0 PEIE disable,bit5=1 TMR0IE enable ,bit4=0 INTE disable external interrupt RB,bit3=0 RBIE disable RB change,bit2=0 TMR0IF disable,bit1=0 INTF disable,bit0=0 RBIF disable RB change flag,

OPTION_REG = 0b00000011; // настройки таймера 1:16 и установка Set timer TMR0 даташит page 54: bit7=0 RBPU pull up enable,bit6=0 INTEDG interrupt on falling edge RB0,bit5=0 T0CS internal cycle clock,bit4=0 T0SE increment low to high,bit3=0 PSA prescailer for timer0,bit2-1=0 Prescaller rate

PORTA = 0; //обнуляем порт а

PORTB = 0;

while (1)

{

};

}

Ссылка на комментарий
Поделиться на другие сайты

Вообщем вот весь код программы, она опять почему то зависает если на выводе RA0 ничего нет. Но в протеусе работает.

int adc;

int .......... valueT=0.......;

.........................

.........................

valueT = ((-0.714 * adc)+162.857);// формула для перевода АЦП в нужное число

Это что такое?

Вы вообще знаете что нибудь о ТИПАХ переменных?

Про тихий ужас с расчетами в прерываниях с преобразованием АЦП и ЧЕТЫРЬМЯ ДЕЛЕНИЯМИ в int я уже молчу... Даже интервала прерываний в 4000 машинных циклов тут может не хватить. Сие конечно не фатально, но зачем тогда вообще прерывания от таймера?

Тактирование АЦП - 500 нс, что В 4 РАЗА меньше допустимого ( 2мкс)...

:lol:

В процедуре Convert() сначала переменной adc присваивается 8 разрядное значение из ADRESH, а потом зачем то проверяется на переполнение 8 разрядов... :crazy:

Изменено пользователем my504

戦う前に相手のベルトの色に注目

Ссылка на комментарий
Поделиться на другие сайты

Первая программа чего вы хотите =)))

int adc поменял на char adc верно?

В процедуре Convert() сначала переменной adc присваивается 8 разрядное значение из ADRESH, а потом зачем то проверяется на переполнение 8 разрядов...

Ну это для того чтобы если значение АЦП 255 то надо выдать на дисплей ERR

А как правильно то вообще?

Ссылка на комментарий
Поделиться на другие сайты

А вообще то правильно использовать все 10 разрядов, для чего сделать ПРАВОЕ выравнивание, а потом:

adc unsigned int;
...............

adc = ADRES; // так как оба регистра расположены подряд и в нужном порядке, то присвоение будет правильным

Правильно будет понимать, что разного рода десятичные дроби констант при целочисленных переменных будут ОКРУГЛЕНЫ компилятором до ЦЕЛОГО. То есть если оперировать в типах int или unsigned int, нужно все дроби превращать из десятичных в обычные, причем в знаменателе лучше всего иметь число 2n, что позволит заменить деление СДВИГОМ. Но при этом нужно следить за тем, чтобы результат умножения на числитель дроби не переполнял используемый тип переменной. Умножение на числитель нужно делать ПЕРВЫМ, а деление на знаменатель последним, чтобы не произошла потеря разрядов при делении.

Правильно будет понимать, что в прерываниях делают ТОЛЬКО БЫСТРЫЕ операции, а на длительные только выставляют флаг требования, чтобы в main() спокойно их исполнить и при этом не забыть опустить флаг требования.

Правильно будет получать результат преобразования АЦП В ПРЕРЫВАНИИ от АЦП, там же выставить флаг готовности данных, чтобы в том же main() их исполнить и сбросить флаг готовности данных.

Ну и так далее, включая проблемы с инициализацией АЦП (тактирование от 2 до 8 мкс), о которых я сказал ранее.

ЗЫ. И мой Вам совет, чтобы понимать КАК и ЧТО нужно и происходит в МК, поиграйте сначала с АСМом.

Меня тут могут зашикать, но я обоснованно полагаю, что без понимания ASM хотя бы первого используемого контроллера, ник чему осмысленно толковому в результате придти нельзя.

Там Вы почувствуете все. И работу прерываний, и взаимодействие контекста с кодом и типы переменных, которые нужно создавать ручками, и вообще все.

Тогда ПОТОМ, когда Вы будете писать на Си, Вы будете понимать что, зачем и для чего...

Изменено пользователем my504

戦う前に相手のベルトの色に注目

Ссылка на комментарий
Поделиться на другие сайты

Сделал вот так valueT = ((-714 * adc)+162857)/1000;

но теперь хрень получается. adc равно 93

На калькуляторе получается 96,455 ну и если компилятор округляет значение то наверно должен округлить до 97 или 96, а в программе получается 161

Тактирование АЦП - 500 нс, что В 4 РАЗА меньше допустимого ( 2мкс)...

да я про это читал и поэтому выставил ADCON0=0b01000001; 7-6 бит выставил 01 что является Fosc/8 так было написано в мануале хоть и не на этот микроконтроллер но рекомендации там такие http://www.microchip.ru/files/d-sheets-rus/FACT2.pdf если тактовая частота МК 4mhz и меньше то ставить Fosc/8

Про прерывания понял, мне нужна еще одна функцие прерывания которая будет прерывать мейн и в которой будет процесс АЦП. Тоесть будет прерывание по таймеру и смена индикации и прерывание по АЦП. Попробую.

Ссылка на комментарий
Поделиться на другие сайты

Знаменатель сделайте равным 1024, тогда деление можно заменить на 10 сдвигов.

Кроме того, умножение на 1024 приведет к ПЕРЕПОЛНЕНИЮ типа int, так что для подобной точности (Вы сами ее задали!), потребуется short long или long.

戦う前に相手のベルトの色に注目

Ссылка на комментарий
Поделиться на другие сайты

знаменатель у вас сейчас 1000

соответсвенно чтобы получить знаменатель 1024 надо все коэффициенты кратно уменьшить. Тогда операция /1000 заменится на /1024, что будет выполнено как сдвиг, а не как деление. Быстрее раз в двадцать

лучше всего конечно будет вручную прописать сдвиг на 10 бит вправо, так надежнее

Изменено пользователем mail_robot

Нужно делать то, что нужно. А то, что не нужно, делать не нужно. (С) Винни Пух

Ссылка на комментарий
Поделиться на другие сайты

я не понимаю как сделать знаминатель 1024 и о каком умножении на 1024 идет речь?

Том самом, на которое вы увеличили числитель.

Ведь умножив исходный коэффициент на 1024, Вы превысили разрядность int.

разбирайтесь

adc= (ADRESH<<8)+ADRESL;

вполне заменяется на

adc= ADRES;

Потому что в хедере

unsigned int ADRES

PS. Предпочитаю, чтобы рыбу ловил ТС. А удочку ему, так и быть, можно снарядить. Иначе толку не будет.

Изменено пользователем my504

戦う前に相手のベルトの色に注目

Ссылка на комментарий
Поделиться на другие сайты

Не всегда оправдано использование прерываний для АЦП, если единственная задача в главном цикле дождаться результатов измерения с АЦП, то смысла городить прерывание нет.

Изменено пользователем Alexeyslav

Учение - изучение правил. Опыт - изучение исключений.

Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу

×
×
  • Создать...