Программное управление технологическим оборудованием
.pdfна ЖКИ unsigned int InputValue(char *str)
{
static char prevKey = 0; unsigned int value = 0;
LCD_Clear();
LCD_WriteString(str);
LCD_WriteValue(value);
while (1)
{
if (prevKey != _key)
{
prevKey = _key; if (_key == '*')
{
value = value / 10;
}
else if (_key == '#')
{
return value;
}
else if (_key != -1)
{
value = value * 10 + _key;
}
LCD_Clear(); LCD_WriteString(st r); LCD_WriteValue(v alue);
561
}
}
} |
|
void main() |
|
{ |
|
AD1PCFGL = 0xFFFF; |
// Отключение входов АЦП |
Kbd_Init(); |
// Инициализация портов |
клавиатуры |
|
Init_Timer1(); |
// Инициализация таймера |
I2C_Init(); |
// Инициализация портов I2C |
LCD_InitPorts(); |
// Инициализация портов для управления |
ЖКИ |
|
LCD_Init(); |
// Инициализация ЖКИ |
while (1) |
|
{ |
|
// Ввод адреса и данных
unsigned int addr = InputValue("Write addr:\0"); unsigned char data = (unsigned char)InputValue("Write data:\0");
1.Сохранение данные в ПЗУ
EE_WriteByte(addr, data); LCD_Clear(); LCD_WriteString("O k"); __delay32(FCY);
2.Ввод адреса чтения
LCD_Clear();
addr = InputValue("Read addr:\0");
// Чтение данных из ПЗУ data =
EE_ReadByte(addr); LCD_Clear();
LCD_WriteString("Read
562
data:\0"); LCD_WriteValue(data); __delay32(2 * FCY);
}
}
4 Варианты индивидуальных заданий к лабораторной работе
Разработать программу для учебного стенда, позволяющую выполнять следующие действия:
1.Записать состояние тумблеров SA3..SA10 в память ПЗУ. Адрес ячейки памяти ввести с клавиатуры.
2.Отобразить значение ячейки памяти ПЗУ с помощью светодиодов VD3..VD10. Адрес ячейки памяти ввести с клавиатуры.
3.Записать значение аналогового сигнала с датчика RP1 в две ячейки памяти ПЗУ. Адрес младшей ячейки памяти ввести с клавиатуры.
4.Отобразить на ЖКИ значение 8 последовательных ячеек памяти ПЗУ. Адрес начальной ячейки памяти ввести с клавиатуры.
5 Контрольные вопросы
1.Для чего предназначена шина I2C?
2.Дайте основные характеристики шины I2C.
3.Каково назначение линий шины I2C?
4.Каким образом происходит адресация устройств?
5.Какое количество устройств может быть одновременно подключено к шине I2C?
6.Каким образом происходит передача данных по шине I2C?
7.Каково назначение микросхемы памяти AT24C128?
8.Каким образом происходит чтение данных из микросхемы памяти?
9.Каким образом происходит запись данных в микросхему памяти?
563
Лабораторная работа 14
Исследование средств вывода аналоговой информации
Цель работы:
Изучить способы вывода аналоговой информации. Изучить схему сопряжения микросхемы цифро-аналого преобразователя с микроконтроллером.
Порядок выполнения работы:
1.Изучить теоретические вопросы, связанные с принципом работы цифроаналогового преобразователя.
2.Изучить принципиальную электрическую схему к лабораторной работе.
3.Разработать программу в соответствии с индивидуальным заданием.
4.Отладить программу в среде MPLAB IDE.
5.Загрузить программу в учебный стенд.
6.Исследовать работу системы вывода аналогового сигнала.
7.Оформить отчёт по лабораторной работе.
8.Ответить на контрольные вопросы.
1 Краткие теоретические сведения
1.1 Цифро-аналоговое преобразование
Цифро-аналоговый преобразователь (ЦАП) — устройство для преобразования цифрового кода в аналоговый сигнал (ток, напряжение либо сопротивление). Цифро-аналоговые преобразователи применяются для сопряжения цифровых устройств с аналоговыми схемами.
Применяются в основном 2 метода цифро-аналогового преобразования: суммирование единичных эталонных величин и суммирование эталонных величин, веса которых различаются. В первом для формирования выходной величины используется только одна эталонная величина, во втором методе применяются эталонные величины с разными весами, зависящими от номера разряда, и суммируются только те эталонные величины, для которых в соответствующем разряде входного кода установлена единица.
Основной характеристикой ЦАП является разрядность. Разрядность — это количество различных уровней выходного сигнала, которые ЦАП может воспроизвести. Разрядность обычно задается в битах; количество бит есть логарифм по основанию 2 от количества уровней. Например, однобитный ЦАП способен воспроизвести два уровня, а восьмибитный — 256 уровней.
564
1.2 Микросхема ЦАП AD5241
Микросхема AD5241 представляет собой переменное сопротивление с 256 уровнями квантования, конфигурируемое по интерфейсу I2C. Условное обозначение микросхемы приведено на рис.1.1, назначение выводов представлено в таблице 1.1.
Рис. 1.1. Условное обозначение микросхемы AD5241
Таблица 1.1
Назначение выводов микросхемы AD5241
Номер вывода |
Обозначение |
Назначение |
|
1, 2, 3 |
A, W, B |
Выводы потенциометра |
|
4 |
|
Vcc |
Напряжение питания |
10 |
DGnd |
Общий провод цифровой части |
|
11 |
Vss |
Общий провод аналоговой части |
|
6, |
7 |
SCL, SDA |
Линии интерфейса I2C |
8, |
9 |
A0, A1 |
Дополнительные адресные входы |
14, |
12 |
Q1, Q2 |
Дополнительные дискретные выходы |
Полное сопротивление между выводами A и B может быть 10кОм, 100кОм, 1Мом (в зависимости от модели микросхемы). Сопротивление разбито на 256 частей, через внутренние ключи подсоединённые к выводу 8- разрядного регистра. Регистр декодирует поступающий цифровой код, коммутируя аналоговый выход микросхемы с выводом соответствующего ключа. Таким образом, микросхему можно представить в виде потенциометра с задаваемым в цифровом виде положением среднего вывода. Напряжение на аналоговом выходе микросхемы при этом можно вычислить по формуле:
565
Управление микросхемой осуществляется по интерфейсу I2C. Любое обращение к микросхеме начинается с цикла посылки идентификатора устройства. После получения подтверждения от микросхемы необходимо отослать управляющий байт. Формат управляющего байта представлен в таблице 1.1.
|
|
Таблица 1.1 |
|
Формат управляющего байта |
|
|
Обозначени |
|
Номер бита |
е |
Назначение |
7 |
A/B |
Выбор одного из двух внутренних регистров. |
|
|
Сброс. Устанавливает аналоговый выход в |
6 |
RS |
среднее |
|
|
положение. |
|
|
Выключение. Аналоговый выход |
5 |
SD |
подключается к |
|
|
выводу B. |
4 |
O1 |
Бит управления дискретным выходом Q1. |
3 |
O2 |
Бит управления дискретным выходом Q2. |
2 |
– |
|
1 |
– |
Не используются. |
0 |
– |
|
2 Электрическая принципиальная схема к лабораторной работе
На рис.2.1 приведена электрическая схема подключения микросхемы ЦАП к микроконтроллеру по интерфейсу I2C.
Рис. 2.1. Электрическая схема подключения микросхемы ЦАП
Линия тактирования SCL подключена к порту RA9 микроконтроллера, линия данных SDA – к порту RA8. Линии имеют подтягивающий резистор.
566
С учётом подключения выводов A и B микросхемы, напряжение на аналоговом выходе микросхемы будет рассчитываться по формуле:
Для визуального отображения уровня напряжения на аналоговом выходе к микросхеме ЦАП подключена линейная светодиодная шкала (LLI).
Адрес микросхемы ЦАП формируется из фиксированной части и битов, формируемых аппаратно в зависимости от схемы подключения дополнительных адресных входов микросхемы. Фиксированная часть представляет собой 01011 в двоичном коде, дополнительная часть адреса равна 01. Таким образом, при обращении к микросхеме ЦАП управляющее слово будет 01011010 (5A в шестнадцатеричном коде)
3 Пример выполнения работы
Задача: Разработать программу для учебного стенда, позволяющую индицировать на LLI уровень аналогового сигнала с регулятора RP1. Значение аналогового сигнала также дублировать на LED.
Анализ задачи: Операции по работе с интерфейсом I2C (чтение, запись данных, формирование стартовой и стопой последовательности) удобней организовать в виде соответствующих функций.
Листинг программы:
#include <P33FJ32MC204.h> #define FOSC 7370000 #define FCY (FOSC / 2)
_FOSCSEL(FNOSC_FRC) // настройка работы микроконтроллера
// от внутреннего тактового генератора
// объявление кодов сегментов
|
0x0 |
#define SEG_A |
8 |
|
0x0 |
#define SEG_B |
1 |
|
0x2 |
#define SEG_C |
0 |
|
0x0 |
#define SEG_D |
4 |
|
0x8 |
#define SEG_E |
0 |
#define SEG_F |
0x1 |
567
|
0 |
|
0x4 |
#define SEG_G |
0 |
|
0x0 |
#define SEG_DP |
2 |
1.--- SEG_A ---
// |
| |
| |
// |
SEG_F |
SEG_B |
// |
| |
| |
//--- SEG_G ---
// |
| |
| |
// |
SEG_E |
SEG_C |
// |
| |
| |
|
|
--- SEG_D --- |
// |
|
SEG_DP |
// объявление кодов цифр
#define N0 SEG_A + SEG_B + SEG_C + SEG_D + SEG_E + SEG_F
#define N1
#define N2 #define N3 #define N4
#define N5
#define N6 SEG_E #define N7 #define N8
SEG_F + SEG_G #define N9 SEG_G
#define DIP #define MINUS
#define OFF
// массив кодов цифр
char DIGITS[] = {N0, N1, N2, N3, N4, N5, N6, N7, N8, N9};
568
|
|
// номер активного вывода |
||
char _i = 0; |
|
дешифратора |
|
|
|
|
|
индикации - массив |
|
char _ind[8]; |
|
// буфер |
кодов |
|
символов |
|
|
|
|
// Инициализация таймера |
|
|
|
|
T1 |
|
|
|
|
void |
|
|
|
|
Init_Timer1() |
|
|
|
|
{ |
|
|
|
|
|
|
// сброс |
|
|
T1CON |
= 0; |
таймера |
|
|
IFS0bits.T1IF = 0; |
// сброс флага прерывания таймера |
|||
IEC0bits.T1IE = 1; |
// разрешение прерывания от таймера |
|||
TMR1 |
= 0x0000; |
// обнуление текущего значения таймера |
||
|
= |
|
|
|
PR1 |
0x0E65; |
// задание периода таймера |
||
|
|
// разрешение работы таймера и его |
||
T1CONbits.TON = 1; |
запуск |
|
|
|
} |
|
|
|
|
// Инициализация линий |
|
|
|
|
портов |
|
|
|
|
void Ind_Init() |
|
|
|
|
{ |
|
|
|
|
TRISBbits.TRISB6 = |
|
|
|
|
0; |
|
// Выход |
A |
(RB6) |
TRISBbits.TRISB7 = |
|
|
|
|
0; |
|
// Выход |
B |
(RB7) |
TRISBbits.TRISB8 = |
|
|
|
|
0; |
|
// Выход |
C |
(RB8) |
TRISBbits.TRISB9 = |
|
|
|
|
0; |
|
// Выход |
D |
(RB9) |
TRISCbits.TRISC3 = |
|
|
|
|
0; |
|
// Выход |
SDI |
(RC3) |
TRISCbits.TRISC4 = |
|
SC |
|
|
0; |
|
// Выход |
K |
(RC4) |
TRISBbits.TRISB5 = |
|
|
|
|
0; |
|
// Выход |
LE |
(RB5) |
} |
|
|
|
|
// Отправление данных в регистр
MBI5168 void Ind_Send(char digit)
{
569
char c;
for (c = 0; c < 8; c++)
{
4.1установка требуемого логического уровня
4.2на последовательном входе SDI
драйвера MBI5168 if ((digit & (1 << c)) != 0)
{
LATCbits.LATC3 = 1;
}
else
{
LATCbits.LATC3 = 0;
}
4.3формирование синхроимпульса на входе SCK
LATCbits.LATC 4 = 1; LATCbits.LATC 4 = 0;
}
// формирование синхроимпульса на входе LE
LATBbits.LATB5 = 1;
LATBbits.LATB5 = 0;
}
5.1 Разбитие числа на цифры void Ind_Show(unsigned int b)
{
_ind[7] = DIGITS[b % 10]; b /= 10; _ind[6] = DIGITS[b % 10]; b /= 10; _ind[5] = DIGITS[b % 10]; b /= 10; _ind[4] = DIGITS[b % 10];
}
570
