Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Пояснительная_записка.doc
Скачиваний:
2
Добавлен:
01.03.2025
Размер:
5.24 Mб
Скачать
  1. Список используемых источников информации

  1. http://www.megachip.ru/images/templates/big/8051F064EK.jpg

  2. Описание МК C8051F064, https://www.silabs.com/Support%20Documents/TechnicalDocs/C8051F064-EK.pdf

  3. Описание семейства МК C8051F06x (перевод), http://www.efo.ru/doc/Silabs/pdf/C8051F06x.pdf

  4. «Новый UART-USB мост CP2102 от фирмы Silicon Laboratories», О.Николайчук, http://www.silabs.ru/pubs/Stat_096.pdf,

  5. «Сетевой комбинированный прибор Осицген», http://npo-rtc.ru/product/oscigen/why.html

  6. Описание Осцигена, http://www.npo-rtc.ru/product/oscigen/

  7. Программное обеспечение для МК фирмы Silicon Laboratories, http://www.efo.ru/doc/Silabs/Silabs.pl?2083#link1

  8. Keil uVision3 - среда разработки ПО для микроконтроллеровсерии х51 на языке С / Asembler, http://binural.ru/soft/print:page,1,1147836023-keil-uvision-3-sreda-razrabotki-po-dlja.html

  9. Библиотека WindowsAPI 32, http://www.microsoft.com/Rus/Msdn/Activ/MSVB/Archive/WindowsAPI/API-DLL-1.mspx

  10. Программное обеспечение OGView, http://www.npo-rtc.ru/product/oscigen/program.html

  11. SiLabs: использование USB, http://www.efo.ru/doc/Silabs/Silabs.pl?2150

  12. Описание платы C8051F064EK, https://www.silabs.com/Support%20Documents/TechnicalDocs/C8051F064-EK.pdf,

  1. Приложения

    1. Исходные тексты модулей программы для мк

#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(); // отправка результатов

}

}