
- •Пояснительная записка к курсовой работе
- •Оглавление
- •1. Постановка задачи.
- •1.1. Стандартное задание
- •1.2. Индивидуальное задание
- •2. Техническое задание
- •3. Описание аппаратных и программных средств лабораторного комплекса
- •3.1. Структура аппаратных средств
- •3.1.1. Структурная схема лабораторного комплекса
- •3.1.2. Плата мк – системы
- •3.1.2.1. Конфигурируемые узлы мк c8051f064
- •Интерфейс прямого доступа к памяти (dma)
- •3.1.2.2. Внешняя память xram
- •3.1.2.3. Входные усилители
- •3.1.2.4. Микросхема моста uart-usb
- •3.1.2.5. Сопряжение платы с pc
- •3.1.2.6. Питание платы
- •3.1.3. Требования к pc
- •3.1.4. Осциген
- •. Перечень программных средств лабораторного комплекса
- •Средства программирования и отладки мк-системы
- •Интегрированная среда разработки фирмы SiLabs ide 2.0
- •3.2.1.2. Ассемблер, компилятор и линкер интегрированной среды разработки Keil
- •3.2.2. Средства разработки Windows-приложений
- •3.2.2.1. Среда разработки
- •3.2.2.2. Библиотека win32 api функций
- •3.2.3. Приложения для осцигеНа.
- •3.2.3.1. Драйвер конфигурируемого выносного блока
- •3.2.3.2. Windows-приложение ogView
- •3.2.4. Драйвер виртуального com-порта фирмы SiLabs
- •Организация бесконечного цикла встроенного приложения
- •Отключение сторожевого таймера
- •Переключение с внутреннего генератора на внешний
- •Конфигурирование портов ввода/вывода
- •Конфигурирование аналого-цифровых преобразователей adc
- •Конфигурирование интерфейса dma
- •Инициализация последовательного интерфейса uart
- •Выбор и инициализация таймера для установки скорости обмена данными по последовательному каналу
- •Инициализация таймера для установки времени дискретизации входного сигнала
- •Прием данных с pc
- •Другие используемые функции
- •Конфигурирование узлов мк с учетом данных, пришедших с pc
- •Разработка Windows-приложения
- •4.4.1. Особенности использования среды разработки
- •4.4.2. Описание файлов проекта
- •4.4.3. Обобщенная схема алгоритма многопоточного приложения
- •4.4.4. Внешний вид и описание графического интерфейса, принципы построения программы
- •Описание структуры и организация программы
- •4.4.5.1. Назначение подключаемых файлов
- •4.4.5.2. Описание прототипов функций
- •4.4.5.3. Функция WinMain()
- •4.4.5.4. Функция главного окна
- •4.4.5.5. Организация дополнительных потоков, их назначение
- •4.4.5.6. Рабочие функции дополнительных потоков
- •4.4.5.7. Синхронизация потоков
- •4.4.5.8. Особенности обработки сообщений Windows в программе
- •4.4.6.2. Организация настроек com-порта в графическом интерфейсе
- •4.4.6.3. Использование функций WaitCommEvent(), WaitForSingleObject(), WaitForMultiplyObject()
- •Работа оператора с приложением
- •4.4.7.1. Последовательность запуска приложения на мк и пк в лаборатории
- •4.4.7.2. Адаптация к спектру входного сигнала
- •Описание протокола rs-232
- •Список используемых источников информации
- •Приложения
- •Исходные тексты модулей программы для мк
- •Фрагменты листингов файлов мк-приложения, полученные в результате трансляций: map-file и др
- •Исходные тексты файлов Windows-приложения
Список используемых источников информации
http://www.megachip.ru/images/templates/big/8051F064EK.jpg
Описание МК C8051F064, https://www.silabs.com/Support%20Documents/TechnicalDocs/C8051F064-EK.pdf
Описание семейства МК C8051F06x (перевод), http://www.efo.ru/doc/Silabs/pdf/C8051F06x.pdf
«Новый UART-USB мост CP2102 от фирмы Silicon Laboratories», О.Николайчук, http://www.silabs.ru/pubs/Stat_096.pdf,
«Сетевой комбинированный прибор Осицген», http://npo-rtc.ru/product/oscigen/why.html
Описание Осцигена, http://www.npo-rtc.ru/product/oscigen/
Программное обеспечение для МК фирмы Silicon Laboratories, http://www.efo.ru/doc/Silabs/Silabs.pl?2083#link1
Keil uVision3 - среда разработки ПО для микроконтроллеровсерии х51 на языке С / Asembler, http://binural.ru/soft/print:page,1,1147836023-keil-uvision-3-sreda-razrabotki-po-dlja.html
Библиотека WindowsAPI 32, http://www.microsoft.com/Rus/Msdn/Activ/MSVB/Archive/WindowsAPI/API-DLL-1.mspx
Программное обеспечение OGView, http://www.npo-rtc.ru/product/oscigen/program.html
SiLabs: использование USB, http://www.efo.ru/doc/Silabs/Silabs.pl?2150
Описание платы C8051F064EK, https://www.silabs.com/Support%20Documents/TechnicalDocs/C8051F064-EK.pdf,
Приложения
Исходные тексты модулей программы для мк
#include <c8051f060.h>
#include <stdio.h>
//-----------------------------------------------------------------------------
// Определение 16-битных SFR для 'F06x
//-----------------------------------------------------------------------------
sfr16 RCAP3 = 0xCA; // Timer3, значение адреса после перезагрзки
sfr16 TMR3 = 0xCC; // Timer3, адрес счетчика
sfr16 ADC0 = 0xBE; // ADC0, адрес результата
sfr16 DMA0CT = 0xF9; // DMA, счетчик операций
sfr16 DMA0DA = 0xD9; // DMA0, адрес начала
//------------------------------------------------------------------------------------
// Глобальные константы
//------------------------------------------------------------------------------------
#define SYSCLK 11059200 // SYSCLK частота в Гц
#define BAUDRATE 115200 // Скорость передачи UART0
sbit P1_6=P1^6;
// инструкции DMA
#define DMA0_END_OF_OP 0x00 // конец операций
#define DMA0_GET_ADC0 0x10 // Получение данных ADC0
#define DMA0_GET_DIFF 0x40 // Получение Retrieve разностных (дифференциальных) данных (ADC0-ADC1)
#define XRAM_START_ADD 0x0000 // DMA0 XRAM стартовый адрес ADC data log
//-------------------------
// Глобальные переменные
//-------------------------
unsigned char xdata * data read_ptr; // указатель XRAM
unsigned int NUM_SAMPLES; // количество выборок ADC (каждая выборка 2 байта)
unsigned char ADC_Mode; // режим ADC
unsigned int SAMP_RATE ; // частота дискретизации ADC в Гц (писать в RCAP3)
//------------------------------------------------------------------------------------
// Конфигурирование портов ввода/вывода
//------------------------------------------------------------------------------------
void Port_Init (void)
{
char old_SFRPAGE = SFRPAGE;
SFRPAGE = CONFIG_PAGE; // Переключение на страницу конфигурации
XBR0=0x04; // запись значения b00000100, включение бита подключения входов/выходов UART0
// TX0 соединен с P0.0; RX0 - с P0.1
XBR1=0x00; // SYSCLK, T2EX, T2, INT1, IN0, T1E, T0E, CP1 не соеденены с портами ввода/вывода
XBR2=0x40; // запись значения b01000000, установка в 1 бита включения матрицы (распределяет выводы)
// слаботоковые подтяжки включены (бит7 = 0)
P0MDOUT=0xFF; // запись значения b11111111, все выводы (P0.0-7) настроены как цифровой двухконтактный выход (Push-Pull)
// по умолчанию они настроены для работы в режиме Open_Drain
P1MDOUT |= 0x40; // запись значения b10111111, все выводы, кроме P1.6 настроены как цифровой двухконтактный выход (Push-Pull)
// порт P1.6 настроен для работы в режиме Open_Drain
SFRPAGE = old_SFRPAGE; // восстановление SFRPAGE
}
//-----------------------------------------------------------------------------
// Инициализация UART0
//-----------------------------------------------------------------------------
// Настройка UART0, использующую Timer1 (режим 2, 8-разрядный автоперезагружаемый таймер-счетчик), в режим 1
// (стандартный асинхронный полудуплексный обмен данными с использованием 10 бит для передачи 1 байта данных)
void UART0_Init (void)
{
char old_SFRPAGE = SFRPAGE;
SFRPAGE = UART0_PAGE; // Переключение на страницу UART0
SCON0 = 0x50; //запись значения b01010000 в регистр управления SCON0
//установка в 01 битов выбора режима UART0 (7 и 8 биты) - режим 1, 8-разрядный UART0, изменяемая скорость передачи
//установка в 1 бита разрешения приема (бит 4) - прием данных UART0 разрешен
// SCON: mode 1, 8-bit UART, enable RX
SSTA0 |= 0x10; //логическое или со значением b00010000 в регистр состояния и выбора счетчика тактирования SSTA0
//бит 4: 1 - скоротсть передачи данных последовательного порта UART0 удваивается
//биты 3-2 (биты выбора генератора скорости передатчика данных): 00 - таймер T1
//биты 1-0 (биты выбора генератора скорости приемника данных): 00 - таймер T1
// инициализация T1
SFRPAGE = TIMER01_PAGE; // Переключение на страницу Timer 0/1
TMOD = 0x20; // запись значения b00100000, режим 2 (8-разрядный автоперезагружаемый таймер-счетчик)
TH1 = -(SYSCLK / BAUDRATE)/16; // задание значения переполнения таймера для скорости передачи данных
TL1 = -(SYSCLK / BAUDRATE)/16; // задание начального значения таймера для скорости передачи данных
TR1 = 1; // запуск T1
CKCON |= 0x10; //логическое или со значением b00010000, таймер Т1 тактируется сичтемных тактовым сигналом SYSCLK
SFRPAGE = old_SFRPAGE; // восстановление SFRPAGE
}
//-----------------------------------------------------------------------------
// инициализация SYSCLK
//-----------------------------------------------------------------------------
// Запуск внешнего осцилятора
void SYSCLK_Init (void)
{
char old_SFRPAGE = SFRPAGE;
int i;
SFRPAGE = CONFIG_PAGE; // Переключение на страницу конфигурации
OSCXCN = 0x77; // запись значения b01110111
//бит 7: 0 -кварцевый генератор не используется или еще не стабилен
//биты 6-4: 111 - режим кварцевого генератора с делением тактовой частоты на 2
//бит 3: зарезервирован
//биты 2-0 (управления частотой внешнего генератора): 111 - частота генератора задается от 10 МГц до 30 МГц
// частота =(22118400/2=11059200)Hz
for (i=0; i <5000; i++) ; // пауза длительностью как минимум 1 мс, чтобы исключить
//преждевременное переключение системы от внешнего генератора
while (!(OSCXCN & 0x80)) ; //(OSCXCN & b10000000) опрашиваем флаг стабилизации кв.генератора до тех пор,
// пока он не установится в 1 (кв.генератор стабилен)
RSTSRC |= 0x04; //логическое или со значением b00000100
// позволяет восстановить отсутствующие часы детектора
CLKSEL |= 0x01; // запись значения b00000001, переключение на работу от внешнего генератора
OSCICN = 0x00; // отключение внутреннего генератора
SFRPAGE = old_SFRPAGE; // восстановление SFRPAGE
}
//-----------------------------------------------------------------------------
// инициализация ADC
//-----------------------------------------------------------------------------
// Настройка ADC0 и ADC1(если нужно) с управлением преобразованием Timer3
void ADC_Init (void)
{
char old_SFRPAGE = SFRPAGE;
int i;
SFRPAGE = ADC0_PAGE; // Переключение на страницу ADC0
ADC0CN = 0xC4; // запись значения b11000100, бит 7: 1 -включение ADC0,
//бит 6: 1 - режим слежения определяется битами 3-2
//бит 3-2: 01 - слежение(выборка) начинается при переполнении таймера 3
REF0CN = 0x03; // запись значения b00000011, включение генератора напряжения смещения ADC0 и
//включение внутреннего буферного усилителя, внутреннее опорное напряжение подается на вход VREF0
for(i=0;i<10000;i++); // задержка для стабилизации генератора опорного напряжения
ADC0CF = 0x00; // установка в качестве периода сигнала дискретизации ADC0 Tconv = 21*Tsysclk
//Режим ADC
if (ADC_Mode == 's')
AMX0SL = 0x00; // режим ADC0
else if (ADC_Mode=='d')
{
AMX0SL = 0x40; // запись значения b10000000, выбор дифференциального режима работы
SFRPAGE = ADC1_PAGE; // Переключение на страницу ADC1
ADC1CN = 0xC4; //запись значения b11000100, бит 7: 1 -включение ADC1,
//бит 6: 1 - режим слежения определяется битами 3-2
//бит 3-2: 01 - слежение(выборка) начинается при переполнении таймера 3
REF1CN = 0x03; // запись значения b00000011, включение генератора напряжения смещения ADC1 и
//включение внутреннего буферного усилителя
for(i=0;i<10000;i++); // задержка для стабилизации генератора опорного напряжения
ADC1CF = 0x00; // установка в качестве периода сигнала дискретизации ADC1 Tconv = 21*Tsysclk
}
SFRPAGE = old_SFRPAGE; // восстановление SFRPAGE
}
//-----------------------------------------------------------------------------
// инициализация DMA0
//-----------------------------------------------------------------------------
// Настройка DMA0 в режим 1 и выбор ADC для извлечения данных
void DMA0_Init()
{
char old_SFRPAGE = SFRPAGE;
SFRPAGE=DMA0_PAGE; // Переключение на страницу DMA0
DMA0CN = 0x00; // отключаем DMA0
DMA0DA = XRAM_START_ADD; //запись 16-разрядной переменной, установка начального адреса данных
DMA0CT = NUM_SAMPLES; // запись значения переменной количества выборок в регистр счетчика повторений
DMA0IPT = 0x00; // запись начального адреса команд в регистр адреса команд
// Помещение инструкций в стек с последующим выполнением
if (ADC_Mode == 's')
DMA0IDT = DMA0_GET_ADC0; // получение данных от ADC0
else DMA0IDT = DMA0_GET_DIFF; // получение данных в дифф. режиме от [ADC0 - ADC1]
DMA0IDT = DMA0_END_OF_OP; // конец операций
DMA0BND = 0x00; // запись адреса, с которого начинается выполнение команд, в регистр границы команд
DMA0CN = 0x20; // запись значения b00100000, включение DMA в первом режиме
SFRPAGE=old_SFRPAGE; // восстановление SFRPAGE
}
//------------------------------------------------------------------------------------
// инициализация Timer3
//------------------------------------------------------------------------------------
// Настройка Timer3 в режим автоперезагрузки и генерирования частоты дискретизации ADC
// указанные <counts>, используя SYSCLK/12 в качестве базового времени.
void Timer3_Init (unsigned int counts)
{
char old_SFRPAGE = SFRPAGE;
SFRPAGE = TMR3_PAGE; // Переключение на страницу Timer 3
TMR3CN = 0x00; // отключение таймера 3
TMR3CF |= 0xC0; // учтановка частоты счетчика SYSCLK / 12
RCAP3 = (0xFFFF-counts); // инициализация значений перезагрузки, counts - значение частоты дискретизации
TMR3 = 0xFFFF; // переполнение таймера
TR3 = 1; // запуск Timer3
SFRPAGE = old_SFRPAGE; // восстановление SFRPAGE
}
//-----------------------------------------------------------------------------
// Отправка данных
//-----------------------------------------------------------------------------
// Отправка данных на ПК (фактически на UART)
void Send_Byte (unsigned char Byte)
{
char old_SFRPAGE = SFRPAGE;
SFRPAGE = UART0_PAGE; // Переключение на страницу UART0
TI0=0; // сброс флага прерывания, разрешение передачи информации
SBUF0=Byte; // запись байта в буфер SBUF0
while(!TI0); // ожидание, пока не закончится передача
SFRPAGE = old_SFRPAGE; // восстановление SFRPAGE
}
//-----------------------------------------------------------------------------
// Прием данных
//-----------------------------------------------------------------------------
// Прием байта от ПК (фактически от UART0)
unsigned char Receive_Byte (void)
{
char old_SFRPAGE = SFRPAGE;
unsigned char rb;
SFRPAGE = UART0_PAGE; // Переключение на страницу UART0
RI0=0; // сброс флага прерывания, разрешение получения информации
REN0=1; // установка флага активного приема
while(!RI0); // ожидание, пока не закончится прием
rb = (unsigned char)SBUF0; // запись байта из буфера SBUF0
REN0=0; // сброс флага активного приема
SFRPAGE = old_SFRPAGE; // восстановление SFRPAGE
return rb;
}
//-----------------------------------------------------------------------------
// Отправка результатов ADC преобразования
//-----------------------------------------------------------------------------
//Отправка всех результатов на ПК
void Send_Data_to_PC (void)
{
unsigned int i;
read_ptr = XRAM_START_ADD; //получение адреса начала данных
Send_Byte('r'); //уведомление ПК о готовностии отправки данных оцифрования
while(Receive_Byte()!= 'a';) //ожидание уведомления со стороны ПК о готовности приема данных
for (i=0; i < 2*NUM_SAMPLES; i++)
{
Send_Byte(*read_ptr); //отправка данных
read_ptr++;
}
}
//-----------------------------------------------------------------------------
// Настройка МК
//-----------------------------------------------------------------------------
void MC_Config (void)
{
EA = 0; // запрет всех прерываний
WDTCN = 0xde; //отключение WDT
WDTCN = 0xad; //между записью этих значений должно пройти не более 4х тактовых циклов,
//иначе операция отключения игнорируется
SYSCLK_Init (); // инициализация генератора
Port_Init(); // конфигурирование портов ввода/вывода
UART0_Init (); // инициализация UART0
EA = 1; // разрешение всех прерываний
}
//------------------------------------------------------------------------------------
// MAIN Routine
//------------------------------------------------------------------------------------
void main(void)
{
unsigned char a,b;
char old_SFRPAGE = SFRPAGE;
int i;
MC_Config(); //Настройка МК
//main loop
while (1)
{
P1_6 = 0;
// соединение с ПК
while (Receive_Byte() != 'c'); //ожидание уведомления со стороны ПК о соединении
Send_Byte('p'); //отправка уведомления ПК о соединении
P1_6=1;
ADC_Mode = Receive_Byte(); // получение настроек ADC
a = Receive_Byte(); // получение старшего байта NUM_SAMPLES
b = Receive_Byte(); // получение младшего байта NUM_SAMPLES
NUM_SAMPLES = a*256 + b; // NUM_SAMPLES
a = Receive_Byte(); // получение старшего байта SAMP_RATE
b = Receive_Byte(); // получение младшего байта SAMP_RATE
SAMP_RATE = a*256 + b; // SAMP_RATE
ADC_Init(); // настройка ADC
Timer3_Init (SYSCLK/SAMP_RATE); // настройка таймера 3
DMA0_Init(); // настройка DMA для получения NUM_SAMP выборок
SFRPAGE=DMA0_PAGE; // Переключение на страницу DMA0
DMA0CN = 0x80; // запуск DMA0
DMA0CF &= 0x4E; // сброс DMA0HLT, установка DMA0BSY, разрешение прерывания Repeat Counter Overflow.
// повторение счетчика прерываний произошло,разрешение прерывания End-Of-Operation.
// end-Of-Operation не была получена.
while(!(DMA0CF & 0x01)); // ожидание, пока DMA получит команду End of Operations
while(DMA0CF & 0x40); // ожидание, пока DMA остановит работа с XRAM
DMA0CF |= 0x80; // разрешение доступа главного процесса к XRAM
Send_Data_to_PC(); // отправка результатов
}
}