| Ваш IP: 3.230.119.106 | Online(9) - гости: 5, боты: 4 | Загрузка сервера: 1.44 ::::::::::::


8-и канальный логический анализатор STM32 (Arduino IDE)

Логический анализатор выполнен на основе микроконтроллера STM32F103C8T6 (отладочная плата), вся информация выводится на TFT-дисплей SPI 320×240 (ILI9341C). Максимальное напряжение подаваемое на входы порта PB8-PB15 STM32F103C8T6 не должно превышать 5 В.

Логический анализатор позволяет отслеживать логическое состояние по 8-и каналом одновременно, а так же измерять временные параметры импульсов. Частотный диапазон от единиц герц до 400 кГц. Память на 3200 точек измерения (10 разверток экрана).

Анализатор имеет три режима работы:

  • AUTO — автоматический режим синхронизации по кану № 0 (PB8)
  • START_1 — режим ожидания, при появлении на входе № 0 лог. 1, анализатор производит один цикл измерения.
  • START_0 — режим ожидания, при появлении на входе № 0 лог. 0, анализатор производит один цикл измерения.

Управление логическим анализатором осуществляется 5-ю кнопками:

  • HOLD — остановка измерения, вывод на экран текущей информации, перезапуск измерения в режиме START_1 и START_0.
  • SET — переключение режимов AUTO, START_1, START_0.
  • UP и DOWN :
    • выбор длительности развертки в режиме AUTO
    • перемещение изображения импульсов в режиме HOLD по горизонтали
  • SET_CURSOR — обнуление показаний измерителя временных интервалов.

Измерительный курсор (красная полоса) позволяющий оценивать логическое состояние одновременно по 8-и каналам (вывод на экран лог. состояния в двоичной и шестнадцатеричной системы счисления), курсор активен в режимах AUTO, START_1 и START_0, перемещение импульсов по горизонтали осуществляется кнопками UP и DOWN. Так при нажатии кнопки SET_CURSOR происходит обнуление показаний измерителя временных интервалов.

Сигналы шины I2C 100 кГц

Сигналы шины I2C 100 кГц при минимальной длительности развертки

Сигнал управления RGB (W2812) ленты 800 кГц

Сигналы шины I2C 400 кГц при минимальной длительности развертки

 

STM32 + TFT-дисплей SPI 320×240 (ILI9341C)

STM32 Arduino IDE

 

#include <SPI.h>
#include <Adafruit_GFX_AS.h>   // https://rcl-radio.ru/wp-content/uploads/2020/06/Adafruit_GFX.zip
#include <Adafruit_ILI9341_STM.h>
#include <EEPROM.h>
 
 
#define TFT_CS         PA0                 
#define TFT_DC         PA1            
#define TFT_RST        PA2
// MOSI                PA7
// SCK                 PA5
Adafruit_ILI9341_STM tft = Adafruit_ILI9341_STM(TFT_CS, TFT_DC, TFT_RST); 
 
byte data[3200],data_old[3200];
bool stopp=0;
unsigned long times;
int i,i2,i3,razv,delays,hh;
byte w=1,w1,st,x,z,mn=8,sett;
 
void setup() {
 Serial.begin(9600);
 EEPROM.init(0x801F000,0x801F800,0x400);// 1024 byte 
 pinMode(PA3,INPUT_PULLUP);// HOLD 
 pinMode(PB0,INPUT_PULLUP);// +++
 pinMode(PB1,INPUT_PULLUP);// --- 
 pinMode(PA4,INPUT_PULLUP);// SET 
 pinMode(PB4,INPUT_PULLUP);// SET_CURSOR 
 tft.begin();tft.setRotation(1);tft.fillScreen(ILI9341_BLACK);
 polos();
 tft.setCursor(180, 5);tft.print("LOGIC ANALYZER");
 tft.setCursor(180, 20);tft.print("RCL-RADIO.RU");
 GPIOB-> regs-> CRH = 0x88888888; // INPUT PB8...PB15
 razv = EEPROM.read(0);
 
}
 
