[lang_ru]Итак, в предыдущей серии мы выяснили, что от нас хочет наша магнитола, теперь неплохо было бы ей сообщить о том, что мы ее поняли![/lang_ru]
[lang_de] Also, in der letzten Folge haben wir festgestelld, was HU von uns braucht. Jetzt wäre nich schlecht zu sagen, das wir den HU verstanden haben. [/lang_de]
[lang_ru]И сделаем мы это с помощью аппаратного таймера, который будет отсылать команды побитно:[/lang_ru]
[lang_de]Und machen wir das mit der Hilfe des hardware Timers, der für und die Kommandos Bit-weise senden wird: [/lang_de]
[codesyntax lang="c" lines_start="266" container="div" title="Transmit Interrupt" ]
/*
* Transmitt timer interrupt
*/
SIGNAL(MBUS_TX_SIG_INT)
{
switch ( MBTProcess.bTxState )
{
case MBTS_START:
if ( MBTProcess.bSending )
{
if ( MBTProcess.bCurBit < MBTProcess.bBitsCount )
{
if ( MBTProcess.bBitsArray[ MBTProcess.bCurBit / 8 ] & ( 1 << ( 7 - ( MBTProcess.bCurBit % 8 ) ) ) )
{
MBUS_TX_TCCR = MBUS_TX_PRESCALE_256;
MBUS_TX_TCNT = MBUS_TX_TCNT_LOW_ONE;
MBTProcess.bTxState = MBTS_LOW_1;
}
else
{
MBUS_TX_TCCR = MBUS_TX_PRESCALE_256;
MBUS_TX_TCNT = MBUS_TX_TCNT_LOW_ZERRO;
MBTProcess.bTxState = MBTS_LOW_0;
}
MBUS_TX_PIN_LOW();
MBTProcess.bCurBit++;
}
else
{
MBUS_TX_PIN_HIGH();
MBUS_SEND_OFF();
MBTProcess.bTxState = MBTS_START;
MBTProcess.bSending = 0;
MBTProcess.bCurBit = 0;
MBTProcess.bBitsCount = 0;
TIMSK &= ~MBUS_TX_INT_EN;
MBUS_TX_TCCR = 0; // MBUS_TX_PRESCALE_1;
MBUS_TX_TCNT = 0xFF;
SWTLoad(SWT_MBUS_ANSWER_TIMER, SWT_MBUS_ANSWER_BETWEEN_PACKETS_TIMER_VAL);
}
}
break;
case MBTS_LOW_0:
MBUS_TX_TCCR = MBUS_TX_PRESCALE_256;
MBUS_TX_TCNT = MBUS_TX_TCNT_HIGH_ZERRO;
MBUS_TX_PIN_HIGH();
MBTProcess.bTxState = MBTS_START;
break;
case MBTS_LOW_1:
MBUS_TX_TCCR = MBUS_TX_PRESCALE_256;
MBUS_TX_TCNT = MBUS_TX_TCNT_HIGH_ONE;
MBUS_TX_PIN_HIGH();
MBTProcess.bTxState = MBTS_START;
break;
default:
case MBTS_END:
MBTProcess.bTxState = MBTS_START;
break;
}
}
[/codesyntax]
[lang_ru]Тут уже немного побольше телодвижений, чем при приеме данных. Опять же весь процесс посылания состоит из нескольких состояний:[/lang_ru]
[lang_de]Hier braucht man ein bisschen mehr Körperbewegungen, als beim Empang. Und wie immer, ganze Prozess besteht aus mehreren Zustände: [/lang_de]
[lang_ru]case MBTS_START: — Ну тут все ясно — бит начался. Опять же проверяем, а надо ли слать, а то может и не стоит вовсе. Так же проверяем, не все ли мы уже послали. А далее смотрим, что за бит — 0 или 1. В зависимости от этого устанавливаем счетчик прерывания таким образом, что бы попасть сюда снова через точно выверенное время, которое зависит от того, что шлем в данный момент — 0 или 1. Если 0, то время, через которое мы снова будем тут — примерно 0.5 милисекунд, если 1, то — примерно 1.8 милисекунд. Общее же время бита — 3 милисекунды. Так же определяем, в какое состояние мы пойдем в следующий раз, чтобы правильно выставить оставшееся время, в течение которого пин должен быть в 1, перед посылкой следующено бита.[/lang_ru]
[lang_de]case MBTS_START: — Hier ist, eigentlich, alles klar — Bit ist angefangen. Und auch, es wird geprüft, ob man senden soll oder nicht. Also wird geprüft, ob alles gesendet wurde oder gibt noch was. Danach schauen wir, was gesendet werden soll — 1 oder 0. Abhänging davon setzten wir den Timer so, dass beim nächsten mal werden wir hier landen genau um den Zeitpunkt, der dem 1 oder 0 entspricht. Für 0 müssen wir 0.5 millisekunden warten, für 1 — 1.8 Milisekunden. Gesamte Zeit für ein Bit ist 3 Milisekunden und daraus wird die Restzeit definiert, um den nächsten Bit am richtigen Zeitpunkt zu starten. [/lang_de]
[lang_ru]Время посчитали и ставим пин в 0.[/lang_ru]
[lang_de]So, die Zeiten sind kalkuliert, setzen wir den Pin in 0. [/lang_de]
[lang_ru]case MBTS_LOW_0: и case MBTS_LOW_1: — состояния, в которые мы попадаем, когда время, в течение которого пин находится в 0, вышло. Тут мы настраиваем наш таймер на оставшееся от всего бита время, когда пин будет находится в 1, и ставим пин в 1. А следующим состоянием будет опять MBTS_START.[/lang_ru]
[lang_de]case MBTS_LOW_0: und case MBTS_LOW_1: — sind die Zustände, wann die Zeit, während der Pin in 0 ist, abgelaufen ist. Hier setzen wir den Pin zurück in 1, und starten den Timer für die Restzeit. [/lang_de]
[lang_ru]Во второй части MBTS_START состояния, когда у нас все биты уже отосланы, мы переключаем наш пин шины в состояние према, включаем прерывание према, и настраиваем систему для следующей посылки. А так же загружаем таймер задержки между пакетами, а то даже люди струдом понимают других людей, которые говорят без пауз.[/lang_ru]
[lang_de]In der zweite Teil des MBTS_START Zustandes, wenn alle Bits empfangen sind, schalten wir den Pin auf eingang, schalten wir den Empfangs-Interrupt, und breiten wird das System für die nächste Sende vor. Also, laden wir den Zwischen-Paketen-Timer. [/lang_de]
[lang_ru]Но естественно, сам таймер посылки у нас стартовать не будет, потому как надо знать, когда слать. Для этого служит функция MBus_SendPacket (), в которой, если есть что слать, запускается таймер:[/lang_ru]
[lang_de]Der Sende-timer startet selber nicht. Den muss man dann starten, wann man es wirklich braucht. Dafür gibt es die Funktion MBus_SendPacket (), die, falls es was zu senden gibt, startet den Timer. [/lang_de]
[codesyntax lang="c" lines_start="331" container="div" title="MBus_SendPacket()" ]
/* * Start transmitt process */ void MBus_SendPacket(void) { if ( MBTProcess.bBitsCount ) { #ifdef MBUS_SEND_DEBUG u08 i; u08 bNibbles; bNibbles = MBTProcess.bBitsCount / 4 + ((MBTProcess.bBitsCount % 4) == 0 ? 0 : 1); DEBUG_OUTP( PSTR("MBus S: |") ); for ( i = 0; i < bNibbles; i++ ) { DEBUG_OUTP(PSTR("%X"), ((MBTProcess.bBitsArray[i / 2] >> (4 - (4 * (i%2))) ) & 0x0F) ); } DEBUG_OUTP( PSTR("|n") ); #endif MBTProcess.bSending = 1; MBUS_SEND_ON(); MBTProcess.bTxState = MBTS_START; MBTProcess.bCurBit = 0; MBUS_TX_TCCR = MBUS_TX_PRESCALE_1; MBUS_TX_TCNT = 0xFF; TIMSK |= MBUS_TX_INT_EN; /* while ( MBTProcess.bSending == 1 ) { wdt_reset(); } */ } } [/codesyntax]
[lang_ru]Тут мы, определив, что нам есть, что сказать, выставляем флаг того, что мы все таки говорим, переключаем наш пин на «выход», настриваем параметры системы посылки и включаем таймер посылок, который практически тут же страбатывает, так как счетчик его мы утстановили на максимально возможное значение.[/lang_ru]
[lang_de] Hier, wen wir sehen dass es was zu senden gibt, setzen den Flag, dass wir gerade sprechen, schalten den Pin auf Ausgan um, setzen einige Parameres für das Senden und schalten den Sende-Timer [/lang_de]
[lang_ru]Все! Ответ ушел.[/lang_ru]
[lang_de]Damit ist das Paket raus. [/lang_de]
[lang_ru]Один момент хотел бы уделить макросу переключения пина на «выход» и обратно на «вход»:[/lang_ru]
[lang_de]Die Makrosen für Umschalten des Pins auf Aingang oder Ausgang sehen so aus: [/lang_de]
[codesyntax lang="c" lines_start="66" container="div" title="Preprocessor defines"]
// switch ports to sending mode on or off
#define MBUS_SEND_ON() sbi(MBUS_DIR, MBUS_RX_PIN); EIMSK &= ~(1 << MBUS_RX_INT);
#define MBUS_SEND_OFF() cbi(MBUS_DIR, MBUS_RX_PIN); EIMSK |= (1 << MBUS_RX_INT); EIFR |= (1 << MBUS_RX_INT);
[/codesyntax]
[lang_ru]Как видно из приведенного выше кода, в этом макросе не только сам пин переключается, но и еще, при посылке — выключается прерывание према, и включается обратно, когда посылка закончилась.[/lang_ru]
[lang_de]Wie man sieht, es wird nicht nur Pin selber umgeschaltet, sonder auch, beim Senden das Empfangs Interrupt augeschalted, und wieder eingeschaltet, wenn man den Pin auf Eingang umschaltet. [/lang_de]
[lang_ru]Это нужно делать для того, что бы мы сами себя не слушали, а то впадем в рекурсию — будем отвечать на свои же команды.[/lang_ru]
[lang_de]Das muss man machen, damit wir unsere Echo nicht hören können, sonst fallen wir in die Rekursion. [/lang_de]
[lang_ru]Вот собственно и весь процесс общения с внешним миром посредством шины M-Bus.[/lang_ru]
[lang_de]Das ist eigentlich ganze Kommuniktaionsprocess über M-Bus. [/lang_de]
[lang_ru]Если у вас будут вопросы по каким то отдельным частям программы — пишите в коментариях, осветим в следующих выпусках.[/lang_ru]
[lang_de]Falls Ihr die Fragen habt, schreib ainfach ein Kommentar da unten, ich werde versuchen die zu beantworten. [/lang_de]
[lang_ru]До скорого![/lang_ru]
[lang_de]Bis Bald! [/lang_de]
22 комментария to “Mazda MP3 Player — Продолжение 4|Mazda MP3 Player — Vierte Folge”
Leave a Reply
You must be logged in to post a comment.
July 11th, 2011 at 1:24
Статьи читал, спасибо за выложенные труды. По ответам вопросов нет) Буду эксперементировать.
July 11th, 2011 at 5:17
Не подскажите сколько должно быть на ноге ACC в разъеме вольт? У меня 5 показывает. По схеме внутренней вроде бы 12 должно быть.
July 11th, 2011 at 8:55
Вообще то 12 вольт. У меня, по крайней мере — 12 вольт. Я еще ставил специально LM2775-05 для понижения питания. И все сигналы MBus тоже 12 вольт, если я правильно помню. По крайней мере в схеме стоит делитель 🙂 на MBus линии. Но про сигнальные линии, я бы уточнил.
July 11th, 2011 at 9:13
Спасибо. 12 Вольт и должно быть)). Транзистор сгорел на схеме, заменили, радио ожило. Попробовали подключить AUX, играет, но очень тихо. Вроде сопротивления большие стоят. Уфффффф. Ощущение как в казино, вроде пора остановится, а не хочется.
July 11th, 2011 at 9:16
🙂 О. Поздравляю, что все заработало!
July 11th, 2011 at 9:34
Спасибо. Только интересно, когда в режим AUX входит на дисплее надпись «RSES» высвечивается. Что это значит? Попробовали сопротивления на 56к убрать с селектора, звук погромче стал, но с шипением.
July 11th, 2011 at 9:43
Про RSES гугль вот такое рассказывает: mazda-cx.ru/oldforum/view...php?f=17&t=3
Пункт 7.
Т.е. скорее всего, когда ваш «эмулятор» представляется ГУ, то он, видимо неправильный код посылает, и ГУ распознает его не как обычный CD чейнджер.
Чего то не пойму, про какие сопротивления вы говорите. Я никаких не ставил между аудио выходом MP3 декодера и входом ГУ. Только конденсаторы-электролиты. Т.е. обычная стандартная схема включения VLSI VS1011.
July 11th, 2011 at 11:34
По RSES примерно понял. Спасибо. А по сопротивлениям, схема такая разъем AUX — С — R — Селектор. Это на всех R+ L+ R- L- такая схема сопротивление на 56 к и 50V2.2 кондюр. Попробовали в обход сделать, но все равно звук тихий и с шипением. По схеме нашли вроде как дифференциальный вход. AUX кстати активировать пришлось — на один из штекеров 5 В подали тогда только RSES появился.
August 1st, 2011 at 13:01
Добрый день, господа!
Появилась необходимость раскурить MBus Mazda3, точнее очень заинтересовали пины TEXT DATA & TEXT CLOCK. Может кто уже использовал их, или знает как использовать ? 🙂 а то гугл меня скоро забанит уже. Цель — научить магнитоллу выводить ан штатный дисплей названия треков, которые принимает блютуз гарнитура, контролируемая через КАН шину.
Кстати если еще актуально — есть наработки в управлении штатной головой, точнее текстом на экране, прям через ОБД2 разъем.