Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Примеры прерываний LPC Cortex
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > ARM, 32bit
vladimir_orl
Здравствуйте. Изучаю LPC Cortex-ы (предпринимаю попытки).

Отладочных плат мне так и не привезли, поэтому использую связку Keil5 + Proteus8.

Сделал учебный проект для LPC1343FBD48. Он нормально эмулируется и кейлом и протеусом.
Помигал светодиодами, поработал с таймером. А с прерываниями - никак.
Честно стараюсь изучить NVIC, но без примеров, похоже, трудно.

Если у кого есть, киньте ссылку на простой пример в кейле для LPC кортекса для таймера или UARTа, etc.
Нечто вроде, мигания светодиодами по прерыванию таймера или по приёму байта от UART/SPI/I2C.

_Артём_
Цитата(vladimir_orl @ Feb 3 2014, 13:30) *
Отладочных плат мне так и не привезли

Это зря - симуляторы не факт что отрабатывают периферию правильно. Лучше в железе проверять. Отладчик недорого стоит.

Цитата(vladimir_orl @ Feb 3 2014, 13:30) *
поэтому использую связку Keil5 + Proteus8.
И что работает? Может этот протез вообще прерывания не отрабатывает? Проверить несложно:

Код
#include "lpc11xx.h"
#include <core_cm0.h>
int main()
{

    __enable_irq();

    NVIC_SetPendingIRQ(UART_IRQn);
    NVIC_EnableIRQ(UART_IRQn);

    NVIC_SetPendingIRQ(TIMER_32_0_IRQn);
    NVIC_EnableIRQ(TIMER_32_0_IRQn);


    while (1) {}

}


Цитата(vladimir_orl @ Feb 3 2014, 13:30) *
А с прерываниями - никак.
Честно стараюсь изучить NVIC, но без примеров, похоже, трудно.
Скачайте среду разработки от NXP - там есть примеры. Переделать на Keil несложно.
vladimir_orl
По крайней мере GPIO и таймеры отрабатывает.

Цитата
Скачайте среду разработки от NXP - там есть примеры


Что за среда? Подскажите. CodeRed?

По крайней мере GPIO и таймеры отрабатывает.

Цитата
Скачайте среду разработки от NXP - там есть примеры


Что за среда? Подскажите. CodeRed?

Смотрю на http://www.nxp.com/, что-то нет ничего похожего...
_Артём_
Цитата(vladimir_orl @ Feb 3 2014, 14:23) *
По крайней мере GPIO и таймеры отрабатывает.
Тогда проверьте происходит ли переход на обработчик при установке его в состояние pending.
Цитата(vladimir_orl @ Feb 3 2014, 14:23) *
Что за среда? Подскажите. CodeRed?
LPCXpresso. Вроде CodeRed или Embedded Artist - точно не помню. Но она бесплатна.
vladimir_orl
Цитата
Отладчик недорого стоит.


В терраэлектронике j-link / u-link около 10000. И плюс плата.

Читал раньше продавали lpcXpresso но сейчас не нахожу где купить.
Да и судя по всему lpcXpresso + CodeRed это нечто из области ардуино.

Хотя для начала можно и его. Чтобы плату сразу с компьютера заливать можно было. Даже если без отладчика. И периферия выведена была.
_Артём_
Цитата(vladimir_orl @ Feb 3 2014, 14:25) *
Смотрю на http://www.nxp.com/, что-то нет ничего похожего...

Смотрите тут или в google.
vladimir_orl
Цитата
Тогда проверьте происходит ли переход на обработчик при установке его в состояние pending


Дело как раз в том что я не знаю как настраивать обработчик NVIC. Как говорится смотрю в книгу (в даташиты), а вижу...

То есть хотя бы пример

Код
NVIC config()

Timer interrupt config()ж

Timer ISR()ж


while(1);



Чтобы понять что и как.

Не "ж" конечно а ";".

