Views: 1184
Введение
Модуль прямого доступа к памяти (DMA) предназначен для обслуживания передачи данных непосредственно между различными областями памяти без вмешательства процессора. Исключив при этом необходимость в интенсивной обработки прерываний процессором, предназначенных для передачи данных. Процессор теперь может больше уделять времени на другие задачи.
Семейство PIC18(L)F2XK42 имеет два модуля DMA, которые могут быть независимо запрограммированы для передачи данных между различными ячейками памяти, перемещение разных размеров данных и использования широкого спектра аппаратных триггеров для инициирования передач. Два регистра DMA могут быть запрограммированы для совместной работы, чтобы выполнять более сложные передачи данных без дополнительных нагрузок на процессор микроконтроллера.
К основным функциям модуля DMA относятся:
- Поддержка доступа к следующим областям памяти:
- Пространство GPR и SFR (R/W) (GPR – память ОЗУ и SFR – регистры модулей и управления)
- Программная флэш-память (только R)
- Память данных EEPROM (только R)
- Программируемый приоритет между DMA и системными ресурсами (процессор и прерывания).
- Программируемые режимы адреса источника и адресата
- Фиксированный адрес
- Адрес после инкремента
- Адрес после декремента
- Программируемые размеры источника и адресата
- Регистр указателя источника и получателя, динамически обновляемые и перезагружаемые
- Регистр счетчика источника и адресата, динамически обновляемый и перезагружаемый
- Программируемая автоматическая остановка на основе счетчика источника или адресата
Передача программного обеспечения- Множественные выбираемые пользователем источники для аппаратно инициированных передач
- Несколько выбираемых пользователем источников для прерывания передачи DMA
DMA регистры
- Регистры управления модулями (DMAxCON0, DMAxCON1)
- Регистр буфера данных (DMAxBUF)
- Источник
- Регистр хранения стартового адреса, откуда будут получены данные (DMAxSSA U:H:L)
- Регистр указателя адреса откуда в текущий момент извлекаются данные (DMAxSPTR U:H:L)
- Регистр размера сообщения (размер буфера данных) (DMAxSSZ H:L)
- Регистр счетчика переданных байт данных (DMAxSCNT H:L)
- Адресат
- Регистр стартового адреса, куда будут записываться данные (DMAxDSA H:L)
- Регистр указателя куда в текущий момент производиться запись (DMAxDPTR H:L)
- Регистр размера сообщения (размер буфера данных) (DMAxDSZ H:L)
- Регистр счетчика принятых байт (DMAxDCNT H:L)
- Регистр указатель на устройство прерывания которого запускает процесc DMA (DMAxSIRQ)
- Регистр указатель на устройство прерывания которого прерывает процесc DMA (DMAxAIRQ)
Организация DMA
Модуль DMA на устройстве PIC18(L)F24/25K42 предназначен для перемещения данных с использованием существующей шины инструкций <16> и шины данных <8> без необходимости использования двухпортовой памяти или периферийных систем. DMA обращается к требуемой шине, когда она будет предоставлена системным арбитром.
В зависимости от приоритета DMA в отношении к процессору, контроллер DMA может перемещать данные двумя способами:
- Прекращение работы процессора до тех пор, пока он не завершит передачу (DMA имеет более высокий приоритет над процессором в этом режиме работы)
- Использование неиспользуемых циклов ЦП для передачи DMA (в этом режиме работы процессор имеет более высокий приоритет по сравнению с DMA). Неиспользованные циклы CPU называются пузырьками (Bubble), которые являются командами цикла, доступными для использования DMA, для выполнения операций чтения и записи. Таким образом, увеличивается эффективная пропускная способность для обработки данных; в то же время операции DMA могут продолжаться, не вызывая остановки процессора.
DMA интерфейс
Модуль DMA передает данные от источника до адресата по одному байту за раз, это наименьшее перемещение данных называется транзакцией данных DMA. Сообщение DMA относится к одной или нескольким транзакциям данных DMA.
Каждая транзакция данных DMA состоит из двух отдельных действий:
- Чтение источника в адресной памяти и сохранение значения в регистре буфера DMA
- Запись содержимого буфера DMA-буфера в память адресата
Движение данных DMA представляет собой двухтактную операцию.
Бит XIP (регистр DMAxCON0) является битом состояния, указывающим, записаны ли данные в регистре DMAxBUF по адресу назначения. Если бит установлен, данные ждут записи в пункт назначения. Если он очищен, это означает, что либо данные были записаны в пункт назначения, либо источник еще не прочитан.
DMA имеет доступ для чтения к PFM, Data EEPROM и пространству SFR/GPR, а также возможность записи в пространство SFR/GPR. Основываясь на этих возможностях доступа к памяти, DMA может поддерживать следующие транзакции памяти:
Чтение источника | Запись в назначение |
Program Flash Memory | GPR |
Program Flash Memory | SFR |
Data EE | GPR |
Data EE | SFR |
GPR | GPR |
SFR | GPR |
GPR | SFR |
SFR | SFR |
Несмотря на то, что модуль DMA имеет доступ ко всей памяти и периферийным устройствам, которые также доступны для ЦП, рекомендуется, чтобы DMA не обращался к любому регистру, который является частью арбитража системы. DMA, как системный арбитражный клиент, не должен быть прочитан или записан сам собой или другим каналом DMA.
В следующих разделах обсуждаются различные интерфейсы управления, необходимые для передачи данных DMA.
DMA адресация
Начальные адреса для операций чтения источника и адресата записываются с использованием регистров DMAxSSA <21:0> и DMAxDSA <15:0> соответственно.
Когда передача сообщений DMA выполняется, регистры DMAxSPTR<21:0> и DMAxDPTR<15:0> содержат текущие указатели адресов для каждой операции чтения источника и записи для адресата, эти регистры изменяются после каждой транзакции на основе режима заданного в регистре управления.
Биты SMODE и DMODE в регистре управления DMAxCON1 определяют режимы адреса управления, контролируя, как биты DMAxSPTR<21:0> и DMAxDPTR<15:0> обновляются после каждой комбинации транзакций данных DMA.
Каждый адрес может быть сконфигурирован отдельно:
- Оставаться без изменений
- Увеличение на 1
- Уменьшение на 1
Примечание 1: Для выполнения правильного доступа к памяти для чтения, сочетание адреса и выбор пространства должно быть действительным.
2: Пункт назначения (адресат) не имеет битов выбора места, поскольку он может записывать только в пространство SFR/GPR.
DMA размер/счетчик сообщения
Транзакция – это передача одного байта. Сообщение состоит из одной или нескольких транзакций. Полный процесс DMA состоит из одного или нескольких сообщений. Регистры размера определяют количество транзакций в сообщении. Регистры DMAxSSZ определяют размер источника, а регистры DMAxDSZ определяют размер адресата.
Когда инициируется передача DMA, регистры размера копируются в соответствующие регистры счетчиков, которые управляют продолжительностью сообщения. Регистры DMAxSCNT подсчитывают транзакции от источника, а регистры DMAxDCNT подсчитывают транзакции к адресату. Оба одновременно уменьшаются на один после каждой транзакции.
Сообщение запускается установкой бит DGO регистра DMAxCON0 и завершается, когда меньший из двух счетчиков достигает нуля.
Когда любой счетчик достигает нуля, бит DGO очищается, а регистры счетчика и указателя немедленно перезагружаются с соответствующими данными размера и адреса. Если другой счетчик не достиг нулевого значения, тогда следующее сообщение будет продолжаться со счетчиком и адресом, соответствующим этому регистру.
Когда регистры размера источника и адресата не равны, отношение наибольшего к наименьшему определяется количеством сообщений в процессе DMA. Например, когда размер адресата равен 6, а исходный размер равен 2, каждое сообщение будет состоять из двух транзакций, а полный процесс DMA будет состоять из трех сообщений. Когда больший размер не является четным целым меньшего размера, последнее сообщение в этом процессе заканчивается раньше, когда большее число достигает нуля. В этом случае более высокий счетчик будет сброшен, а меньший счетчик будет иметь остаток, искажающий любые последующие сообщения на эту разность.
Примечание: Чтение регистров DMAxSCNT или DMAxDCNT никогда не будет возвращать ноль. Когда любой регистр уменьшается с «1» в «0», он немедленно перезагружается из соответствующего регистра размера.
Таблица примеров сообщений
Операция | Пример | SCNT | DCNT | Комментарии |
Чтение из отдельного регистра SFR в ОЗУ |
U1RXB | 1 | N | N равно числу байтов, которые требуются в буфере назначения. N> = 1. |
Запись в один регистр SFR из ОЗУ |
U1TXB | N | 1 | N равно числу байтов, которые требуются в исходном буфере. N> = 1. |
Чтение из нескольких регистров SFR | ADRES[H:L] | 2 | 2*N | N равно числу результатов АЦП, которые должны храниться в памяти. N> 1 |
TMR1[H:L] | 2 | 2*N | N равно количеству результатов захвата TMR1, которые должны храниться в памяти. N> 1 | |
SMT1CPR[U:H:L] | 3 | 3*N | N равно числу измерений ширины импульса захвата, которые должны храниться в памяти. N> 1 | |
Запись в несколько регистров SFR | PWMDC[H:L] | 2*N | 2 | N равно числу значений рабочего цикла PWM, которые должны быть загружены из таблицы памяти. N> 1 |
All ADC registers | N*31 | 31 | Использование DMA для передачи полного контекста АЦП из ОЗУ в регистры ADC. N> = 1 |
DMA Передача сообщений
После того, как бит Enable установлен для запуска передачи сообщений DMA, указатели источника/адресата и регистры счетчиков инициализируются условиями, показанными в таблице.
DMA Условия инициализации
Регистр | Загружаемое значение |
DMAxSPTR<21:0> | DMAxSSA<21:0> |
DMAxSCNT<11:0> | DMAxSSZ<11:0> |
DMAxDPTR<15:0> | DMAxDSA<15:0> |
DMAxDCNT<11:0> | DMAxDSZ<11:0> |
Во время операции DMA после каждой транзакции следующие таблицы показывают, как изменяются указатель источника/адресата и регистры счетчиков.
DMA ИСТОЧНИК УКАЗАТЕЛЬ/СЧЕТЧИК ВО ВРЕМЯ РАБОТЫ
Регистр | Изменение счетчика/указателя источника |
DMAxSCNT<11:0> != 1 | DMAxSCNT = DMAxSCNT – 1 (счетчик транзакций) |
SMODE = 00: DMAxSPTR = DMAxSPTR (указатель на память) | |
SMODE = 01: DMAxSPTR = DMAxSPTR + 1 (указатель на память) | |
SMODE = 10: DMAxSPTR = DMAxSPTR – 1 (указатель на память) | |
DMAxSCNT<11:0> == 1 | DMAxSCNT = DMAxSSZ (инициализация счетчика по размеру буфера данных) |
DMAxSPTR = DMAxSSA (инициализация указателя) |
DMA АДРЕСАТ УКАЗАТЕЛЬ/СЧЕТЧИК ВО ВРЕМЯ ЭКСПЛУАТАЦИИ
Регистр | Изменение счетчика/указателя получателя |
DMAxDCNT<11:0> != 1 | DMAxDCNT = DMAxDCNT -1 |
DMODE = 00: DMAxDPTR = DMAxDPTR | |
DMODE = 01: DMAxDPTR = DMAxDPTR + 1 | |
DMODE = 10: DMAxDPTR = DMAxDPTR – 1 | |
DMAxDCNT<11:0> == 1 | DMAxDCNT = DMAxDSZ |
DMAxDPTR = DMAxDSA |
В следующих разделах обсуждается, как инициировать и прекратить передачу DMA.
DMA ЗАПУСК ПЕРЕДАЧИ СООБЩЕНИЙ
DMA может инициировать транзакции данных одним из следующих двух условий:
1. Управление программным обеспечением пользователя, управлением битом DGO.
2. Аппаратным триггером, посредством стартового прерывания SIRQ.
Управление пользовательским программным обеспечением.
Программное обеспечение запускает или останавливает транзакцию DMA, устанавливая/очищая бит DGO. Бит DGO также используется, чтобы указать, был ли получен аппаратный триггер DMA и какое сообщение выполняется.
Примечание:
- Запуск программного обеспечения возможен только в том случае, если установлен бит EN (DMAxCON1).
- Если процессор записывает бит DGO в то время как он уже установлен, Это не окажет влияния на систему, и DMA будет продолжать работать в обычном режиме.
Аппаратный триггер, SIRQ
Аппаратный триггер – запрос прерывания от другого модуля, отправленного в DMA с целью запуска транзакции DMA. Источник триггера запуска DMA выбирается пользователем с использованием регистра DMAxSIRQ.
Бит SIRQEN (регистр DMAxCON0) используется для включения внешних триггеров прерываний, с помощью которых можно начать передачу DMA. При установке бита SIRQEN DMA будет запускаться от выбранного источника прерывания, а при очистке бита SIRQEN DMA игнорирует выбранный источник прерываний. Очистка бита SIRQEN не останавливает транзакцию DMA в текущем прогрессе, он останавливается только окончанию транзакций или после аппаратного управления.
DMA ОСТАНОВКА ПЕРЕДАЧИ СООБЩЕНИЙ
Контроллер DMA может остановить транзакции данных одним из следующих условий:
- Очистка бит DGO
- Аппаратный триггер, AIRQ (через прерывания)
- Перезагрузка источника
- Повторная загрузка адресата
- Очистка бит Enable
Управление пользовательским программным обеспечением
Если пользователь очистит бит DGO, передача сообщения будет остановлена и DMA останется в текущей конфигурации.
Например, если пользователь очищает бит DGO после того, как исходные данные были прочитаны, но до того, как они будут записаны в пункт назначения, данные в DMAxBUF не достигнут своего адресата.
Это также называется мягкой остановкой, так как операция может возобновиться при желании, снова установив бит DGO.
Аппаратный триггер, AIRQ
Бит AIRQEN (регистр DMAxCON0) используется для включения внешних триггеров прерываний, с помощью которых транзакция DMA может быть прервана.
После того, как был получен запрос прерывания прерывания, DMA выполнит мягкую остановку, очистив бит DGO, а также очистив бит SIRQEN, чтобы переполнение не происходило. Бит AIRQEN также очищается, чтобы предотвратить дополнительные сигналы прерывания от срабатывания ложных прерываний.
При желании бит DGO может быть установлен снова, и DMA возобновит работу с того места, где оно было остановлено после того, как был установлен «мягкий останов», поскольку ни одна из информации состояния DMA не изменяется в случае прерывания.
Счетчик источника
Сообщение DMA считается завершенным, когда регистр счетчика источника уменьшается с «1» в «0», а затем перезагружается (т.е. После того, как произошела записи последнего байта из источника или запись к адресату). Когда бит SSTP установлен (регистр DMAxCON1), и регистр счетчика источника перезагружается, дальнейшая передача сообщений прекращается.
Перезагрузка счетчика назначения
Сообщение DMA считается завершенным, когда регистр счетчика назначения уменьшается с «1» в «0», а затем перезагружается (т.е. как только произошло чтение последний байт из любого источника или записи последний байта регистр адресата).
Когда бит DSTP установлен (DMAxCON1), и регистр счетчика назначения перезагружается, дальнейшая передача сообщения останавливается.
Чтение регистров DMAxSCNT или DMAxDCNT никогда не будет возвращать ноль. Когда любой регистр уменьшается с «1» в «0», он немедленно перезагружается из соответствующего регистра размера.
Очистка бита включения
Если пользователь очистит бит EN, сообщение будет остановлено, и DMA вернется к своей конфигурации по умолчанию. Это также называется жесткой остановкой, поскольку DMA не может возобновить работу с того места, где она была прервана.
Примечание:
После того, как передача сообщения DMA остановлена, для выполнения условия остановки требуется дополнительный цикл команд. Таким образом, после того, как произошло условие «Стоп», может произойти чтение источника или запись адресата в зависимости от доступности источника или шины.
ОТКЛЮЧИТЬ DMA ПО ЗАВЕРШЕНИЮ ПЕРЕДАЧИ СООБЩЕНИЯ
После передачи сообщения DMA может быть желательно остановлено, чтобы отключить источник запуска, или чтобы предотвратить переполнение при пробеге данных. Это может быть сделано одним из следующих способов:
- Очистка бит SIRQEN
- Установка бит SSTP
- Установка бит DSTP
Очистка бита SIRQEN
Очистка бит SIRQEN (регистр DMAxCON1) останавливает выборку от прерывании внешних источников запуска, тем самым предотвращая дальнейшую передачу сообщений DMA.
Примером может служить связь периферии с прерыванием, вызванным уровнем. Периферийное устройство будет продолжать запрашивать данные (поскольку его буфер пуст), хотя больше данных не нужно перемещать. Отключение бита SIRQEN не позволит DMA обрабатывать эти запросы.
Остановка Источника или Получателя
Биты SSTP и DSTP (регистр DMAxCON0) определяют, следует ли отключать аппаратные источники запуска (SIRQEN = 0) после завершения сообщения DMA.
Когда бит SSTP установлен, а DMAxSCNT = 0, бит SIRQEN будет очищен. Аналогично, когда бит DSTP установлен и DMAxDCNT = 0, бит SIRQEN будет очищен.
Биты SSTP и DSTP являются независимыми функциями и не зависят друг от друга. Возможно, сообщение будет остановлено либо счетчиком на конце сообщения, либо обоими счетчиками на конце сообщения.
Типы аппаратных тригеров.
DMA имеет два разных триггерных входа: триггер запуска и триггер прерывания работы. Каждый из этих источников триггера настраивается пользователем с использованием регистров DMAxSIRQ и DMAxAIRQ.
На основе источника, выбранного для каждого триггера, есть два типа запросов, которые могут быть отправлены в DMA.
• Тригеры изменения
• Тригеры Уровня
ЗАПРОСЫ ТРИГГЕРА изменения
Запрос Edge возникает только один раз, когда заданные требования к прерыванию модуля верны.
ЗАПРОСЫ УРОВЕНЬ ТРИГГЕРА
Утверждается запрос уровня, если условие, вызывающее прерывание, истинно.
Типы передачи данных
На основе возможностей доступа к памяти в DMA (Таблица 17-1), в следующих разделах описываются различные типы перемещения данных между источником и регионами назначения памяти.
N: 1
Этот тип передачи распространен при отправке предопределенных пакетов данных (например, строк) через единую точку интерфейса (например, регистры передачи модулей связи).
N: N
Этот тип передачи используется для перемещения информации из Program Flash или EEPROM данных в SRAM для обработки с помощью процессора или других периферийных устройств.
1: N
Этот тип передачи распространен при соединении двух разных потоков данных модулей (мост связи).
1: N
Этот тип передачи полезен для перемещения информации из одного источника данных в буфер памяти (регистры приема сообщений).
Прерывания DMA
Каждый DMA имеет свой собственный набор из четырех флагов прерывания, используемых для указания диапазона условий во время передачи данных. К битам флага прерывания можно получить доступ с помощью соответствующих регистров PIR.
Прерывания от DMA по счетчику Источника
Флаг прерывания источника DMAxSCNTIF устанавливается каждый раз, когда DMAxSCNT<11:0> достигает нуля и перезагружается до его начального значения.
Прерывания от DMA по счетчику Получателя
Флаг прерывания Получателя DMAxDCNTIF устанавливается каждый раз, когда DMAxDCNT<11:0> достигает нуля и перезагружается до его начального значения.
Прерывания DMA от счетчиков Источника и Получателя при переходе в ноль используются вместе, чтобы определить, когда нужно оповестить ЦП о завершении сообщений DMA.
Прерывания от Остановки DMA (ABORT)
Флаг прерывания остановки DMAxAIF используется, чтобы сигнализировать о том, что DMA остановил активность из-за сигнала прерывания от одного из источников прерывания. Это используется, чтобы указать, что транзакция была остановлена по какой-либо причине.
OVERRUN INTERRUPT ПРЕРЫВАНИЯ Переполнения
Когда DMA получает триггер для запуска нового сообщения до завершения текущего сообщения, устанавливается флаг прерывания DMAxORIF Overrun.
Это условие указывает, что DMA запрашивается до завершения текущей транзакции. Это означает, что активный DMA может не справиться с требованиями обслуживаемого периферийного модуля, что может привести к потере данных.
Установленный флаг DMAxORIF не приводит к завершению текущей передачи DMA.
Прерывание переполнения доступно только для источников триггеров, которые основаны на границах и недоступны для источников, основанных на уровне. Поэтому источник прерываний на основе уровня не вызывает ошибку переполнения DMA из-за возможных проблем с задержкой в системе.
Примером прерывания, которое могло бы использовать прерывание переполнения, было бы прерывание таймера (или совпадение периода). Это событие происходит только каждый раз, когда таймер переполняется и не зависит от каких-либо других системных условий.
Примером прерывания, которое не допускает прерывание переполнения, будет буфер UARTTX. UART будет продолжать утверждать прерывание, пока DMA не сможет обработать MSG. Из-за проблем с задержкой DMA может не иметь возможности немедленно обслуживать пустой буфер, но UART продолжает утверждать свое прерывание передачи до тех пор, пока оно не будет обслуживаться. Если в этом случае разрешено перерасход, переполнение произойдет почти сразу, поскольку модуль проверит источники прерываний на каждый цикл команд.
Установка и эксплуатация DMA
Следующие шаги иллюстрируют, как настроить DMA для передачи данных:
- Запрограммируйте соответствующие адреса источника и назначения для транзакции в регистры DMAxSSA и DMAxDSA
- Выберите область памяти источника, которая адресована регистром DMAxSSA, используя бит SMR<1:0>.
- Запрограммируйте биты SMODE и DMODE, чтобы выбрать режим адресации.
- Запрограммируйте размер источника DMAxSSZ и размер DMAxDSZ размера адресата с количеством передаваемых байтов. Для правильной работы рекомендуется, чтобы регистры размера были кратными друг другу.
- Если пользователь желает отключить передачу данных после завершения сообщения, необходимо установить бит SSTP и DSTP в регистре DMAxCON0.
- При использовании аппаратных триггеров для передачи данных настройте источники прерывания аппаратного триггера для пуска и прерывания передачи DMA (DMAxSIRQ и DMAxAIRQ) и установите соответствующие бит разрешения запроса прерывания (SIRQEN и AIRQEN).
- Выберите уровень приоритета для DMA и заблокируйте приоритеты.
- Включите DMA (DMAxCON1bits. EN = 1)
- При использовании программного обеспечения для передачи данных установите бит DGO, иначе этот бит будет установлен аппаратным триггером.
Как только DMA настроен, следующая блок-схема описывает последовательность операций, когда DMA использует аппаратные триггеры и использует неиспользуемые циклы CPU (пузырь) для передачи DMA.
ТАБЛИЦА Примеров использования DMA
Варианты использования DMA | |||||
Модуль Источник | Регистр (ы) источника | Модуль получателя | Регистр(ы) получателя | DCHxSIRQ | Комментарий |
Таймер измерения сигнала(SMT) | SMTxCPW[U:H:L] | GPR | GPR[x,y,z] | SMTxPWAIF | Сохранение значений ширины импульса захвата |
SMTxCPR[U:H:L] | SMTxPRAIF | Сохранить значение захваченного периода | |||
GPR/SFR/Program Flash/Data EEPROM | MEMORY[x,y] | TMR0 | TMR0[H:L] | TMR0IF | Использовать в качестве перезагрузки Timer0 для пользовательского 16-битного значения |
GPR/SFR/ Program Flash/Data EEPROM | MEMORY[x] | TMR0 | PR0 | ANY | Частота обновления TMR0 на основе конкретного триггера |
GPR/SFR/ Program Flash/Data EEPROM | MEMORY[x,y] | TMR1 | TMR1[H:L] | TMR1IF | Использовать в качестве перезагрузки Timer1 для пользовательского 16-битного значения |
TMR1 | TMR1[H:L] | GPR | GPR[x,y] | TMR1GIF | Используйте флаг прерывания TMR1 Gate для чтения данных из регистра TMR1 |
GPR/SFR/ Program Flash/Data EEPROM | MEMORY[x] | TMR2 | PR2 | TMR2IF | Задание периода таймера |
GPR/SFR/ Program Flash/Data EEPROM | MEMORY[x,y,z] | TMR2 CCP or PWM |
PR2 CCPR[H:L] or PWMDC[H:L] |
ANY | Частота генератор с 50% рабочим циклом просмотра таблицы |
CCP | CCPR[H:L] | GPR | GPR[x,y] | CCPxIF | Перемещение данных из CCP 16b Capture |
GPR/SFR/ Program Flash/Data EEPROM | MEMORY[x,y] | CCP | CCPR[H:L] | ANY | Загрузка значений сравнения или значений ШИМ в CCP |
GPR/SFR/ Program Flash/Data EEPROM | MEMORY [x,y,z,u,v,w] | CCPx CCPy CCPz |
CCPxR[H:L] CCPyR[H:L] CCPzR[H:L] |
ANY | Одновременное обновление нескольких значений ШИМ например Трехфазное управление двигателем |
GPR/SFR/ Program Flash/Data EEPROM | MEMORY[x,y,z] | NCO | NCOxINC[U:H:L] | ANY | Таблица поиска генератора частоты |
GPR/SFR/ Program Flash/Data EEPROM | MEMORY[x] | DAC | DACxCON0 | ANY | Обновить значения ЦАП |
GPR/SFR/ Program Flash/Data EEPROM | MEMORY[x] | OSCTUNE | OSCTUNE | ANY | Автоматическая частота размывание |
Регистры DMA
DMAxCON0 – DMAx регистр управления 0 |
|||||||||
bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 | Назначение | Описание |
R/W -0/0 |
R/W/ HC -0/0 |
R/W/ HS/HC -0/0 |
U-0 | U-0 | R/W/ HC -0/0 |
U-0 | R/W/ HC -0/0 |
||
EN | Бит разрешения работы модуля DMA | 1 = Включает модуль | |||||||
0 = отключает модуль | |||||||||
SIRQEN | Бит разрешения запуска транзакций аппаратными триггерами | 1 = аппаратным триггерам разрешено запускать передачу DMA | |||||||
0 = аппаратные триггеры не могут запускать передачу DMA | |||||||||
DGO | Бит транзакции DMA | 1 = выполняется транзакция DMA | |||||||
0 = транзакция DMA не выполняется | |||||||||
AIRQEN | Бит разрешения прерывания транзакций аппаратными триггерами | 1 = Аппаратные триггеры могут прервать передачу DMA | |||||||
0 = аппаратные триггеры не могут отменять передачу DMA | |||||||||
XIP | Бит состояния передачи данных буфером DMA | 1 = Регистр DMAxBUF в настоящее время содержит содержимое из операции чтения и не передал данные адресату. |
|||||||
0 = регистр DMAxBUF пуст или успешно передал данные адресату |
DMAxCON1 – DMAx регистр управления 1 |
|||||||||
bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 | Назначение | Описание |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/00 |
||
DAMODE <1:0> |
Биты режима управления указателем адресата | 11 = Reserved, Do not use | |||||||
10 = DMAxDPTR<15:0> уменьшается после каждого завершения передачи | |||||||||
01 = DMAxDPTR<15:0> увеличивается после каждого завершения передачи | |||||||||
00 = DMAxDPTR<15:0> остается неизменным после каждого завершения передачи | |||||||||
DSTP | Бит управления перезагрузкой счетчика транзакций адресата | 1 = бит SIRQEN очищается при перезагрузке счетчика назначения | |||||||
0 = бит SIRQEN не очищается при перезагрузке счетчика назначения | |||||||||
SMR <1:0> |
Биты выбор область памяти источника | 1x = DMAxSSA<21:0> указывает на Data EEPROM | |||||||
01 = DMAxSSA<21:0> указывает на Program Flash Memory | |||||||||
00 = DMAxSSA<21:0> указывает на пространство данных SFR/GPR | |||||||||
SMODE <1:0> |
Биты выбора режима работы указателя источника | 11 = Reserved, Do not use | |||||||
10 = DMAxSPTR<21:0> уменьшается после каждого завершения передачи | |||||||||
01 = DMAxSPTR<21:0> увеличивается после каждого завершения передачи | |||||||||
00 = DMAxSPTR<21:0> остается неизменным после каждого завершения передачи | |||||||||
SSTP | Бит управления перезагрузкой счетчика транзакций источника | 1 = бит SIRQEN очищается при перезагрузке Source Counter | |||||||
0 = бит SIRQEN не очищается при перезагрузке счетчика источника |
DMAxBUF – DMAx DATA BUFFER REGISTER |
|||||||
bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 |
R-0 | R-0 | R-0 | R-0 | R-0 | R-0 | R-0 | R-0 |
BUF7 | BUF6 | BUF5 | BUF4 | BUF3 | BUF4 | BUF1 | BUF0 |
Этот регистр содержит последние данные которые перемещаются от источника адресату |
DMAxSSAL – регистр (младший байт) стартового адреса источника |
|||||||
bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/00 |
SSA<7:0> |
DMAxSSAH – регистр (средний байт) стартового адреса источника |
|||||||
bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/00 |
SSA<15:8> |
DMAxSSAU – регистр (старший байт) стартового адреса источника |
|||||||
bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 |
U-0 | U-0 | R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/00 |
SSA<21:16> |
DMAxSPTRL – регистр (младший байт) указатель текущего адреса чтения источника |
|||||||
bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 |
R-0 | R-0 | R-0 | R-0 | R-0 | R-0 | R-0 | R-0 |
SPTR<7:0> |
DMAxSPTRH – регистр (средний байт) указатель текущего адреса чтения источника |
|||||||
bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 |
R-0 | R-0 | R-0 | R-0 | R-0 | R-0 | R-0 | R-0 |
SPTR<15:8> |
DMAxSPTRU – регистр (старший байт) указатель текущего адреса чтения источника |
|||||||
bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 |
U-0 | U-0 | R-0 | R-0 | R-0 | R-0 | R-0 | R-0 |
SPTR<21:16> |
DMAxSSZL – регистр (младший байт) размера “буфера данных” источника |
|||||||
bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
SSZ<7:0> |
DMAxSSZH – регистр (старший байт) размера “буфера данных” источника |
|||||||
bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 |
U-0 | U-0 | U-0 | U-0 | R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
SSZ<11:8> |
DMAxSCNTL – регистр (младший байт) счетчик переданных байт источника |
|||||||
bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
SCNT<7:0> |
DMAxSCNTH – регистр (старший байт) счетчик переданных байт источника |
|||||||
bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
SCNT<11:8> |
DMAxDSAL – регистр (младший байт) стартового адреса адресата |
|||||||
bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
DSA<7:0> |
DMAxDSAH – регистр (старший байт) стартового адреса адресата |
|||||||
bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
DSA<15:8> |
DMAxDPTRL – регистр (младший байт) текущего положения указателя адресата |
|||||||
bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 |
R-0 | R-0 | R-0 | R-0 | R-0 | R-0 | R-0 | R-0 |
DPTR<7:0> |
DMAxDPTRH – регистр (старший байт) текущего положения указателя адресата |
|||||||
bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 |
R-0 | R-0 | R-0 | R-0 | R-0 | R-0 | R-0 | R-0 |
DPTR<15:8> |
DMAxDSZL – регистр (младший байт) размера “буфера данных” адресата |
|||||||
bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
DSZ<7:0> |
DMAxDSZH – регистр (младший байт) размера “буфера данных” адресата |
|||||||
bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
DCNT<11:8> |
DMAxDCNTL – регистр (младший байт) счетчика переданных байт адресата |
|||||||
bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
DCNT<7:0> |
DMAxDCNTH – регистр (старший байт) счетчика переданных байт адресата |
|||||||
bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
DCNT<11:8> |
DMAxSIRQ – регистр выбора триггера источника запуска DMA |
|||||||
bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 |
U-0 | R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
SIRQ6 | SIRQ5 | SIRQ4 | SIRQ3 | SIRQ2 | SIRQ1 | SIRQ0 |
DMAxAIRQ – регистр выбора триггера источника остановки DMA |
|||||||
bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 |
U-0 | R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
R/W -0/0 |
AIRQ6 | AIRQ5 | AIRQ4 | AIRQ3 | AIRQ2 | AIRQ2 | AIRQ0 |
DMAxSIRQ и DMAxAIRQ ИСТОЧНИКИ ПРЕРЫВАНИЯ |
||||||
DMAxSIRQ DMAxAIRQ |
Trigger Source |
Level Triggered |
———- | DMAxSIRQ DMAxAIRQ |
Trigger Source |
Level Triggered |
0 | Reserved | 42 | DMA2SCNT | No | ||
1 | LVD | No | 43 | DMA2DCNT | No | |
2 | OSF | No | 44 | DMA2OR | No | |
3 | CSW | No | 45 | DMA2A | No | |
4 | NVM | No | 46 | I2C2RX | Yes | |
5 | SCAN | No | 47 | I2C2TX | Yes | |
6 | CRC | Yes | 48 | I2C2 | Yes | |
7 | CRC | No | 49 | I2C2E | Yes | |
8 | INT0 | No | 50 | U2RX | Yes | |
9 | ZCD | No | 51 | U2TX | Yes | |
10 | AD | No | 52 | U2E | Yes | |
11 | ADT | No | 53 | U2 | No | |
12 | CMP1 | No | 54 | TMR3 | No | |
13 | SMT1 | No | 55 | TMR3G | No | |
14 | SMT1PRA | No | 56 | TMR4 | No | |
15 | SMT1PWA | No | 57 | CCP2 | No | |
16 | DMA1SCNT | No | 58 | Reserved | Yes | |
17 | DMA1DCNT | No | 59 | CWG2 | No | |
18 | DMA1OR | No | 30 | CWG2 | No | |
19 | DMA1A | No | 51 | CWG2 | No | |
20 | SPI1RX | Yes | 62 | Reserved | ||
21 | SPI1TX | Yes | 63 | Reserved | ||
22 | SPI1 | Yes | 64 | Reserved | ||
23 | I2C1RX | Yes | 65 | Reserved | ||
24 | I2C1TX | Yes | 66 | Reserved | ||
25 | I2C1 | Yes | 67 | Reserved | ||
26 | I2C1E | Yes | 68 | Reserved | ||
27 | U1RX | Yes | 69 | Reserved | ||
28 | U1TX | Yes | 70 | TMR5 | No | |
29 | U1E | Yes | 71 | TMR5G | No | |
30 | U1 | No | 72 | TMR6 | No | |
31 | TMR0 | No | 73 | CCP3 | No | |
32 | TMR1 | No | 74 | CWG3 | No | |
33 | TMR1G | No | 75 | CLC3 | No | |
34 | TMR2 | No | 76 | Reserved | ||
35 | CCP1 | No | 77 | Reserved | ||
36 | Reserved | 78 | Reserved | |||
37 | NCO | No | 79 | Reserved | ||
38 | CWG1 | No | 80 | CCP4 | No | |
39 | CLC1 | No | 81 | CLC4 | No | |
40 | INT1 | No | 82 – 127 | Reserved | ||
41 | CMP2 | No |
Пример настройки для работы ДМА память – память
#define SIZEBUF 120 // размер буферов данных
uint8_t input_buf[SIZEBUF]; // источник
uint8_t output_buf[SIZEBUF]; // приемник
void DMA1_Initialize(void)
{
DMA1CON1 = 0b01000011; //настройка регистра управлени 1
/* |||||||| источник
* |||||||+--- SSTP: 1 - сбросить SIRQEN когда передача выполнена
* |||||++---- SMODE[1:0]: 01 - увеличение указатель DMAxSPTR<21:0> после передачи
* |||++------ SMR[1:0]: 00 - данные из памяти
* ||| получатель
* ||+-------- DSTP: 0 - не сбросывать при получении данных
* ++--------- DAMODE<1:0>: 01 - увеличение указатель DMAxDPTR<15:0> после завершения передачи
*/
// DMA1SSA = 0x000000; //откуда будут браться данные
// DMA1SSA = (uint24_t) &input_buf[0];
DMA1SSA = (uint24_t) input_buf;
// DMA1DSA = 0x0000; //куда будут записываться данные
// DMA1DSA = (uint24_t) &output_buf[0];
DMA1DSA = (uint24_t) output_buf;
DMA1SSZ = SIZEBUF; //размер источника данных
DMA1DSZ = SIZEBUF; //размер получателя данных
// DMA1SSZ = 0x0000; //размер источника данных
// DMA1DSZ = 0x0000; //размер получателя данных
DMA1SIRQ = 0x00; //тригер запуска ДМА
DMA1AIRQ = 0x00; //триггер остановки ДМА
PIR2bits.DMA1DCNTIF =0; // clear Destination Count Interrupt Flag bit
PIR2bits.DMA1SCNTIF =0; // clear Source Count Interrupt Flag bit
PIR2bits.DMA1AIF =0; // clear abort Interrupt Flag bit
PIR2bits.DMA1ORIF =0; // clear overrun Interrupt Flag bit
PIE2bits.DMA1DCNTIE =0; // disable Destination Count 0 Interrupt
PIE2bits.DMA1SCNTIE =0; // disable Source Count Interrupt
PIE2bits.DMA1AIE =0; // disable abort Interrupt
PIE2bits.DMA1ORIE =0; // disable overrun Interrupt
// заблокировать изменение приоритета
asm("BCF INTCON0,7");
asm ("BANKSEL PRLOCK");
asm ("MOVLW 0x55");
asm ("MOVWF PRLOCK");
asm ("MOVLW 0xAA");
asm ("MOVWF PRLOCK");
asm ("BSF PRLOCK, 0");
asm("BSF INTCON0,7");
DMA1CON0 = 0x00; //set control register0
}
DMA1CON0bits.EN = 1; // включить ДМА
Для теста инициализируем данные
for(uint8_t a=0;a<SIZEBUF;a++)
{
input_buf[a]=(uint8_t)(a);
output_buf[a]=0;
}
DMA1CON0bits.DGO = 1; // запустить DMA принудительно
Настройка DMA для передачи в UART одному байту из буфера, с ручным запуском каждой передачи
Инициализация DMA (перед этим понятно, что надо описать сам буфер и его размер.
void DMA1_Initialize(void) { DMA1CON1 = 0b00000010; //настройка регистра управлени 1 /* |||||||| источник * |||||||+--- SSTP: * |||||++---- SMODE[1:0]: 01 - увеличение указатель источника DMAxSPTR<21:0> после передачи * |||++------ SMR[1:0]: 00 - данные из берем памяти из ОЗУ * ||| адресат * ||+-------- DSTP: 0 - не сбросывать при получении данных * ++--------- DAMODE<1:0>: 00 - не изменять указатель адресата DMAxDPTR<15:0> после завершения передачи */ //откуда будут браться данные - берем данные с буфера input_buf DMA1SSA = (uint24_t) input_buf; //куда будут записываться данные в регистр данных U1TXB передатчика DMA1DSA = (uint24_t) &U1TXB; // для регистра модуля DMA1SSZ = SIZEBUFIN; //размер источника данных - размер нашего буфера input_buf DMA1DSZ = 1; //размер адресата данных - один регистр // тут нули запускать будем в ручную DMA1SIRQ = 0x00; //триггер запуска ДМА DMA1AIRQ = 0x00; //триггер остановки ДМА PIR2bits.DMA1DCNTIF =0; // clear Destination Count Interrupt Flag bit PIR2bits.DMA1SCNTIF =0; // clear Source Count Interrupt Flag bit PIR2bits.DMA1AIF =0; // clear abort Interrupt Flag bit PIR2bits.DMA1ORIF =0; // clear overrun Interrupt Flag bit PIE2bits.DMA1DCNTIE =0; // disable Destination Count 0 Interrupt PIE2bits.DMA1SCNTIE =0; // disable Source Count Interrupt PIE2bits.DMA1AIE =0; // disable abort Interrupt PIE2bits.DMA1ORIE =0; // disable overrun Interrupt // заблокировать изменение приоритета asm("BCF INTCON0,7"); asm ("BANKSEL PRLOCK"); asm ("MOVLW 0x55"); asm ("MOVWF PRLOCK"); asm ("MOVLW 0xAA"); asm ("MOVWF PRLOCK"); asm ("BSF PRLOCK, 0"); asm("BSF INTCON0,7"); DMA1CON0 = 0x00; //set control register0 }
После этой функции, для передачи данных используем команду
DMA1CON0bits.DGO = 1; // запустить DMA принудительно
При этом, DMA передает один байт из буфера. Биты SMODE[1:0]: 01 настроены, что при каждой следующем установки бита DGO, будет передаваться следующий бит. После выборки буфера, передача байт будет повторяться.
Следующая задача передать весь буфер за один раз. Как это сделать?
После передачи байта UART выставить флаг прерывания, что байт передал, этот флаг надо использовать для запуска DMA для передачи следующего байта. Из таблицы надо взять код 28 – U1TX. Для этого в регистре DMA1SIRQ надо прописать 28, что после передачи UARTом активизировал передачу следующего байта.
DMA1SIRQ = 28; //триггер запуска ДМА U1TX
Для остановки работы после передачи буфера, надо установить бит SSTP в регистре DMA1CON1, это создаст автомат что после передачи всего буфера будет сброшен бит SIRQEN и DMA остановит передачу. Если бит SSTP оставить сброшенным, то передача буфера будет идти непрерывно.
Еще раз. Если надо передать один раз весь буфер:
DMA1CON0bits.SIRQEN = 1; // разрешить прерывание от внешнего тригера DMA1CON0bits.DGO = 1; // запустить DMA принудительно
передача буфера из 20 байт.
Но если надо передать не весть буфер а только, например, 5 байт? Для этого надо, сделать так:
DMA1SSZ=5; // задаем размер передаваемых данных DMA1CON0bits.SIRQEN = 1; // разрешить прерывание от внешнего тригера DMA1CON0bits.DGO = 1; // запустить DMA принудительно
Передача первых 5 байт из нашего буфера (20 байт).
А если надо передать не первые 8 байт, а например, 6 байт начина с 12 байта. Для это необходимо сделать так:
DMA1SSA = (uint24_t) &input_buf[11]; DMA1SSZ=6; // задаем размер передаваемых данных DMA1CON0bits.SIRQEN = 1; // разрешить прерывание от внешнего тригера DMA1CON0bits.DGO = 1; // запустить DMA принудительно
Это может быть интересно
- DIXELL XWEB500D-EVO + RUT900 или как пробить NAT-серверViews: 1012 Когда необходимо под какой нибудь контроллер имеющий вэб сервер в инет, то нужен статический IP, что оказалось проблемой при работе с операторами сотовых сетей, конкретно с оператором сети …
- Просто о структурах и объединениях в СиViews: 2177 Какие задачи нам позволяют решать структуры и объединения? Для разработчика встроенных систем эффективность и компактность кода всегда на первом месте. Если программировании на Ассемблере ты сам определяешь как …
- MPLAB® Code ConfiguratorViews: 1768 MPLAB ® Code конфигуратор (MCC) является свободно распространяемым плагином, это графическая среда программирования, которая генерирует бесшовный, легкий для понимания кода на Cи, чтобы вставить его в свой проект.
- Проект с использованием MCC часть 13Views: 1073 Так как используя MCC мы можем его использовать со своими библиотеками, поэтому настало время и свое создать. Для начала откроем наш заголовочный файл в нем очень много букв: По …
- Development Boards PIC18F47Q84Views: 3169 Microchip тішить новими мікроконтролерами. Особливістю цього MCU – це багата інтелектуальна периферія, що дозволяє вирішувати такі завдання на 8 бітних MCU, які неможливо реалізувати на деяких навіть 32 …
- Простой оптический сенсор приближенияОптический сенсор, назначение оптический концевик, для автоматики, бесконтактный выключатель с функцией автоматического отключения...
- LCD драйвер – UC1601sViews: 1621 http://svetomuzyka.narod.ru/project/UC1601s.html Читайте обновление на http://catcatcat.d-lan.dp.ua/?page_id=178 В данный момент можно приобрести в ООО “Гамма” несколько типов индикаторов на драйвере UC1601s. RDX0048-GC, RDX0077-GS, RDX0154-GC и RDX0120-GC выполнены по технологии COG.
- Audio-bluetooth modules F-6188 (BK8000L)Views: 2304Следующий модуль на чипе BK8000L. Заводское обозначение F-6188 также основным производителем не выпускается и отдан на тиражирование. с нижней стороны имеет маркировку В этом варианте мне попалась вроде полноценная …
- Customs codes for exportViews: 157 Митні коди (HS Code) для надсилання посилок за кордон. Для відправки товару за кордон на сьогодні необхідно зазначати митні коди. Часто визначення коду займає багато часу. Для …
- PIC18F25K42 – v. A001 – выявленные баги.Views: 615 Модуль I2C Не работает при использовании в стандартной конфигурации MCC. Требует особой нестандартной конфигурации и управления для нормальной работы. Обойти Обход проблемы возможен библиотека см статью. Модуль ADC2 На …