Реклама на сайте English version  DatasheetsDatasheets

KAZUS.RU - Электронный портал. Принципиальные схемы, Datasheets, Форум по электронике

Новости электроники Новости Литература, электронные книги Литература Документация, даташиты Документация Поиск даташитов (datasheets)Поиск PDF
  От производителей
Новости поставщиков
В мире электроники

  Сборник статей
Электронные книги
FAQ по электронике

  Datasheets
Поиск SMD
Он-лайн справочник

Принципиальные схемы Схемы Каталоги программ, сайтов Каталоги Общение, форум Общение Ваш аккаунтАккаунт
  Каталог схем
Избранные схемы
FAQ по электронике
  Программы
Каталог сайтов
Производители электроники
  Форумы по электронике
Помощь проекту

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

 
Опции темы
Непрочитано 10.08.2011, 10:30  
tarasov128
Частый гость
 
Регистрация: 01.11.2007
Сообщений: 27
Сказал спасибо: 0
Сказали Спасибо 4 раз(а) в 4 сообщении(ях)
tarasov128 на пути к лучшему
По умолчанию Странный глюк с sprinf, помогите разобраться

Здравствуйте! Собрал разрядное устройство для аккомуляторов, как напряжение упадет ниже 0.9в разряд отключаеться. На экран циклически выводиться информация о напряжении и отданной емкости на разряд. Каждые 3 секунды меняеться информация на LCD. При каждой смене ощущение что переменные u1,u2,u3,u4,c1,c2,c3,c4 обнуляються. Причем происходит во время команды
"sprintf(str1,"v1=%-.2f v2=%-.2f\nv3=%-.2f v4=%-.2f",u1,u2,u3,u4);"
"sprintf(str1,"c1=%-.2f c2=%-.2f\nc3=%-.2f c4=%-.2f",c1/1000,c2/1000,c3/1000,c4/1000);"
Что я делаю не так? Код программы прилагаю ниже:
/*******************************/
/* Подключим библиотеку контроллера */
# include "mega8.h"
# include "delay.h"
# include "stdio.h"

/* Объявим порт подключения LCD */
#asm
.equ __lcd_port=0x12
#endasm





/*Библиотека LCD*/
# include "lcd.h"



char str1[16];
float u1;
float u2;
float u3;
float u4;
float c1;
float c2;
float c3;
float c4;
float set;
float resist;

int f1;
int f2;
int f3;
int f4;
int count;

bit cap;


void test()//Тест
{
DDRB=0xFF;//Порт В на выход
PORTB=0x00;//Выключить все реле
sprintf(str1," auto test...");
lcd_init(16);
lcd_puts(str1);
PORTB=0x00;
delay_ms(500);
PORTB=0x00;
PORTB.0=1;
delay_ms(500);
PORTB=0x00;
PORTB.1=1;
delay_ms(500);
PORTB=0x00;
PORTB.2=1;
delay_ms(500);
PORTB=0x00;
PORTB.3=1;
delay_ms(500);
PORTB.0=1;
PORTB.1=1;
PORTB.2=1;
PORTB.3=1;
delay_ms(500);
PORTB=0x00;
sprintf(str1," starting ");
lcd_init(16);
lcd_puts(str1);
delay_ms(500);
}

/*Вывод напряжения на на LCD*/
void dispu(void)
{
lcd_clear();
sprintf(str1,"v1=%-.2f v2=%-.2f\nv3=%-.2f v4=%-.2f",u1,u2,u3,u4);
lcd_puts(str1);
}


/*Вывод емкость на на LCD*/
void dispc(void)
{
lcd_clear();
sprintf(str1,"c1=%-.2f c2=%-.2f\nc3=%-.2f c4=%-.2f",c1/1000,c2/1000,c3/1000,c4/1000);
lcd_puts(str1);
}

//Настройка таймера//
void tm_init()
{
ASSR|=0x08; // Тактировать T2 от асинхронного генератора таймера, установка бита AS2 в регистре assr
TCCR2|=0x05;//делим на 128 такт кварца
TIMSK|=0x40;//Включаем прерываение по переполнению таймера 2
}