А codered разве бесплатный? Подскажите где для него платочку купить можно?
_Артём_
Цитата(vladimir_orl @ Feb 3 2014, 14:30) *
В терраэлектронике j-link / u-link около 10000. И плюс плата.
Дешевле китайский jlink купить - MT-Link тоже клон.
Цитата(vladimir_orl @ Feb 3 2014, 14:30) *
Читал раньше продавали lpcXpresso но сейчас не нахожу где купить.
Да и судя по всему lpcXpresso + CodeRed это нечто из области ардуино.
Нет. lpcXpresso - тот же jlink, но привязанный к среде lpcXpresso. Зато дешево. Сама среда - это Eclipse+GCC. GCC можете выбрать сами, какая больше нравится.
Цитата(vladimir_orl @ Feb 3 2014, 14:30) *
Хотя для начала можно и его. Чтобы плату сразу с компьютера заливать можно было. Даже если без отладчика. И периферия выведена была.
Всё есть + отладчик.
mempfis_
Может Вам стоит зарегистрироваться на http://www.lpcware.com/ и скачать оттуда примеры?
Регистрация там бесплатная и примеры есть и под Keil и под IAR.
Если есть желание - можете поставить последний иар с ключиком. Там есть много примеров.
_Артём_
Цитата(vladimir_orl @ Feb 3 2014, 14:36) *
Дело как раз в том что я не знаю как настраивать обработчик NVIC. Как говорится смотрю в книгу (в даташиты), а вижу...
То есть хотя бы пример

Так приводил же...
Более подробно так:

Код
#include "lpc11xx.h"
#include <core_cm0.h>

volatile uint8_t UartIntWas;
void UART_IRQ_Handler()
{
    UartIntWas=1;
    LPC_GPIO0->DATA|=(1<<7);
}

