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

AVR динамическая индикация .Вывод вещественного числа(результата) на

Спойлер

void ledprint(unsigned int number)
{
    R1 = number%10;
    R2 = number%100/10;
    R3 = number%1000/100;
    R4 = number/1000;
}

void segchar (unsigned char seg)
{

    switch(seg)

    {
        case 0: SPDR = 0b11000000; break;

        case 1: SPDR = 0b11111001; break;

        case 2: SPDR = 0b10100100; break;

        case 3: SPDR = 0b10110000; break;

        case 4: SPDR = 0b10011001; break;

        case 5: SPDR = 0b10010010; break;

        case 6: SPDR = 0b10000010; break;

        case 7: SPDR = 0b11111000; break;

        case 8: SPDR = 0b10000000; break;

        case 9: SPDR = 0b10010000; break;


        case 10: SPDR = 0b10111111; break; // знак —

        case 11: SPDR = 0b11111111; break; // пустое место

        case 12: SPDR = 0b11000110; break; // буква С для показаний температуры
        case 13: SPDR = 0b01111111; break; // буква С для показаний температуры

    }

}


void PORTS_init(void)
{
    
    
}
ISR (TIMER1_COMPA_vect)
{
    if(n_count==0)
    {
        PORTB &= ~(1<<PORTB4); //низкий уровень
        
        segchar(R1);
        while(!(SPSR & (1<<SPIF)));//подождем пока данные передадутся
        
        SPDR = 0b00001110;
        while(!(SPSR & (1<<SPIF)));//подождем пока данные передадутся
        //сгенерируем отрицательный фронт для записи в STORAGE REGISTER
        PORTB |= (1<<PORTB4); //высокий уровень
        //PORTB &= ~(1<<PORTB4); //низкий уровень
        
    }
    if(n_count==1)
    {
        PORTB &= ~(1<<PORTB4); //низкий уровень
        
        segchar(R2);
        while(!(SPSR & (1<<SPIF)));//подождем пока данные передадутся
        
        SPDR = 0b00001101;
        while(!(SPSR & (1<<SPIF)));//подождем пока данные передадутся
        //сгенерируем отрицательный фронт для записи в STORAGE REGISTER
        PORTB |= (1<<PORTB4); //высокий уровень
        //PORTB &= ~(1<<PORTB4); //низкий уровень
        
    }
    if(n_count==2)
    {
        PORTB &= ~(1<<PORTB4); //низкий уровень
        
        segchar(R3);
        while(!(SPSR & (1<<SPIF)));//подождем пока данные передадутся
        
        SPDR = 0b00001011;
        while(!(SPSR & (1<<SPIF)));//подождем пока данные передадутся
        //сгенерируем отрицательный фронт дл¤ записи в STORAGE REGISTER
        PORTB |= (1<<PORTB4); //высокий уровень
        //PORTB &= ~(1<<PORTB4); //низкий уровень
        
    }
    if(n_count==3)
    {
        PORTB &= ~(1<<PORTB4); //низкий уровень
        
        segchar(R4);
        while(!(SPSR & (1<<SPIF)));//подождем пока данные передадутся
        
        SPDR = 0b00000111;
        while(!(SPSR & (1<<SPIF)));//подождем пока данные передадутся
        //сгенерируем отрицательный фронт дл¤ записи в STORAGE REGISTER
        PORTB |= (1<<PORTB4); //высокий уровень
        //PORTB &= ~(1<<PORTB4); //низкий уровень
        
    }
    
    n_count++;
    if (n_count>3) n_count=0;
}
//--------------------------------------------