/* ADC */
/* Инициализация */
void ADC_init()
{
ADMUX=0xE0;
ADCSRA=0x8D;
}
/* Преобразование */
float ADC_result(unsigned char adc_input)
{
ADC_init();
ADMUX=adc_input|(ADMUX & 0xFF);
delay_ms(10);
/*Старт преобразования */
ADCSRA|=0x40;
while((ADCSRA & 0x10)==0);
ADCSRA|=0x10;
return ADCH*0.01;
}

//Установка битов порта В
void port()
{
if (u1›set) {if (f1==0){PORTB.3=1;}}
if (u1‹set) {f1=1; PORTB.3=0;};
if (u1‹0.1) {f1=0; c1=0; PORTB.3=0;};

if (u2›set) {if (f2==0){PORTB.2=1;}}
if (u2‹set) {f2=1; PORTB.2=0;};
if (u2‹0.1) {f2=0; c2=0; PORTB.2=0;};

if (u3›set) {if (f3==0){PORTB.1=1;}}
if (u3‹set) {f3=1; PORTB.1=0;};
if (u3‹0.1) {f3=0; c3=0; PORTB.1=0;};

if (u4›set) {if (f4==0){PORTB.0=1;}}
if (u4‹set) {f4=1; PORTB.0=0;};
if (u4‹0.1) {f4=0; c4=0; PORTB.0=0;};
}

interrupt [TIM2_OVF] void timer2_ovf_isr(void)//Прерывание по таймеру 2
{
#asm("cli")
u1=ADC_result(0x00);//Измерение напряжения
u2=ADC_result(0x01);
u3=ADC_result(0x02);
u4=ADC_result(0x03);
//Расчет емкости
c1=c1+(u1/resist)*0.2777777;//ma*час
c2=c2+(u1/resist)*0.2777777;
c3=c3+(u1/resist)*0.2777777;
c4=c4+(u1/resist)*0.2777777;

count++;
if (count›3) {
if (cap==0) {dispu();};//Показ напряжения
if (cap==1) {dispc();}; //Показ емкости
cap=cap^1;//инверсия бита показа
count=0;
}

PORTC.4=PORTC.4^1;//Мигаем диодом

port();//Переключаем реле
#asm("sei")//иначе не работает задержка
}
/*Основная программа */
void main(void)
{


test();//Тест реле 3 секунды

DDRC|=0x10;//Установить порт РС4 на Выход мигалка
PORTC.4=0;;//Установить на порту РС4 1


tm_init();//Запуск таймера и прерываний
set=0.9;//Напряжение окончания разряда
f1=0;f2=0;f3=0;f4=0;//Сброс флагов состояния каналов

resist=1;//сопротивление в цепи разряда
count=3;//через сколько секунд будет смена показа на LCD
#asm("sei")//для дальнейшей работы по таймеру

while(1)
{
}

}
Реклама:
tarasov128 вне форума  
Сказали "Спасибо" tarasov128
warel (28.06.2019)
Непрочитано 10.08.2011, 11:36  
SasaVitebsk
Гражданин KAZUS.RU
 
Регистрация: 04.08.2006
Сообщений: 911
Сказал спасибо: 28
Сказали Спасибо 180 раз(а) в 139 сообщении(ях)
SasaVitebsk на пути к лучшему
По умолчанию Re: Странный глюк с sprinf, помогите разобраться

