Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Лаб_4 Головков И.Е. 12002108

.docx
Скачиваний:
1
Добавлен:
26.06.2024
Размер:
1.69 Mб
Скачать

ФЕДЕРАЛЬНОЕ Государственное АВТОНОМНОЕ образовательное УЧРЕЖДЕНИЕ ВЫСШЕГО образования

«БЕЛГОРОДСКИЙ ГОСУДАРСТВЕННЫЙ НАЦИОНАЛЬНЫЙ

ИССЛЕДОВАТЕЛЬСКИЙ УНИВЕРСИТЕТ»

(НИУ «БелГУ»)

ИНСТИТУТ ИНЖЕНЕРНЫХ И ЦИФРОВЫХ ТЕХНОЛОГИЙ

Кафедра информационных и робототехнических систем

Отчет по лабораторной работе №4 Тема работы: «ИЗУЧЕНИЕ ПРИНЦИПОВ ОБРАБОТКИ ПРЕРЫВАНИЙ НА ПРИМЕРЕ УПРАВЛЕНИЯ ВСТРОЕННЫМИ В МИКРОКОНТРОЛЛЕР ТАЙМЕРАМИ СЧЕТЧИКАМИ И КОМПАРАТОРОМ. ИЗУЧЕНИЕ ПРИНЦИПОВ ПРОГРАММНОГО УПРАВЛЕНИЯ ВСТРОЕННЫМ В МИКРОКОНТРОЛЛЕР ЦИФРО АНАЛОГОВОГО ПРЕОБРАЗОВАТЕЛЯ» по дисциплине «Микроконтроллеры и микроконтроллерные системы»

студента очного отделения

3 курса 12002108 группы

Головкова Игоря Евгеньевича

Проверил:

Шамраев А.А.

Белгород 2024

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

Задание: разработать в среде программирования IAR Embedded Workbench программу на языке С для микроконтроллера MSP430, которая обеспечивает измерение сопротивления переменного резистора и выводит рассчитанное значение на ЖКИ. Для решения задачи необходимо использовать встроенный компаратор и таймер А в режиме захвата.

Ход работы: в ходе лабораторной работы был написан код.

Рисунок 1 – Результат выполнения работы программы на микроконтроллере MSP430F1611

Рисунок 2 – Результат выполнения работы программы на микроконтроллере MSP430F1611

Рисунок 3 – Результат выполнения работы программы на микроконтроллере MSP430F1611

Листинг программы:

Файл main.c:

#include <msp430.h>

#include "stdio.h"

#include "system_define.h"

#include "system_variable.h"

#include "function_prototype.h"

#include "main.h"