void timers_init(void)
{
    TCCR1B |= (1<<WGM12); // устанавливаем режим СТС (сброс по совпадению)
    TIMSK |= (1<<OCIE1A);    //устанавливаем бит разрешения прерывания 1ого счетчика по совпадению с OCR1A(H и L)
    OCR1AH = 0b00001111; //записываем в регистр число для сравнения
    OCR1AL = 0b01000010;
    TCCR1B |= (1<<CS11);//установим делитель.
}
void SPI_init(void)
{
   DDRB |= ((1<<PORTB4)|(1<<PORTB5)|(1<<PORTB7)); //ножки SPI на выход

    PORTB &= ~((1<<PORTB4)|(1<<PORTB5)|(1<<PORTB7)); //низкий уровень

   SPCR = ((1<<SPE)|(1<<MSTR));//включим шину, объявим ведущим    
    
}

Есть у меня дисплей LED 7 сигментный.Как мне вывести вещественное число ?Помогите советом.

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

Поделиться сообщением


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

Перед этим нужно printf-у рассказать о том что существуют 7-сегментные индикаторы и научить на них выводить.

А так же, делением на степени десятки не получается? Простой вариант - функция ftoa. Может быть есть готовая в вашей среде, но и в интернете есть исходники.

Если данные идут с простого цифрового термометра и никакой математики нет, то проще работать с фиксированной запятой.

Поделиться сообщением


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

В 09.07.2023 в 23:54, vov4ick сказал:

Перед этим нужно printf-у рассказать о том что существуют 7-сегментные индикаторы и научить на них выводить.

Я предполагаю, что автор умеет выводить на свои индикаторы :) Вопрос был с акцентом на вещественность.

Поделиться сообщением


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

В 10.07.2023 в 18:38, v05 сказал:

Ага. Вопрос был просто с акцентом. Ужос!( И эти люди пишут на электрониксе...!

Акцент есть и будет.Акцент на вывод вещественное число на 7-сегментный индикатор так и не нашёл примеров с динамической индикацией?

Поделиться сообщением


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

27 minutes ago, dimir said:

вывод вещественное число на 7-сегментный индикатор так и не нашёл примеров с динамической индикацией?

Обычно делают в 2 фазы - формирование строки из вашего числа в памяти, и отдельно вывод этой строки на индикатор.

Не стоит пытаться совместить эти фазы

Поделиться сообщением


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

В 10.07.2023 в 20:42, xvr сказал:

Обычно делают в 2 фазы - формирование строки из вашего числа в памяти, и отдельно вывод этой строки на индикатор.

Не стоит пытаться совместить эти фазы

Ну пример не мой.А ваш пример покажите?

Поделиться сообщением


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

3 hours ago, dimir said:

А ваш пример покажите?

А что тут показывать? snprintf + вывод из буфера в индикаторы (приблизительно как у вас, но только не по символам R1/R2/R... а из буфера, по индексу)

Вот переделанный кусок вашего кода:

unsigned char buf[4];
unsigned char n_count =0;

ISR (TIMER1_COMPA_vect)
{
        PORTB &= ~(1<<PORTB4); //низкий уровень
        
        segchar(buf[n_count]);
        while(!(SPSR & (1<<SPIF)));//подождем пока данные передадутся
        
        SPDR = (1 << n_count) ^ 0xF;
        while(!(SPSR & (1<<SPIF)));//подождем пока данные передадутся
        //сгенерируем отрицательный фронт для записи в STORAGE REGISTER
        PORTB |= (1<<PORTB4); //высокий уровень

        ++n_count;
        n_count &= 3;
}

 

Поделиться сообщением


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

А у  меня ещё один вопрос.Можно ли изменить программу что бы зажигалась точка при определённом условии в разрядах?

Поделиться сообщением


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

В 11.07.2023 в 10:20, v05 сказал:

А у меня тоже один вопрос. Что получится если к члену приделать перо? Член корреспондент, не так ли?

Вы правы.Но как  то же выводят число вещественное?

Поделиться сообщением


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

3 hours ago, dimir said:

Можно ли изменить программу что бы зажигалась точка при определённом условии в разрядах?

Можно. Самое простое не декодировать числа (в 7 сегментов) при выводе, а складывать в буфер индикации декодиованное значение. Тогда точка будет зажигаться просто установкой соответствуещего бита в соотвествующем элементе буфера

 

Поделиться сообщением


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

В 11.07.2023 в 12:30, xvr сказал:

Можно. Самое простое не декодировать числа (в 7 сегментов) при выводе, а складывать в буфер индикации декодиованное значение. Тогда точка будет зажигаться просто установкой соответствуещего бита в соотвествующем элементе буфера

 

Пример можете привести?

Поделиться сообщением


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

unsigned char buf[4];
unsigned char n_count =0;

ISR (TIMER1_COMPA_vect)
{
        PORTB &= ~(1<<PORTB4); //низкий уровень
        
        SPDR = buf[n_count];
        while(!(SPSR & (1<<SPIF)));//подождем пока данные передадутся
        
        SPDR = (1 << n_count) ^ 0xF;
        while(!(SPSR & (1<<SPIF)));//подождем пока данные передадутся
        //сгенерируем отрицательный фронт для записи в STORAGE REGISTER
        PORTB |= (1<<PORTB4); //высокий уровень

        ++n_count;
        n_count &= 3;
}

void putc(int position, char symbol)
{
  char encoded;
  switch(symbol)
  {
    case '0': encoded = 0b00111111; break;
    case '1': encoded - ....
  }
  buf[position] = encoded;
}

void add_comma(int position)
{
  buf[position] |= 0x80;
}

предполагаю что точка в старшей позиции (и включается 1)

Ну и в putc лучше сделать массив для перекодировки, а не switch

Поделиться сообщением


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

В 11.07.2023 в 17:44, xvr сказал:
unsigned char buf[4];
unsigned char n_count =0;

ISR (TIMER1_COMPA_vect)
{
        PORTB &= ~(1<<PORTB4); //низкий уровень
        
        SPDR = buf[n_count];
        while(!(SPSR & (1<<SPIF)));//подождем пока данные передадутся
        
        SPDR = (1 << n_count) ^ 0xF;
        while(!(SPSR & (1<<SPIF)));//подождем пока данные передадутся
        //сгенерируем отрицательный фронт для записи в STORAGE REGISTER
        PORTB |= (1<<PORTB4); //высокий уровень

        ++n_count;
        n_count &= 3;
}

void putc(int position, char symbol)
{
  char encoded;
  switch(symbol)
  {
    case '0': encoded = 0b00111111; break;
    case '1': encoded - ....
  }
  buf[position] = encoded;
}

void add_comma(int position)
{
  buf[position] |= 0x80;
}

предполагаю что точка в старшей позиции (и включается 1)

Ну и в putc лучше сделать массив для перекодировки, а не switch

Нужно точку выделить в отдельный разряд но как это сджелать.Эксперименты показывают(в протеусе)что выделение точки возможно.Но как прописать её как разряд.Правда работает не так как  нужно.

Спойлер
ISR (TIMER1_COMPA_vect)
{
	
 //if(N==0) { PORTB|=127; PORTD=8; segment(A1); }
 if(N==1) { PORTB|=127; PORTD=4; segment(A2); }
 if(N==2) { PORTB|=127; PORTD=2; segment(A3); }
	 if (N==0)
	 {
           //PORTB |= 127; // минусовой знак (-)
                 // PORTD=8;
		 
                 //segment(A1);
                 
		 
		if (adc_data[0] < 512) {
                 // PORTD&=~(1<<PD3);
           PORTB |= 128; // минусовой знак (-)
                 segment(A1);
                 
			}
			 else {
                  PORTD=8;
                 
			PORTB &= ~128; // плюсовой знак (+)
		} 
	 }
	 
// if(N==3) { PORTB|=127; PORTD=1; segment(A3); }
 
 N+=1;
 if(N==2){N=0;}
}

 

 

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

Поделиться сообщением


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

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

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

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

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

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

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

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