Битовый UART

Мой полный код находится здесь .

По сути, я передаю на Arduino и не получаю правильное значение (вы заметите, что я пытаюсь отправить d'22'). Вот метод, в котором я на самом деле отключил передачу:

// Method for transmitting value using serial bit banging
void uart_tx_bit_bang(unsigned char val) {
    unsigned char i;
    Tx_Pin = 0;                         // Start bit
    uart_time_delay();
    for ( i = 8 ; i != 0 ; --i ) {
        if (val & 0x01) Tx_Pin = 1;   // Begin with LSB
        else            Tx_Pin = 0;
        val >>= 1;
        uart_time_delay();
        }
    Tx_Pin = 1;                         // Stop bit
    uart_time_delay();
}

Поскольку задержка должна быть 1/бод, uart_time_delay()задержка должна быть 104 мкс. Я использую __delay_us(104)из библиотек PIC. Любая помощь в этом очень ценится.

Я уверен, что использую правильную скорость передачи данных на обоих концах.

UART фактически сначала отправляет LSB.
Этот код отправляет LSB-first
Какое значение вы получаете? Знание этого поможет в устранении неполадок.
Я получал несколько разных значений, а не только одно постоянное значение.
@markrages, да ты прав, обратный порядок цикла и комментарий через меня
Мои извинения за комментарий. Я адаптировал это из другой процедуры битового удара и забыл изменить комментарий.
Разве в сериале нет перевернутых уровней? Из вики: «Для линий передачи данных (TxD, RxD и их эквиваленты вторичных каналов) логическая единица определяется как отрицательное напряжение». Хотя это не объясняет тот факт, что принимаемые данные меняются. Я думаю, что стоп-бит тоже низкий, глядя на последовательные трассировки вики.
Кроме того, задержка не равна точно 1/бод, если только запись в порт не занимает времени. Хотя, если вы используете 300 бод, скорость выполнения инструкций не будет иметь значения. На какой тактовой частоте работает ваш PIC?
Я использую внутренний генератор 4 МГц. И 9600 бод
И вы подключаетесь к аппаратным последовательным контактам TX / RX Arduino?
Все, что я делаю, это передача с моего PIC на Arduino. Итак, у меня есть Tx_PinPIC, подключенный к Rx на Arduino.
@angelatlarge инвертированы только уровни RS-232. На микроконтроллере уровни обычные CMOS.
@markrages Да, уровни TTL не инвертированы (я хотел отредактировать это, прочитав еще немного, но срок истек. Вот почему я спросил об Arduino: есть ли что-то среднее между Arduino и PIC (максимум чип «Две максимальные фишки» маловероятно, конечно) тогда уровни могут быть неверными.

Ответы (1)

Хотя ваш расчет 104 мкс верен для 9600 бит/с, ваш цикл и различные операции, которые он выполняет, добавят дополнительную задержку. Есть несколько способов настроить время:

  • Вычтите константу из вашей задержки в США, пока она не начнет работать. Вероятно, было бы лучше определить минимальное/максимальное число, с которым он работает, и выбрать среднее значение.

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

  • Посмотрите на ассемблерный вывод компилятора и определите, сколько циклов занимает цикл.

Я также вижу, что вы используете радиоуправляемые часы. Обычно я предпочитаю поддерживать последовательную синхронизацию в пределах 2% для надежной работы, поэтому также проверяйте, чтобы деталь обладала такой же стабильностью при использовании часов RC для надежной работы.

Спасибо! Я попробую некоторые из этих предложений утром и вернусь к вам.
Я бы согласился с PeterJ. Обычно мне приходится использовать внешние часы (кристалл или резонатор), чтобы получить точную передачу данных. Кроме того, бит, вращающийся внутри цикла, увеличивает вашу задержку.
Так что я думаю, что понял это. Я не думаю, что моя uart_time_delay()рутина вообще задерживается. Я использую встроенный __delay_us()метод. Есть мысли по этому поводу? Как я могу сделать более надежную задержку в C? Мне нужно, чтобы это было 1/бод
@WillemEllis, я только что заметил, что у вас _XTAL_FREQ определено как 4.0 - я думаю, что это должно быть в герцах, поэтому 4000000, это может делать что-то странное.
Это было!!! Я так счастлив прямо сейчас! Я изменил _XTAL_FREQ на 4000000 и снизил скорость передачи данных до 4800, и это работает! Спасибо @PeterJ
@PeterJ, не уверен, что тебя это волнует, но в качестве вознаграждения вот то, что ты помог мне сделать! youtube.com/watch?v=BvSl8_K2UX4