Цитата(shadow86 @ Dec 18 2011, 22:45)

Уважаемые программисты, подскажите, пожалуйста, где мне (и что) добавить, чтоб программа считала импульсы в течение 46с и выдавала на индикатор последнее посчитанное значение,
Для этого вам надо отсчитать 46 секунд. Единственное место у вас, где есть какая то известная периодичность - это динамическое сканирование индикатора (прерывание от таймера), вот в нем и отсчитывайте.
Как насчитаете - копируйте накопленное значение счетчика в переменную, из которой и будете выводить на индикаторы, а счетчик сбрасывайте
Vladex
Dec 19 2011, 11:03
Цитата(shadow86 @ Dec 7 2011, 00:11)

чтоб во время счетного периода выводилось последнее посчитанное число импульсов, а не 1, 2, 3, .. и т.д.
буферизуй индикацию регистрами-защелками (ИР24 или им подобными)по окончанию счета, и не надо микроконтроллера будет
shadow86
Dec 23 2011, 13:31
Попробывал соеденить один из выходов-катодов с еще одной ножкой-входом, чтоб считать изменения уровня на этой ножке и от него отталкиваясь, получить 46с задержки, но что-то опять не получается ((
. . .
PORTA.3 = 0;
DDRA.3 = 0;
PORTA.4 = 0;
DDRA.4 = 0;
ACSR = 0x80;
#asm("sei");
while(1){
while (PINA.3 == 1) {counterProg++;} // регистрирую изменение уровня на входе РА3 (соединенного с одним из зажигаемых катодов индикатора)
while (PINA.4 == 1){} //считаю импульсы
{imp ++;}
while (PINA.4 == 0){}
if (imp >= 1000) {
imp -= 1000;
}
if (counterProg == 10) { //обнуляю количество импульсов
imp = 0;
counterProg = 0;}
IND_Conv(imp); //вывожу количество имп. за счетный период на индикатор
}
toweroff
Dec 23 2011, 13:52
Да зачем такие извращения?
Один таймер в счетном режиме, на него заводим то, что нужно считать
Второй отсчитывает время. Прошло 46 сек - читаем состояние вервого счетного таймера и обнуляем его
shadow86
Dec 23 2011, 14:05
вот вам легко говорить... у меня 0-й работает на динамическую индикацию. когда пытаюсь запустить 1-й, то фигня какая-то получается.. либо индикация отказывает, либо счет останавливается.. не могу победить пока что использование 2 счетчиков-таймеров одновременно (((
toweroff
Dec 23 2011, 14:22
Цитата(shadow86 @ Dec 23 2011, 18:05)

вот вам легко говорить... у меня 0-й работает на динамическую индикацию. когда пытаюсь запустить 1-й, то фигня какая-то получается.. либо индикация отказывает, либо счет останавливается.. не могу победить пока что использование 2 счетчиков-таймеров одновременно (((
А вот тут нужно смотреть, что там наваяно
Как приоритеты расставлены, как что...
А зачем использовать два таймера для временных интервалов? Тот, который динамическую индикацию осуществляет, вполне посчитает и 46сек...
shadow86
Dec 23 2011, 14:37
а как это должно выглядеть? у меня вынесена отдельная функция на динамику:
void IND_Update(void)
{
static unsigned char count = 0;
PORT_K &= ~((1<<KAT1)|(1<<KAT2)|(1<<KAT3));
PORT_IND = data[count];
{
if (count == 0) {
PORT_K |= (0<<KAT1);
PORT_K |= (1<<KAT2);
PORT_K |= (1<<KAT3);
}
if (count == 1){
PORT_K |= (0<<KAT2);
PORT_K |= (1<<KAT1);
PORT_K |= (1<<KAT3);
}
if (count == 2) {
PORT_K |= (0<<KAT3);
PORT_K |= (1<<KAT1);
PORT_K |= (1<<KAT2);
}
count++;
if (count == 3) {count = 0;}
}
}
допустим, я могу повышать еще некоторую переменную на ряду с count, а как потом мне ее значение вынести в тело основной программы?
toweroff
Dec 23 2011, 15:14
да покажите уже полностью, что там наваяли
shadow86
Dec 24 2011, 08:40
Нажмите для просмотра прикрепленного файлаВот моя программа
Она считает импульсы на РА3 и выводит их количество на 3-х знаковый 7-ми сегментный индикатор.
shadow86
Dec 27 2011, 09:28
Вот попробывал добавить функцию на счет некоторой переменной.. ПОМОГИТЕ ПОЖАЛУЙСТА!!! У меня уже фантазия иссякла
#include <tiny26.h>
unsigned char number[] =
{
0x3f, //0
0x06, //1
0x5b, //2
0x4f, //3
0x66, //4
0x6d, //5
0x7d, //6
0x07, //7
0x7f, //8
0x6f //9
};
#define PORT_IND PORTB
#define DDR_IND DDRB
#define PORT_K PORTA
#define DDR_K DDRA
#define KAT1 0
#define KAT2 1
#define KAT3 2
volatile unsigned char data[3];
static unsigned int time;
void IND_Init(void)
{
//порт, к которому подкл. сегменты
PORT_IND = 0xff;
DDR_IND = 0xff;
//порт, к которому подкл. катод
PORT_K &= ~((1<<KAT1)|(1<<KAT2)|(1<<KAT3));
DDR_K |= ((1<<KAT1)|(1<<KAT2)|(1<<KAT3));
data[0] = 0;
data[1] = 0;
data[2] = 0;
}
void IND_Conv(unsigned int value)
{
unsigned char tmp0, tmp1, tmp2;
tmp0=tmp1=0;
while (value >= 100)
{ value -= 100;
tmp0++;
}
while (value >= 10)
{ value -= 10;
tmp1++;
}
tmp2 = value;
data[0]=number[tmp0]; //вывод сотен
data[1]=number[tmp1]; //вывод десятков
data[2]=number[tmp2]; //вывод единиц
}
void IND_Update(void)
{
static unsigned char count = 0;
PORT_K &= ~((1<<KAT1)|(1<<KAT2)|(1<<KAT3));
PORT_IND = data[count];
{
if (count == 0) {
PORT_K |= (0<<KAT1);
PORT_K |= (1<<KAT2);
PORT_K |= (1<<KAT3);
}
if (count == 1){
PORT_K |= (0<<KAT2);
PORT_K |= (1<<KAT1);
PORT_K |= (1<<KAT3);
}
if (count == 2) {
PORT_K |= (0<<KAT3);
PORT_K |= (1<<KAT1);
PORT_K |= (1<<KAT2);
}
count++;
if (count == 3) {count = 0;}
}
}
int Wait (void)
{
time++;
return time;
}
unsigned int imp = 0;
void main( void )
{
IND_Init();
//инициализация таймера Т0
//частота прерываний 50Гц при частоте кварца 4МГц
TIMSK = (1<<TOIE0);
TCCR0 = (1<<CS02)|(0<<CS01)|(1<<CS00);
TCNT0 = 0xb2;
PORTA.3 = 1;
DDRA.3 = 0;
TCCR1A = (1<<CS13)|(0<<CS12)|(0<<CS11)|(1<<CS10);
TCNT1 = 0x00;
#asm("sei");
while(1){
while (PINA.3 == 1){}
{imp ++;}
while (PINA.3 == 0){}
if (imp >= 1000) {
imp -= 1000;
}
IND_Conv(imp);
if (Wait()>=10){
time=0;
imp=0;}
}
}
//прерывания таймера Т0 - вывод на индикатор
interrupt [TIM0_OVF] void Timer0Ovf(void)
{
TCNT0 = 0xb2;
IND_Update();
Wait();
}
Поскольку у Вас таймер "тикает" с частотой 50 Гц (верю Вам на слово), то за 49 сек таймер "натикает" 50 * 49 = 2450 раз. Поэтому:
Код
unsigned int t= 0;
//прерывания таймера Т0 - вывод на индикатор
interrupt [TIM0_OVF] void Timer0Ovf(void)
{
TCNT0 = 0xb2;
if(++t >= 2450)
{
t=0;
IND_Conv(imp);
imp= 0;
}
IND_Update();
}
Возникает проблема с неатомарностью изменения переменной imp в функции main. Там, где эта переменная изменяется в main - необходимо обрамить командами запрета и разрешения прерывания.
PS. Другое решение: не трогать переменную imp в обработчике прерывания от таймера, а по истечению 49 сек взвести некий флаг, а уж в main этот флаг анализировать, и, по нему вызывать IND_Conv и сбрасывать imp :
Код
unsigned int t= 0;
volatile char flag= 0;
в main
........
if(flag)
{
flag=0;
IND_Conv(imp);
imp= 0;
}
........
//прерывания таймера Т0 - вывод на индикатор
interrupt [TIM0_OVF] void Timer0Ovf(void)
{
TCNT0 = 0xb2;
if(++t >= 2450) { t=0; flag= 1; }
IND_Update();
}
shadow86
Jan 4 2012, 20:05
Всех с новым годом!!!
Спасибо огромное, Палыч!
muravei
Jan 12 2012, 12:38
С МК, конечно, пральнее

, но можно было не париться, сделать: жд. мульт. -интегр. фильтр- измеритель
shadow86
Feb 2 2012, 11:59
Снова здравствуйте, уважаемые программисты! У меня такой вопрос образовался: если я не хочу применять кварц для тактирования МК, а хочу, чтоб он от внутреннего генератора на 1МГц работал, мне в программе что-либо указывать нужно, или он по умолчанию от него запустится?
Цитата(shadow86 @ Feb 2 2012, 15:59)

если я не хочу применять кварц для тактирования МК, а хочу, чтоб он от внутреннего генератора на 1МГц работал, мне в программе что-либо указывать нужно
Вам нужно правильным образом прошить фьюзы при програмировании вашей прошивки
shadow86
Feb 5 2012, 16:40
спасибо! буду теперь с этим разбираться..
shadow86
Mar 19 2012, 00:48
Уважаемые форумчане, помогите разобраться с очередным бзиком моего Гейгера. Преобразователь на питание МК из 2.4В в 5В работает идеально: напряжение 5.02В, пульсации не вижу на осциллографе даже при максимальном усилении. На вход МК (РВ4) подаю сформированные подготовленные импульсы с ждущего мультивибратора на к155аг1 (пробовал разные длительности: от 0.1с до 0.1мс), а после заданного промежутка времени и счета на индикатор выводятся какие-то космические значения (как я заметил, кратные 10)!!! которых в принципе быть не может - вместо 11-17 -- 510-820. Как понимать что он считает и как это исправить??? на питании МК стоит 10мк+0.1мк потом дроссель на 10мкГн потом 0.1мк; после преобразователя - 0.1мк+220мк+1500мк. я так понимаю, что по входу идет наводка. как бы ее зашунтировать?
Ну так найдите ошибку.... Уменьшите свои 46 секунд до удобного в отладке значения (можно текущее число импульсов сразу выводить на индикацию а не ждать какое-то время) и сымитируйте 1 импульс на счетный вход. Ищите ошибку в программе до тех пор пока поведение не будет адекватным.... Очевидно либо импульс с дребезгом либо программа на один импульс увеличивает счетчик множество раз. А может само число счетчика неправильно формируется для вывода на индикатор (на что косвенно намекает кратность 10)
shadow86
Mar 19 2012, 05:15
Спасибо за совет, Олег! Попробую так.
shadow86
Mar 19 2012, 08:51
Спасибо большое за внимание! разобрался! это не наводка была по входу.. а кривые руки.. при изготовлении платы индикатора отзеркалил 1 и 3 разряд, вот у меня 3-х значные числа и лезли ))).
shadow86
Mar 25 2012, 17:54
А подскажите, пожалуйста, как должен выглядеть текст программы, если я хочу сделать короткий звуковой сигнал с одной из ножек МК, который будет звучать при появлении счетного импульса на входной ножке? Интересует момент формирования звука.
ILYAUL
Mar 25 2012, 19:20
Цитата(shadow86 @ Mar 25 2012, 21:54)

А подскажите, пожалуйста, как должен выглядеть текст программы, если я хочу сделать короткий звуковой сигнал с одной из ножек МК, который будет звучать при появлении счетного импульса на входной ножке? Интересует момент формирования звука.
Вам нужно два счётчика . Счетчик- длительности звучания и счётчик -частота звучания. Второе выбирается из DS на пищалку. Длительность на слух.
shadow86
Mar 26 2012, 10:09
спасибо за ответ! Бум стараться )
Для просмотра полной версии этой страницы, пожалуйста,
пройдите по ссылке.