Вт ноя 13, 2018 20:41:22
Вт ноя 13, 2018 21:48:49
Сейчас есть широкий выбор 32-ух битных МК. Они не сложные. Для них даже программатор не нужен. Прошиваются через конвертер COM-USART, проще говоря виртуальный COM порт._deep_ писал(а):И второй вопрос, с какого микроконтроллера лучше начать изучение?
Вт ноя 13, 2018 21:50:58
Вт ноя 13, 2018 22:19:13
Ср ноя 14, 2018 13:20:42
Ср ноя 14, 2018 19:53:33
Ср ноя 14, 2018 21:21:17
Ср ноя 14, 2018 21:26:36
Ср ноя 14, 2018 21:45:06
Ср ноя 14, 2018 23:09:13
Сколько AVRов поддерживают JTAG? Всего несколько - ATmega16, ATmega32, ATmega64, ATmega128, ATmega2560 и все. Вряд ли отладчик вообще понадобится. В современных МК, к которым 8-ми битные PIC и AVR не относятся, отладка поддерживается во всех моделях МК и стоят они недорого.AAX писал(а):В случае с атмеловскими микроконтроллерами отладчиком является atmel ice, китайские клоны продаются от $4.
20 выводов это много?Ivanoff-iv писал(а):начать изучение АВР я бы посоветовал с тини 2313 — бошьшое количество ног позволяет делать отладку прицепив кнопки или светодиоды к ногам микросхемы
Ну да, это тот случай когда недостаток выдают за достоинство, а то что за туже цену можно купить гораздо более лучший МК, это ничего не значит? Зачем тратить много и получать мало?Ivanoff-iv писал(а):а относительно неболшое количество периферии позволит не запутаться в ней
Зачем это было писать на асме? Разве бейсик не позволял это делать? Скажу по секрету, на бейсике можно написать драйвер для LPT порта под Windows. Где-то даже был пример обработки прерывания от LPT порта, естественно в драйвере и работало на Windows XP, 7 и др. системах._deep_ писал(а):В ассемблере самое сложное писал модуль - обработчик событий от LPT порта для подключения кнопок.
Ср ноя 14, 2018 23:42:38
Не забывайте, что речь идёт об изучении начинающего. А для такого случая, простота периферии - достоинство.Мурик писал(а):Ну да, это тот случай когда недостаток выдают за достоинство,
На сколько я знаю, винда просто не даст обращаться к регистрам порта напрямую, только через API. По этому написать собственный нормальный драйвер вряд ли получится.Мурик писал(а):Скажу по секрету, на бейсике можно написать драйвер для LPT порта под Windows.
Чт ноя 15, 2018 00:06:11
Чт ноя 15, 2018 00:30:27
Чт ноя 15, 2018 08:50:26
Чт ноя 15, 2018 09:41:24
Аlex писал(а):Да, помню эту dll-ку, юзал её когда писал ещё на VB (лет эдак 15 назад ).
Аlex писал(а):А если с нуля начинать... может и правда стоит что то из арм. На будущее так сказать.
Чт ноя 15, 2018 10:08:31
Чт ноя 15, 2018 12:51:58
Не скажу что чем больше периферии тем сложнее с ней работать. Уровень сложности примерно одинаков так что...Аlex писал(а):Не забывайте, что речь идёт об изучении начинающего. А для такого случая, простота периферии - достоинство.
Так я и писал выше о разработке драйвера LPT порта. http://www.cyberforum.ru/blogs/204791/blog3078.htmlАlex писал(а):На сколько я знаю, винда просто не даст обращаться к регистрам порта напрямую, только через API. По этому написать собственный нормальный драйвер вряд ли получится.
; Сделано по материалам сайта http://www.kernelchip.ru/pcports/PS024.php
; http://www.kernelchip.ru/pcports/PS025.php
Declare DriverEntry(*DriverObject, *RegistryPath)
*Point=@DriverEntry()
!jmp [p_Point]
IncludePath #PB_Compiler_Home+"DDK\"
XIncludeFile "ntddk.pbi"
XIncludeFile "ntstatus.pbi"
XIncludeFile "ntfunct.pbi"
EnableExplicit
#PortAddress = $378
#CONTROL = #PortAddress+2
#IOCTL_hEvent = $200
Structure LOCAL_DEVICE_INFO Align #PB_Structure_AlignC
*InterruptObject.KINTERRUPT
Level.l
Vector.l
Affinity.KAFFINITY
*pEventObject.KEVENT
EndStructure
Procedure Isr(*Interrupt.KINTERRUPT, *Context)
Protected *DeviceObject.DEVICE_OBJECT = *Context
IoRequestDpc(*DeviceObject, *DeviceObject\CurrentIrp, #Null)
ProcedureReturn #True
EndProcedure
Procedure DpcRoutine(*Dpc.KDPC, *DeviceObject.DEVICE_OBJECT, *IrpIRP, *Context)
Protected *DeviceExtension.LOCAL_DEVICE_INFO, *pIrp.IRP
*pIrp = *DeviceObject\CurrentIrp
*DeviceExtension = *DeviceObject\DeviceExtension
WRITE_PORT_UCHAR(#PortAddress, 0)
WRITE_PORT_UCHAR(#PortAddress, 60)
If *DeviceExtension\pEventObject
KeSetEvent(*DeviceExtension\pEventObject, 0, #False);
EndIf
ProcedureReturn 0
EndProcedure
Procedure DeviceIoControl(*DeviceObject.DEVICE_OBJECT, *pIrp.IRP)
Protected ntStatus, *Stack.IO_STACK_LOCATION
Protected inBuffersize, hEvent, *DeviceExtension.LOCAL_DEVICE_INFO
*Stack = IoGetCurrentIrpStackLocation(*pIrp)
inBuffersize = *Stack\Parameters\DeviceIoControl\InputBufferLength
ntStatus = #STATUS_SUCCESS
If *pIrp\SystemBuffer And inBuffersize>=4
Select *Stack\Parameters\DeviceIoControl\IoControlCode
Case #IOCTL_hEvent
hEvent = PeekL(*pIrp\SystemBuffer)
If hEvent
*DeviceExtension = *DeviceObject\DeviceExtension
If *DeviceExtension\pEventObject
ObDereferenceObject(*DeviceExtension\pEventObject)
*DeviceExtension\pEventObject=0
EndIf
ObReferenceObjectByHandle(hEvent, #SYNCHRONIZE, #Null, #UserMode, @*DeviceExtension\pEventObject, #Null)
EndIf
Default
ntStatus = #STATUS_UNSUCCESSFUL
EndSelect
Else
ntStatus = #STATUS_BUFFER_TOO_SMALL
EndIf
*pIrp\IoStatus\Information = 0
*pIrp\IoStatus\Status = ntStatus
IoCompleteRequest(*pIrp, #IO_NO_INCREMENT)
ProcedureReturn ntStatus
EndProcedure
Procedure CreateDispatch(*DeviceObject.DEVICE_OBJECT, *Irp.IRP)
*Irp\IoStatus\Information = 0
*Irp\IoStatus\Status = #STATUS_SUCCESS
IoCompleteRequest(*Irp, #IO_NO_INCREMENT)
ProcedureReturn #STATUS_SUCCESS
EndProcedure
Procedure DriverUnload(*DriverObject.DRIVER_OBJECT)
Protected uniDOSString.UNICODE_STRING
Protected *Extension.LOCAL_DEVICE_INFO = *DriverObject\DeviceObject\DeviceExtension
; Disable Parallel Port IRQ's
WRITE_PORT_UCHAR(#CONTROL, READ_PORT_UCHAR(#CONTROL) & $EF)
; Disconnect Interrupt
IoDisconnectInterrupt(*Extension\InterruptObject)
If *Extension\pEventObject
ObDereferenceObject(*Extension\pEventObject)
*Extension\pEventObject=0
EndIf
; Delete Symbolic Link
RtlInitUnicodeString(@uniDOSString, ?DosDevices)
IoDeleteSymbolicLink (@uniDOSString)
; Delete Device
IoDeleteDevice(*DriverObject\DeviceObject)
DbgPrint("Unload Driver")
!CALL _PB_EOP ; Освобождение ресурсов.
EndProcedure
Procedure DriverEntry(*DriverObject.DRIVER_OBJECT, *RegistryPath.UNICODE_STRING)
Protected *DeviceObject.DEVICE_OBJECT, *DeviceExtension.LOCAL_DEVICE_INFO
Protected MappedVector.l, Irql.KIRQL, EventHandle.l, Status.i
Protected.UNICODE_STRING uniNameString, uniDOSString, EventName
SetPoolMode(#Pool_Auto) ; Автоматический выбор типа памяти в зависимости от IRQL.
DbgPrint("Load Driver")
RtlInitUnicodeString(@uniNameString, ?Device)
RtlInitUnicodeString(@uniDOSString, ?DosDevices)
Status = IoCreateDevice(*DriverObject,SizeOf(LOCAL_DEVICE_INFO),@uniNameString,
#FILE_DEVICE_UNKNOWN,0,#True,@*DeviceObject)
If Status = #STATUS_SUCCESS
*DeviceExtension = *DeviceObject\DeviceExtension
Status = IoCreateSymbolicLink(@uniDOSString, @uniNameString);
If Status = #STATUS_SUCCESS
*DeviceExtension\Level = 7
*DeviceExtension\Vector = *DeviceExtension\Level
MappedVector = HalGetInterruptVector(#Isa,0,*DeviceExtension\Level,
*DeviceExtension\Vector,@Irql,
@*DeviceExtension\Affinity)
IoInitializeDpcRequest(*DeviceObject, @DpcRoutine())
Status = IoConnectInterrupt(@*DeviceExtension\InterruptObject,@Isr(),
*DeviceObject,#Null,MappedVector,Irql,Irql,
#Latched,#False,*DeviceExtension\Affinity,#False)
If Status = #STATUS_SUCCESS
; Enable Parallel Port IRQ's
WRITE_PORT_UCHAR(#CONTROL, READ_PORT_UCHAR(#CONTROL) | $10)
*DriverObject\MajorFunction[#IRP_MJ_CREATE] = @CreateDispatch()
*DriverObject\MajorFunction[#IRP_MJ_CLOSE] = @CreateDispatch()
*DriverObject\MajorFunction[#IRP_MJ_DEVICE_CONTROL] = @DeviceIoControl()
*DriverObject\DriverUnload = @DriverUnload()
RtlInitUnicodeString(@EventName, ?Event)
*DeviceExtension\pEventObject = 0
EndIf
EndIf
EndIf
ProcedureReturn Status
EndProcedure
DataSection
Device:
!du '\Device\pbIntLPT', 0, 0
DosDevices:
!du '\DosDevices\pbIntLPT', 0, 0
Event:
!du '\BaseNamedObjects\SignalEventLPT', 0, 0
EndDataSection
Declare DriverEntry(*DriverObject, *RegistryPath)
*A=@DriverEntry()
!jmp [p_A]
IncludePath #PB_Compiler_Home+"DDK\"
XIncludeFile "ntddk.pbi"
XIncludeFile "ntstatus.pbi"
XIncludeFile "ntfunct.pbi"
#IOCTL_READ_PORT_UCHAR = $200
#IOCTL_WRITE_PORT_UCHAR = $400
; Прямая запись в порт.
Procedure.b InPort(Port.u)
Protected Result.b=0
EnableASM
MOV DX, Port
IN al,DX
MOV Result, al
DisableASM
ProcedureReturn Result
EndProcedure
; Прямое чтение из порта.
Procedure OutPort(Port.u, Byte.a)
EnableASM
MOV al, Byte
MOV DX, Port
OUT DX, al
DisableASM
EndProcedure
Procedure DeviceIoControl(*DeviceObject.DEVICE_OBJECT, *pIrp.IRP)
Protected ntStatus, *Point, *Stack.IO_STACK_LOCATION
*Stack = *pIrp\Tail\Overlay\CurrentStackLocation
inBuffersize = *Stack\Parameters\DeviceIoControl\InputBufferLength
outBuffersize = *Stack\Parameters\DeviceIoControl\OutputBufferLength
CtrlBuff = PeekI(*pIrp\SystemBuffer)
address = CtrlBuff & $FFFF
Byte.a = (CtrlBuff>>16)&255
Code = *Stack\Parameters\DeviceIoControl\IoControlCode
ntStatus = #STATUS_SUCCESS
Select Code
Case #IOCTL_READ_PORT_UCHAR
InByte.b=InPort(address)
PokeB(*pIrp\SystemBuffer, InByte)
*pIrp\IoStatus\Information = 1
Case #IOCTL_WRITE_PORT_UCHAR
OutPort(address, Byte)
*pIrp\IoStatus\Information = 0
Default
ntStatus = #STATUS_UNSUCCESSFUL
*pIrp\IoStatus\Information = 0
EndSelect
*pIrp\IoStatus\Status = ntStatus
IoCompleteRequest(*pIrp, #IO_NO_INCREMENT)
ProcedureReturn ntStatus
EndProcedure
Procedure CreateDispatch(*DeviceObject.DEVICE_OBJECT, *pIrp.IRP)
*pIrp\IoStatus\Information = 0
*pIrp\IoStatus\Status = #STATUS_SUCCESS
IoCompleteRequest(*pIrp, #IO_NO_INCREMENT)
ProcedureReturn #STATUS_SUCCESS
EndProcedure
Procedure UnloadDriver(*DriverObject.DRIVER_OBJECT)
Protected uniDOSString.UNICODE_STRING
RtlInitUnicodeString(@uniDOSString, ?DosDevices)
IoDeleteSymbolicLink (@uniDOSString)
IoDeleteDevice(*DriverObject\DeviceObject)
!CALL _PB_EOP ; Освобождение ресурсов.
EndProcedure
Procedure DriverEntry(*DriverObject.DRIVER_OBJECT, *RegistryPath.UNICODE_STRING)
Protected deviceObject.DEVICE_OBJECT
Protected uniNameString.UNICODE_STRING
Protected uniDOSString.UNICODE_STRING
RtlInitUnicodeString(@uniNameString, ?Device)
RtlInitUnicodeString(@uniDOSString, ?DosDevices)
status = IoCreateDevice(*DriverObject, 0, @uniNameString, #FILE_DEVICE_UNKNOWN, 0, #False, @deviceObject)
If status <> #STATUS_SUCCESS
ProcedureReturn status
EndIf
status = IoCreateSymbolicLink(@uniDOSString, @uniNameString)
If status <> #STATUS_SUCCESS
IoDeleteDevice(@deviceObject) ; Мы должны сами убирать "хвосты" в режиме ядра!
ProcedureReturn status
EndIf
*DriverObject\DriverUnload = @UnloadDriver()
*DriverObject\MajorFunction[#IRP_MJ_CREATE] = @CreateDispatch()
*DriverObject\MajorFunction[#IRP_MJ_DEVICE_CONTROL] = @DeviceIoControl()
ProcedureReturn #STATUS_SUCCESS
EndProcedure
;
DataSection
CompilerSelect #PB_Compiler_Processor
CompilerCase #PB_Processor_x86
Device:
!du '\Device\pbdriverio', 0, 0
DosDevices:
!du '\DosDevices\pbdriverio', 0, 0
CompilerCase #PB_Processor_x64
Device:
!du '\Device\pbdriverio_x64', 0, 0
DosDevices:
!du '\DosDevices\pbdriverio_x64', 0, 0
CompilerEndSelect
EndDataSection
Соврешенно верно. Современные МК только кажутся сложными, а как начнешь изучать выясняется что они довольно простые.AndTer писал(а):А если с нуля начинать... может и правда стоит что то из арм. На будущее так сказать.
Нужен драйвер для x64 и с цифровой подписью.Repytw писал(а):К Win7 x64 прикрутить это у меня её не вышло.
А вы пробовали? Или не глядя осуждаете?Repytw писал(а):Новичку ARM??? Чтобы сразу отбить желание?
#include "stm32f10x_conf.h"
extern uint32_t SystemCoreClock; // В переменной хранится текущая частота ядра МК.
void TIM2_IRQHandler(void) // Функция обработки прерывания от TIM2.
{
// Прерывание по переполнению таймера.
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
{
TIM_ClearITPendingBit(TIM2, TIM_IT_Update); // Сброс флага прерывания.
GPIOC->ODR ^= GPIO_Pin_13; // Инвертирование вывода PC13.
}
}
void Init(void) // Инициализация периферии.
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); // Включение тактирования таймера
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); // и порта GPIOC.
// Настройка порта в/в PC13.
GPIO_InitTypeDef gpio;
gpio.GPIO_Pin = GPIO_Pin_13; // Пин 13.
gpio.GPIO_Mode = GPIO_Mode_Out_PP; // Выход типа push-pull.
gpio.GPIO_Speed = GPIO_Speed_50MHz; // Предельная частота выхода.
GPIO_Init(GPIOC, &gpio); // Конфигурация GPIOC.
// Настройка таймера.
TIM_TimeBaseInitTypeDef Tim;
TIM_TimeBaseStructInit(&Tim); // Настройки таймера по умолчанию.
Tim.TIM_Prescaler = SystemCoreClock / 10000 - 1; // Настройка предделителся чтобы получить частоту 10 КГц.
Tim.TIM_Period = 5000 - 1; // Таймер будет переполняться 10000 / 5000 = 2 раза в секунду.
TIM_TimeBaseInit(TIM2, &Tim); // Инициализация таймера TIM2 с заданными настройками.
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); // Разрешение прерываний по переполнению.
NVIC_EnableIRQ(TIM2_IRQn); // Разрешение прерываний от таймера.
TIM_Cmd(TIM2, ENABLE); // Запуск таймера.
}
int main(void)
{
SystemCoreClockUpdate(); // Вычисление текущей частоты ядра.
Init(); // Инициализация периферии.
while(1)
{
}
}
Может он про другие МК ничего не знает. Зачем изучать устаревшие технологии? Это в дальнейшем вызовет трудности из-за нехватки ресурсов платформы и придется переучиваться. Зачем зря тратить время на то что устарело?Ivanoff-iv писал(а):изначально ТС'ом было сказано про "АВР" и "не ардуино"
Чт ноя 15, 2018 14:28:57
Сколько AVRов поддерживают JTAG?AAX писал(а):В случае с атмеловскими микроконтроллерами отладчиком является atmel ice, китайские клоны продаются от $4.
Чт ноя 15, 2018 14:52:05
Китайские за 4$ тоже поддерживают или нужно покупать фирменный? В вики читали какие ограничения у debugWire?AAX писал(а):Atmel Ice поддерживает debugWireСколько AVRов поддерживают JTAG?AAX писал(а):В случае с атмеловскими микроконтроллерами отладчиком является atmel ice, китайские клоны продаются от $4.
Программные точки останова формируются с помощью входящей в систему команд AVR команды Break. Интегрированная среда разработки обеспечивает сохранение оригинальной команды, заменяемой Break в памяти настольного компьютера, с последующим её восстановлением и продолжением исполнения программы. Таким образом использование программных точек останова тратит ограниченный ресурс данных микроконтроллеров — максимально возможное количество циклов записи стирания программной памяти. Нужно следить, чтобы отладчик не израсходовал его полностью.
Поскольку для отладки используется вход внешнего сброса RESET, становится невозможным проверять схемы внешнего сброса.
В момент останова процессора, чтобы не нарушить работу системы, надо соблюдать осторожность при обращении через отладчик к регистрам ввода-вывода.
В режиме с разрешённой отладкой потребляемая процессором мощность возрастает, поэтому не следует забывать по окончании отладки перевести fuse-переключатель DWEN в исходное состояние.
Представьте что кто-то хочет научится писать для компа или телефона. Он должен начинать с подробного изучения работы процессора?AAX писал(а):Но если цель стоит разобраться с тем, как работает процессор _внутри_, так сказать...
Выше я выкладывал пример без HAL. На уровне регистров STM32 такой же как PIC и AVR. Разве что регистры собраны в группы и находяться в одном адресном пространстве с флешем и ОЗУ, что даже удобнее.AAX писал(а):Получается, что либо ты используешь HAL или, прости Господи, CubeMX - тогда у тебя тонна книг, примеров, и т.д.
Слабо верится в то что вы пробовали что-то писать для STM32. То что вы написали даже близко не соответствует реальности. Еще скажите что писали на асме для STM32, компилировали с помощью makefile и даже не знаете как пользоваться отладчиком?AAX писал(а):Либо вдумчивое чтение 100500-страничной документации производителя от корки до корки.
Автомобиль, комп, смартфон сами с нуля разработали и сделали? Дом сами построили с нуля без чьей либо помощи и не используя ничего готового?AAX писал(а):Плюс собирать софт из чужих "кубиков" мне лично не нравится, т.к. всё, что написано не мной, написано неправильно
Чт ноя 15, 2018 15:19:22