void loop() {
  ////////// SET 
 if(digitalRead(PA4)==LOW){sett++;w=1;w1=1;stopp=0;if(sett>2){sett=0;}delay(200);tft.fillRect(50,0,65,8,ILI9341_BLACK);polos();cif();tft.fillRect(50,10,80,25,ILI9341_BLACK);} 
 
   //////////////////// HOLD ON OFF ///////////////////////////////////////////
 if(digitalRead(PA3)==LOW&&stopp==0){stopp=1;w1=1;polos();cif();tft.fillRect(50,10,80,25,ILI9341_BLACK);delay(300);i2=0;}  
 if(digitalRead(PA3)==LOW&&stopp==1){stopp=0;w1=1;polos();cif();tft.fillRect(50,10,80,25,ILI9341_BLACK);delay(300);i2=0;}
 
 if(digitalRead(PB0)==LOW&&stopp==1){i2++;w1=1;if(i2>2880){i2=2880;}delay(1);}
 if(digitalRead(PB1)==LOW&&stopp==1){i2--;w1=1;if(i2<0){i2=0;}delay(1);}
 
 if(digitalRead(PB4)==LOW){i3=i2;w1=1;delay(200);}
  if(stopp==1&&w1==1){
  tft.fillRect(0,10,60,8,ILI9341_BLACK);tft.setCursor(0, 10);
  //if(digitalRead(PB4)==LOW){i3=i2;delay(200);}
  if(((float)times/10/mn/320*mn)*(i2-i3)>1000){tft.print(((float)times/10000/mn/320*mn)*(i2-i3),1);tft.print(" mS  ");}
  else{tft.print(((float)times/10/mn/320*mn)*(i2-i3),1);tft.print(" uS  ");}
  }
  if(stopp==0){tft.fillRect(0,10,65,8,ILI9341_BLACK);}
 
 
 if(stopp==1){tft.fillRect(i2/10,235,4,3,ILI9341_BLACK);tft.fillRect(i2/10+2,235,30,3,ILI9341_GREEN);tft.fillRect(i2/10+32,235,4,3,ILI9341_BLACK);}
 if(stopp==0&&w1==1){tft.fillRect(0,235,320,3,ILI9341_BLACK);}
 tft.setCursor(0, 25);
 if(stopp==0){tft.fillRect(295,0,25,8,ILI9341_BLACK);tft.fillRect(0,25,65,8,ILI9341_BLACK);}else{tft.print("HOLD");}
 
 ///// SET = 0 //////////////////////////////////////////////////////////////
 if(digitalRead(PB0)==LOW&&stopp==0){razv++;w=1;if(razv>12){razv=12;}EEPROM.update(0,razv);delay(300);}
 if(digitalRead(PB1)==LOW&&stopp==0){razv--;w=1;if(razv<0){razv=0;}EEPROM.update(0,razv);delay(300);}
 
 switch(razv){
   case 0: mn=1;delays=500;break;
   case 1: mn=1;delays=200;break;
   case 2: mn=1;delays=100;break;
   case 3: mn=1;delays=50;break;
   case 4: mn=1;delays=25;break;
   case 5: mn=1;delays=12;break;
   case 6: mn=1;delays=5;break;
   case 7: mn=1;delays=2;break;
   case 8: mn=1;delays=1;break;
   case 9: mn=1;delays=0;break;
  case 10: mn=2;delays=0;break;
  case 11: mn=4;delays=0;break;
  case 12: mn=8;delays=0;break;
  }
   sinhr();
 
 
///////////// измерение //////////////////////////
  if(stopp==0&&delays>0){
  times=micros();
  i=0;while(i<3200){i++;delay_us(delays);data[i] = (GPIOB-> regs-> IDR & 0b1111111100000000) >> 8;}
  times=micros()-times;}
 
  if(stopp==0&&delays==0){
  times=micros();
  i=0;while(i<3200){i++;data[i] = (GPIOB-> regs-> IDR & 0b1111111100000000) >> 8;}
  times=micros()-times;}
  if(sett>0){stopp=1;}
////////////// end ////////////////////////////////
 
 
  if(w==1){w=0;polos();
  tft.fillRect(0,0,65,8,ILI9341_BLACK);tft.setCursor(0, 0);
  if(times/10/mn>1000){tft.print((float)times/10/mn/1000,2);tft.print(" mS  ");}
  else{tft.print((float)times/10/mn,1);tft.print(" uS  ");}
 
  cif();
 
  tft.setCursor(65, 0);
  if(sett==0){tft.print("AUTO   ");}
  if(sett==1){tft.print("START_1");}
  if(sett==2){tft.print("START_0");}
  }
 
 
 i=10/mn;while(i<320){i++;
 for(x=0;x<mn;x++){if(x==0){z=1;}else{z=0;}
 tft.drawLine(i*mn-x, 55-((data_old[i]>>0)&1)*15,i*mn-x, 55-((data_old[i+z]>>0)&1)*15, 0x000F);
 tft.drawLine(i*mn-x, 55-((data[i+i2]>>0)&1)*15,i*mn-x, 55-((data[i+z+i2]>>0)&1)*15,  ILI9341_WHITE);}}
 
 i=10/mn;while(i<320){i++;
 for(x=0;x<mn;x++){if(x==0){z=1;}else{z=0;}
 tft.drawLine(i*mn-x, 80-((data_old[i]>>1)&1)*15,i*mn-x, 80-((data_old[i+z]>>1)&1)*15, 0x000A);
 tft.drawLine(i*mn-x, 80-((data[i+i2]>>1)&1)*15,i*mn-x, 80-((data[i+z+i2]>>1)&1)*15,  ILI9341_WHITE);}}
 
 i=10/mn;while(i<320){i++;
 for(x=0;x<mn;x++){if(x==0){z=1;}else{z=0;}
 tft.drawLine(i*mn-x, 105-((data_old[i]>>2)&1)*15,i*mn-x, 105-((data_old[i+z]>>2)&1)*15, 0x000F);
 tft.drawLine(i*mn-x, 105-((data[i+i2]>>2)&1)*15,i*mn-x, 105-((data[i+z+i2]>>2)&1)*15,  ILI9341_WHITE);}} 
 
 i=10/mn;while(i<320){i++;
 for(x=0;x<mn;x++){if(x==0){z=1;}else{z=0;}
 tft.drawLine(i*mn-x, 130-((data_old[i]>>3)&1)*15,i*mn-x, 130-((data_old[i+z]>>3)&1)*15, 0x000A);
 tft.drawLine(i*mn-x, 130-((data[i+i2]>>3)&1)*15,i*mn-x, 130-((data[i+z+i2]>>3)&1)*15,  ILI9341_WHITE);}} 
 
 i=10/mn;while(i<320){i++;
 for(x=0;x<mn;x++){if(x==0){z=1;}else{z=0;}
 tft.drawLine(i*mn-x, 155-((data_old[i]>>4)&1)*15,i*mn-x, 155-((data_old[i+z]>>4)&1)*15, 0x000F);
 tft.drawLine(i*mn-x, 155-((data[i+i2]>>4)&1)*15,i*mn-x, 155-((data[i+z+i2]>>4)&1)*15,  ILI9341_WHITE);}}  
 
 i=10/mn;while(i<320){i++;
 for(x=0;x<mn;x++){if(x==0){z=1;}else{z=0;}
 tft.drawLine(i*mn-x, 180-((data_old[i]>>5)&1)*15,i*mn-x, 180-((data_old[i+z]>>5)&1)*15, 0x000A);
 tft.drawLine(i*mn-x, 180-((data[i+i2]>>5)&1)*15,i*mn-x, 180-((data[i+z+i2]>>5)&1)*15,  ILI9341_WHITE);}} 
 
 i=10/mn;while(i<320){i++;
 for(x=0;x<mn;x++){if(x==0){z=1;}else{z=0;}
 tft.drawLine(i*mn-x, 205-((data_old[i]>>6)&1)*15,i*mn-x, 205-((data_old[i+z]>>6)&1)*15, 0x000F);
 tft.drawLine(i*mn-x, 205-((data[i+i2]>>6)&1)*15,i*mn-x, 205-((data[i+z+i2]>>6)&1)*15,  ILI9341_WHITE);}} 
 
 i=10/mn;while(i<320){i++;
 for(x=0;x<mn;x++){if(x==0){z=1;}else{z=0;}
 tft.drawLine(i*mn-x, 230-((data_old[i]>>7)&1)*15,i*mn-x, 230-((data_old[i+z]>>7)&1)*15, 0x000A);
 tft.drawLine(i*mn-x, 230-((data[i+i2]>>7)&1)*15,i*mn-x, 230-((data[i+z+i2]>>7)&1)*15,  ILI9341_WHITE);}} 
 
i=0;while(i<3199){i++;data_old[i]=data[i+i2];}
 
 
  if(stopp==1&&w1==1){w1=0;
  tft.fillRect(50,10,75,25,ILI9341_BLACK);
  if(mn<=2){tft.setCursor(65, 10);tft.print("0B");tft.print(data[i2+60/mn],BIN);}
  if(mn>2){tft.setCursor(65, 10);tft.print("0B");tft.print(data[i2+60/mn+1],BIN);}
  if(mn<=2){tft.setCursor(65, 25);tft.print("0X");tft.print(data[i2+60/mn],HEX);}
  if(mn>2){tft.setCursor(65, 25);tft.print("0X");tft.print(data[i2+60/mn+1],HEX);}
  tft.drawLine(60, 10,60, 230,  ILI9341_RED);
  tft.drawLine(60, 20,125, 20,  ILI9341_RED);
  }
  }
 