char message[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

void main(void) {

WDTCTL = WDTPW + WDTHOLD;

Init_System();

Init_System_Clock();

LCD_init();

__enable_interrupt();

while(1) {

unsigned long resistance = R22_get_resistance();

LCD_clear();

LCD_set_pos(0,0);

sprintf(message,"R22 = %lu Ом", resistance);

LCD_message(message);

wait_1ms(500);

}

}

Вывод: в ходе лабораторной работы были изучены принципы разработки процедур обработки прерываний в микроконтроллере MSP430F1xxx, а также изучены принципы функционирования встроенных в микроконтроллер 16 – разрядных таймеров-счетчиков и компаратора для измерения сопротивления резистивного датчика.

Приложение А

// инициализация портов системы

void Init_System()

{

P1DIR |= (nSS + nWR_nRST + MCU_SEL_0 + MCU_SEL_1); // установка направления портов на вывод

DB_DIR = 0x00; // шина данных настроена на ввод

}

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

void Init_System_Clock()

{

volatile byte i;

BCSCTL1 &= ~XT2OFF; // включение осцилятора XT2

// MCLK = XT2, SMCLK = XT2

do // ожидание запуска кварца

{

IFG1 &= ~OFIFG; // Clear OSCFault flag

for (i = 0xFF; i > 0; i--); // Time for flag to set

}

while ((IFG1 & OFIFG)); // OSCFault flag still set?

BCSCTL2 |= SELM_2 | SELS; // установка внешнего модуля тактирования

}

void Init_I2C()

{

P3SEL |= 0x0A; // Выбор альтернативной функции для линий порта P3

// в режиме I2C SDA->P3.1, SCL->P3.3

U0CTL |= I2C + SYNC; // Выбрать режим I2C для USART0

U0CTL &= ~I2CEN; // Выключить модуль I2C

// Конфигурация модуля I2C

I2CTCTL=I2CSSEL_2; // SMCLK

I2CSCLH = 0x82; // High period of SCL

I2CSCLL = 0x82; // Low period of SCL

U0CTL |= I2CEN; // Включить модуль I2C

// формирование строба сброса I2C-регистров PCA9538 - RST_RG1->P3.1 и RST_RG2->P3.2

P3DIR |= 0x05; // переключаем эти ножки порта на вывод,

P3SEL &= ~0x05; // выбираем функцию ввода-вывода для них

P3OUT &= ~0x05; // и формируем строб сброса на 1 мс

wait_1ms(1);

P3OUT |= 0x05;

}

// Выключить все светодиоды

void LED_clear()

{

LED_out(0x00);

}

void I2C_WriteByte(char reg, char data, char i2c_addr)

{

Tx_Data[0] = reg; // выбираем регистр

Tx_Data[1] = data; // записываемые данные

Send_I2C(&Tx_Data[0], 2, i2c_addr); // вывод по I2C на устройство

}

// отправка данных по протоколу I2C

void Send_I2C(unsigned char* buffer,unsigned int num, unsigned char address)

{

while (I2CBUSY & I2CDCTL); // проверка готовности модуля I2C

BufTptr=buffer;

I2CSA = address; // установка адреса приемнмка

I2CNDAT =num; // количество передаваемых байт

I2CIE = TXRDYIE+ALIE; // разрешение прерываний по окончанию передачи байта и по потере арбитража

U0CTL |= MST; // режим Master

I2CTCTL |= I2CSTT + I2CSTP + I2CTRX; // инициализировать передачу

while ((I2CTCTL & I2CSTP) == 0x02); // ожидание условия СТОП

}

// чтение байта из регистра устройства на шине I2C

byte I2C_ReadByte(char reg, char i2c_addr)

{

Tx_Data[0] = reg; // выбираем регистр

Send_I2C(&Tx_Data[0], 1, i2c_addr);

Receive_I2C(&Rx_Data[0], 1, i2c_addr); // получаем значение из регистра

return Rx_Data[0];

}

// Получить значение сопротивления подстроечного резистора R22, Ом

unsigned long R22_get_resistance()

{

P2SEL &= ~(Rref+Rx); // функция ввода-вывода для ножек P2.4 и P2.5

word Nref = res_measure(Rref); // время разряда через опорный резистор

word Nx = res_measure(Rx); // время разряда через подстроечный резистор

return (((unsigned long)100000*Nx)/Nref)-10000; // R22 = (100000 * Nx / Nref) - 10000

}

// Измерение времени разряда конденсатора через resistor (Rref или Rx)

word res_measure(byte Rpin)

{

P2DIR &= ~Rx; // отключить Rx от конденсатора (направление - ввод)

// заряд конденсатора через опорный резистор Rref

CAPD = ~Rref; // отключение аналоговых сигналов от порта компаратора

P2DIR |= Rref; // подключить Rref к конденсатору (направление - на вывод)

P2OUT |= Rref; // установка ножки Rref- заряд кондесатора

TACCR1 = 65000; // время заряда

TACCTL1 = CCIE; // разрешить прерывания

// тактирование от SMCLK, делитель /4, очистка счетчика, непрерывный режим счета

TACTL = TASSEL_2 + ID_2 + TACLR + MC_2;

LPM0; // перейти в режим пониженного потребления и ожидать прерывания

CACTL2 = P2CA0 | CAF; // вход компаратора подключается к CA0, вкл.выходного фильтра

// включение компаратора, опорное напр. 0.25*Vcc прикладывается к "-"

CACTL1 = CARSEL+CAREF_1+CAON;

CAPD = ~(Rpin+CA0);

P2DIR &= ~Rref; // отключить Rref от конденсатора (направление - ввод)

P2DIR |= Rpin; // будем разряжать через ножку Rpin

P2OUT &= ~Rpin; // низкий уровень на Rpin - разряд конденсатора

// захват по заднему фронту, входной сигнал - CCI1B, режим захвата, прерывания разрешены

TACCTL1 = CM_2+CCIS_1+CAP+CCIE;

TACTL |= TACLR; // сбросить счетчик таймера

LPM0; // перейти в режим пониженного потребления и ожидать прерывания

TACTL = 0x00; // остановить таймер

CACTL1 = 0x00; // отключить компаратор

CAPD = 0; // включить входные буферы компаратора

return TACCR1; // возвращаем значение счетчика таймера

}

// обработчик прерываний от таймера

#pragma vector=TIMERA1_VECTOR

__interrupt void isrTIMERA(void)

{

LPM0_EXIT; // выход из LPM0

TACCTL1 &= ~CCIFG; // очистка флага прерывания

}

Файл system_define.h:

#ifndef __SYSTEM_DEFINE_H__

#define __SYSTEM_DEFINE_H__

#include <msp430.h>

#ifndef __BYTE_H__

#define __BYTE_H__

typedef unsigned char byte;

typedef unsigned int word;

#endif

#define nSS BIT0

#define Set_nSS() P1OUT |= nSS

#define Reset_nSS() P1OUT &= ~nSS

#define nWR_nRST BIT2

#define Set_nWR_nRST() P1OUT |= nWR_nRST

#define Reset_nWR_nRST() P1OUT &= ~nWR_nRST

#define MCU_SEL_0 BIT3

#define Set_MCU_SEL_0() P1OUT |= MCU_SEL_0

#define Reset_MCU_SEL_0() P1OUT &= ~MCU_SEL_0

#define MCU_SEL_1 BIT4

#define Set_MCU_SEL_1() P1OUT |= MCU_SEL_1

#define Reset_MCU_SEL_1() P1OUT &= ~MCU_SEL_1

#define A0 BIT0

#define A1 BIT1

#define DB_DIR P4DIR

#define DB_OUT P4OUT

#define DB_IN P4IN

#define D_nC_LCD BIT4

#define Set_D_nC_LCD() P3OUT |= D_nC_LCD

#define Reset_D_nC_LCD() P3OUT &= ~D_nC_LCD

#define EN_LCD BIT5

#define Set_EN_LCD() P3OUT |= EN_LCD

#define Reset_EN_LCD() P3OUT &= ~EN_LCD

#endif

Файл function_prototype:

/******************************** TIMERA.c ************************************/

float HIH_get_hum();

float INA_get_curr();

unsigned long R22_get_resistance();

word res_measure(byte Rpin);