int main()
{
    NVIC_SetPendingIRQ(UART_IRQn);
    NVIC_EnableIRQ(UART_IRQn);
    while (UartIntWas==0);

    asm("nop");
    while (1);

vladimir_orl
Цитата
Если есть желание - можете поставить последний иар с ключиком


Может ссылку дадите?

На LPCWare тоже смотрел. Там тоже сразу с lib-ов начинается.

Спасибо, буду искать "букварь" по LPC...
SyncLair
Цитата(vladimir_orl @ Feb 3 2014, 16:30) *
Читал раньше продавали lpcXpresso но сейчас не нахожу где купить.
Да и судя по всему lpcXpresso + CodeRed это нечто из области ардуино.

Пользую olimex-ов ским отладчиком -- не идеален но работает.

А по поводу настройки прерываний -- это вопрос даже не LPC? а ядра Cortex оно везде одно и то же
поэтому, чисто гипотетически код настройки прерываний не зависит от среды, зависит только от ревизии ядра. Работа с перываниями описана в стандарте CMSIS -- "NVIC Functions".
mempfis_
Цитата(vladimir_orl @ Feb 3 2014, 16:54) *
Может ссылку дадите?

На LPCWare тоже смотрел. Там тоже сразу с lib-ов начинается.

Спасибо, буду искать "букварь" по LPC...


Попроситесь в свои. На ftp лежит.
Можно тут посмотреть http://kinozal.tv/details.php?id=928594 (естественно с регистрацией), могу на файлобменник скинуть.

В CORTEXax для обслуживания прерываний используется NVIC. Для работы с ним необх. несколько простых процедур:

CODE

/*************************************************************************
*
* Used with ICCARM and AARM.
*
* © Copyright IAR Systems 2009
*
* File name : irq.c
* Description : Nested Vectored Interrup Controller fuctions
*
******************************************************************************/


/*************************************************************************
* Function Name: NVIC_IntEnable
* Parameters: IntNumber - Interrup number
* Return: void
*
* Description: Enable interrup at NVIC
*
*
*************************************************************************/
void NVIC_IntEnable(unsigned int IntNumber)
{
if(IntNumber>31) return;

NVIC_ISER = (1UL<<IntNumber);
}

/*************************************************************************
* Function Name: NVIC_IntDisable
* Parameters: IntNumber - Interrup number
* Return: void
*
* Description: Disables interrup at NVIC
*
*
*************************************************************************/
void NVIC_IntDisable(unsigned int IntNumber)
{
if(IntNumber>31) return;

NVIC_ICER = (1UL<<IntNumber);
}

/*************************************************************************
* Function Name: NVIC_ClrPend
* Parameters: IntNumber - Interrup number
* Return: void
*
* Description:Clear pending interrupt at NVIC
*
*
*************************************************************************/
void NVIC_ClrPend(unsigned int IntNumber)
{
if(IntNumber>31) return;

NVIC_ICPR = (1UL<<IntNumber);
}

/*************************************************************************
* Function Name: NVIC_ClrPend
* Parameters: IntNumber - Interrup number, Interrupt Priority
* Return: void
*
* Description:Sets Interrupt priority
*
*
*************************************************************************/
void NVIC_IntPri(unsigned int IntNumber, unsigned char Priority)
{
if(IntNumber>31) return;

volatile unsigned char * pNVIC_IntPri = (unsigned char *)&NVIC_IPR0;

pNVIC_IntPri += IntNumber;
*pNVIC_IntPri = Priority&0x3;
}

void install_irq(unsigned int IntNumber, unsigned int Priority)
{
NVIC_IntDisable(IntNumber);
NVIC_IntPri(IntNumber, Priority);
NVIC_IntEnable(IntNumber);
NVIC_ClrPend(IntNumber);
}

/******************************************************************************
** End Of File
******************************************************************************/


Гдето в файле описания регистров вашего мк находите номера прерываний (пример для mkl15):

CODE
/** Interrupt Number Definitions */
typedef enum {
INT_Initial_Stack_Pointer = 0, /**< Initial stack pointer */
INT_Initial_Program_Counter = 1, /**< Initial program counter */
INT_NMI = 2, /**< Non-maskable interrupt */
INT_Hard_Fault = 3, /**< Hard fault exception */
INT_Reserved4 = 4, /**< Reserved interrupt 4 */
INT_Reserved5 = 5, /**< Reserved interrupt 5 */
INT_Reserved6 = 6, /**< Reserved interrupt 6 */
INT_Reserved7 = 7, /**< Reserved interrupt 7 */
INT_Reserved8 = 8, /**< Reserved interrupt 8 */
INT_Reserved9 = 9, /**< Reserved interrupt 9 */
INT_Reserved10 = 10, /**< Reserved interrupt 10 */
INT_SVCall = 11, /**< A supervisor call exception */
INT_Reserved12 = 12, /**< Reserved interrupt 12 */
INT_Reserved13 = 13, /**< Reserved interrupt 13 */
INT_PendableSrvReq = 14, /**< PendSV exception - request for system level service */
INT_SysTick = 15, /**< SysTick interrupt */
INT_DMA0 = 16, /**< DMA channel 0 transfer complete/error interrupt */
INT_DMA1 = 17, /**< DMA channel 1 transfer complete/error interrupt */
INT_DMA2 = 18, /**< DMA channel 2 transfer complete/error interrupt */
INT_DMA3 = 19, /**< DMA channel 3 transfer complete/error interrupt */
INT_Reserved20 = 20, /**< Reserved interrupt 20 */
INT_FTFA = 21, /**< FTFA command complete/read collision interrupt */
INT_LVD_LVW = 22, /**< Low Voltage Detect, Low Voltage Warning */
INT_LLW = 23, /**< Low Leakage Wakeup */
INT_I2C0 = 24, /**< I2C0 interrupt */
INT_I2C1 = 25, /**< I2C0 interrupt 25 */
INT_SPI0 = 26, /**< SPI0 interrupt */
INT_SPI1 = 27, /**< SPI1 interrupt */
INT_UART0 = 28, /**< UART0 status/error interrupt */
INT_UART1 = 29, /**< UART1 status/error interrupt */
INT_UART2 = 30, /**< UART2 status/error interrupt */
INT_ADC0 = 31, /**< ADC0 interrupt */
INT_CMP0 = 32, /**< CMP0 interrupt */
INT_TPM0 = 33, /**< TPM0 fault, overflow and channels interrupt */
INT_TPM1 = 34, /**< TPM1 fault, overflow and channels interrupt */
INT_TPM2 = 35, /**< TPM2 fault, overflow and channels interrupt */
INT_RTC = 36, /**< RTC interrupt */
INT_RTC_Seconds = 37, /**< RTC seconds interrupt */
INT_PIT = 38, /**< PIT timer interrupt */
INT_Reserved39 = 39, /**< Reserved interrupt 39 */
INT_USB0 = 40, /**< USB0 interrupt */
INT_DAC0 = 41, /**< DAC0 interrupt */
INT_TSI0 = 42, /**< TSI0 interrupt */
INT_MCG = 43, /**< MCG interrupt */
INT_LPTimer = 44, /**< LPTimer interrupt */
INT_Reserved45 = 45, /**< Reserved interrupt 45 */
INT_PORTA = 46, /**< Port A interrupt */
INT_PORTD = 47 /**< Port D interrupt */
} IRQInterruptIndex;


Прерывания, обслуживаемые NVIC начинаются с прерывания #16 - INT_DMA0
Поэтому номер прерывания необходимо передавать как номер инсталлируемого прерывания-16
Или преопределить номера так:
CODE
/* Interrupt Vector Table Function Pointers */
#define DMA0_irq_no 0 // Vector No 16 /**< DMA channel 0 transfer complete/error interrupt */
#define DMA1_irq_no 1 // Vector No 17 /**< DMA channel 1 transfer complete/error interrupt */
#define DMA2_irq_no 2 // Vector No 18 /**< DMA channel 2 transfer complete/error interrupt */
#define DMA3_irq_no 3 // Vector No 19 /**< DMA channel 3 transfer complete/error interrupt */
#define FTFA_irq_no 5 // Vector No 21 /**< FTFA command complete/read collision interrupt */
#define LVD_irq_no 6 // Vector No 22 /**< Low Voltage Detect, Low Voltage Warning */
#define LLWU_irq_no 7 // Vector No 23 /**< Low Leakage Wakeup */
#define I2C0_irq_no 8 // Vector No 24 /**< I2C0 interrupt */
#define I2C1_irq_no 9 // Vector No 25 /**< I2C0 interrupt 25 */
#define SPI0_irq_no 10 // Vector No 26 /**< SPI0 interrupt */
#define SPI1_irq_no 11 // Vector No 27 /**< SPI1 interrupt */
#define UART0SE_irq_no 12 // Vector No 28 /**< UART0 status/error interrupt */
#define UART1SE_irq_no 13 // Vector No 29 /**< UART1 status/error interrupt */
#define UART2SE_irq_no 14 // Vector No 30 /**< UART2 status/error interrupt */
#define ADC0_irq_no 15 // Vector No 31 /**< ADC0 interrupt */
#define CMP0_irq_no 16 // Vector No 32 /**< CMP0 interrupt */
#define FTM0_irq_no 17 // Vector No 33 /**< TPM0 fault, overflow and channels interrupt */
#define FTM1_irq_no 18 // Vector No 34 /**< TPM1 fault, overflow and channels interrupt */
#define FTM2_irq_no 19 // Vector No 35 /**< TPM2 fault, overflow and channels interrupt */
#define RTCA_irq_no 20 // Vector No 36 /**< RTC interrupt */
#define RTCS_irq_no 21 // Vector No 37 /**< RTC seconds interrupt */
#define PIT_irq_no 22 // Vector No 38 /**< PIT timer interrupt */
#define USBOTG_irq_no 24 // Vector No 40 /**< USB0 interrupt */
#define DAC_irq_no 25 // Vector No 41 /**< DAC0 interrupt */
#define TSI_irq_no 26 // Vector No 42 /**< TSI0 interrupt */
#define MCG_irq_no 27 // Vector No 43 /**< MCG interrupt */
#define LPTMR_irq_no 28 // Vector No 44 /**< LPTimer interrupt */
#define PortA_irq_no 30 // Vector No 46 /**< Port A interrupt */
#define PortD_irq_no 31 // Vector No 47 /**< Port D interrupt */


2 эквивалентных варианта инсталляции прерывания
Код
install_irq(INT_UART2-16, 0);
install_irq(UART2SE_irq_no, 0);


Самое интересно - это правильно расположить обработчики прерываний в программе.
Для этого необходимо определить таблицу векторов прерываний, расположив её по адресу .intvec:
CODE
#pragma language=extended
#pragma segment="CSTACK"

typedef void (*vector_entry)(void);
typedef union { vector_entry __fun; void * __ptr; } intvec_elem;

const intvec_elem __vector_table[] @ ".intvec" =
{
{ .__ptr = __sfe( "CSTACK" ) }, /* Initial SP */
VECTOR_001, /* Initial PC */
VECTOR_002,
VECTOR_003,
VECTOR_004,
VECTOR_005,
VECTOR_006,
VECTOR_007,
VECTOR_008,
VECTOR_009,
VECTOR_010,
VECTOR_011,
VECTOR_012,
VECTOR_013,
VECTOR_014,
VECTOR_015,
VECTOR_016,
VECTOR_017,
VECTOR_018,
VECTOR_019,
VECTOR_020,
VECTOR_021,
VECTOR_022,
VECTOR_023,
VECTOR_024,
VECTOR_025,
VECTOR_026,
VECTOR_027,
VECTOR_028,
VECTOR_029,
VECTOR_030,
VECTOR_031,
VECTOR_032,
VECTOR_033,
VECTOR_034,
VECTOR_035,
VECTOR_036,
VECTOR_037,
VECTOR_038,
VECTOR_039,
VECTOR_040,
VECTOR_041,
VECTOR_042,
VECTOR_043,
VECTOR_044,
VECTOR_045,
VECTOR_046,
VECTOR_047,
};


Также ранее переопределить VECTOR_xxx

CODE
// Address Vector IRQ Source module Source description
#define VECTOR_001 __startup // 0x0000_0004 1 - ARM core Initial Program Counter
#define VECTOR_002 default_isr // 0x0000_0008 2 - ARM core Non-maskable Interrupt (NMI)
#define VECTOR_003 default_isr // 0x0000_000C 3 - ARM core Hard Fault
#define VECTOR_004 default_isr // 0x0000_0010 4 -
#define VECTOR_005 default_isr // 0x0000_0014 5 -
#define VECTOR_006 default_isr // 0x0000_0018 6 -
#define VECTOR_007 default_isr // 0x0000_001C 7 -
#define VECTOR_008 default_isr // 0x0000_0020 8 -
#define VECTOR_009 default_isr // 0x0000_0024 9 -
#define VECTOR_010 default_isr // 0x0000_0028 10 -
#define VECTOR_011 default_isr // 0x0000_002C 11 - ARM core Supervisor call (SVCall)
#define VECTOR_012 default_isr // 0x0000_0030 12 -
#define VECTOR_013 default_isr // 0x0000_0034 13 -
#define VECTOR_014 default_isr // 0x0000_0038 14 - ARM core Pendable request for system service (PendableSrvReq)
#define VECTOR_015 default_isr // 0x0000_003C 15 - ARM core System tick timer (SysTick)
#define VECTOR_016 default_isr // 0x0000_0040 16 0 DMA DMA Channel 0 transfer complete and error
#define VECTOR_017 default_isr // 0x0000_0044 17 1 DMA DMA Channel 1 transfer complete and error
#define VECTOR_018 default_isr // 0x0000_0048 18 2 DMA DMA Channel 2 transfer complete and error
#define VECTOR_019 default_isr // 0x0000_004C 19 3 DMA DMA Channel 3 transfer complete and error
#define VECTOR_020 default_isr // 0x0000_0050 20
#define VECTOR_021 default_isr // 0x0000_0054 21 5 FTFA Command complete and read collision
#define VECTOR_022 default_isr // 0x0000_0058 22 6 PMC Low Voltage detect, low-voltage warning
#define VECTOR_023 default_isr // 0x0000_005C 23 7 LLWU Low Leakage Wakeup
#define VECTOR_024 default_isr // 0x0000_0060 24 8 IIC0
#define VECTOR_025 default_isr // 0x0000_0064 25 9 IIC1
#define VECTOR_026 default_isr // 0x0000_0068 26 10 SPI0 Single interrupt vector for all sources
#define VECTOR_027 default_isr // 0x0000_006C 27 11 SPI1 Single interrupt vector for all sources
#define VECTOR_028 default_isr // 0x0000_0070 28 12 UART0 Status and error
#define VECTOR_029 default_isr // 0x0000_0074 29 13 UART1 Status and error
#define VECTOR_030 default_isr // 0x0000_0078 30 14 UART2 Status and error
#define VECTOR_031 default_isr // 0x0000_007C 31 15 ADC0
#define VECTOR_032 default_isr // 0x0000_0080 32 16 CMP0
#define VECTOR_033 default_isr // 0x0000_0084 33 17 TPM0
#define VECTOR_034 default_isr // 0x0000_0088 34 18 TPM1
#define VECTOR_035 default_isr // 0x0000_008C 35 19 TPM2
#define VECTOR_036 default_isr // 0x0000_0090 36 20 RTC Alarm interrupt
#define VECTOR_037 default_isr // 0x0000_0094 37 21 RTC Seconds interrupt
#define VECTOR_038 default_isr // 0x0000_0098 38 22 PIT Single interrupt vector for all channels
#define VECTOR_039 default_isr // 0x0000_009C 39 23
#define VECTOR_040 default_isr // 0x0000_00A0 40 24 USB OTG
#define VECTOR_041 default_isr // 0x0000_00A4 41 25 DAC0
#define VECTOR_042 default_isr // 0x0000_00A8 42 26 TSI0
#define VECTOR_043 default_isr // 0x0000_00AC 43 27 MCG
#define VECTOR_044 default_isr // 0x0000_00B0 44 28 LPTMR0
#define VECTOR_045 default_isr // 0x0000_00B4 45 29
#define VECTOR_046 default_isr // 0x0000_00B8 46 30 Port Control Module Pin detect (Port A)
#define VECTOR_047 default_isr // 0x0000_00BC 47 31 Port Control Moudle Pin detect (Port D)
#define VECTOR_PADDING (pointer*)0xffffffff/*not used*/

//тут переопределяем реальные вектора прерываний
extern void UART2_IRQHandler(void);
#undef VECTOR_030
#define VECTOR_030 UART2_IRQHandler



В некоторых примерах названия обработчиков прерываний и их расположение во flash определены в стартапе, а в некоторых необходимо вот таким образом всё определять.


В итоге если всё правильно сделаете, то в этой таблице будут находится адреса всех обработчиков прерываний. Если вектор прерывания не определён, то в соотв. позици будет адрес default_isr, иначе адрес реального обработчика прерывания (UART2_IRQHandler).
_Артём_
Цитата(mempfis_ @ Feb 3 2014, 15:36) *
Попроситесь в свои. На ftp лежит.

Можно проще - IAR, Keil, Atollic и другие дают возможность попробовать свои IDE бесплатно с ограничениями.

Цитата(mempfis_ @ Feb 3 2014, 15:36) *
Можно тут посмотреть http://kinozal.tv/details.php?id=928594 (естественно с регистрацией), могу на файлобменник скинуть.
На rutracker-е есть более свежие версии.

Цитата(mempfis_ @ Feb 3 2014, 15:36) *
Самое интересно - это правильно расположить обработчики прерываний в программе.
Для этого необходимо определить таблицу векторов прерываний, расположив её по адресу .intvec:
CODE
#pragma language=extended
#pragma segment="CSTACK"

typedef void (*vector_entry)(void);
typedef union { vector_entry __fun; void * __ptr; } intvec_elem;

const intvec_elem __vector_table[] @ ".intvec" =
{
{ .__ptr = __sfe( "CSTACK" ) }, /* Initial SP */
VECTOR_001, /* Initial PC */
VECTOR_002,
VECTOR_003,
VECTOR_004,
Вот им в IAR-е неймётся - дай чего нибудь переопределить по-своему...

Цитата(mempfis_ @ Feb 3 2014, 15:36) *
Также ранее переопределить VECTOR_xxx
Код
                                        // Address   Vector IRQ   Source module   Source description
#define VECTOR_001      __startup          // 0x0000_0004 1 -          ARM core        Initial Program Counter
#define VECTOR_002      default_isr     // 0x0000_0008 2 -          ARM core        Non-maskable Interrupt (NMI)
А это вообще зачем?

Цитата(mempfis_ @ Feb 3 2014, 15:36) *
В некоторых примерах названия обработчиков прерываний и их расположение во flash определены в стартапе, а в некоторых необходимо вот таким образом всё определять.
Прямо-таки "необходимо"? Зачем?
mempfis_
Цитата(_Артём_ @ Feb 3 2014, 20:11) *
Прямо-таки "необходимо"? Зачем?


Не я писал - так что не спрашивайте у меня.
Можно было доработать стартап для mkl15:
CODE
/*
* File: crt0.s
* Purpose: Lowest level routines for Kinetis L Family.
*
* Notes:
*
*/


; AREA Crt0, CODE, READONLY ; name this block of code
SECTION .noinit : CODE

EXPORT __startup
__startup
LDR r0,=0 ; Initialize the GPRs
LDR r1,=0
LDR r2,=0
LDR r3,=0
LDR r4,=0
LDR r5,=0
LDR r6,=0
LDR r7,=0

CPSIE i ; Unmask interrupts
import start
BL start ; call the C code
__done
B __done

END


и сделать его похожим на стартап lpc11:

CODE
/**************************************************
*
* Part one of the system initialization code, contains low-level
* initialization, plain thumb variant.
*
* Copyright 2012 IAR Systems. All rights reserved.
*
* $Revision: 55913 $
*
**************************************************/

;
; The modules in this file are included in the libraries, and may be replaced
; by any user-defined modules that define the PUBLIC symbol _program_start or
; a user defined start symbol.
; To override the cstartup defined in the library, simply add your modified
; version to the workbench project.
;
; The vector table is normally located at address 0.
; When debugging in RAM, it can be located in RAM, aligned to at least 2^6.
; The name "__vector_table" has special meaning for C-SPY:
; it is where the SP start value is found, and the NVIC vector
; table register (VTOR) is initialized to this address if != 0.
;
; Cortex-M version
;

MODULE ?cstartup

;; Forward declaration of sections.
SECTION CSTACK:DATA:NOROOT(3)

SECTION .intvec:CODE:NOROOT(2)

EXTERN __iar_program_start

PUBLIC __vector_table
PUBLIC __vector_table_0x1c
DATA
__vector_table
DCD sfe(CSTACK) ; Top of Stack
DCD __iar_program_start ; Reset Handler
DCD NMI_Handler ; NMI Handler
DCD HardFault_Handler ; Hard Fault Handler
DCD MemManage_Handler ; MPU Fault Handler
DCD BusFault_Handler ; Bus Fault Handler
DCD UsageFault_Handler ; Usage Fault Handler
__vector_table_0x1c
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD SVC_Handler ; SVCall Handler
DCD DebugMon_Handler ; Debug Monitor Handler
DCD 0 ; Reserved
DCD PendSV_Handler ; PendSV Handler
DCD SysTick_Handler ; SysTick Handler

; External Interrupts
DCD FLEX_INT0_IRQHandler ; All GPIO pin can be routed to FLEX_INTx
DCD FLEX_INT1_IRQHandler
DCD FLEX_INT2_IRQHandler
DCD FLEX_INT3_IRQHandler
DCD FLEX_INT4_IRQHandler
DCD FLEX_INT5_IRQHandler
DCD FLEX_INT6_IRQHandler
DCD FLEX_INT7_IRQHandler
DCD GINT0_IRQHandler
DCD GINT1_IRQHandler ; PIO0 (0:7)
DCD Reserved_IRQHandler ; Reserved
DCD Reserved_IRQHandler
DCD Reserved_IRQHandler
DCD Reserved_IRQHandler
DCD SSP1_IRQHandler ; SSP1
DCD I2C_IRQHandler ; I2C
DCD TIMER16_0_IRQHandler ; 16-bit Timer0
DCD TIMER16_1_IRQHandler ; 16-bit Timer1
DCD TIMER32_0_IRQHandler ; 32-bit Timer0
DCD TIMER32_1_IRQHandler ; 32-bit Timer1
DCD SSP0_IRQHandler ; SSP0
DCD UART_IRQHandler ; UART
DCD Reserved_IRQHandler ; Reserved
DCD Reserved_IRQHandler ; Reserved
DCD ADC_IRQHandler ; A/D Converter
DCD WDT_IRQHandler ; Watchdog timer
DCD BOD_IRQHandler ; Brown Out Detect
DCD FMC_IRQHandler ; Flash Memory Controller
DCD Reserved_IRQHandler ; Reserved
DCD Reserved_IRQHandler ; Reserved
DCD Reserved_IRQHandler ; Reserved
DCD Reserved_IRQHandler ; Reserved

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Default interrupt handlers.
;;
THUMB
SECTION .text:CODE:REORDER:NOROOT(1)

PUBWEAK NMI_Handler
PUBWEAK HardFault_Handler
PUBWEAK MemManage_Handler
PUBWEAK BusFault_Handler
PUBWEAK UsageFault_Handler
PUBWEAK SVC_Handler
PUBWEAK DebugMon_Handler
PUBWEAK PendSV_Handler
PUBWEAK SysTick_Handler
PUBWEAK FLEX_INT0_IRQHandler
PUBWEAK FLEX_INT1_IRQHandler
PUBWEAK FLEX_INT2_IRQHandler
PUBWEAK FLEX_INT3_IRQHandler
PUBWEAK FLEX_INT4_IRQHandler
PUBWEAK FLEX_INT5_IRQHandler
PUBWEAK FLEX_INT6_IRQHandler
PUBWEAK FLEX_INT7_IRQHandler
PUBWEAK GINT0_IRQHandler
PUBWEAK GINT1_IRQHandler
PUBWEAK SSP1_IRQHandler
PUBWEAK I2C_IRQHandler
PUBWEAK TIMER16_0_IRQHandler
PUBWEAK TIMER16_1_IRQHandler
PUBWEAK TIMER32_0_IRQHandler
PUBWEAK TIMER32_1_IRQHandler
PUBWEAK SSP0_IRQHandler
PUBWEAK UART_IRQHandler
PUBWEAK ADC_IRQHandler
PUBWEAK WDT_IRQHandler
PUBWEAK BOD_IRQHandler
PUBWEAK FMC_IRQHandler
PUBWEAK Reserved_IRQHandler

NMI_Handler:
B .
HardFault_Handler:
B .
MemManage_Handler:
B .
BusFault_Handler:
B .
UsageFault_Handler:
B .
SVC_Handler:
B .
DebugMon_Handler:
B .
PendSV_Handler:
B .
SysTick_Handler:
B .
FLEX_INT0_IRQHandler:
B .
FLEX_INT1_IRQHandler:
B .
FLEX_INT2_IRQHandler:
B .
FLEX_INT3_IRQHandler:
B .
FLEX_INT4_IRQHandler:
B .
FLEX_INT5_IRQHandler:
B .
FLEX_INT6_IRQHandler:
B .
FLEX_INT7_IRQHandler:
B .
GINT0_IRQHandler:
B .
GINT1_IRQHandler:
B .
SSP1_IRQHandler:
B .
I2C_IRQHandler:
B .
TIMER16_0_IRQHandler:
B .
TIMER16_1_IRQHandler:
B .
TIMER32_0_IRQHandler:
B .
TIMER32_1_IRQHandler:
B .
SSP0_IRQHandler:
B .
UART_IRQHandler:
B .
ADC_IRQHandler:
B .
WDT_IRQHandler:
B .
BOD_IRQHandler:
B .
FMC_IRQHandler:
B .
Reserved_IRQHandler:
B .
Default_Handler:
B .

SECTION .crp:CODE:ROOT(2)
DATA
/* Code Read Protection
NO_ISP 0x4E697370 - Prevents sampling of pin PIO0_1 for entering ISP mode
CRP1 0x12345678 - Write to RAM command cannot access RAM below 0x10000300.
- Copy RAM to flash command can not write to Sector 0.
- Erase command can erase Sector 0 only when all sectors
are selected for erase.
- Compare command is disabled.
- Read Memory command is disabled.
CRP2 0x87654321 - Read Memory is disabled.
- Write to RAM is disabled.
- "Go" command is disabled.
- Copy RAM to flash is disabled.
- Compare is disabled.
CRP3 0x43218765 - Access to chip via the SWD pins is disabled. ISP entry
by pulling PIO0_1 LOW is disabled if a valid user code is
present in flash sector 0.
Caution: If CRP3 is selected, no future factory testing can be
performed on the device.
*/
DCD 0xFFFFFFFF

END


тогда не нужно было бы всей этой ерунды с созданием таблицы векторов и их переопределениями.
Но мне что так, что так понятно как оно работает и что получится в итоге.
vladimir_orl
Да. Спасибо. Это как учиться плавать. Вначале всё делаешь как надо и удивляешься почему не получается.
Потом, когда научился, удивляешься почему раньше не умел.

Вначале прерывание от таймера детально разберу, а там уже на более серьёзное переходить буду.

Сделал программу для LPC1343. По совпадению таймера должно генерироваться прерывание:


Код
#include <LPC13xx.h>
#include <core_cm3.h>

void TIMER_32_0_IRQ_Handler()
{
    LPC_GPIO0->DATA|=(1<<7);
}



int main()
{
    LPC_GPIO0->DIR = 0xFFFF;
    LPC_TMR32B0->MCR = 0x01;
    LPC_TMR32B0->MR0 = 0x30;
    __enable_irq();
    NVIC_EnableIRQ(TIMER_32_0_IRQn);
    NVIC_SetPendingIRQ(TIMER_32_0_IRQn);
    LPC_TMR32B0->TCR = 0x01;
    while(1){
        __asm("nop");
    }
}



Программа зависает на строке NVIC_SetPendingIRQ(TIMER_32_0_IRQn);
Подскажите, может в стартапе подправить что надо?

И SystemInit(); вначале дописал, всё равно зависает.
vladimir_orl
Заработало!


Вот код:


Код
#include <LPC13xx.h>
#include <core_cm3.h>

unsigned long p = 0;


void TIMER32_0_IRQHandler()
{
    LPC_GPIO0->DATA = p;
    ++p;
}



int main()
{
    SystemInit();
    LPC_GPIO0->DIR = 0xFFFFFFFF;

    LPC_TMR32B0->MCR = 0x01;
    LPC_TMR32B0->MR0 = 0x30;
    
    __enable_irq();
    
    
    NVIC_EnableIRQ(TIMER_32_0_IRQn);
    TIMER32_0_IRQHandler(TIMER_32_0_IRQn);
    
    LPC_TMR32B0->TCR = 0x01;
    while(1){
        __asm("nop");
        __asm("nop");
        __asm("nop");
    }
}


Всем большое спасибо!
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.