void polos(){
 tft.fillRect(0,210,320,25,0x000A);
 tft.fillRect(0,185,320,25,0x000F);
 tft.fillRect(0,160,320,25,0x000A);
 tft.fillRect(0,135,320,25,0x000F);
 tft.fillRect(0,110,320,25,0x000A);
 tft.fillRect(0,85,320,25,0x000F);
 tft.fillRect(0,60,320,25,0x000A);
 tft.fillRect(0,35,320,25,0x000F);
  }  
 
void sinhr(){
  if(sett==0){
  while(((GPIOB-> regs-> IDR & 0b0000000100000000) >> 8)==1){hh++;delay_us(1);if(hh>1000){hh=0;break;}}
  while(((GPIOB-> regs-> IDR & 0b0000000100000000) >> 8)==0){hh++;delay_us(1);if(hh>1000){hh=0;break;}}
  while(((GPIOB-> regs-> IDR & 0b0000000100000000) >> 8)==1){hh++;delay_us(1);if(hh>1000){hh=0;break;}}
  }
  if(sett==1){
  while(((GPIOB-> regs-> IDR & 0b0000000100000000) >> 8)==0){zap();}}
  if(sett==2){
  while(((GPIOB-> regs-> IDR & 0b0000000100000000) >> 8)==1){zap();}}
  }
 
