Перейти к содержанию

Smith2007

Members
  • Постов

    93
  • Зарегистрирован

  • Посещение

Весь контент Smith2007

  1. В руках оказался китайский клон PLC FX1N-14MT Используя GX Works 2 получилось написать простые конструкции на языке ST. Удалось даже управление ШД. Однако некоторые моменты просто вводят в ступор. Подключил к ПЛК панель оператора OP320. На панель вывожу два регистра D132, D168 На панели повесил две кнопки и указал на установку маркеров M0, M3 IF M8002=1 THEN M0 := 0; M3 := 0; stepProg := 0; END_IF; IF LDP( M8000 , M0 ) THEN D132 := 1; END_IF; IF LDP( M8000 , M3 ) THEN D168 := 100; END_IF; Включаю ПЛК (не трогаю ни какие кнопки), регистры D132, D168 получили значения. Как будто выполнены условия. С панели обнуляю данные регистры. Далее код ведет себя верно. Жмем кнопку с привязкой к маркеру М0 и в регистр D132 записывается 1. Но почему при старте ПЛК происходит выполнение кода под условием? Что за особенности такие и как это можно обойти? Может кто сталкивался с подобным? (GX Work 2 Version 1.560J)
  2. Smith2007

    STM32F103: ADC+DMA

    Добавил настройку, но ни чего не поменялось. void Init_ADC_DMA(void) { uint32_t pin; // Включаем тактирование GPIOA, AFIO, ADC1 RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_AFIOEN | RCC_APB2ENR_ADC1EN; RCC->CFGR |= RCC_CFGR_ADCPRE_DIV8; //Предделитель АЦП 72/6 = 12 МГц // Очистим настройки пинов. Нулевое значение соответствует Input Analog GPIOA->CRL &= ~( GPIO_CRL_CNF0 | GPIO_CRL_MODE0 | GPIO_CRL_CNF1 | GPIO_CRL_MODE1 | GPIO_CRL_CNF5 | GPIO_CRL_MODE5 | GPIO_CRL_CNF6 | GPIO_CRL_MODE6 | GPIO_CRL_CNF7 | GPIO_CRL_MODE7 ); // Настройка DMA1 RCC->AHBENR |= RCC_AHBENR_DMA1EN; // Включаем тактирование DMA1 // Deinit DMA1 Channel1 DMA1_Channel1->CCR &= ~DMA_CCR1_EN; // Отключаем DMA1 CH1 //DMA1_Channel1->CCR = 0; // Reset DMA1 Channel1 control register DMA1->IFCR |= DMA_ISR_GIF1 | DMA_ISR_TCIF1 | DMA_ISR_HTIF1 | DMA_ISR_TEIF1; // Reset interrupt pending bits for DMA1 Channel1 // Настраиваем DMA DMA1_Channel1->CNDTR = ADC_COUNT; // Количество передаваемых данных DMA1_Channel1->CPAR = (uint32_t) &(ADC1->DR );// Адрес перифирии DMA1_Channel1->CMAR = (uint32_t) arrSignal; // Адрес памяти DMA1_Channel1->CCR |= DMA_CCR1_MINC // Инкремент памяти | DMA_CCR1_PSIZE_0 // Режим периферии 16 бит | DMA_CCR1_MSIZE_0 // Режим памяти 16 бит | DMA_CCR1_PL_1 // Channel Priority level hight | DMA_CCR1_CIRC // Circular mode | DMA_CCR1_TEIE // Transfer error interrupt enable | DMA_CCR1_TCIE; // Transfer complete interrupt enable DMA1_Channel1->CCR |= DMA_CCR1_EN; // Включаем DMA1 Channel3 // Очистим настройки ADC1 ADC1->CR1 = 0; ADC1->CR2 = 0; ADC1->SMPR2 = 0; ADC1->SQR1 = 0; ADC1->SQR2 = 0; ADC1->SQR3 = 0; // Настраиваем ADC1 ADC1->CR1 |= ADC_CR1_SCAN; // Scan mode ADC1->CR2 |= ADC_CR2_CONT; // Continuous Conversion ADC1->CR2 |= ADC_CR2_DMA; // DMA mode ADC1->CR2 |= ADC_CR2_TSVREFE; // Temperature Sensor and VREFINT Enable ADC1->CR2 |= ADC_CR2_EXTSEL; ADC1->CR2 &= ~ADC_CR2_ALIGN; // Data Alignment ADC1->SQR1 |= ((uint32_t)(ADC_COUNT - 1) << 20); // Сканируем 6 каналов (6-1 = 5) // Настройка семплирования. Номер канала совпадает с номером пина ADC1->SMPR2 |= ADC_SMPR2_SMP0; // Channel 0 Sample time selection 111: 239.5 cycles ADC1->SMPR2 |= ADC_SMPR2_SMP1; // Channel 1 Sample time selection 111: 239.5 cycles ADC1->SMPR2 |= ADC_SMPR2_SMP5; // Channel 2 Sample time selection 111: 239.5 cycles ADC1->SMPR2 |= ADC_SMPR2_SMP6; // Channel 3 Sample time selection 111: 239.5 cycles ADC1->SMPR2 |= ADC_SMPR2_SMP7; // Channel 4 Sample time selection 111: 239.5 cycles ADC1->SMPR1 |= ADC_SMPR1_SMP16; // Channel 5 Sample time selection 111: 239.5 cycles // Настройка пинов pin = 0x00; ADC1->SQR3 |= (pin << (5 * 0)); // Pin0 pin = 0x01; ADC1->SQR3 |= (pin << (5 * 1)); // Pin1 pin = 0x06; ADC1->SQR3 |= (pin << (5 * 2)); // Pin5 pin = 0x07; ADC1->SQR3 |= (pin << (5 * 3)); // Pin6 pin = 0x05; ADC1->SQR3 |= (pin << (5 * 4)); // Pin7 pin = 0x10; ADC1->SQR3 |= (pin << (5 * 5)); // Pin16 - Температурный сенсор ADC1->CR2 |= ADC_CR2_ADON; // A/D Converter ON / OFF // Обнуляем калибровку ADC1->CR2 |= ADC_CR2_RSTCAL; while (ADC1->CR2 & ADC_CR2_RSTCAL); //запускаем калибровку и ждем ее завершение ADC1->CR2 |= ADC_CR2_CAL; while (ADC1->CR2 & ADC_CR2_CAL); ADC1->CR2 |= ADC_CR2_EXTTRIG; //ADC_CR2_SWSTART; //ADC1->CR2 |= ADC_CR2_DMA; // DMA mode ADC1->CR2 |= ADC_CR2_SWSTART; }
  3. Smith2007

    STM32F103: ADC+DMA

    Пробовал. DMA не выставляет флаг ошибки и в прерывание не попадаю.
  4. Smith2007

    STM32F103: ADC+DMA

    Я думаю, что ДМА счетчик не сдвинул как раз. Пропустил запрос от ADC. Следующий запрос от ADC к DMA: DMA принял, но данные поместил уже не во второй элемент массива, а в первый. Затем ADC шлет еще и еще запросы и некоторые из них DMA вновь пропускает. И количество пропусков *считай смещений) может составлять от 1 до 6. Вот это и объясняет, что сдвиг данных всегда на разную величину происходит.
  5. Smith2007

    STM32F103: ADC+DMA

    Смещение индекса произвольное. Без канала4 дма - все работает верно. Я думаю, что как раз происходит пропуск чтения и соответственно не инкрементируется счетчик. Т.е. Ацп пнул дма, а дма пропустил. Ацп перешел к следующему каналу - снова пнул дма. Дма щагрузил. Потом еще несколько циклов и несколько прпусков. Это как раз объясняет тот факт, что смещение индекса постоянно меняется В нулевой элемент массива или в любой другой в зависимости от сиещения Зв. Движек форумя тяжел для смартфона.
  6. Smith2007

    STM32F103: ADC+DMA

    Я подозреваю, что дело не в массиве, а в том, что при операциях с регистрами дма1 канал4, каким-то образом происходит пропуск запроса на чтение. Т.е ацп дергает дма - читай, у меня готовы данные для элемента1. А дма1 тем временем очень занят и пропустил мимо ушей эту инфу. Нет буферы не пересекаются. Если я преобразую int в ascii, я это делаю в отдельном статическом буфере
  7. Smith2007

    STM32F103: ADC+DMA

    На уарт терминал висит. В него идет как отладочная инфа так и служебная. Есть строковые константы. Есть даже большие. Ацп считывает данные с датчиков, а дальше они пройдут через медианные фильтры, нормированы и будут использованы в отдельной задаче.
  8. Smith2007

    STM32F103: ADC+DMA

    Буфер adc и буфер для usart не пересекаются. Просто из отрывков кода это не видно. Я искал зацепку в даташите, но ничего вразумительного не нашел. Вероятно это глюк самого контроллера, а точнее его периферии. Поэкспериментирую еще сегодня. Результат отпишу.
  9. Smith2007

    STM32F103: ADC+DMA

    Это может быть очень большим временем. Если отправить в медленный юсарт буфер в пару килобайт.... Попробую при входе в прерывание по окончанию передачи в юсарт приостановить adc По крайней мере это всего несколько тактов
  10. Smith2007

    STM32F103: ADC+DMA

    Передача по юсарт может быть несколько килобайт. За границы массива точно не выхожу. Я смотрел память. И смотрел элементы массива отладчиком Данные пишутся верно по всем каналам, но смещается номер элемента массива. Ставлю заглушку на вывод в юсарт по дма - проблема исчезает. Понимаю, что можно каждый раз пересинхронизировать adc-dma. Но это же костыль будет
  11. Smith2007

    STM32F103: ADC+DMA

    Данные загружаются в массив но со смещением (циклическим) Т.е нулевой канал перескочил с нулевого элемента массива на первый элемент. А пятый канал стал грузиться не в пятый элемент массива, а в нулевой. Проверял как в отладчике так и в памяти. Так же делал вывод массива в юсарт. Ощущение, что во время операций с каналом 4, на канале1 происходит пропуск запроса на чтение , поступившего от adc. При этом само смещение в массиве постоянно меняется. Может на 1 позицию сместиться, может на 2,3 и т.д.
  12. Smith2007

    STM32F103: ADC+DMA

    Преобразования по 6ти каналам uint16. Т.е не 4 байта, а 12. Но дело даже не в этом... Настроил adc-dma однажды и забыл. Когда нужно просто забираем данные из массива. Проц не участвует в чтении и сохранении данных adc. И просто такой конфиг работал очень долго, пока не подключил канал4
  13. Smith2007

    STM32F103: ADC+DMA

    С этим асе нормально. Объявлен массив Uint16t arrSignal[6] Этот вариант работает довольно давно и до подключения канала1 ни каких сбоев не замечал Нет. Не отключаю. Думал об этом. Возможно надо приостановить ADC. Единственный общий ресурс, который я меняю это регистр DMA1->IFCR Когда произвожу сброс флага по окончании обработки прерывания (Окончание передачи)
  14. Smith2007

    STM32F103: ADC+DMA

    Добрый день, уважаемые форумчане. Столкнулся со странной проблемой в работе связки ADC-DMA В проекте используется 2 канала DMA1. Канал 1 для циклического чтения регулярных регистров ADC И канал 4 для вывода буфера в USART. (После добавления этого канала в работу и начались чудеса ADC по преобразует сигналы и дергает DMA, который последовательно раскладывает значения в буфер uint16_t signal[6] Все работало длительное время пока я не решил задействовать DMA Для вывода в USART. Например: ADC1- Канал1 - записывался в нулевой элемент массива signal[ 0 ] ADC1- Канал2 - записывался в первый элемент массива signal[ 1 ] ADC1- Канал3 - записывался во второй элемент массива signal[ 2 ] После вывода буфера по каналу 4, на канале 1 происходит смещение индекса массива и данные от ADC начинают записываться по другим адресам. Например: ADC1- Канал1 - записывался во второй элемент массива signal[ 2 ] ADC1- Канал2 - записывался в третий элемент массива signal[ 3 ] ADC1- Канал3 - записывался во четвертый элемент массива signal[ 4 ] Каким образом DMA->Канал4 может вносить проблемы на работу DMA->Канал1? Ниже привожу инит и вывод Инициализация и запуск циклического считывания значений в массив arrSignal[] void Init_ADC_DMA(void) { uint32_t pin; // Включаем тактирование GPIOA, AFIO, ADC1 RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_AFIOEN | RCC_APB2ENR_ADC1EN; RCC->CFGR |= RCC_CFGR_ADCPRE_DIV8; //Предделитель АЦП 72/6 = 12 МГц // Очистим настройки пинов. Нулевое значение соответствует Input Analog GPIOA->CRL &= ~( GPIO_CRL_CNF0 | GPIO_CRL_MODE0 | GPIO_CRL_CNF1 | GPIO_CRL_MODE1 | GPIO_CRL_CNF5 | GPIO_CRL_MODE5 | GPIO_CRL_CNF6 | GPIO_CRL_MODE6 | GPIO_CRL_CNF7 | GPIO_CRL_MODE7 ); // Настройка DMA1 RCC->AHBENR |= RCC_AHBENR_DMA1EN; // Включаем тактирование DMA1 // Deinit DMA1 Channel1 DMA1_Channel1->CCR &= ~DMA_CCR1_EN; // Отключаем DMA1 CH1 //DMA1_Channel1->CCR = 0; // Reset DMA1 Channel1 control register DMA1->IFCR |= DMA_ISR_GIF1 | DMA_ISR_TCIF1 | DMA_ISR_HTIF1 | DMA_ISR_TEIF1; // Reset interrupt pending bits for DMA1 Channel1 // Настраиваем DMA DMA1_Channel1->CNDTR = ADC_COUNT; // Количество передаваемых данных DMA1_Channel1->CPAR = (uint32_t) &(ADC1->DR );// Адрес перифирии DMA1_Channel1->CMAR = (uint32_t) arrSignal; // Адрес памяти DMA1_Channel1->CCR |= DMA_CCR1_MINC // Инкремент памяти | DMA_CCR1_PSIZE_0 // Режим периферии 16 бит | DMA_CCR1_MSIZE_0 // Режим памяти 16 бит | DMA_CCR1_PL_1 // Channel Priority level hight | DMA_CCR1_CIRC // Circular mode | DMA_CCR1_TEIE; // Transfer error interrupt enable DMA1_Channel1->CCR |= DMA_CCR1_EN; // Включаем DMA1 Channel3 // Очистим настройки ADC1 ADC1->CR1 = 0; ADC1->CR2 = 0; ADC1->SMPR2 = 0; ADC1->SQR1 = 0; ADC1->SQR2 = 0; ADC1->SQR3 = 0; // Настраиваем ADC1 ADC1->CR1 |= ADC_CR1_SCAN; // Scan mode ADC1->CR2 |= ADC_CR2_CONT; // Continuous Conversion ADC1->CR2 |= ADC_CR2_DMA; // DMA mode ADC1->CR2 |= ADC_CR2_TSVREFE; // Temperature Sensor and VREFINT Enable ADC1->CR2 &= ~ADC_CR2_ALIGN; // Data Alignment ADC1->SQR1 |= ((uint32_t)(ADC_COUNT - 1) << 20); // Сканируем 6 каналов (6-1 = 5) // Настройка семплирования. Номер канала совпадает с номером пина ADC1->SMPR2 |= ADC_SMPR2_SMP0; // Channel 0 Sample time selection 111: 239.5 cycles ADC1->SMPR2 |= ADC_SMPR2_SMP1; // Channel 1 Sample time selection 111: 239.5 cycles ADC1->SMPR2 |= ADC_SMPR2_SMP5; // Channel 2 Sample time selection 111: 239.5 cycles ADC1->SMPR2 |= ADC_SMPR2_SMP6; // Channel 3 Sample time selection 111: 239.5 cycles ADC1->SMPR2 |= ADC_SMPR2_SMP7; // Channel 4 Sample time selection 111: 239.5 cycles ADC1->SMPR1 |= ADC_SMPR1_SMP16; // Channel 5 Sample time selection 111: 239.5 cycles // Настройка пинов pin = 0x00; ADC1->SQR3 |= (pin << (5 * 0)); // Pin0 pin = 0x01; ADC1->SQR3 |= (pin << (5 * 1)); // Pin1 pin = 0x06; ADC1->SQR3 |= (pin << (5 * 2)); // Pin5 pin = 0x07; ADC1->SQR3 |= (pin << (5 * 3)); // Pin6 pin = 0x05; ADC1->SQR3 |= (pin << (5 * 4)); // Pin7 pin = 0x10; ADC1->SQR3 |= (pin << (5 * 5)); // Pin16 - Температурный сенсор ADC1->CR2 |= ADC_CR2_ADON; // A/D Converter ON / OFF // Обнуляем калибровку ADC1->CR2 |= ADC_CR2_RSTCAL; while (ADC1->CR2 & ADC_CR2_RSTCAL); //запускаем калибровку и ждем ее завершение ADC1->CR2 |= ADC_CR2_CAL; while (ADC1->CR2 & ADC_CR2_CAL); ADC1->CR2 |= ADC_CR2_EXTTRIG; //ADC_CR2_SWSTART; ADC1->CR2 |= ADC_CR2_DMA; // DMA mode } Вывод буфера в usart //################################################################## // function Передача буфера в USART1 по DMA1 Ch4 // argument buf - указатель на буфер char* // len - длина буфера // return void //################################################################## void DMA1Ch4_SendBuf8(const char* buf, uint32_t len) { // Deinit DMA1 Channel4 DMA1_Channel4->CCR &= ~DMA_CCR4_EN; // Отключаем DMA1 CH2 //DMA1_Channel4->CCR = 0; // Reset DMA1 Channel4 control register DMA1->IFCR |= DMA_ISR_GIF4 | DMA_ISR_TCIF4 | DMA_ISR_HTIF4 | DMA_ISR_TEIF4; // Reset interrupt pending bits for DMA1 Channel4 // Настраиваем DMA1 Channel4 DMA1_Channel4->CNDTR = len; // Количество передаваемых данных DMA1_Channel4->CPAR = (uint32_t) &(USART1->DR); // Адрес перифирии DMA1_Channel4->CMAR = (uint32_t) buf; // Адрес памяти DMA1_Channel4->CCR |= DMA_CCR4_MINC // Инкремент памяти //| DMA_CCR4_PL_0 // Channel Priority level Medium | DMA_CCR4_DIR //Data transfer direction. 0 - from peripheria 1 - from memory | DMA_CCR4_TCIE; // Transfer complete interrupt enable //DMA1_Channel4->CCR |= DMA_CCR4_TEIE; // Transfer error interrupt enable DMA1_Channel4->CCR |= DMA_CCR4_EN; // Включаем DMA1 Channel5 } По окончании передачи формируется прерывание в котором просто отключаем DMA1->Channel4 //################################################################## //function Прерывание по окончании передачи по DMA CH4 # //argument none # //return void # //################################################################## void DMA1_Channel4_IRQHandler(void) { if ((DMA1->ISR & DMA_ISR_TCIF4)) { // Transfer Complete flag DMA1_Channel4->CCR &= ~DMA_CCR4_EN; // Отключаем DMA. DMA1->IFCR |= DMA_IFCR_CTCIF4; // Channel4 Transfer Complete clear usart.Status_Tx = Tx_None; xSemaphoreGiveFromISR(mtxUsart, 0); } } Есть у кого мысли в чем может быть проблема? Второй день поисков - не дает результата. Понимаю, что можно обойти путем пересинхронизации ADC-DMA после каждого вызова отправки буфера по 4 каналу ДМА. Но это костыль получается.
  15. Один байт пришел на спи - одно прерывание. Вошли в обработчик прерывания, сохранили байт в буфер, инкрементировали счетчик буфера, завершили обработчик прерывания. Вообще внутри обработчика использовать циклы это не лучшее решение. А в данном примерк еще и ошибка Ps. Инкремент счетчика .. #define MAX_BUF 64 uint32_t idx; В прерывании инкремент счетчика кольцевого буфера idx = (idx+1) % MAX_BUF;
  16. Smith2007

    CAN снифер

    Сам себе отвечу. Написал небольшую тестовую программку, которая сканирует прием перебирая все возможные скорости. //**********************************************************************/ // Тестирование скорости приема с CAN // //**********************************************************************/ void app_CANScaner (void *argument) { USARTSend("CAN Scaner\n\r"); CanRxMsg msg; uint32_t speed; uint32_t ratio; uint8_t rec; uint8_t lec; while(1) { USARTSend("Prescaler\tBS1\tBS2\tSpeed\tRatio \n\r"); for (uint16_t prescaler = 1; prescaler < 15; prescaler++) { for (uint8_t bs1 = CAN_BS1_1tq; bs1 <= CAN_BS1_16tq; bs1++) { for (uint8_t bs2 = CAN_BS2_1tq; bs2 <= CAN_BS2_8tq; bs2++) { //while (CAN_RxFrameCount() == 0); CAN_InitStructure.CAN_Prescaler = prescaler; CAN_InitStructure.CAN_BS1 = bs1; CAN_InitStructure.CAN_BS2 = bs2; CAN_InitStructure.CAN_SJW = CAN_SJW_1tq; //CAN_InitStructure.CAN_Mode = CAN_Mode_LoopBack; // Для тестирования без подключенных устройств шины Reinit_CAN(); osDelay(200); lec = CAN_GetLastErrorCode(CAN1); // err == CAN_ErrorCode_NoErr rec = CAN_GetReceiveErrorCounter(CAN1); if (rec == 0 and lec == 0) { speed = 36000000/CAN_InitStructure.CAN_Prescaler/(1+ CAN_InitStructure.CAN_BS1 + 1 + CAN_InitStructure.CAN_BS2 + 1); ratio = CAN_InitStructure.CAN_BS1 * 1000 / (1+ CAN_InitStructure.CAN_BS1 + 1 + CAN_InitStructure.CAN_BS2 + 1); USARTSend("\t"); USARTSend(CAN_InitStructure.CAN_Prescaler, 'd'); USARTSend(" \t"); USARTSend(CAN_InitStructure.CAN_BS1 + 1, 'd'); USARTSend(" \t"); USARTSend(CAN_InitStructure.CAN_BS2 + 1, 'd'); //USARTSend("\t"); USARTSend(CAN_InitStructure.CAN_SJW + 1, 'd'); USARTSend(" \t"); USARTSend(speed, 'd'); USARTSend(" \t"); USARTSend(ratio, 'd'); USARTSend(" "); USARTSend("\n\r"); } else { USARTSend("\t"); USARTSend(CAN_InitStructure.CAN_Prescaler, 'd'); USARTSend(" \t"); USARTSend(CAN_InitStructure.CAN_BS1 + 1, 'd'); USARTSend(" \t"); USARTSend(CAN_InitStructure.CAN_BS2 + 1, 'd'); USARTSend(" "); USARTSend("\r"); } //osDelay(50); } } } } } Загрузил в контроллер, подключил к шине авто и запустил. Через некоторое время получил результат. Затем сравнил полученные показатели настроек с тем, что я делал и сразу обнаружил ошибку. Ранее при настройке BS1, BS2 я указывал просто числа 1, 2, 3 ..и т.д. Однако если взглянуть на дефайны /** @defgroup CAN_time_quantum_in_bit_segment_1 * @{ */ #define CAN_BS1_1tq ((uint8_t)0x00) /*!< 1 time quantum */ #define CAN_BS1_2tq ((uint8_t)0x01) /*!< 2 time quantum */ #define CAN_BS1_3tq ((uint8_t)0x02) /*!< 3 time quantum */ #define CAN_BS1_4tq ((uint8_t)0x03) /*!< 4 time quantum */ #define CAN_BS1_5tq ((uint8_t)0x04) /*!< 5 time quantum */ #define CAN_BS1_6tq ((uint8_t)0x05) /*!< 6 time quantum */ #define CAN_BS1_7tq ((uint8_t)0x06) /*!< 7 time quantum */ #define CAN_BS1_8tq ((uint8_t)0x07) /*!< 8 time quantum */ #define CAN_BS1_9tq ((uint8_t)0x08) /*!< 9 time quantum */ #define CAN_BS1_10tq ((uint8_t)0x09) /*!< 10 time quantum */ #define CAN_BS1_11tq ((uint8_t)0x0A) /*!< 11 time quantum */ #define CAN_BS1_12tq ((uint8_t)0x0B) /*!< 12 time quantum */ #define CAN_BS1_13tq ((uint8_t)0x0C) /*!< 13 time quantum */ #define CAN_BS1_14tq ((uint8_t)0x0D) /*!< 14 time quantum */ #define CAN_BS1_15tq ((uint8_t)0x0E) /*!< 15 time quantum */ #define CAN_BS1_16tq ((uint8_t)0x0F) /*!< 16 time quantum */ 1 тайм квант (1tq) указывается как 0, а не 1. Указал верные значения и вуаля! CANHacker подцепился с ходу.
  17. Smith2007

    CAN снифер

    Ни одного прерывания не получаю
  18. Smith2007

    CAN снифер

    Собрал с нуля проект из примеров Кейла. Не читает Завтра соберу два МК и соединю их по КАН. Проверю работу КАН таким образом.
  19. Smith2007

    CAN снифер

    define подставляется
  20. Smith2007

    CAN снифер

    Прерывание, фильтры и т.д. - все работает. Я же проверяю работу в режиме loopback. Все принимается и отправляется. Параллельно слежу осцилографом за сигналом. Вижу изменения и уже различаю 0 и 1. Скорость задается при подключении CAN Hacker. Происходит переинициализация структуры настроек.
  21. Smith2007

    CAN снифер

    3 дня вожусь и не пойму в чем причина. Может это СФТ протокол особенный (ISO15765-4CAN11/500), который stm32 не понимает?
  22. Smith2007

    CAN снифер

    Вопрос еще закрался.... Если после инициализации контроллера я создаю новые настройки (собираю структуру с новыми параметрами) и выполняю CAN_Init(CAN1, &CAN_InitStructure); Это правильно? Или нужно сначала сделать DeInit? upd. Подключился к шине в режиме отладки. Изменения наблюдаю только в одном регистре MSR
  23. Smith2007

    CAN снифер

    Автомобиль УАЗ Патриот 2016 года. На разъеме OBD имеются пины 6 и 14. Судя по описанию распиновки разъема (найдено в инете) это и есть CANH, CANL В этот разъем подключаю ELM327 -, загружаю torque pro. Если я правильно понимаю, то ELM327 цепляется через этот разъем к скоростной шине 500 кбит. Доступные датчики. Частота тактирования CAN шины 36 МГц Prescaler= 6, Seg1 = 6, Seg2 = 5 36/6/(1+6+5) = 500 кбит. SJW ставил 1, 2, 3 - не помогло. Осцилограмма сигнала Процедура инициализации CAN //***************************************************************** // // Модуль CAN шины // // // //***************************************************************** #include "can.h" void init_CAN(void) { GPIO_InitTypeDef GPIO_InitStructure; /* CAN GPIOs configuration */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); // включаем тактирование AFIO RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // включаем тактирование порта RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE); // включаем тактирование CAN-шины // Настраиваем CAN RX pin GPIOA Pin11 GPIO_InitStructure.GPIO_Pin = CAN1_RX_SOURCE; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(CAN1_GPIO_PORT, &GPIO_InitStructure); // Настраиваем CAN TX pin GPIOA Pin12 GPIO_InitStructure.GPIO_Pin = CAN1_TX_SOURCE; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(CAN1_GPIO_PORT, &GPIO_InitStructure); // Включаем трансивер GPIOB Pin1 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); GPIO_InitStructure.GPIO_Pin = CAN1_STB_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_Init(CAN1_STB_PORT, &GPIO_InitStructure); GPIO_WriteBit(CAN1_STB_PORT, CAN1_STB_PIN, Bit_SET ); #ifdef CAN1_ReMap GPIO_PinRemapConfig(GPIO_Remap1_CAN1, ENABLE); // Переносим Can1 на PB8, PB9 #endif // Инициализация режима CAN шины по умолчанию CAN_InitStructure.CAN_TTCM = DISABLE; CAN_InitStructure.CAN_ABOM = DISABLE; // DISABLE CAN_InitStructure.CAN_AWUM = ENABLE; CAN_InitStructure.CAN_NART = ENABLE; // DISABLE CAN_InitStructure.CAN_RFLM = DISABLE; CAN_InitStructure.CAN_TXFP = DISABLE; CAN_InitStructure.CAN_Mode = CAN_Mode_Normal; // Обычный режим работы устройства //CAN_InitStructure.CAN_Mode = CAN_Mode_LoopBack; // Для тестирования без подключенных устройств шины CAN_InitStructure.CAN_BS1 = CAN_BS1_13tq; CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq; CAN_InitStructure.CAN_SJW = CAN_SJW_1tq; CAN_InitStructure.CAN_Prescaler = CAN1_SPEED_500KB; // Выбираем нужную скорость CAN_Init(CAN1, &CAN_InitStructure); // CAN filter init CAN_Filter.CAN_FilterNumber = 0; CAN_Filter.CAN_FilterMode = CAN_FilterMode_IdMask; CAN_Filter.CAN_FilterScale = CAN_FilterScale_32bit; CAN_Filter.CAN_FilterIdHigh = 0x0000; CAN_Filter.CAN_FilterIdLow = 0x0000; CAN_Filter.CAN_FilterMaskIdHigh = 0x0000; CAN_Filter.CAN_FilterMaskIdLow = 0x0000; CAN_Filter.CAN_FilterFIFOAssignment = CAN_FIFO0; CAN_Filter.CAN_FilterActivation = ENABLE; CAN_FilterInit(&CAN_Filter); // CAN FIFO0 message pending interrupt enable CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE); // NVIC Configuration // Enable CAN1 RX0 interrupt IRQ channel NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } #ifdef __cplusplus extern "C" { #endif //********************************************** // Устанавливаем параметры шины // //********************************************** void CAN_Setup(CAN_InitTypeDef CAN_InitStructure){ CAN_Init(CAN1, &CAN_InitStructure); } //********************************************** // Устанавливает скорость CAN // //********************************************** void CAN_Speed(uint16_t prescaler, uint8_t bs1, uint8_t bs2, uint8_t sjw) { CAN_InitStructure.CAN_BS1 = bs1; CAN_InitStructure.CAN_BS2 = bs2; CAN_InitStructure.CAN_SJW = sjw; CAN_InitStructure.CAN_Prescaler = prescaler; // Выбираем нужную скорость CAN_Setup(CAN_InitStructure); } В данном случае скорость шины выставляется настройками CANHacker.
  24. Smith2007

    CAN снифер

    Имеется контроллер STM32F103RET6. На CAN интерфейс подключен трансивер TJA1040 USART подключаю к компьютеру на котором запускаю CAN Hacker. Создал проект (Keil) с использованием библиотек cmsis. Включаю режим CAN_Mode_LoopBack. Отправляю пакет в цикле из CAN Hacker и получаю его же обратно. Прием пакетов по прерыванию в кольцевой буфер. Осцилографом становлюсь на выход трансивера (CANH, CANL) Количество отправленных пакетов = количеству принятых. При разных установленных скоростях шины - длительность сигналов так же меняется. Подключаюсь к CAN Шине авто. Ни одного пакета принять не могу. Подозреваю, что я не верно выставляю тайминги. Как правильно определить параметры таймингов по форме сигнала? (цена деления 2 мкс)
  25. Как можно реализовать автонумерацию билдов?
×
×
  • Создать...