Прерывание PIC16 I2C не происходит, если последовательный порт включен

Я использую PIC среднего уровня PIC16F1825, и я использовал его с UART и SPI в течение длительного времени без проблем. Когда я добавил код для обработки I2C (вместо SPI — на этом PIC либо одно, либо другое), я столкнулся с проблемами с отсутствием получения прерывания I2C — таким образом, SCL останется растянутым навсегда.

После некоторой серьезной отладки я понял, что удаление кода, который активировал последовательный порт, устранило проблему - I2C ISR вызывается и работает нормально.

Все, что я делаю в серийной инициализации, это устанавливаю SPBRG, а затем:

 bcf         TXSTA, SYNC             ; Async (default)
 bsf         RCSTA, SPEN             ; Active serial port

 bsf         TXSTA, TXEN             ; Enable TX
 bsf         RCSTA, CREN             ; Enable RX

Это. Прерывания не включены (я просто устанавливаю флаг на передачу)

Я искал документы и опечатки и не нашел намека на то, что включение последовательного порта исказит функциональность I2C, как это. Это мое недоразумение или здесь действительно силиконовая ошибка?

Я не вижу этого в списке ошибок для устройства. Чтобы исключить программную ошибку, не могли бы вы также вставить свой ISR? Однако не исключено, что вы обнаружили новую проблему с кремнием.
Я не могу вставить весь код из-за проблем компании и т. д. Код похож на мой код PIC16F88 ( github.com/conoror/picmicro ). Хотя я не новичок в ассемблере :-) Я действительно пытался узнать, видел ли кто-нибудь это раньше. Что я сделаю (это должно произойти через несколько дней), так это переключу биты порта в ISR, чтобы увидеть, куда он попадает, если куда-нибудь. Интересно, будет ли Microchip принимать отчеты об ошибках (от нелюбителей).
Я всегда находил, что Microchip очень восприимчива к сообщениям об ошибках, когда я обращался к ним с ошибками компилятора в прошлом. У меня есть учетная запись, зарегистрированная на их сайте, и хотя моя компания определенно не настолько велика, чтобы быть на их «радарах», они все равно воспринимают меня всерьез.
@brhans: Приятно знать, спасибо. Моя компания состоит из 3 человек, так что совсем не большая. Я собираюсь найти логический анализатор, чтобы убедиться, прежде чем тратить их время! Я напишу ответ здесь, когда узнаю.

Ответы (1)

Это не силиконовый жук. Это я полный идиот.

Происходит то, что мой код uart был написан год назад и полагался на тот факт, что PIR1, TXIF были высокими, если буфер передачи UART был пуст . Мой код перебирает данные, на которые указывает FSR0, пока не достигнет «\ 0», а затем отключает TXIE. Таким образом, когда я загружаю FSR и устанавливаю TXIE, данные автоматически передаются. Проходит год, и я пишу ISR следующим образом:

    .intr   CODE        4

    ; Enhanced Midrange CPU does a context save on:
    ; W, STATUS, BSR, FSR, PCLATH
    ; retfie restores context

    pagesel     $

    ifbset      INTCON, TMR0IF          ; Timer0
      goto      Timer0_Entry

    banksel     PIR1                    ; Bank #0
    ifbset      PIR1, TXIF              ; Serial transmit
      goto      SerialTX_Entry

    ifbset      PIR1, SSP1IF
      goto      I2C_Entry               ; I2C Peripheral

    retfie                              ; Nothing else

Ну это полная и полнейшая ерунда. Если получено какое-либо прерывание, кроме прерывания по таймеру - так что либо UART, либо I2C, будет вызван SerialTX_Entry. TXIF всегда устанавливается, если UART включен и для передачи не удерживается ни один символ. Таким образом, в приведенном выше примере I2C_Entry никогда не будет достигнут.

Здесь есть урок - опубликуйте код! Когда я показал кому-то ISR, он сразу его увидел.