Честно говоря, немного поднадоело повторять прописные истины ... Вы их похоже всё равно не читаете...
1. Прерывание на то и прерывание, чтобы быть максимально коротким.
2. Всякие sprintf - это самые тяжеловесные библиотеки. Которые занимают максимум времени и кучу стэка. Надо применять их крайне осторожно.
3. Сам вывод в LCD - крайне медленная операция в связи с тем, что приходится формировать временную диаграму работы с дисплеем.
4. НИКОГДА не всовывайте операторы не понимая причины неработоспособности. Вы просто маскируете ошибку но не устраняете её. При неработоспособности нужно разобраться и найти ошибку, а не тыкать куда попало пальцем.
===
Теперь касаемо вашего проекта... В конце прерывания у вас стоит "#asm("sei")//иначе не работает задержка". Это бессмысленный оператор, так как по выходу из прерывания процессор сам, аппаратно, разрешит прерывания. Таким образом, если бы у вас всё было правильно, то данная строчка не дала бы не малейшего результата. Отсюда следует, что скорее всего, ваше прерывание не успевает выполнится за время ему отведённое. Оно и понятно, вы в него впёрли неизвестно что... Соответственно, когда вы ставите разрешение прерывания вы скорее всего разрешаете повторный вход в прерывание. У вас скорее всего плывёт стек и происходит крах программы с последующим перезапуском. Поведение такой программы предсказать невозможно. Оно будет меняться при любом изменении текста программы. От компиляции к компиляции.
===
Вам необходимо выкинуть ненужное... вынести из прерывания вывод в голову либо в разы увеличить время между прерываниями.
SasaVitebsk вне форума  
Сказали "Спасибо" SasaVitebsk
warel (28.06.2019)
Непрочитано 10.08.2011, 11:58  
tarasov128
Частый гость
 
Регистрация: 01.11.2007
Сообщений: 27
Сказал спасибо: 0
Сказали Спасибо 4 раз(а) в 4 сообщении(ях)
tarasov128 на пути к лучшему
По умолчанию Re: Странный глюк с sprinf, помогите разобраться

1. Контроллер успевает выполнить код внутри прерывания, прерывания раз в секунду происходят.
2. Sprintf работает, если просто выводить текст на экран и использовать форматирование и переменные.
3.Прерывания разрешаю, потому-что сам запрещал их, и не знал что потом автоматически они будут разрешены. Вреда от строчки не вижу.
4. Памяти конкретно на эту программу у 8й меги хватает, и краха стека не происходит, если бы процессор повис или ушел в reset я бы увидел это на устройстве.
Расскажите почему так странно переменные меняються(надеюсь дело вних)? Или расскажите пример вывода без sprintf, я мало работал с CodeVision и вообще с контроллерами, это всего мой второй проект, не ругайте сильно)
Я понимаю, что если помучаюсь, могу уйти от sprintf, но почему оно как уже написано не работает?
tarasov128 вне форума  
Сказали "Спасибо" tarasov128
warel (28.06.2019)
Непрочитано 10.08.2011, 12:24  
heady69
Прописка
 
Регистрация: 25.09.2009
Адрес: Ivanovo
Сообщений: 156
Сказал спасибо: 3
Сказали Спасибо 67 раз(а) в 60 сообщении(ях)
heady69 на пути к лучшему
По умолчанию Re: Странный глюк с sprinf, помогите разобраться

Обявите перем. как volatile может оптимизатор чего косячит. И на счет времени входа в прер. проверте еще раз. На всякий...
heady69 вне форума  
Сказали "Спасибо" heady69
warel (28.06.2019)
Непрочитано 10.08.2011, 12:46  
tarasov128
Частый гость
 
Регистрация: 01.11.2007
Сообщений: 27
Сказал спасибо: 0
Сказали Спасибо 4 раз(а) в 4 сообщении(ях)
tarasov128 на пути к лучшему
По умолчанию Re: Странный глюк с sprinf, помогите разобраться

Извините, разобрался, кривизна рук виновата. Исправил char str1[16]; на char str1[32]; с все заработало...)))
tarasov128 вне форума  
Сказали "Спасибо" tarasov128
warel (28.06.2019)
 

Закладки
Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Дозиметр (индикатор радиации и т.д.). Помогите разобраться со схемой Timoh Измерительное оборудование 4 03.04.2012 18:00
Помогите разобраться с PIC18F4550 и USB john2103 Микроконтроллеры, АЦП, память и т.д 26 02.08.2011 11:52
Помогите разобраться с микроконтроллером igor140329 Микроконтроллеры, АЦП, память и т.д 7 07.03.2011 03:27
Помогите разобраться ,АЦП Тину 13, что то не так... Botan Микроконтроллеры, АЦП, память и т.д 2 14.09.2010 18:31
Помогите разобраться с импульсными стабилизаторами Vas2 Источники питания и свет 8 07.12.2007 17:27


Часовой пояс GMT +4, время: 20:53.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot