
- •Министерство образования и науки Российской Федерации санкт-петербургский государственный электротехнический университет "лэти" имени в.И. Ульянова (ленина)
- •197376, Санкт-Петербург, ул. Проф. Попова, 5.
- •1 Задание на курсовой проект
- •2 Уточнение задания
- •3 Программная модель устройства
- •3.1 Регистр csr(base)
- •4 Выбор элементной базы
- •4.1 Аналого-цифровой преобразователь
- •4.2 Коммутатор каналов
- •4.3 Инструментальный усилитель
- •4.4 Источник опорного напряжения
- •4.5 Стабилизатор напряжения
- •4.6 Элемент гальванической развязки
- •4.7 Dc/dc преобразователь
- •4.8 Кварцевый генератор
- •4.9 Микросхема fifo
- •4.10 Микросхема программируемой логики
- •5. Описание схемы сопряжения с интерфейсом на языке ahdl
- •5 Пример программы для работы с устройством
- •6 Электрическая схема
- •Заключение
4.8 Кварцевый генератор
Кварцевый генератор необходим для создания основного тактирующего сигнала для всего устройства. В нашем устройстве будем использовать микросхему HOSONICHD-21C
Основные параметры:
Резонансная частота: 10 Мгц
Точность настройки: 100
Напряжение питания: 5В
Выход: HCMOS/TTL
Ток нагрузки: 20мА
Рабочая температура: 0-70 C
4.9 Микросхема fifo
Микросхема FIFOв данном устройстве используется для временного хранения данных, поступающих от АЦП (через ПЛИС) с целью их последующей передачи на интерфейсISA.
Остановим
свой выбор на микросхеме асинхронного
буфераFIFOCY7C419
фирмыCypress.
Основные параметры:
Организация: 256x9
Тип памяти: двухпортовая
Частота чтения/записи: 50 МГц
Ток потребления: 35 мА
Напряжение питания: 5В
Наличие признаков:
Буфер пуст
Буфер полон
Возможность перевода выходов FIFOв третье состояние
Так как данная фирма обладает широким
ассортиментом совместимых между собой микросхем, то при необходимости не возникнет проблем с увеличение объёма буфера FIFO.
В качестве аналога данного устройства можно привести
микросхему SN74ACT7814 фирмыTexasInstrumentsс организацией 64х18 и хотя данная микросхема более удобна для нас с точки зрения организации, но она имеет недостаток, а именно 56-ти выводной корпус, против 26-ти выводного у микросхемыCypress.
Необходимо также отметить, что для реализации поставленной задачи нам потребуется использовать две микросхемы CY7C419, чтобы обеспечить требуемую длину слова данных.
4.10 Микросхема программируемой логики
Задачей микросхемы программируемой логики (ПЛИС) является обеспечение интерфейса между измерительной частью разрабатываемого устройства и магистралью ISA.
Для описания поведения регистровой модели я использовал САПР Max+plus2 фирмыAlteraи язык описания дискретных устройствAHDL.
В результате синтеза, САПР предложил использовать микросхему EPM7128SQC160.
4.11 Мультиплексор
Мультиплексор используется для переключения значений с выходов инструментальных усилителей и последующей передачи на вход АЦП. Главным условием для выбора мультиплексора является его выходное сопротивление, которое не должно превышать входное сопротивление АЦП. Исходя из этого условия я выбрал микросхему CD74AC153, выходное сопротивление которой – 230 Ом.
5. Описание схемы сопряжения с интерфейсом на языке ahdl
CONSTANTid=B"1000000";
subdesignreg_mod
(
clk_extinput;
start_ext : input;
base_addr[9..0] : input;
iord : input;
iowr : input;
aen : input;
isa_addr[9..0] : input;
fifo_in_data[11..0] : input;
fifo_is_not_empty[1..0] : input;
fifo_is_not_full[1..0] : input;
dack : input;
reset_device : input;
t_c : input;
busy : input;
adc_sdata : input;
-----------------------------------------------------------------------
isa_io_data[15..0] : bidir;
-----------------------------------------------------------------------
fifo_out_data[15..0] : output;
fifo_rd : output;
fifo_wr : output;
fifo_reset : output;
drq : output;
irq : output;
start_adc : output;
clk_adc : output;
number_channel[2..0] : output;
range_voltage[1..0] : output;
cs16 : output;
)
variable
is_addr_csr : node;
is_addr_dr : node;
isa_out_csr_node[15..0] : node
isa_out_dr_node[15..0] : node;
isa_in_csr_node[15..0] : node;
isa_in_dr_node[15..0] : node;
fifo_overflow : node;
pdp_overflow : node;
err_start : node;
data_ready : node;
en_timer_start : node;
timer_start : node;
en_prog_start : node;
en_external_start : node;
channel_namber[2..0] : node;
commutator_mode : node;
en_irq_data_ready : node;
en_irq_overflow : node;
en_pdp : node;
reset_channel_count : node;
start_adc_signal : node;
reset_err_start_overflow_pdp : node;
reset_fifo_signal : node;
timer_clk : node;
csr_wr : node;
dr_wr : node;
csr_rd : node;
dr_rd : node;
id_cod[6..0] : node;
count_channel[2..0] : dff;
count_read_data_adc[3..0] : dff;
count_read_data_overflow : node;
shift_reg[15..0] : dffe;
timer[15..0] : dffe;
isa_out_csr_reg[15..0] : dff;
isa_out_dr_reg[15..0] : dff;
isa_in_csr_reg[15..0] : dff;
isa_in_dr_reg[15..0] : dff;
isa_io_data_tri[15..0] : tri;
cs16_tri : tri;
begin
csr_wr = !iowr&!aen&is_addr_csr;
dr_wr = !iowr&!aen&is_addr_dr;
csr_rd = !iord&!aen&is_addr_csr;
dr_rd = !iord&!aen&is_addr_dr;
if base_addr[] == isa_addr[] then is_addr_csr = VCC;
else is_addr_csr = GND;
end if;
if base_addr[] == (isa_addr[]+2) then is_addr_dr = VCC;
else is_addr_dr = GND;
end if;
isa_io_data[] = isa_io_data_tri[].out;
if is_addr_csr == VCC then
isa_io_data_tri[].in = isa_out_csr_node[];
isa_in_csr_node[] = isa_io_data[];
elsif is_addr_dr == VCC then
isa_io_data_tri[].in = isa_out_dr_node[];
isa_in_dr_node[] = isa_io_data[];
end if;
isa_io_data_tri[].oe = is_addr_csr#is_addr_csr;
cs16_tri.in = (is_addr_csr&!aen)#(is_addr_dr&!aen);
cs16_tri.oe = is_addr_csr#is_addr_dr;
cs16 = cs16_tri.out;
if reset_device then
isa_in_dr_reg[].d = 0;
isa_in_dr_reg[].clk = dr_wr;
else
isa_in_dr_reg[].d = isa_in_dr_node[];
isa_in_dr_reg[].clk = dr_wr;
end if;
if reset_device then
isa_in_csr_reg[].d = 0;
isa_in_csr_reg[].clk = 1;
else
isa_in_csr_reg[].d = isa_in_csr_node[];
isa_in_csr_reg[].clk = csr_wr;
end if;
en_prog_start = isa_in_csr_reg0.q;
en_timer_start = isa_in_csr_reg1.q;
en_external_start = isa_in_csr_reg2.q;
channel_namber[] = (isa_in_csr_reg5.q,isa_in_csr_reg4.q,isa_in_csr_reg3.q);
range_voltage[] = (isa_in_csr_reg10.q,isa_in_csr_reg11.q,);
commutator_mode = isa_in_csr_reg6.q;
reset_channel_count = isa_in_csr_reg7.q;
en_irq_data_ready = isa_in_csr_reg8.q;
en_irq_overflow = isa_in_csr_reg9.q;
en_pdp = isa_in_csr_reg13.q;
reset_fifo_signal = isa_in_csr_reg14.q;
reset_err_start_overflow_pdp = isa_in_csr_reg15.q;
if (commutator_mode == 1)&(en_pdp == 1) then
number_channel[] = count_channel[].q;
if reset_channel_count then
count_channel[].d = 0;
count_channel[].clk = iowr;
elsif count_channel[].q == channel_namber[]then
count_channel[].d = 0;
count_channel[].clk = busy;
else
count_channel[].d = count_channel[].q + 1;
count_channel[].clk = busy;
end if;
else
number_channel[] = channel_namber[];
end if;
start_adc_signal = !((en_prog_start & !iowr & !aen & is_addr_csr) #
(en_timer_start & timer_start)#(en_external_start & start_ext));
start_adc = start_adc_signal;
drq = (fifo_is_not_empty0 & fifo_is_not_empty1) & dack & en_pdp;
if((fifo_is_not_empty0 & fifo_is_not_empty1 & en_irq_data_ready)#
(((!fifo_is_not_full0 & !fifo_is_not_full1) # t_c) & en_irq_overflow))then
irq = GND;
elsif csr_wr == 1 & reset_err_start_overflow_pdp then
irq = VCC;
else
irq = VCC;
end if;
fifo_overflow = !fifo_is_not_full0 & !fifo_is_not_full1;
data_ready = fifo_is_not_empty0 & fifo_is_not_empty1;
if (busy == 1) & (!start_adc_signal) then
err_start = VCC;
elsif reset_err_start_overflow_pdp & csr_wr == 1 then
err_start = GND;
end if;
if csr_wr == 1 & reset_err_start_overflow_pdp then
pdp_overflow = GND;
elsif t_c ==1 then
pdp_overflow = VCC;
end if;
isa_out_dr_node[] = isa_out_dr_reg[].q;
if fifo_is_not_empty0&fifo_is_not_empty1 then
isa_out_dr_reg[].d =(0,0,0,0,fifo_in_data[]);
isa_out_dr_reg[].clk = dr_rd;
fifo_rd = !dr_rd;
else
isa_out_dr_reg[].d = (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
isa_out_dr_reg[].clk = dr_rd;
end if;
isa_out_dr_node[] = isa_out_dr_reg[].q;
id_cod[]= id;
isa_out_csr_node[] = isa_out_csr_reg[].q;
isa_out_csr_reg[].d = (pdp_overflow,fifo_overflow,0,err_start,0,0,0,0,id_cod[],data_ready);
isa_out_csr_reg[].clk = csr_rd;
fifo_reset = !(reset_fifo_signal & csr_wr);
if !busy & (count_read_data_adc[].q < 15) then
count_read_data_adc[].d = count_read_data_adc[].q + 1;
elsif !start_adc_signal & busy then
count_read_data_adc[].d = 0;
end if;
count_read_data_adc[].clk = clk_ext;
if !busy & count_read_data_adc[].q < 15 then
shift_reg0.d = adc_sdata;
shift_reg[].ena = VCC;
elsif !busy & count_read_data_adc[].q == 15 then
shift_reg0.d = VCC;
shift_reg[].ena = GND;
elsif !start_adc_signal & busy then
shift_reg[].d = 0;
end if;
shift_reg1.d = shift_reg0.q;
shift_reg2.d = shift_reg1.q;
shift_reg3.d = shift_reg2.q;
shift_reg4.d = shift_reg3.q;
shift_reg5.d = shift_reg4.q;
shift_reg6.d = shift_reg5.q;
shift_reg7.d = shift_reg6.q;
shift_reg8.d = shift_reg7.q;
shift_reg9.d = shift_reg8.q;
shift_reg10.d = shift_reg9.q;
shift_reg11.d = shift_reg10.q;
shift_reg12.d = shift_reg11.q;
shift_reg13.d = shift_reg12.q;
shift_reg14.d = shift_reg13.q;
shift_reg15.d = shift_reg14.q;
shift_reg[].clk = clk_ext;
if count_read_data_adc[].q == 15 then
fifo_wr = GND;
else
fifo_wr = VCC;
end if;
fifo_out_data[] = shift_reg[].q;
timer_clk = clk_ext & en_timer_start;
if en_timer_start then
timer[].d = isa_in_dr_reg[].q;
else
timer[].d = 0;
end if;
if en_timer_start & timer[].q >0 then
timer[].d = timer[].q - 1;
elsif en_timer_start & timer[].q == 0 then
timer_start = VCC;
end if;
timer[].clk = timer_clk;
clk_adc = clk_ext & !busy & (count_read_data_adc[].q < 15);
end;