История изменений
Исправление vbr, (текущая версия) :
Использовать таймер можно не только через прерывание но и через обычный polling цикл. Когда таймер проходит через 0, то выставляется бит COUNT FLAG в регистре STK_CTRL. Для начала стоит попробовать этот вариант, чтобы убедиться, что этот таймер работает (уж не знаю, почему он может не работать):
void start(void)
{
*((volatile int *) 0xe000e010) = 0x00000001;
*((volatile int *) 0xe000e014) = 500000;
while (*((volatile int *) 0xe000e010) & 0x00010000 == 0) {
}
// led on
while (*((volatile int *) 0xe000e010) & 0x00010000 == 0) {
}
// led off
}
(код пишу в браузере, не проверял)
Кроме того надо иметь в виду, что во-первых таймер тикает со скоростью, пропорциональной частоте процессора и если процессор работает на очень низкой частоте, то значение 500000 нужно уменьшить. Если наоборот на очень высокой, то увеличить, очень часто моргающий диод невооружённым глазом не отличить от просто включенного.
Если удастся «завести» код с polling режимом, значит проблема в вызове обработчика прерывания. Во-первых нужно перепроверить, что в прошивке стоит правильный адрес, во-вторых нужно убедиться, что загрузчик не меняет адрес таблицы обработчиков прерываний. Я сам это не пробовал делать, но насколько я знаю, это настраивается с помощью регистра SCB_VTOR, в-третьих нужно убедиться, что нужное прерывание не отключено (регистры NVIC_ISERx / NVIC_ICERx).
Исправление vbr, :
Использовать таймер можно не только через прерывание но и через обычный polling цикл. Когда таймер проходит через 0, то выставляется бит COUNT FLAG в регистре STK_CTRL. Для начала стоит попробовать этот вариант, чтобы убедиться, что этот таймер работает (уж не знаю, почему он может не работать):
void start(void)
{
*((volatile int *) 0xe000e010) = 0x00000001;
*((volatile int *) 0xe000e014) = 500000;
while (*((volatile int *) 0xe000e010) & 0x00010000 == 0) {
}
// led on
while (*((volatile int *) 0xe000e010) & 0x00010000 == 0) {
}
// led off
}
(код пишу в браузере, не проверял)
Кроме того надо иметь в виду, что во-первых таймер тикает со скоростью, пропорциональной частоте процессора и если процессор работает на очень низкой частоте, то значение 500000 нужно уменьшить.
Если удастся «завести» код с polling режимом, значит проблема в вызове обработчика прерывания. Во-первых нужно перепроверить, что в прошивке стоит правильный адрес, во-вторых нужно убедиться, что загрузчик не меняет адрес таблицы обработчиков прерываний. Я сам это не пробовал делать, но насколько я знаю, это настраивается с помощью регистра SCB_VTOR, в-третьих нужно убедиться, что нужное прерывание не отключено (регистры NVIC_ISERx / NVIC_ICERx).
Исправление vbr, :
Использовать таймер можно не только через прерывание но и через обычный polling цикл. Когда таймер проходит через 0, то выставляется бит COUNT FLAG в регистре STK_CTRL. Для начала стоит попробовать этот вариант, чтобы убедиться, что этот таймер работает (уж не знаю, почему он может не работать):
void start(void)
{
*((volatile int *) 0xe000e010) = 0x00000001;
*((volatile int *) 0xe000e014) = 500000;
while (*((volatile int *) 0xe000e010) & 0x00010000 == 0) {
}
// led on
while (*((volatile int *) 0xe000e010) & 0x00010000 == 0) {
}
// led off
}
(код пишу в браузере, не проверял)
Кроме того надо иметь в виду, что во-первых таймер тикает со скоростью, пропорциональной частоте процессора и если процессор работает на очень низкой частоте, то значение 500000 нужно уменьшить.
Если удастся «завести» код с polling режимом, значит проблема в вызове обработчика прерывания. Во-первых нужно перепроверить, что в прошивке стоит правильный адрес, во-вторых нужно убедиться, что загрузчик не меняет адрес таблицы обработчиков прерываний. Я сам это не пробовал делать, но насколько я знаю, это настраивается с помощью регистра SCB_VTOR, в-третьих нужно убедиться, что нужное прерывание не отключено (регистры NVIC_ISERx / NVIC_ICERx).
На мой взгляд наиболее вероятная причина это именно перенос таблицы прерываний в другое место загрузчиком.
Исправление vbr, :
systick управляется двумя регистрами по адресам 0xE000E010 (Control and Status Register) и 0xE000E014 (Reload Value Register). Я в своём коде меняю отдельные биты, но можно и присвоить целое значение, таким образом убрав шанс на то, что его кто-то меняет.
Использовать таймер можно не только через прерывание но и через обычный polling цикл. Когда таймер проходит через 0, то выставляется бит COUNT FLAG в регистре STK_CTRL. Для начала стоит попробовать этот вариант, чтобы убедиться, что этот таймер работает (уж не знаю, почему он может не работать):
void start(void)
{
*((volatile int *) 0xe000e010) = 0x00000001;
*((volatile int *) 0xe000e014) = 500000;
while (*((volatile int *) 0xe000e010) & 0x00010000 == 0) {
}
// led on
while (*((volatile int *) 0xe000e010) & 0x00010000 == 0) {
}
// led off
}
(код пишу в браузере, не проверял)
Кроме того надо иметь в виду, что во-первых таймер тикает со скоростью, пропорциональной частоте процессора и если процессор работает на очень низкой частоте, то значение 500000 нужно уменьшить.
Если удастся «завести» код с polling режимом, значит проблема в вызове обработчика прерывания. Во-первых нужно перепроверить, что в прошивке стоит правильный адрес, во-вторых нужно убедиться, что загрузчик не меняет адрес таблицы обработчиков прерываний. Я сам это не пробовал делать, но насколько я знаю, это настраивается с помощью регистра SCB_VTOR, в-третьих нужно убедиться, что нужное прерывание не отключено (регистры NVIC_ISERx / NVIC_ICERx).
На мой взгляд наиболее вероятная причина это именно перенос таблицы прерываний в другое место загрузчиком.
Исправление vbr, :
systick управляется двумя регистрами по адресам 0xE000E010 (Control and Status Register) и 0xE000E014 (Reload Value Register). Я в своём коде меняю отдельные биты, но можно и присвоить целое значение, таким образом убрав шанс на то, что его кто-то меняет.
Использовать таймер можно не только через прерывание но и через обычный polling цикл. Когда таймер проходит через 0, то выставляется бит COUNT FLAG в регистре STK_CTRL. Для начала стоит попробовать этот вариант, чтобы убедиться, что этот таймер работает (уж не знаю, почему он может не работать):
void start(void)
{
*((volatile int *) 0xe000e010) = 0x00000001;
*((volatile int *) 0xe000e014) = 500000;
while (*((volatile int *) 0xe000e010) & 0x00010000 == 0) {
}
// led on
while (*((volatile int *) 0xe000e010) & 0x00010000 == 0) {
}
// led off
}
(код пишу в браузере, не проверял)
Кроме того надо иметь в виду, что во-первых таймер тикает со скоростью, пропорциональной частоте процессора и если процессор работает на очень низкой частоте, то значение 500000 нужно уменьшить.
Если удастся «завести» код с polling режимом, значит проблема в вызове обработчика прерывания. Во-первых нужно перепроверить, что в прошивке стоит правильный адрес, во-вторых нужно убедиться, что загрузчик не меняет адрес обработчика прерывания. Я сам это не пробовал делать, но насколько я знаю, это настраивается с помощью регистра SCB_VTOR, в-третьих нужно убедиться, что нужное прерывание не отключено (регистры NVIC_ISERx / NVIC_ICERx).
На мой взгляд наиболее вероятная причина это именно перенос таблицы прерываний в другое место загрузчиком.
Исходная версия vbr, :
systick управляется двумя регистрами по адресам 0xE000E010 (Control and Status Register) и 0xE000E014 (Reload Value Register). Я в своём коде меняю отдельные биты, но можно и присвоить целое значение, таким образом убрав шанс на то, что его кто-то меняет.
Использовать таймер можно не только через прерывание но и через обычный polling цикл. Когда таймер проходит через 0, то выставляется бит COUNT FLAG в регистре STK_CTRL. Для начала стоит попробовать этот вариант, чтобы убедиться, что этот таймер работает (уж не знаю, почему он может не работать):
void start(void)
{
*((volatile int *) 0xe000e010) = 0x00000001;
*((volatile int *) 0xe000e014) = 500000;
while (*((volatile int *) 0xe000e010) & 0x00010000 == 0) {
}
// led on
while (*((volatile int *) 0xe000e010) & 0x00010000 == 0) {
}
// led off
}
(код пишу в браузере, не проверял)
Кроме того надо иметь в виду, что во-первых таймер тикает со скоростью, пропорциональной частоте процессора и если процессор работает на очень низкой частоте, то значение 500000 нужно уменьшить.
Если удастся «завести» код с polling режимом, значит проблема в вызове обработчика прерывания. Во-первых нужно перепроверить, что в прошивке стоит правильный адрес, во-вторых нужно убедиться, что загрузчик не меняет адрес обработчика прерывания. Я сам это не пробовал делать, но насколько я знаю, это настраивается с помощью регистра SCB_VTOR, в-третьих нужно убедиться, что нужное прерывание не отключено (регистры NVIC_ISERx).