close

Вход

Забыли?

вход по аккаунту

?

lab 5 (2)

код для вставкиСкачать
Министерство образования Республики Беларусь
Учреждение образования
"БЕЛОРУССКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ ИНФОРМАТИКИ И РАДИОЭЛЕКТРОНИКИ"
Кафедра электронных вычислительных машин
Факультет компьютерных систем и сетей
Дисциплина: Архитектура Вычислительных Машин и Систем
Отчет по лабораторной работе № 5
Тема: "Texas Instruments MSP430F5529"
Выполнили: Проверил: студенты гр.050504 Краев Д. Г. Демидчук А.И.
Позняк В.Ю.
Тихонович Д. В.
Минск 2013
Задание
Произвести детальное описание взаимодействия с используемыми устройствами:
* дисплей
* акселерометр
* колесо
* диоды
1.Описание архитектуры
- Возможность понижения рабочего напряжения с 3,6 до 1,8 В
- Режимы работы:
- Активный режим -все таймеры включены, 290 мкА / МГц с частотой
8 МГц
- Режим ожидания - активны все таймеры, поддержание оперативной
памяти и быстрый переход в активный режим
- Режим энергосбережения - полное сохранение оперативной памяти,
активен 1 таймер, быстрый переход в активный режим
- Переход из режима энергосбережения в активный режим за 3,5 мкс
- 16-битная RISC-архитектура, возможность использования внешней памяти
- Гибкое управление энергопотреблением
- Унифицированный генератор частоты
- 4 16-битных аппаратных таймера (TA0, TA1, TA2, TB0)
- Поддержка двух USCI
- Поддержка шины USB
- 12-битный АЦП
- Аппаратная поддержка 32-битных операций
- Не требуется источника повышенного напряжения для программирования
- Трёхканальный контроллер DMA
- часы RTC
2.Дисплей
Texas Instruments MSP430F5529 имеет встроенный LCD контроллер, который обеспечивает прямую работу с дисплеем посредством автоматической подачи переменного тока и общего напряжения питания.
Особенности встроенного LCD контроллера: • память сегментирована
• автоматическая генерация сигналов
• конфигурируемая частота регенерации
• мигание отдельными сегментами памяти дисплея
• регулируемый заряд
• контрастность управления программным обеспечением
• поддержка 4 типов дисплеев
- статический
- 2-mux, 1/2 смещение или 1/3 смещение
- 3-mux, 1/2 смещение или 1/3 смещение
- 4-mux, 1/2 смещение или 1/3 смещение
• максимальное количество сегментов составляет 160 шт (зависит от дисплея и от конкретного устройства)
• сегменты памяти могут быть адресованы побитово либо по слову (word-wise)
• автоматическая очистка сегментов дисплея по установке бита LCDCLRM
Работа с дисплеем реализована в функции ZombieCat(). Функция производит прорисовку анимации бегающего зомби-кота на дисплее посредством обновления ячеек памяти контроллера дисплея через заданный промежуток времени, что обеспечивает покадровую прорисовку анимации.
Функция производит вывод в память контроллера дисплея ASCII символов - символов, через которые производится прорисовка изображения зомби-кота:
, , )
|\_/|_____|
|+ + o
|_^ _|- ||_||
U || ||
(_|(_|
изображение ASCII зомби-кота
С целью минимизации кода, изображение кота в каждой из его возможных позиций существует в единичном экземпляре, а для изменения позиции изображения кота осуществляется изменение координат прорисовки изображения кота, что обеспечивает эффект анимации. Прорисовка изображения производится в построчном режиме посредством функции void Dogs102x6_stringDraw(uint8_t row, uint8_t col, char *word, uint8_t style)
* uint8_t row - номер прорисовываемой строки
* uint8_t col - номер прорисовываемого столбца (колонки)
* char *word - указатель на строку для прорисовки
* uint8_t style - стиль вывода символов
Номер прорисовываемой строки должен быть в диапазоне [0; 7], номер прорисовываемого столбца - [0; 101] (указывается номер пикселя lcd в строке). Если строка символов, находящаяся по указателю char *word не влазит в строку дисплея, или указан индекс uint8_t col или uint8_t row более допустимого диапазона, то прорисовка происходит циклически на следующем номере строки или столбца в зависимости от того, какой индекс вышел за пределы допустимого (это для дисплея), сама же функция просто переназначит значение элемента на максимально возможный (101 и 7 для col и row).
uint8_t style может принимать значения 0 и 1, или проще - определённых макросов - DOGS102x6_DRAW_INVERT и DOGS102x6_DRAW_NORMAL - прорисовка символов в нормальном режиме (чёрные символы на белом фоне), или прорисовка символов в инвертированном режиме (белые символы на чёрном фоне). Dogs102x6_stringDraw(0, x-1, ", , )", DOGS102x6_DRAW_NORMAL); Dogs102x6_stringDraw(1, x-1, "|)_(|_____|", DOGS102x6_DRAW_NORMAL);Dogs102x6_stringDraw(2, x-1, "|+ + o", DOGS102x6_DRAW_NORMAL);Dogs102x6_stringDraw(3, x-1, "|_^_|-||_||", DOGS102x6_DRAW_NORMAL);Dogs102x6_stringDraw(4, x-1, " U || ||", DOGS102x6_DRAW_NORMAL);
Dogs102x6_stringDraw(5, x-1, " (_|(_|", DOGS102x6_DRAW_NORMAL); Dogs102x6_stringDraw(6, 0, "_________________", DOGS102x6_DRAW_NORMAL); Dogs102x6_stringDraw(7, 0, " ZOMBIE-CAT ", DOGS102x6_DRAW_NORMAL);
Библиотечная функция void Dogs102x6_stringDraw(uint8_t row, uint8_t col, char *word, uint8_t style)
использует функцию void Dogs102x6_charDraw(uint8_t row, uint8_t col, uint16_t f, uint8_t style) для посимвольной прорисовки строки.
Функция же void Dogs102x6_charDraw(uint8_t row, uint8_t col, uint16_t f, uint8_t style) задействует функцию void Dogs102x6_setAddress(uint8_t pa, uint8_t ca) для установки последующего прорисовываемого символа и функцию void Dogs102x6_writeData(uint8_t *sData, uint8_t i) для записи символа в память контроллера lcd.
изображение ASCII зомби-кота
void Dogs102x6_charDraw(uint8_t row, uint8_t col, uint16_t f, uint8_t style)
{
// Each Character consists of 6 Columns on 1 Page
// Each Page presents 8 pixels vertically (top = MSB)
uint8_t b;
uint16_t h;
uint8_t inverted_char[6];
// Row boundary check
if (row > 7)
row = 7;
// Column boundary check
if (col > 101)
col = 101; // handle characters not in our table
if (f < 32 || f > 129)
// replace the invalid character with a '.'
f = '.'; // subtract 32 because FONT6x8[0] is "space" which is ascii 32,
// multiply by 6 because each character is columns wide
h = (f - 32) * 6;
Dogs102x6_setAddress(row, col);
if (style == DOGS102x6_DRAW_NORMAL)
// write character
Dogs102x6_writeData((uint8_t *)FONT6x8 + h, 6);
else
{
for (b = 0; b < 6; b++)
{
// invert the character
inverted_char[b] = FONT6x8[h + b] ^ 0xFF;
}
// write inverted character
Dogs102x6_writeData(inverted_char, 6);
}
}
Прорисовка изображения требует удаления предыдущего прорисованного кадра анимации, т.к. координаты прорисовываемых кадров накладываются лишь частично. Для этого была задействована функция очистки экрана - Dogs102x6_clearScreen(), которая производит обнуление всей памяти lcd-контроллера посредством записи "0" в каждую ячейку памяти циклическим вызовом Dogs102x6_writeData(LcdData, 1), где LcdData = 0. Изменение адреса ячейки видеопамяти происходит с помощью функции Dogs102x6_setAddress(row, col), где row - номер строки, col - номер колонки/столбца. Функция осуществляет свою работу с помощью макросов SET_PAGE_ADDRESS, SET_COLUMN_ADDRESS_MSB, SET_COLUMN_ADDRESS_LSB которые представляют собой предопределённые байтовые значения команд (к примеру SET_PAGE_ADDRESS эквивалентно 0xB0). Посредство функции Dogs102x6_writeCommand происходит изменение номера строки и номера вывода колонки. При этом формирование команды изменение адреса страницы происходит следующим образом: Page Address Command = Page Address Initial Command + Page Address, аналогично происходит изменение адреса колонки: Column Address CommandLSB = Column Address Initial Command + Column Address bits 0..3 а также Column Address CommandMSB = Column Address Initial Command + Column Address bits 4..7.
void Dogs102x6_setAddress(uint8_t pa, uint8_t ca)
{
uint8_t cmd[1]; // Page boundary check
if (pa > 7) pa = 7;
// Column boundary check
if (ca > 101)
ca = 101;
// Page Address Command = Page Address Initial Command + Page Address
cmd[0] = SET_PAGE_ADDRESS + (7 - pa);
uint8_t H = 0x00;
uint8_t L = 0x00;
uint8_t ColumnAddress[] = { SET_COLUMN_ADDRESS_MSB, SET_COLUMN_ADDRESS_LSB };
currentPage = pa;
currentColumn = ca;
if (drawmode == DOGS102x6_DRAW_ON_REFRESH) return; // exit if drawmode on refresh
// Separate Command Address to low and high
L = (ca & 0x0F);
H = (ca & 0xF0);
H = (H >> 4);
// Column Address CommandLSB = Column Address Initial Command
// + Column Address bits 0..3
ColumnAddress[0] = SET_COLUMN_ADDRESS_LSB + L;
// Column Address CommandMSB = Column Address Initial Command
// + Column Address bits 4..7
ColumnAddress[1] = SET_COLUMN_ADDRESS_MSB + H;
// Set page address
Dogs102x6_writeCommand(cmd, 1);
// Set column address
Dogs102x6_writeCommand(ColumnAddress, 2);
}
При этом отправка команды осуществояется следующей функцией: Dogs102x6_writeCommand(cmd, 1), а отправка команды установки номера колонки функцией Dogs102x6_writeCommand(ColumnAddress, 2);
Эта функция получает значение регистра состояния SR посредством вызова функции __get_SR_register(), устанавливает флаг глобального разрешения прерываний (Global Interrupt Enable), затем отключает все прерывания посредством вызова функции__disable_interrupt(), пересылает данные в специальный буфер для видеопамяти UCB1TXBUF, ожидает завершения операции передачи данных и готовности буфера посредством контроля битов UCB1STAT и UCBUSY, если они оба = 0, то всё последняя операция передачи прошла успешно и буфер свободен для новых данных. После успешного выполнения функция восстанавливает предыдущее значение регистра состояния SR - предыдущее состояние бита глобального разрешения прерываний (Global Interrupt Enable) - GIE посредством вызова функции __bis_SR_register(gie), где gie - сохранённое перед вызовом функции предыдущее значение SP регистра.
3.Акселерометр
Экспериментальная плата MSP-EXP430F5529 содержит в себе трёх-осевой акселерометр CMA3000-D01 (Разработан VTI Technologies). Питание акселерометра подключено к пину P3.6
Характеристики:
- диапазон измеряемых ускорений: ±2g, ±8g;
- оси измерения: X, Y, Z;
- чувствительность: 14 LSB/g;
- частота среза: 80 Гц;
- интерфейс: SPI, I2C;
- ток потребления: менее 11 мкА;
- напряжение питания: 1,7...3,6 В;
- температурный диапазон: -40°C...+85°С;
- размеры корпуса: 2х2х0,94 мм.
Структурная схема
Взаимодействие с акселерометром происходит посредством USCI. Контроль за обменом информацией между акселерометром и контроллером приходится проводить в "ручном" режиме (инициализация USCI, выбор частоты и режима работы, установка временных задержек при передачи).
Акселерометр имеет 3 регистра, хранимых текущее ускорение в 3 плоскостях: DOUTX, DOUTY и DOUTZ. С определенным временным интервалом происходит опрос этих регистров. Обмен информацией происходит по интерфейсу USCI. Для обмена используются 2 регистра TX и RX. TX используется для выбора номера регистра и типа операции (запись/чтение), RX - для результат чтения или информирует о результативности записи
Описание взаимодействия:
int8_t Cma3000_xAccel, int8_t Cma3000_yAccel и int8_t Cma3000_zAccel - значение по осям акселерометра.
Для работы акселерометра используются 2 функции:
Cma3000_init() - запускает и инициализирует акселерометр;
Cma3000_readAccel() - запускается через фиксированный интервал времени и сохраняет текущее значение ускорения по осям в глобальные переменные int8_t Cma3000_xAccel, int8_t Cma3000_yAccel и int8_t Cma3000_zAccel.
Cma300_readRegister() - возвращает значение указанного регистра акселерометра
Описание работы функций:
void Cma3000_init(void)
{
do//Повторять пока акселерометр не проинициализируется
{
ACCEL_OUT |= ACCEL_PWR;//Подать питание на акселерометр
ACCEL_DIR |= ACCEL_PWR;
ACCEL_SEL |= ACCEL_SIMO + ACCEL_SOMI;//Установка пина 3.3, 3.4 в режим
//Slave In Master Out
//Slave On Master In
//Должно соответствовать дальнейшей конфигурации USCI
ACCEL_SCK_SEL |= ACCEL_SCK;//Разрешить передачу данных в режиме Slave
ACCEL_INT_DIR &= ~ACCEL_INT;
ACCEL_INT_IES &= ~ACCEL_INT;//Генерировать прерывание фронту (/)
ACCEL_INT_IFG &= ~ACCEL_INT;//Очистить флаг прерываний
// Unselect acceleration sensor
ACCEL_OUT |= ACCEL_CS;
ACCEL_DIR |= ACCEL_CS;
//Работа с перефирийным интерфейсом Universal Serial Communication Interface
UCA0CTL1 |= UCSWRST;//Отключить порт (0/1 отключить/включить)
UCA0CTL0 = UCMST + UCSYNC + UCCKPH + UCMSB;//USCI_Ax Control Register 0
//Ведущий
//Синхронный режим
//Данные снимаются по установке UCLK
//Режим SPI - синхронный, используется 3 пина
//Размер кадра - 8 бит
//Кадр начинается с MSB
UCA0CTL1 = UCSWRST + UCSSEL_2;//USCI_Bx Control Register 1 - управление генератором CLK
//UCSSELx - выбор режима - синхронный
//UCSWRST - сброс порта перед каждой передачей
UCA0BR0 = 0x30;//USCI baud rate 0 - младший байт делителя частоты
UCA0BR1 = 0;//USCI baud rate 1 - старший майт делителя частоты
UCA0MCTL = 0;//USCI modulation control - SPI без модуляции
UCA0CTL1 &= ~UCSWRST;//Включить порт
RevID = Cma3000_readRegister(REVID);//Получить номер прошивки акселерометра
__delay_cycles(50 * TICKSPERUS);//Ожидание после принятия данных
accelData = Cma3000_writeRegister(//Записать в регистр
CTRL,//CTRL - регистр управления
G_RANGE_2 | I2C_DIS | MODE_400//Максимальное ускорение 2g
//Включить интерфейс между датчиком и контроллером(0/1 - включить/выключить)
//Частота измерения - 400 Гц
);
__delay_cycles(1000 * TICKSPERUS);//Ожидание отправки и обработки
ACCEL_INT_IE &= ~ACCEL_INT;//Сброс флага прерывания
} while (!(ACCEL_INT_IN & ACCEL_INT));//Пока устройство не будет проинициализированно (установка флага прерывания)
}
void Cma3000_readAccel(void)//Получить текущее значение смещения
{
Cma3000_xAccel = Cma3000_readRegister(DOUTX);//Читаем значение из регистра DOUTX
//Сохраняем результат в глобальную переменную
__delay_cycles(50 * TICKSPERUS);//Задержка на переинициаизацию USCI
Cma3000_yAccel = Cma3000_readRegister(DOUTY);//Читаем значение из регистра DOUTY
//Сохраняем результат в глобальную переменную
__delay_cycles(50 * TICKSPERUS);//Задержка на переинициаизацию USCI
Cma3000_zAccel = Cma3000_readRegister(DOUTZ);//Читаем значение из регистра DOUTZ
//Сохраняем результат в глобальную переменную
}
int8_t Cma3000_readRegister(uint8_t Address)//Чтение регистра акселерометра
{
uint8_t Result;//Результат регистра
Address <<= 2;//Сдвигаем номер регистра на 2 бита влево
ACCEL_OUT &= ~ACCEL_CS;//Направление передачи
Result = UCA0RXBUF;//Сборс флага прерывания
while (!(UCA0IFG & UCTXIFG));//Ждем пока устройство не будет готово принять адрес
UCA0TXBUF = Address;//Запись адреса в буфер RX
while (!(UCA0IFG & UCRXIFG)) ;//Ждем пока данные запишутся
Result = UCA0RXBUF;//Сброс флага прерывания
while (!(UCA0IFG & UCTXIFG));//Ждем пока устройство не будет готово принять адрес
UCA0TXBUF = 0;//Пишем ноль в буфер RX (просто так)
while (!(UCA0IFG & UCRXIFG)) ;//Ждем пока данные запишутся
Result = UCA0RXBUF;//Получаем значение регистра из RX-буфера
while (UCA0STAT & UCBUSY);//Ждем когда завершится работа USCI
ACCEL_OUT |= ACCEL_CS;//Прекращаем взаимодействие с акселерометром
return Result;//Возвращаем результат
}
int8_t Cma3000_writeRegister(uint8_t Address, int8_t accelData)//Установить значение регистра акселерометра
{
uint8_t Result;//Результат записи
Address <<= 2;//Сдвигаем номер регистра на 2 бита влево
Address |= 2;//Выбираем режим записи
ACCEL_OUT &= ~ACCEL_CS;//Выбирем целью акселерометр
Result = UCA0RXBUF;//Читаем RX-буфер
while (!(UCA0IFG & UCTXIFG)) ;//Ждем когда устройство будет готово принять данные
UCA0TXBUF = Address;//Записываем адрес в TX буфер
while (!(UCA0IFG & UCRXIFG)) ;//Ждем принятие данных
Result = UCA0RXBUF;//Сбрасываем флаг прерывания
while (!(UCA0IFG & UCTXIFG)) ;//Ждем когда устройство будет готово принять данные
UCA0TXBUF = accelData;//Записываем значеине регистра в TX-буфер
while (!(UCA0IFG & UCRXIFG)) ;//Ждем пока данные будут записаны
Result = UCA0RXBUF;//Сбрасываем флаг прерывания
while (UCA0STAT & UCBUSY) ;//Ждем пока USCI освободится
ACCEL_OUT |= ACCEL_CS;//Прекращаем взаимодействие с USCI
return Result;//Возвращаем результат
}
4. Колесо
Экспериментальная плата MSP-EXP430F5529 имеет в своем составе поцентриометрическое колесо. Колесо подключено к пину P8.0. Расположение на плате
Колесо представляет собой потенциометр, который при прокручивании меняет свое сопротивление, что соответственно меняет уровень протекающего через него тока. Т.к. колесо представляет собой аналоговое устройство, оно поддержано помехам - при получении его состояния учитывается возможная погрешность в +- 10 единиц.
Описание взаимодействия:
Перед началом работы колесо нужно проинициализировать функцией Wheel_init(); Для получения позиции колеса (0-7) используется функция Wheel_getPosition(), которая в своей работе использует функцию Wheel_getValue(), которая возвращает абсолютное значение потенциометра. Wheel_getValue() для своей работы использует прерывания таймера. При каждом запуске оно инициализирует таймер, включает его прерывания и переходит в режим пониженного энергопотребления и ожидает, пока обработчик прерываний таймера не зафиксирует новое значение колеса, и при завершении своей работы вернет процессор в активный режим.
void Wheel_init(void)//Инициализация колеса
{
WHEEL_PORT_DIR |= WHEEL_ENABLE;//Включаем вывод на колесо
WHEEL_PORT_OUT |= WHEEL_ENABLE; //Включаем колесо
ADC12CTL0 = ADC12SHT02 + ADC12ON; //Выбор таймера ADC12
ADC12CTL1 = ADC12SHP; //Включить выборку значений по таймеру
ADC12MCTL0 = ADC12INCH_5; //Использовать колесо
ADC12CTL0 |= ADC12ENC; //Включить преобразование значений
ADC_PORT_SEL |= ADC_INPUT_A5; //Подать выход часов на колесо
}
uint8_t Wheel_getPosition(void)//Получить позицию колеса (0 - 7)
{
uint8_t position = 0;//Позиция по умолчанию
Wheel_getValue();
if (positionData > 0x0806)//Если значение колеса больше 0x0806
position = 7 - (positionData - 0x0806) / 260;//Если колесо выкручено в край
else
position = positionData / 260;//Высчитываем значение колеса
return position;//Возвращаем результат
}
uint16_t Wheel_getValue(void)//Получаем абсолютное значение колеса
{
ADC12IE = 0x01; //Включаем прерывания
ADC12CTL0 |= ADC12SC; //Включем обработку данных
__bis_SR_register(LPM0_bits + GIE); //LPM0 режим при ожидании прерывания
//Т.е. процессор уходит в экономный режим пока не произойдет прерывание
ADC12IE = 0x00; //Отключаем прерывание
if (positionData > positionDataOld)//Избегаем флуктуации из-за помех
if ((positionData - positionDataOld) > 10)
positionDataOld = positionData; //Если данные сильное измениились
//Значит колесо переместили
else
positionData = positionDataOld; //Иначе это помехи и поэтому возвращаем старые данные
else
if ((positionDataOld - positionData) > 10)// -//-
positionDataOld = positionData; else
positionData = positionDataOld; return positionData;//Возвращаем результат
}
#pragma vector = ADC12_VECTOR//Обработчик прерывания таймера
__interrupt void ADC12_ISR(void)
{
switch (__even_in_range(ADC12IV, ADC12IV_ADC12IFG15))
{
...
case ADC12IV_ADC12IFG0://Если прерывание произошло по колесу
positionData = ADC12MEM0; //Получаем оцифрованное значение потенциометра
__bic_SR_register_on_exit(LPM0_bits); //Уходим из прерывания в активном режиме
break;
...
}
}
5.Диоды
Экспериментальная плата MSP-EXP430F5529 имеет в своем составе программируемые светодиоды в количестве 8шт. Отдельные светодиоды (3шт)являются пользовательскими и имеют отличные цвета: жёлтый, красный и зелёный, остальные светодиоды в количестве 5шт относятся к тач-панели и все имеют синий цвет. Так же присутствует отдельный светодиод питания, он не является конфигурируемым, поэтому интереса не представляет.
Светодиоды и кнопки программируются с помощью установок значений специальных регистров P1OUT, P2OUT, P1IN, P1REN и т.д.
К примеру PxDIR отвечает за направление порта 1. Когда конкретный бит данного регистра установлен в 0, соответствующий пин работает на вход. И наоборот, если соответствующий бит установлена в 1, то пин работает на выход. В примере фигурируют 3 пина: P1.2 - кнопка, P1.0 - красный светодиод, P1.1 - зеленый светодиод.
PxREN включает внутренний резистор подтяжки. Кнопка замыкает пин на землю, и, соответственно, переводит его в состояние нуля. Когда кнопка не нажата пин ни к чему не подключен и для обеспечения логической единицы на нём требуется подключить его через резистор к питанию, что и делает регистр P1REN.
PxIN и PxOUT содержат в себе состояние пинов порта. Устанавливая ноль или единицу в регистр PxOUT мы меняем напряжение на лапке микроконтроллера, тем самым включая и выключая светодиод. Читая конкретный бит из регистра PxIN мы получаем логический сигнал, который сейчас подан на пин.
Константы BIT0..BITF содержатся в файле msp430f2274.h и представляют собой 16-ти разрядные слова в заданном разряде которых содержится 1, все остальные разряды содержат 0. В работе используются побитовые операции Си, "|=" установит соответствующий значению справа бит в регистре слева в единицу, а "&= ~" напротив установит его в 0.
конкретный pin (вывод) на микросхеме
void Board_ledOn(uint8_t ledMask) // функция включения светодиодов
{
if (ledMask & LED1) LED145678_PORT_OUT |= BIT0;
if (ledMask & LED2) LED23_PORT_OUT |= BIT1;
if (ledMask & LED3) LED23_PORT_OUT |= BIT2;
if (ledMask & LED4) LED145678_PORT_OUT |= BIT1;
if (ledMask & LED5) LED145678_PORT_OUT |= BIT2;
if (ledMask & LED6) LED145678_PORT_OUT |= BIT3;
if (ledMask & LED7) LED145678_PORT_OUT |= BIT4;
if (ledMask & LED8) LED145678_PORT_OUT |= BIT5;
}
void Board_ledOff(uint8_t ledMask) // функция выключения светодиодов
{
if (ledMask & LED1) LED145678_PORT_OUT &= ~BIT0;
if (ledMask & LED2) LED23_PORT_OUT &= ~BIT1;
if (ledMask & LED3) LED23_PORT_OUT &= ~BIT2;
if (ledMask & LED4) LED145678_PORT_OUT &= ~BIT1;
if (ledMask & LED5) LED145678_PORT_OUT &= ~BIT2;
if (ledMask & LED6) LED145678_PORT_OUT &= ~BIT3;
if (ledMask & LED7) LED145678_PORT_OUT &= ~BIT4;
if (ledMask & LED8) LED145678_PORT_OUT &= ~BIT5;
}
void Board_ledToggle(uint8_t ledMask) // функция переключения светодиодов
{
if (ledMask & LED1) LED145678_PORT_OUT ^= BIT0;
if (ledMask & LED2) LED23_PORT_OUT ^= BIT1;
if (ledMask & LED3) LED23_PORT_OUT ^= BIT2;
if (ledMask & LED4) LED145678_PORT_OUT ^= BIT1;
if (ledMask & LED5) LED145678_PORT_OUT ^= BIT2;
if (ledMask & LED6) LED145678_PORT_OUT ^= BIT3;
if (ledMask & LED7) LED145678_PORT_OUT ^= BIT4;
if (ledMask & LED8) LED145678_PORT_OUT ^= BIT5;
}
2
Документ
Категория
Рефераты
Просмотров
74
Размер файла
694 Кб
Теги
lab
1/--страниц
Пожаловаться на содержимое документа