Jump to content

carlogulliani

Members
  • Content Count

    37
  • Joined

  • Last visited

Community Reputation

0 Обычный

About carlogulliani

  • Rank
    Новенький

Электроника

  • Стаж в электронике
    Менее года

Recent Profile Visitors

1119 profile views
  1. Спасибо за ваш комментарий! Прерывание по переполнению сделал для того, чтобы, когда досчитает то предельного значения (в данном случае до 65535) и обнулится, не получилось так, что при первом вызове значения, условно будут, 60000, а во втором 14000, то есть дельта тогда будет не правильно считаться. CС хотел использовать для подсчета периода сигнала, условно, когда первый раз дрыгнулась нога и флаг 0, включаю таймер, как только прошел период - считаю значения СС. Про остановку таймера, вы правы, незачем.
  2. Добрый день, пытаюсь разобраться с декодированием сигнала ASK/OOK на stm8s003. В OOK главную роль играют период сигнала, так, например, 0 - 400 мкс, 1 - 800 мкс. +- 10%. Поэтому основная для меня проблема считать количество микросекунд между событиями, в ардуино за это отвечает функция micros() Включаю внутреннее тактирование 16МГц, настраиваю таймер TIM1 на частоту 1MHz (1 микросекунда), у таймера стоит прерывание по переполнению, и когда счетчик доходит до предела, я в некую переменную добавляю максимальное значение счетчика, на выводе вижу не те значения, которые ожидаю, также попробовал считать через capture compare, тоже безрезультатно #include "stm8s.h" #include "timer.h" #include "gpio.h" volatile uint32_t tick = 0; //Interruption ISR_TIM1(TIM1_OVF) { tick += 65535; TIM1_SR1 &= ~0x01; // clear all interrupt flags TIM1_SR1 = 0; TIM1_SR2 = 0; TIM1_CR1 = 0; TIM1_CCER1 &= ~0X11; // STOP TIMER //TIM1_SR1 = 0; //PinToggle(PORTD, PIN5); } uint8_t flag = 0; ISR_TIM1_CC(TIM1_CAP_COM) { if (TIM1_SR1 & 0x01) { TIM1_SR1 = 0; TIM1_CR1 = 0; TIM1_CCER1 &= ~0x11; if (TIM1_SR2) { TIM1_SR2 = 0; flag = 1; } else { flag = 0; } } if (TIM1_SR1 & 0x02) { TIM1_SR1 &= ~0x02; } } uint32_t systick() { return (uint32_t)(TIM1_CNTRH << 8) | TIM1_CNTRL; } uint32_t millis() { return tick + (systick() / (F_CPU / 1000)); } uint32_t micros() { return tick + (systick() / (F_CPU / 1000000ul)); } void tim1_init(void) { // 1MHz = 1uS TIM1_PSCRH = 0x00; TIM1_PSCRL = 0x15; TIM1_IER = 0x04 | 0x02 | 0x01; // Enable interrups TIM1_CCMR1 = 1; TIM1_CCMR2 = 2; TIM1_CCER1 = 0x20; TIM1_SMCR = 0x54; } void tim1_start() { TIM1_CNTRH = 0; TIM1_CNTRL = 0; TIM1_CCR2H = 0; TIM1_CCR2L = 0; TIM1_CCER1 |= 0x11; TIM1_CR1 = 0x01; } uint16_t tim1_pulse_len() { return ((uint16_t)(TIM1_CCR2H << 8) | TIM1_CCR2L); } Принимаю сигнал ISR_PORTD(handlerD) { state = PinRead(GD0_PORT, GD0_PIN); uint32_t m = micros(); if (state == HIGH) { lolen = m - prevtime; printf("//"); } else { hilen = m - prevtime; printf("\\"); } prevtime = m; if (state == HIGH) { if (flag == 0) { // the end of packet if (CheckValue(Pe, hilen) && CheckValue(Pe2, lolen)) // valid 1 { printf("OK-PE\r\n"); if (bcounter < 32) code1 = (code1 << 1) | 1; else if (bcounter < 64) code2 = (code2 << 1) | 1; bcounter++; } else if (CheckValue(Pe2, hilen) && CheckValue(Pe, lolen)) // valid 0 { printf("OK-PE2\r\n"); if (bcounter < 32) code1 = (code1 << 1) | 0; else if (bcounter < 64) code2 = (code2 << 1) | 0; bcounter++; } else bcounter = 0; } else { if (bcounter < 32) code1 = (code1 << 1) | 1; else if (bcounter < 64) code2 = (code2 << 1) | 1; bcounter++; } } //printf("bcounter: %d\r\n", bcounter); if (bcounter >= 65) { printf("Got: %x %x\r\n", code1, code2); Pe2 = lolen; Pe = hilen; flag = 1; bcounter = 0; code1 = 0; code2 = 0; } }
  3. Добрый день, собрал в кубе проект для USB HID, ничего лишнего, только инициализация USB, выбор HID и настройка внешнего кварца. Частота 72 для всего устройства и 48 для USB, скорость передачи 12Мбит/с Затем изменил несколько дефайнов и сам дескриптор устройства #define HID_EPIN_SIZE 0x08 #define HID_MOUSE_REPORT_DESC_SIZE 187 ... 0x01, /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/ дескриптор устройства забрал из видео от STMElectronics Там же в видео и описана структура данных для передачи Отправляю один символ R (код 0x15 согласно этому документу) uint8_t USB_TX_BUF[8] = {0}; ... while(1) { USB_TX_BUF[3] = 0x15; USBD_HID_SendReport(&hUsbDeviceFS, USB_TX_BUF, 8); HAL_Delay(100); USB_TX_BUF[3] = 0x00; USBD_HID_SendReport(&hUsbDeviceFS, USB_TX_BUF, 8); HAL_Delay(100); } И ничего не отправляется, хотя lsusb выводит мое устройство, может кто сталкивался с подобным?
  4. Вот решение void SPI1_IRQHandler(void) { if (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE)) { RX_BUF[index] = SPI_I2S_ReceiveData(SPI1); index++; if(index >= RX_LEN) { index = 0; print_buf(32); } } } Спасибо за помощь. Код в первом посте действительно с ошибками, так как из проекта выдирал куски и дописывал уже в дело стенде недостающие объявления, где-то глаз замылился
  5. Проблема решилась. В SPI1_IRQHandler я считывал данные в цикле, надо было писать в буффер, инкрементируя его индекс. Вроде получается, что пришёл один байт, а я в цикле его BUF_LEN раз читаю. Ещё переписал немного обработчик, доберусь до компа, выложу решение
  6. Код работает, до момента приемки данных. А в чем "явные ошибки"??? Что не так с GPIO? На текущий момент есть задача использовать stdperph, причем тут HAL?
  7. в main.c есть бесконечный цикл, где постоянно опрашиваются датчики, управляется светодиодами и тд. И вот когда срабатывает прерывание на приемку SPI, после чтения всех байтов - управление не возвращается и бесконечный цикл не возобновляется (светодиоды не мигают а находятся в последнем состоянии перед прерывание, принт не печатает). Пакет данным у меня 32 байта, при этом в самом прерывании все 32 байта считываются. Если убрать while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET); в ф-ции SPI_RW(), то бесконечный цикл работает, но каждый байт считывается по много раз (иногда слишком много) - то есть проблема либо с этим циклом, либо с приоритетом прерывания у SPI, пробовал ему 7 выставлять - то же самое. Я собрал тестовый стенд с минимум кода, где эта проблема воспроизводится // SPI.c #include "SPI.h" #include "stdio.h" #include "stm32f10x.h" void SPI_Init(void) { GPIO_InitTypeDef GPIO_InitDef; SPI_InitTypeDef SPI_InitDef; // initialize init structs GPIO_StructInit(&GPIO_InitDef); SPI_StructInit(&SPI_InitDef); // initialize clocks RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1 | RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA, ENABLE); // initialize A4/SS alternate function open-drain (50 MHz) GPIO_InitDef.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_6; GPIO_InitDef.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitDef.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitDef); // initialize A5/SCK alternate function open-drain (50 MHz) GPIO_InitDef.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7; GPIO_InitDef.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitDef.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitDef); // initialize SPI slave // for slave, no need to define SPI_BaudRatePrescaler SPI_InitDef.SPI_Direction = SPI_Direction_2Lines_FullDuplex; SPI_InitDef.SPI_Mode = SPI_Mode_Slave; SPI_InitDef.SPI_DataSize = SPI_DataSize_8b; // 8-bit transactions SPI_InitDef.SPI_FirstBit = SPI_FirstBit_MSB; // MSB first SPI_InitDef.SPI_CPOL = SPI_CPOL_Low; // CPOL = 0, clock idle low SPI_InitDef.SPI_CPHA = SPI_CPHA_1Edge; // CPHA = 1 SPI_InitDef.SPI_NSS = SPI_NSS_Soft; // use hardware SS SPI_InitDef.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64; // APB2 72/64 = 1.125 MHz SPI_InitDef.SPI_CRCPolynomial = 7; SPI_Init(SPI1, &SPI_InitDef); SPI_I2S_ITConfig(SPI1, SPI_I2S_IT_RXNE, ENABLE); SPI_Cmd(SPI1, ENABLE); NVIC_EnableIRQ(SPI1_IRQn); NVIC_SetPriority(SPI1_IRQn, 7); printf("SPI bus init success...\r\n"); } void SPI_RW() { while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_IT_RXNE) == RESET); return SPI_I2S_ReceiveData(SPI1); } // main.c #include "stm32f10x.h" #include "stm32f10x_gpio.h" #include "stm32f10x_rcc.h" #include "stm32f10x_spi.h" #include "SPI.h" #ifdef OS_USE_SEMIHOSTING extern void initialise_monitor_handles(void); #endif static void SysTickConfig(void) { /* Setup SysTick Timer for 10ms interrupts */ if (SysTick_Config(SystemCoreClock / 1000)) { /* Capture error */ while (1); } /* Configure the SysTick handler priority */ NVIC_SetPriority(SysTick_IRQn, 1); // if I change Priority to 0 then I can't catch SPI' interruption } uint8_t RX_LEN = 32; uint8_t RX_BUF[RX_LEN] = {0}; void print_buf(uint8_t len) { for (uint8_t i=0; i<len; i++) { printf("0x%02x \r\n", RX_BUF[i]); } printf("\r\n"); } void SPI1_IRQn(void) { for (uint8_t i=0; i<RX_LEN; i++) { RX_BUF[i] = SPI_RW(); } print_buf(RX_LEN); } void main() { /* Enable semihosting */ #ifdef OS_USE_SEMIHOSTING initialise_monitor_handles(); #endif /* SysTickConfig */ SysTickConfig(); SPI_Init(); while(1) { printf("hello\r\n"); } } Помогите разобраться и пофиксить этот баг
  8. Я имел ввиду резервуар в диспенсере, но судя по-всему его там нет
  9. Спасибо! А что значит стравливать? Устройство не разбирал, но предполагаю, что там есть свой резервуар для воздуха, я же могу по монометру отследить, например, наполнение до 90%?
  10. Добрый день, прошу совета. Приобрел у китайцев диспенсер AD-982 для паяльной пасты. Расчитанно на давление 2.5 - 7 бар, вопрос в следующем, что будет, если я подключу к нему автомобильный компрессор (10-12 бар), не хочется покупать отдельный компрессор для этой штуки, так как большую часть он будет стоять и занимать место. Автомобильный планирую питать через блок питания (220 -> 12) с необходимым током
  11. Ну соответственно 4-5А. А контроллер от такого тока не сгорит?
  12. Верно, соответственно блок на 12В 2А, он же идёт на дисплей и от него же через этот конвертер питаю малину?
×
×
  • Create New...