Посмотрите код на предмет оптимизации. (вывод на семисегментные индикаторы) - C (СИ)

Узнай цену своей работы

Формулировка задачи:

/*
* 7Segment.c
*
* Created: 10.09.2016 14:51:07
* Author : igora
*/
#define F_CPU 8000000
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
//Вектор прерывания по таймеру
ISR( TIMER2_COMP_vect )
{
        //Выводим вольтаж
        PrintLedVolt();
}
//Разряды вольт
volatile int RV1 = 0;
volatile int RV2 = 0;
volatile int RV3 = 0;
volatile int RV4 = 0;
// точка вольт
volatile int Vdot = 0;
 
//Разряды ампер
volatile int RA1 = 0;
volatile int RA2 = 0;
volatile int RA3 = 0;
volatile int RA4 = 0;
// точка ампер
volatile int Adot = 0;
 
//Цифры без точки 16чная система
const unsigned char digits[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
//Время перехода
const int perehod = 3;
//Задаем начальные установки
void preset(){
    TIMSK = (1<<OCIE2);  // timer2: Режим перехода по совпадению включен
    TCCR2 = (1<<WGM21);  // Устанавливаем режим перехода в прерывание по совпадению
    TCCR2|= (1<<CS22) |(1<<CS21)| (1<<CS20); // делитель основной частоты 1/1024
    OCR2  = 128;  //Число при котором уходит в вектор прерывания
    sei();                // выставляем бит общего разрешения прерываний
    //ADCSRA
    ADCSRA |= (1<<ADEN) //Включаем АЦП
    |(1<<ADPS2)|(1<<ADPS1); //Делитель на 64
    //ADMUX
    ADMUX |= (1<<REFS0) | (1<<REFS0); //Опорное напряжение 
    DDRD = 0xFF;
    PORTD = 0x00;
    // ноги для управления катодами семисегментными индикаторами
    DDRC |=(1<<5) | (1<<4) | (1<<3) | (1<<2) | (1<<1);
    DDRB |=(1<<2) | (1<<1) | (1<<0);
}
//Функция расчета напряжения
float ReadADC(){
    ADMUX |= (0<<MUX3)|(0<<MUX2)|(0<<MUX1)|(0<<MUX0); //Строка только для понятия, какая нога зайдействована как АЦП
    _delay_us(10);
    float Vtmp = 0;
    //Вычисляем средне арифметическое для значения ADC (50 проходов)
    for(int i = 0; i<50; i++){
        ADCSRA |= (1<<ADSC); // Начало преобразования
        while(ADCSRA &(1<<ADSC)); // Ждем конец преобразования
        Vtmp += ADC;
    }
    return Vtmp/50;
}
//Функция разбиения дробного числа на разряды для вольт
void PutRazryadVolt( double volt){
    int y = volt;
    double z = volt-y;
 
    if(y>9){
        RV1 = y/10;
        RV2 = y%10;
        int RD = z*100;
        Vdot=2;
        RV3 = RD/10;
        RV4 = RD%10;
    }
    else if(y<10 && y>=1){
        RV1 = y;
        Vdot = 1;
        int RD  = z*1000;
        RV2 = RD/100;
        RD = RD-(100*RV2);
        RV3 = RD/10;
        RV4 = RD%10;
    }
    else{
        RV1 = 0;
        Vdot = 1;
        int RD  = z*1000;
        RV2 = RD/100;
        RD = RD-(100*RV2);
        RV3 = RD/10;
        RV4 = RD%10;
    }
}
//Функция разбиения дробного числа на разряды для ампер
void PutRazryadAmp( double amp){
    int y = amp;
    double z = amp-y;
 
    if(y>9){
        RA1 = y/10;
        RA2 = y%10;
        int RD = z*100;
        Adot=2;
        RA3 = RD/10;
        RA4 = RD%10;
    }
    else if(y<10 && y>1){
        RA1 = y;
        Adot = 1;
        int RD  = z*1000;
        RA2 = RD/100;
        RD = RD-(100*RA2);
        RA3 = RD/10;
        RA4 = RD%10;
    }
    else{
        RA1 = 0;
        Adot = 1;
        int RD  = z*1000;
        RA2 = RD/100;
        RD = RD-(100*RA2);
        RA3 = RD/10;
        RA4 = RD%10;
    }
}
//Display 1
//PORTC От 2 ноги до 5
//Display 2
//PORTC 1 нога PORTB 0-2 нога
//Функция вывода дробного числа на семисегментный индикатор для вольт
void PrintLedVolt(){
    
    if (Vdot == 2){
        PORTD=0x00;
        //display 1
        PORTC =(1<<2);
        PORTD = digits[RV1];
        _delay_ms(perehod);
        PORTC = (1<<3);
        PORTD = digits[RV2];
        PORTD |= (1<<7); //Добавляем точку к разряду
        _delay_ms(perehod);
        PORTC = (1<<4);
        PORTD = digits[RV3];
        _delay_ms(perehod);
        PORTC = (1<<5);
        PORTD = digits[RV4];
        _delay_ms(1);// Задержка меньше основной, для того, чтобы выровнять яркость разрядов
    }
    else{
        //display 1
        PORTD=0x00;
        PORTC =(1<<2);
        PORTD = digits[RV1];
        PORTD |= (1<<7); //Добавляем точку к разряду
        _delay_ms(perehod);
        PORTC = (1<<3);
        PORTD = digits[RV2];
        _delay_ms(perehod);
        PORTC = (1<<4);
        PORTD = digits[RV3];
        _delay_ms(perehod);
        PORTC = (1<<5);
        PORTD = digits[RV4];
        _delay_ms(1);// Задержка меньше основной, для того, чтобы выровнять яркость разрядов
    }
}
//Функция вывода дробного числа на семисегментный индикатор для ампер
void PrintLedAmp(){
    if (Adot == 2){
        //display 2
        PORTC =(1<<1);
        PORTD = digits[RA1];
        _delay_ms(perehod);
        PORTC &=~0xFF;
        PORTB = (1<<0);
        PORTD = digits[RA2];
        PORTD |= (1<<7); //Добавляем точку к разряду
        _delay_ms(perehod);
        PORTB = (1<<1);
        PORTD = digits[RA3];
        _delay_ms(perehod);
        PORTB = (1<<2);
        PORTD = digits[RA4];
        _delay_ms(perehod);
        PORTB &=~0xFF;
    }
    else{
        //display 2
        PORTC =(1<<1);
        PORTD = digits[RA1];
        PORTD |= (1<<7); //Добавляем точку к разряду
        _delay_ms(perehod);
        PORTC &=~0xFF;
        PORTB = (1<<0);
        PORTD = digits[RA2];
        _delay_ms(perehod);
        PORTB = (1<<1);
        PORTD = digits[RA3];
        _delay_ms(perehod);
        PORTB = (1<<2);
        PORTD = digits[RA4];
        _delay_ms(perehod);
        PORTB &=~0xFF;
    }
}
 
int main(void)
{
    preset(); // Запускаем функцию, задающую начальные параметры
    while (1)
    {
        //2.56/1023 чтобы узнать цену деления, умножаем на ReadADC (количество делений), и умножаем на коэффицент делителя
        //53.76/2.56, чтобы узнать вольтаж
        PutRazryadVolt(2.49/1024*ReadADC()*(52.29/2.49));
    }
}

Решение задачи: «Посмотрите код на предмет оптимизации. (вывод на семисегментные индикаторы)»

textual
Листинг программы
ADMUX |= (0<<MUX3)|(0<<MUX2)|(0<<MUX1)|(0<<MUX0); //Строка только для понятия, какая нога зайдействована как АЦП

Объяснение кода листинга программы

  1. Переменная ADMUX - это регистр, который используется для выбора источника аналогового сигнала для АЦП.
  2. 0<<MUX3 - это способ выбора определенной ноги для АЦП. В данном случае, это означает, что мы выбираем ногу с номером 0 для использования в качестве аналогового входа.
  3. 0<<MUX2 - это еще один способ выбора ноги для АЦП. В данном случае, это означает, что мы выбираем ногу с номером 0 для использования в качестве аналогового входа.
  4. 0<<MUX1 - это еще один способ выбора ноги для АЦП. В данном случае, это означает, что мы выбираем ногу с номером 0 для использования в качестве аналогового входа.
  5. 0<<MUX0 - это последний способ выбора ноги для АЦП. В данном случае, это означает, что мы выбираем ногу с номером 0 для использования в качестве аналогового входа.
  6. Весь код вместе устанавливает ADMUX так, чтобы он использовал ногу с номером 0 в качестве аналогового входа для АЦП.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

11   голосов , оценка 4 из 5
Похожие ответы