void cif(){ for(byte cc=0;cc<8;cc++){tft.setCursor(0, 45+cc*25);tft.print(cc);}}
 
void zap(){
if(digitalRead(PA4)==LOW){sett++;w=1;w1=1;stopp=0;if(sett>2){sett=0;}delay(200);tft.fillRect(50,0,65,8,ILI9341_BLACK);polos();cif();tft.fillRect(50,10,80,25,ILI9341_BLACK);}  
if(digitalRead(PA3)==LOW&&stopp==1){stopp=0;w1=1;polos();cif();tft.fillRect(50,10,80,25,ILI9341_BLACK);delay(300);i2=0;}
  tft.setCursor(65, 0);
  if(sett==0){tft.print("AUTO   ");}
  if(sett==1){tft.print("START_1");}
  if(sett==2){tft.print("START_0");}
  }

Добавить комментарий

Войти с помощью: 

Случайные статьи

  • Простое зарядное уст-во с регулируемым током зарядки

    Простое зарядное уст-во с регулируемым током зарядки

    На рисунке показана схема простого зарядного уст-ва автомобильных аккумуляторов с регулируемым током зарядки. Зарядное уст-во основано на стабилизаторе L200 регулятора. Основные параметры стабилизатора L200CV: Максимальное входное напряжение 40В Максимальная разница напряжений «вход-выход» 32В Выходное напряжение 2,8..36В Выходной ток до 2А Минимальное падение напряжения «вход-выход» (dropout) <2,5В Ток потребления (по выводу …Подробнее...
  • УНЧ на TDA1558Q

    УНЧ на TDA1558Q

    Напряжение питания 6…18В Максимальный ток нагрузки 4А Выходная мощность при Uп=14,4В и Rн=4Ом: КНИ=0,5% — 5Вт КНИ=10% — 6Вт Ток покоя 80мАПодробнее...
  • Недорогой узкополосный FM-приемник на 68…88МГц

    На рисунке показана схема простого приемника FM-диапазона, настройка на станцию осуществляется потенциометром Р2. Полевой транзистор Т1 обеспечивает усиление входного радиосигнала на 18дБ, запитывая входную цепь TDA7000 через разделительный конденсатор С5. Ряд конденсаторов вокруг микросхемы предназначен для формирования полосы пропускания около 70 кГц. Перестраиваемый генератор строится на базе варикапа D1. Напряжение …Подробнее...
  • Полицейская сирена на LM324

    Полицейская сирена на LM324

    Данная схема издает звук напоминающий полицейскую сирену. Схема основана на ОУ LM324 представляющий собой генератор ЗЧ. При нажатии на кнопку SA1 начнет быстро заряжаться С1, сирена начнет издавать звук. При размыкании контактов SA1  сирена будет работать до тех пор пока не разрядится через R2 конденсатор С1. Источник — http://www.eleccircuit.com/police-bicycle-siren-circuits/Подробнее...
  • Простой тестер проверки радиоэлементов

    При регулировке и настройке электронной аппаратуры применяют вспомогательные устройства: индикаторы состояний, «прозвоночные” приборы и тестеры, с помощью которых выполняют различные операции: от простейшей – по проверке целостности цепей до сложной – по измерению параметров радиоэлементов. Сложные тестеры необходимы, когда выполнена проверка работоспособности радиоэлемента и необходимо уточнить значения его параметров. Оценку …Подробнее...