Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Курчас 9 вариант.docx
Скачиваний:
1
Добавлен:
01.05.2025
Размер:
2 Мб
Скачать
☆
      1. Работа с портами ввода-вывода.

Порт ввода-вывода – логическое объединение сигнальных линий, через которые принимаются и передаются данные.

Микроконтроллер ATmega8535 имеет 4 порта ввода-вывода: PORTA, PORTAB, PORTAC, PORTAD, каждый из которых состоит из 8 линий. Каждая линия обозначается как Pnx, где n – обозначение порта (A, B, C, D); x – номер бита (линии) в порте (0 … 7).

Каждый порт ввода-вывода обслуживают 3 служебных регистра:

  • PORTN – регистр, содержащий данные (уровни сигналов) на всех линиях порта, используется для записи сигналов в порт (рис.10а);

  • DDRn – регистр направления линии порта: каждая линия порта может быть сконфигурирована как вход (если соответствующий бит регистра DDRn равен «0») или как выход (если соответствующий бит регистра DDRn равне «1»)(рис.10б);

  • PINn – регистр, содержащий состояние входов порта, доступен только для чтения, используется при чтении данных из порта (рис.10в);

Рис.10. Регистры обслуживания портов ввода-вывода микроконтроллера

Если какая-то линия порта ввода-вывода в схеме не используется, она должна быть определена как вход (соответствующий бит регистра ddRn должен быть равен нулю).

Рис.11 Подключение подтягивающих резисторов

Большинство линий ввода-вывода могут быть сконфигурированы для выполнения альтернативных функций, обозначенных на цоколевке процессора.

Для всех линий портов ввода-вывода доступна программная конфигурация входных подтягивающих резисторов (рис.11).

Подтягивающие резисторы осуществляют доопределение потенциалов «брошенных» входов напряжением высокого уровня (логической «1»).

Отключение подтягивающих резисторов осуществляется установкой в «1» бита PUD регистра SFIOR (рис.12).

  1. Программирование в среде CodeVision avr.

    1. Решение системы по разностной схеме.

Программа, соответствующая системе разностных уравнений, на языке С++ представлена ниже.

#include <mega8535.h>

#include <math.h>

#define ADC_VREF_TYPE 0x60

//unsigned int ss, dat, YY, Y2;

unsigned char adc_data,I1,I2,I3;

float Y1,

EE_n, EE_n_1, EE_n_2,

X1_n, X1_n_1, X1_n_2,

X2_n, X2_n_1, X2_n_2,

X3_n, X3_n_1, X3_n_2,

X11_n, X11_n_1, X11_n_2,

X22_n, X22_n_1, X22_n_2,

X33_n, X33_n_1, X33_n_2,

R1=1.2, R2=10.5, R3=0.5, Rn=1.9,

C1=0.1, C2=0.01, L3=0.6,

cnt=0, dt=0.0252;

unsigned char adc_input=0;

// задание временных интервалов таймер T0

interrupt [TIM0_OVF] void timer0_ovf_isr(void)

{ TCNT0=0x3A; // начальная инициализация таймера

PORTA.7=!PORTA.7;

ADMUX=adc_input|ADC_VREF_TYPE;

ADCSRA|=0x40; // запуск АЦП

}

interrupt [ADC_INT] void adc_isr(void)

{

adc_data=ADCH; // получение данных напряжения от АЦП

Y1=ADCH;

Y1=Y1*5./255-0.5*0;

// задание начальных условий

// начальные условия в момент времени 0

if(Y1>0.5) {

if (cnt==0){

EE_n_2=Y1;

X1_n_2=Y1/(R1+R2);

X2_n_2=Y1/(R1+R2);

X3_n_2=0;

X11_n_2=(R2*Y1)/(L3+(R1+R2));

X33_n_2=(R2*Y1)/(L3+(R1+R2));

X22_n_2=0;

X1_n_1=0;

X2_n_1=0;

X3_n_1=0;

X1_n=0;

X2_n=0;

X3_n=0;

X11_n_1=0;

X22_n_1=0;

X33_n_1=0;

X11_n=0;

X22_n=0;

X33_n=0;

// начальные условия в момент времени 1

PORTA.1=1;}

if (cnt==1){

EE_n_1=Y1;

X1_n_1=X1_n_2+X11_n_2*dt;

X2_n_1=X2_n_2+X22_n_2*dt;

X3_n_1=X3_n_2+X33_n_2*dt;

X33_n_1=X33_n_2+((R2*X22_n_2)/L3+X2_n_2/(C2*L3)-((R3*X33_n_2)/L3)-(Rn*X33_n_2)/L3)*dt;

X11_n_1=(1/(1+R2/R1))*((1/R1)*((Y1-Y1)/dt)-(1/(R1*C1))*X1_n_1+R2/R1*X33_n_1-(1*X2_n_1)/(R1*C2));

X22_n_1=X11_n_1-X33_n_1;

/*

X1_n=0;

X2_n=0;

X3_n=0;

X11_n=0;

X22_n=0;

X33_n=0; */

PORTA.1=0;}

// решение диф. Уравнения методом Эйлера

if (cnt>1){

EE_n=Y1;

X1_n=X1_n_1+X11_n_1*dt;

X2_n=X2_n_1+X22_n_1*dt;

X3_n=X3_n_1+X33_n_1*dt;

X33_n=X33_n_1+((R2*X22_n_1)/L3+X2_n_1/(C2*L3)-(R3*X33_n_1)/L3-(Rn*X33_n_1)/L3)*dt;

X11_n=(1/(1+R2/R1))*((1/R1)*((Y1-Y1)/dt)-(1/(R1*C1))*X1_n+R2/R1*X33_n-(1*X2_n)/(R1*C2));

X22_n=X11_n-X33_n;

// рекурсия

EE_n_2=EE_n_1; EE_n_1=EE_n;

X3_n_2=X3_n_1; X3_n_1=X3_n;

X2_n_2=X2_n_1; X2_n_1=X2_n;

X1_n_2=X1_n_1; X1_n_1=X1_n;

X33_n_2=X33_n_1; X33_n_1=X33_n;

X22_n_2=X22_n_1; X22_n_1=X22_n;

X11_n_2=X11_n_1; X11_n_1=X11_n;

}

// вывод результатов на виртуальный ЦАП VMLAB

I3=25*X3_n*25+128; // ток i3

I2=25*X2_n*25+128; // ток i2

I1=25*X1_n*25+128; // ток i1

PORTC=I3;PORTD=I2;PORTB=I1;

// контроль времени интегрирования

cnt=cnt+1;

if(cnt>100){cnt=101;}

}

}

void main(void)

{

// инициализация микроконтроллера

// конфигурирование порта A на ввод

PORTA=0x00;

DDRA=0xfe;

// конфигурирование порта B на вывод

PORTB=0x00;

DDRB=0xff;

// конфигурирование порта C на вывод

PORTC=0x00;

DDRC=0xff;

// конфигурирование порта D на вывод

PORTD=0x00;

DDRD=0xff;

// инициализация таймера временных интервалов

TCCR0=0x05; // установка режима таймера

TCNT0=0x3A; // установка начальных значений

OCR0=0x00;

// разрешение прерываний о т таймера

TIMSK=0x01; // установка режима таймера T0

// инициализация АЦП

// установка разрядности АЦП

// установка опорного напряжения АЦП

// установка способа запуска АЦП

ADMUX=ADC_VREF_TYPE;

ADCSRA=0x8D;

SFIOR&=0xEF;

// глобальное разрешение прерываний

#asm("sei")

while (1)

{// холостой цикл };

}

}