Электроника - это просто Теоретические и практические вопросы для начинающих электронщиков. |
04.04.2012, 00:25
|
|
Почётный гражданин KAZUS.RU
Регистрация: 20.08.2010
Адрес: Днепр
Сообщений: 8,565
Сказал спасибо: 5,041
Сказали Спасибо 10,615 раз(а) в 3,604 сообщении(ях)
|
Re: резисторные делители и т.д.
Сообщение от avp94
|
Тогда: Vab=Vr2(R1+R3)/R3
Ток через Rx Irx=(Vab - Vrx)/R2
Rx=Vrx/Irx все
|
avp94 привел вам абсолютно верное решение, которое выполняется для любых номиналов резисторов, и для любых питающих напряжений.
А то, что вы делите одно напряжение на другое, и при этом радуетесь - это неправильно. Вы проверяете, изменяя только напряжение питания. Конечно, при этом отношение напряжений будет оставаться равным отношению коэффициентов деления делителей. Но ведь вся суть в том, что вам надо вычислять текущее значение Rx, которое будет меняться. И тут начнут вылезать погрешности, причем довольно приличные. Вы уходили от неточности измерения, вызванной напряжением питания. А пришли к еще большей неточности.
Вам надо вернуться к формулам, предложенным avp94.
|
|
|
|
04.04.2012, 00:55
|
|
Почётный гражданин KAZUS.RU
Регистрация: 04.12.2009
Сообщений: 5,455
Сказал спасибо: 73
Сказали Спасибо 2,510 раз(а) в 1,414 сообщении(ях)
|
Re: резисторные делители и т.д.
А вот это вам не пригодится? Преобразователь сопротивления в напряжение:
http://pclas.ru/usel/elekt74.html
Рис. 12.17
|
|
|
Сказали "Спасибо" Scadauser
|
|
|
04.04.2012, 01:06
|
|
Заблокирован
Регистрация: 27.03.2007
Сообщений: 1,328
Сказал спасибо: 12
Сказали Спасибо 576 раз(а) в 460 сообщении(ях)
|
Re: резисторные делители и т.д.
Сообщение от Alex9797
|
avp94 привел вам абсолютно верное решение, которое выполняется для любых номиналов резисторов, и для любых питающих напряжений.
|
Да оба способа идентичны! Если Вы пройдёте весь путь до конца и подставите все промежуточные формулы в окончательную, то увидите, что Rx зависит от величин R1, R2, R3 и ... отношения V2/V1. То есть, если принять, что величины резисторов - константы, то Rx однозначно определяется тем самым отношением напряжений, которое и вычисляет ТС.
|
|
|
|
04.04.2012, 01:22
|
|
Почётный гражданин KAZUS.RU
Регистрация: 20.08.2010
Адрес: Днепр
Сообщений: 8,565
Сказал спасибо: 5,041
Сказали Спасибо 10,615 раз(а) в 3,604 сообщении(ях)
|
Re: резисторные делители и т.д.
Сообщение от Yurkin2007
|
Да оба способа идентичны! Если Вы пройдёте весь путь до конца и подставите все промежуточные формулы в окончательную, то увидите, что Rx зависит от величин R1, R2, R3 и ... отношения V2/V1. То есть, если принять, что величины резисторов - константы, то Rx однозначно определяется тем самым отношением напряжений, которое и вычисляет ТС.
|
Пересмотрел все комменты, чуть глаза не лопнули, но так и не увидел, в чем идентичность.
Сообщение от Yurkin2007
|
По-моему, надо так:
X = 100 * RES_VAL / BATT_VAL
|
Вот этот способ? Так тут вообще в результате получится безразмерная величина, а должны получиться омы.
Или я что-то пропустил, и есть еще формулы? Хотя похоже, что это и есть та, окончательная.
Тогда покажите, как с ее помощью вы получите значение Rx, Например, для трех значений - 0,5к , 3к , 5к.
Собственно, показывать мне не обязательно, я уже у себя это смоделировал. А хотя бы для себя это сделайте, чтобы убедиться.
|
|
|
|
05.04.2012, 01:07
|
|
Почётный гражданин KAZUS.RU
Регистрация: 26.11.2011
Адрес: Анапа
Сообщений: 1,620
Сказал спасибо: 284
Сказали Спасибо 129 раз(а) в 111 сообщении(ях)
|
Re: Резисторные делители и т.д.
Сообщение от Alex9797
|
есть еще формулы?
|
в принципе, мне сопротивление не нужно. Мне нужно чтобы не плавал порог оцифровки (0..255) с двух "каналов", что то вроде процентного соотношения. Нужные мне значения я вывед, накидал калькулятор в экселе..
Scadauser, нет, мне просто АЦП заюзать в МК надо..
В протеусе завелось, нормально. Теперь силовую часть до ума довести - соседняя тема, и буду пробовать ставить, отлаживать.
|
|
|
|
05.04.2012, 01:09
|
|
Почётный гражданин KAZUS.RU
Регистрация: 26.11.2011
Адрес: Анапа
Сообщений: 1,620
Сказал спасибо: 284
Сказали Спасибо 129 раз(а) в 111 сообщении(ях)
|
Re: Резисторные делители и т.д.
Сообщение от alx25v
|
используй как опорное для АЦП
|
тини13, АРЕФ нету.. Да и мне все равно надо знать напряжение бортсети - определяю так, что двигатель заведен.
Сообщение от ForcePoint
|
который Вы желаете заменить (угадал?)
|
нет, он остается. Надо парралельно ему снимать значения для включения вентилятора мосфетом - несколько порогов мощности.
|
|
|
|
05.04.2012, 10:02
|
|
Почётный гражданин KAZUS.RU
Регистрация: 20.03.2007
Адрес: "Братское кольцо враждебности", т.е. ближайшее заМКАДье.
Сообщений: 7,053
Сказал спасибо: 3,041
Сказали Спасибо 3,212 раз(а) в 2,182 сообщении(ях)
|
Re: Резисторные делители и т.д.
Сообщение от whoim
|
Да и мне все равно надо знать напряжение бортсети - определяю так, что двигатель заведен.
|
Тем более tiny25. Определять будете - поключая на вход АЦП внутренюю опору (ADMUX3:0 = 1100) при Vref = "12В через делитель".
|
|
|
|
05.04.2012, 11:46
|
|
Почётный гражданин KAZUS.RU
Регистрация: 26.11.2011
Адрес: Анапа
Сообщений: 1,620
Сказал спасибо: 284
Сказали Спасибо 129 раз(а) в 111 сообщении(ях)
|
Re: Резисторные делители и т.д.
ForcePoint, зачем?
|
|
|
|
06.04.2012, 11:38
|
|
Почётный гражданин KAZUS.RU
Регистрация: 20.03.2007
Адрес: "Братское кольцо враждебности", т.е. ближайшее заМКАДье.
Сообщений: 7,053
Сказал спасибо: 3,041
Сказали Спасибо 3,212 раз(а) в 2,182 сообщении(ях)
|
Re: Резисторные делители и т.д.
Что "зачем"? tiny25 - для того, что-бы упростить программу. Или что-то ещё?
|
|
|
|
09.04.2012, 09:40
|
|
Почётный гражданин KAZUS.RU
Регистрация: 26.11.2011
Адрес: Анапа
Сообщений: 1,620
Сказал спасибо: 284
Сказали Спасибо 129 раз(а) в 111 сообщении(ях)
|
Re: Резисторные делители и т.д.
ForcePoint, да проще расчет делать, тем более программа нормально укладывается в 13 тини (килобайт). Пин то все равно аналоговый юзать - надо знать бортовое для других целей.
Вот программка (предварительно), что в ней можно упростить, да и вообще - какие замечания? В протеусе все почти ровно.
Цитата:
|
#define F_CPU 9600000UL // 9,6 MHz attiny13
//#define F_CPU 8000000UL // 8 MHz attiny45
#include ‹avr/io.h›
#include ‹avr/interrupt.h›
#include ‹stdbool.h›
#include ‹util/delay.h›
//пины
#define LED_PIN PB1 //светодиод
//остальное
//13,3В (103) - порог включения, 12,8 (100) - порог выключения.
#define POWER_ON 86 //порог включения 13,3В
#define POWER_OFF 78 //порог выключения 12,8В
//пороги включения
// LEVEL_ГРАДУС ЗНАЧЕНИЕ_X
// X = 100 * TEMP_VAL / BATT_VAL;
//значение для сравнения в TEMP_PER
#define LEVEL_ERR 74 //Ошибка датчика (в нижнюю t сторону)
#define LEVEL_82 51 //82C
#define LEVEL_85 50 //85C
#define LEVEL_87 49 //87C
#define LEVEL_89 48 //89C
#define LEVEL_90 47 //90C
#define LEVEL_92 46 //92C
#define CHECK_TIME 1000 //время проверок (каждые ХХ миллисекунд, не менее 255 + время на горение)
//переменные
volatile long millis;
volatile long tcounter; //переменные для расчета времени
volatile long prev_millis; //для расчета разницы прошедшего времени
unsigned char BATT_VAL; //оцифрованное значение напряжения бортовой сети
unsigned char TEMP_VAL; //оцифрованное значение датчика температуры
unsigned char TEMP_PER; //Значения показаний датчика температуры в процентном сравнении с напряжением бортовой сети
unsigned char LED_CB; //Сколько раз мигнуть
//Вспомогательные функции и процедуры
void timer_setup(void) {
//Настройка ШИМ
TCCR0A = (1 ‹‹ WGM01)|(1 ‹‹ WGM00); // non inverting fast pwm
//выбор предделителя
//TCCR0B = (1 ‹‹ CS00); //делитель 0, частота 9600000/255=37640
TCCR0B = (1 ‹‹ CS01); //делитель 8, частота 9600000/8/255=4705гц
//TCCR0B = ((1 ‹‹ CS01)|(1 ‹‹ CS00)); //делитель 64, частота 9600000/64/255=490,19гц
//TCCR0B = (1 ‹‹ CS02); //делитель 256, частота 9600000/256/255=147гц
//TCCR0B = ((1 ‹‹ CS02)|(1 ‹‹ CS00)); //делитель 1024, частота 9600000/1024/255=36гц
// отслеживаем прерывания по переполнению (TOIE2)
TIMSK0 = (1‹‹OCIE0A); //attiny13
//TIMSK = (1‹‹OCIE0A); //attiny45
asm("sei"); //разрешить прерывания
}
//Отслеживаем переполнение
ISR (TIM0_COMPA_vect) { //tiny13a
//ISR (TIMER0_COMPA_vect) { //tiny45
tcounter++;
//обработка счетчика таймера для расчета времени
if(tcounter == 5) { //для частоты 4705гц, каждые 4705гц / 1000 такта увеличиваем микросекунду
tcounter = 0;
millis++;
}
}
//ADC function - оцифровка
unsigned char ADC_process(unsigned char _pin) {
//выбор пина
if (_pin == PB2) ADMUX = (1 ‹‹ ADLAR)|(1 ‹‹ MUX0); //ADC1
if (_pin == PB4) ADMUX = (1 ‹‹ ADLAR)|(1 ‹‹ MUX1); //ADC2
if (_pin == PB3) ADMUX = (1 ‹‹ ADLAR)|(1 ‹‹ MUX1)|(1 ‹‹ MUX0); //ADC3
ADCSRA |= (1 ‹‹ ADEN); // Включаем оцифровку
ADCSRA |= (1 ‹‹ ADSC);
while (ADCSRA & (1 ‹‹ ADSC)); //Ждем окончания
ADCSRA &= ~(1‹‹ADEN); // остановим оцифровку
return ADCH; //отдаем результат
}
//Главное тело программы
int main(void) {
//настройки пинов
DDRB = 0b00000011;
PORTB = 0b00000000;
//настройка ШИМ
timer_setup();
//настраиваем АЦП
ADCSRA = (1 ‹‹ ADPS1)|(1 ‹‹ ADPS0); // Делитель clock / 8
//главный цикл
while(1) {
//Если пришло время проверок
if(millis › (prev_millis + CHECK_TIME)) {
prev_millis = millis; //уровняем время
//Определяем напряжение бортовой сети через ADC1(PB2)
BATT_VAL = ADC_process(PB2); //заносим значение в переменную
//определим, заведен ли двигатель по пороговым значениям бортового напряжения.
if (!(PINB&(1‹‹LED_PIN)) && BATT_VAL ›= POWER_ON) PORTB |= (1‹‹LED_PIN); //Если было выключено и включили двигатель
if (PINB&(1‹‹LED_PIN) && BATT_VAL ‹= POWER_OFF) PORTB &= ~(1‹‹LED_PIN); //Если было включено и выключили двигатель
if (PINB&(1‹‹LED_PIN)) { //Если двигатель включен
//Считаем показания датчика температуры
TEMP_VAL = ADC_process(PB3); //заносим значение с датчика температуры в переменную
//Считаем показания подстроечного резистора и преобразуем в -10..10
//рассчитываем оцифрованное значение с датчика температуры с учетом подстроечного резистора
TEMP_VAL = TEMP_VAL + ((ADC_process(PB4) - 127) / 13); //TEMP_VAL + (-10..10) [0..255]
//рассчитываем значения показаний датчика температуры в соотношении с напряжением бортовой сети
//получаем значение датчика, не зависящее от напряжения бортовой сети
TEMP_PER = 100 * TEMP_VAL / BATT_VAL;
//работа с ШИМ
if (TEMP_PER › LEVEL_82 && TEMP_PER ‹= LEVEL_ERR && OCR0A != 0) OCR0A = 0; //если был включен и не обнулен - обнулить скважность ШИМ
if (OCR0A == 0 && TCCR0A&(1 ‹‹ COM0A1)) TCCR0A &= ~(1 ‹‹ COM0A1); //выключить вывод на пин ШИМ
//выбор уровня ШИМ
if (TEMP_PER ‹= LEVEL_82 && TEMP_PER ›LEVEL_85) { OCR0A = 77; LED_CB = 1; } //30% при 82
else if (TEMP_PER ‹= LEVEL_85 && TEMP_PER ›LEVEL_87) { OCR0A = 128; LED_CB = 2; } //50% при 85
else if (TEMP_PER ‹= LEVEL_87 && TEMP_PER ›LEVEL_89) { OCR0A = 179; LED_CB = 3; } //70% при 87
else if (TEMP_PER ‹= LEVEL_89 && TEMP_PER ›LEVEL_90) { OCR0A = 204; LED_CB = 4; } //80% при 89
else if (TEMP_PER ‹= LEVEL_90 && TEMP_PER ›LEVEL_92) { OCR0A = 230; LED_CB = 5; } //90% при 90
else if (TEMP_PER ‹= LEVEL_92 || TEMP_PER ›= LEVEL_ERR) { OCR0A = 250; LED_CB = 6; } //99% при 92
//отладка
//OCR0A = ADC_process(PB4);
if (OCR0A != 0 && !(TCCR0A&(1 ‹‹ COM0A1))) TCCR0A |= (1 ‹‹ COM0A1); //включим пин ШИМ, если нужно и он выключен
//индикация светодиодом
if (OCR0A != 0) {
for (int time = 0; time ‹= LED_CB; time ++) {
PORTB &= ~(1‹‹LED_PIN); //выключим светодиод
_delay_ms(70); //держим выключенным некоторое время
PORTB |= (1‹‹LED_PIN); //включим
_delay_ms(70); //держим включенным некоторое время
}
}
}
else { //двигатель выключен но остался включен ШИМ
if (TCCR0A&(1 ‹‹ COM0A1)) TCCR0A &= ~(1 ‹‹ COM0A1); //выключить вывод на пин ШИМ
}
}
}
}
|
Последний раз редактировалось whoim; 09.04.2012 в 09:44.
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 07:29.
|
|