logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

LPC2364 - konfiguracja PLL w Eclipse z projektem dla LPC2103

Yaro126 25 Mar 2012 00:03 1779 10
  • #1 10716130
    Yaro126
    Poziom 20  
    Posty: 497
    Pomógł: 31
    Ocena: 43
    Witam,
    Posiadam mikrokontroler LPC2364, w którym nie potrafię uruchomić pętli PLL. Środowisko programistyczne to Eclipse skonfigurowane według tutoriala Freddiego Chopina. Do uruchomienia LPC2364 posłużyłem się projektem przykładowym naipisanym dla LPC2103 i znajdującym się również na stronie Freddiego Chopina.

    Zmieniony został plik linkera:
    /******************************************************************************
    * author: Freddie Chopin, http://www.freddiechopin.info/
    * file: LPC2103_rom.ld
    * last change: 2012-01-08
    *
    * chip: LPC2364
    * compiler: arm-none-eabi-gcc (Sourcery CodeBench Lite 2011.09-69) 4.6.1
    *
    * description:
    * Linker script for LPC2364 chip (128kB Flash, 34kB SRAM).
    ******************************************************************************/
    
    SEARCH_DIR(.);
    
    /*
    +=============================================================================+
    | format configurations
    +=============================================================================+
    */
    
    OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm");
    OUTPUT_ARCH(arm);
    
    /*
    +=============================================================================+
    | stacks sizes
    +=============================================================================+
    */
    
    __user_system_stack_size = 1024;
    __fiq_stack_size = 0;
    __irq_stack_size = 0;
    __supervisor_stack_size = 0;
    __abort_stack_size = 0;
    __undefined_stack_size = 0;
    
    PROVIDE(__user_system_stack_size = __user_system_stack_size);
    PROVIDE(__fiq_stack_size = __fiq_stack_size);
    PROVIDE(__irq_stack_size = __irq_stack_size);
    PROVIDE(__supervisor_stack_size = __supervisor_stack_size);
    PROVIDE(__abort_stack_size = __abort_stack_size);
    PROVIDE(__undefined_stack_size = __undefined_stack_size);
    
    /*
    +=============================================================================+
    | available memories definitions
    +=============================================================================+
    */
    
    MEMORY
    {
    	rom (rx)	: org = 0x00000000, len = 128k
    	ram (rwx)	: org = 0x40000000, len = 34k
    }
    
    __rom_start = ORIGIN(rom);
    __rom_size = LENGTH(rom);
    __rom_end = __rom_start + __rom_size;
    
    __ram_start = ORIGIN(ram);
    __ram_size = LENGTH(ram);
    __ram_end = __ram_start + __ram_size;
    
    PROVIDE(__rom_start = __rom_start);
    PROVIDE(__rom_size = __rom_size);
    PROVIDE(__rom_end = __rom_end);
    
    PROVIDE(__ram_start = __ram_start);
    PROVIDE(__ram_size = __ram_size);
    PROVIDE(__ram_end = __ram_end);
    
    /*
    +=============================================================================+
    | entry point
    +=============================================================================+
    */
    
    ENTRY(Reset_Handler);
    
    /*
    +=============================================================================+
    | put data in sections
    +=============================================================================+
    */
    
    SECTIONS
    {
    	.text :
    	{
    		. = ALIGN(4);
    		__text_start = .;
    		PROVIDE(__text_start = __text_start);
    
    		. = ALIGN(4);
    		KEEP(*(.vectors));
    		. = ALIGN(4);
    		*(.text .text.* .gnu.linkonce.t.*);
    		. = ALIGN(4);
    		*(.glue_7t .glue_7);
    		. = ALIGN(4);
    		*(.rodata .rodata.* .gnu.linkonce.r.*);
    
    		. = ALIGN(4);
    		*(.ARM.extab* .gnu.linkonce.armextab.*);	/* exception unwinding information */
    		. = ALIGN(4);
    		*(.gcc_except_table);						/* information used for stack unwinding during exception */
    		. = ALIGN(4);
    		*(.eh_frame_hdr);							/* additional information about .ex_frame section */
    		. = ALIGN(4);
    		*(.eh_frame);								/* information used for stack unwinding during exception */
    
    		. = ALIGN(4);
    		KEEP(*(.init));
    		. = ALIGN(4);
    		__preinit_array_start = .;
    		KEEP(*(.preinit_array));
    		. = ALIGN(4);
    		__preinit_array_end = .;
    		__init_array_start = .;
    		KEEP(*(SORT(.init_array.*)));
    		. = ALIGN(4);
    		KEEP(*(.init_array));
    		. = ALIGN(4);
    		__init_array_end = .;
    		KEEP(*(.fini));
    		. = ALIGN(4);
    		__fini_array_start = .;
    		KEEP(*(.fini_array));
    		. = ALIGN(4);
    		KEEP(*(SORT(.fini_array.*)));
    		. = ALIGN(4);
    		__fini_array_end = .;
    
    		. = ALIGN(4);
    		__text_end = .;
    		PROVIDE(__text_end = __text_end);
    	} > rom AT > rom
    
    	. = ALIGN(4);
    	__exidx_start = .;
    	PROVIDE(__exidx_start = __exidx_start);
    
    	.ARM.exidx :
    	{
    		*(.ARM.exidx* .gnu.linkonce.armexidx.*);
    	} > rom AT > rom								/* index entries for section unwinding */
    
    	. = ALIGN(4);
    	__exidx_end = .;
    	PROVIDE(__exidx_end = __exidx_end);
    
    	.data :
    	{
    		. = ALIGN(4);
    		__data_init_start = LOADADDR (.data);
    		PROVIDE(__data_init_start = __data_init_start);
    		__data_start = .;
    		PROVIDE(__data_start = __data_start);
    
    		. = ALIGN(4);
    		*(.data .data.* .gnu.linkonce.d.*)
    
    		. = ALIGN(4);
    		__data_end = .;
    		PROVIDE(__data_end = __data_end);
    	} > ram AT > rom
    
    	.bss :
    	{
    		. = ALIGN(4);
    		__bss_start = .;
    		PROVIDE(__bss_start = __bss_start);
    
    		. = ALIGN(4);
    		*(.bss .bss.* .gnu.linkonce.b.*)
    		. = ALIGN(4);
    		*(COMMON);
    
    		. = ALIGN(4);
    		__bss_end = .;
    		PROVIDE(__bss_end = __bss_end);
    	} > ram AT > ram
    
    	.stack :
    	{
    		. = ALIGN(8);
    		__stack_start = .;
    		PROVIDE(__stack_start = __stack_start);
    
    		. = ALIGN(8);
    		__user_system_stack_start = .;
    		PROVIDE(__user_system_stack_start = __user_system_stack_start);
    
    		. += __user_system_stack_size;
    
    		. = ALIGN(8);
    		__user_system_stack_end = .;
    		PROVIDE(__user_system_stack_end = __user_system_stack_end);
    
    		. = ALIGN(8);
    		__fiq_stack_start = .;
    		PROVIDE(__fiq_stack_start = __fiq_stack_start);
    
    		. += __fiq_stack_size;
    
    		. = ALIGN(8);
    		__fiq_stack_end = .;
    		PROVIDE(__fiq_stack_end = __fiq_stack_end);
    		
    		. = ALIGN(8);
    		__irq_stack_start = .;
    		PROVIDE(__irq_stack_start = __irq_stack_start);
    
    		. += __irq_stack_size;
    
    		. = ALIGN(8);
    		__irq_stack_end = .;
    		PROVIDE(__irq_stack_end = __irq_stack_end);
    		
    		. = ALIGN(8);
    		__supervisor_stack_start = .;
    		PROVIDE(__supervisor_stack_start = __supervisor_stack_start);
    
    		. += __supervisor_stack_size;
    
    		. = ALIGN(8);
    		__supervisor_stack_end = .;
    		PROVIDE(__supervisor_stack_end = __supervisor_stack_end);
    		
    		. = ALIGN(8);
    		__abort_stack_start = .;
    		PROVIDE(__abort_stack_start = __abort_stack_start);
    
    		. += __abort_stack_size;
    
    		. = ALIGN(8);
    		__abort_stack_end = .;
    		PROVIDE(__abort_stack_end = __abort_stack_end);
    		
    		. = ALIGN(8);
    		__undefined_stack_start = .;
    		PROVIDE(__undefined_stack_start = __undefined_stack_start);
    
    		. += __undefined_stack_size;
    
    		. = ALIGN(8);
    		__undefined_stack_end = .;
    		PROVIDE(__undefined_stack_end = __undefined_stack_end);		
    
    		. = ALIGN(8);
    		__stack_end = .;
    		PROVIDE(__stack_end = __stack_end);
    	} > ram AT > ram
    
    	. = ALIGN(4);
    	__heap_start = .;
    	PROVIDE(__heap_start = __heap_start);
    
    	. = ALIGN(4);
    	__heap_end = __ram_end;
    	PROVIDE(__heap_end = __heap_end);
    
    	.stab 				0 (NOLOAD) : { *(.stab) }
    	.stabstr 			0 (NOLOAD) : { *(.stabstr) }
    	/* DWARF debug sections.
    	* Symbols in the DWARF debugging sections are relative to the beginning
    	* of the section so we begin them at 0. */
    	/* DWARF 1 */
    	.debug				0 : { *(.debug) }
    	.line				0 : { *(.line) }
    	/* GNU DWARF 1 extensions */
    	.debug_srcinfo		0 : { *(.debug_srcinfo) }
    	.debug_sfnames		0 : { *(.debug_sfnames) }
    	/* DWARF 1.1 and DWARF 2 */
    	.debug_aranges		0 : { *(.debug_aranges) }
    	.debug_pubnames		0 : { *(.debug_pubnames) }
    	/* DWARF 2 */
    	.debug_info			0 : { *(.debug_info .gnu.linkonce.wi.*) }
    	.debug_abbrev		0 : { *(.debug_abbrev) }
    	.debug_line			0 : { *(.debug_line) }
    	.debug_frame		0 : { *(.debug_frame) }
    	.debug_str			0 : { *(.debug_str) }
    	.debug_loc			0 : { *(.debug_loc) }
    	.debug_macinfo		0 : { *(.debug_macinfo) }
    	/* SGI/MIPS DWARF 2 extensions */
    	.debug_weaknames	0 : { *(.debug_weaknames) }
    	.debug_funcnames	0 : { *(.debug_funcnames) }
    	.debug_typenames	0 : { *(.debug_typenames) }
    	.debug_varnames		0 : { *(.debug_varnames) }
    
    	.note.gnu.arm.ident	0 : { KEEP(*(.note.gnu.arm.ident)) }
    	.ARM.attributes		0 : { KEEP(*(.ARM.attributes)) }
    	/DISCARD/				: { *(.note.GNU-stack) }
    }
    
    PROVIDE(__text_size = __text_end - __text_start);
    PROVIDE(__exidx_size = __exidx_end - __exidx_start);
    PROVIDE(__data_size = __data_end - __data_start);
    PROVIDE(__bss_size = __bss_end - __bss_start);
    PROVIDE(__stack_size = __stack_end - __stack_start);
    PROVIDE(__heap_size = __heap_end - __heap_start);
    
    /******************************************************************************
    * END OF FILE
    ******************************************************************************/
    


    Zmieniona została nazwa projektu w makefile oraz nagłówek - podłączono LPC23xx.h

    Kod w pliku main.c
    /** \file main.c
     * \brief Sample ARM project
     * \details This file holds a very basic ARM code for LPC2103. This code
     * initializes the Fast GPIOs, starts the MAM (Memory Acceleration Module) and
     * enables the PLL to achieve the highest allowed frequency for LPC2103 (72MHz).
     * Main code block just blinks the LED. The LED port and pin are defined in
     * config.h file. Target core frequency and quartz crystal resonator
     * frequency are defined there as well.
     *
     * \author Freddie Chopin, http://www.freddiechopin.info/
     * \date 2012-01-08
     */
    
    /******************************************************************************
    * project: lpc2103_blink_led
    * chip: LPC2103
    * compiler: arm-none-eabi-gcc (Sourcery CodeBench Lite 2011.09-69) 4.6.1
    *
    * prefix: (none)
    *
    * available global functions:
    * 	int main(void)
    *
    * available local functions:
    * 	static void mam_start(uint32_t frequency)
    * 	static void pll_feed(void)
    * 	static uint32_t pll_start(uint32_t crystal, uint32_t frequency)
    * 	static void system_init(void)
    *
    * available interrupt handlers:
    ******************************************************************************/
    
    /*
    +=============================================================================+
    | includes
    +=============================================================================+
    */
    
    #include <stdint.h>
    
    #include "inc/LPC23xx.h"
    
    #include "config.h"
    
    #include "hdr/hdr_scb.h"
    #include "hdr/hdr_mam.h"
    
    /*
    +=============================================================================+
    | module variables
    +=============================================================================+
    */
    
    /*
    +=============================================================================+
    | local functions' declarations
    +=============================================================================+
    */
    
    static void mam_start(uint32_t frequency);
    static void pll_feed(void);
    static uint32_t pll_start(uint32_t crystal, uint32_t frequency);
    static void system_init(void);
    
    /*
    +=============================================================================+
    | global functions
    +=============================================================================+
    */
    
    /*------------------------------------------------------------------------*//**
    * \brief main code block
    * \details Call some static initialization functions and blink the led with
    * frequency defined via count_max variable.
    *//*-------------------------------------------------------------------------*/
    
    int main(void)
    {
    	volatile uint32_t count, count_max = 1000000;
    
    	system_init();
    	pll_start(CRYSTAL, FREQUENCY);
    
    	//PINSEL0 = 0x00000000;
    	LED_DIR |= LED;
    
    	while (1)
    	{
    		for (count = 0; count < count_max; count++);	// delay
    		LED_SET |= LED;	// change LED state
    		for (count = 0; count < count_max; count++);	// delay
    		LED_CLR |= LED;	// change LED state
    	}
    }
    
    /*
    +=============================================================================+
    | local functions
    +=============================================================================+
    */
    
    /*------------------------------------------------------------------------*//**
    * \brief Start MAM
    * \details Enables the Memory Acceleration Module in LPC2103, which allows the
    * CPU to work full-speed out of Flash.
    *
    * \param [in] frequency defines the target frequency of the core
    *//*-------------------------------------------------------------------------*/
    
    static void mam_start(uint32_t frequency)
    {
    	uint32_t latency;
    
    	if (frequency < 20000000)				// 1 cycle latency for core speed below 20MHz
    		latency = 1;
    	else if (frequency < 40000000)			// 2 cycle latency for core speed between 20MHz and 40MHz
    		latency = 2;
    	else									// 3 cycle latency for core speed over 40MHz
    		latency = 3;
    
    	MAMTIM = latency;						// set the latency
    	MAMCR = MAMCR_MODE_FULL;				// enable MAM
    }
    
    /*------------------------------------------------------------------------*//**
    * \brief PLL feed sequence
    * \details Issues a special "PLL feed sequence" which validates the changes to
    * PLL control registers
    *//*-------------------------------------------------------------------------*/
    
    static void pll_feed(void)
    {
    	PLLFEED = PLLFEED_FIRST;
    	PLLFEED = PLLFEED_SECOND;
    }
    
    /*------------------------------------------------------------------------*//**
    * \brief Starts the PLL
    * \details Configure and enable PLL to achieve some frequency with some crystal.
    * Before the speed change MAM is enabled via mam_start(). PLL parameters m and p
    * are based on function parameters. The PLL is set up, started and connected.
    * Finally, APB clock ratio is set to 1:1.
    *
    * \param [in] crystal is the frequency of the crystal resonator connected to the
    * LPC2103
    * \param [in] frequency is the desired target frequency after enabling the PLL
    *
    * \return real frequency that was set
    *//*-------------------------------------------------------------------------*/
    
    static uint32_t pll_start(uint32_t crystal, uint32_t frequency)
    {
    	uint32_t m, p = 0, fcco;
    
    	mam_start(frequency);					// reconfigure/enable MAM before changing speed
    
    	m = frequency / crystal;				// M is the PLL multiplier
    	fcco = m * crystal * 2;					// FCCO is the internal PLL frequency
    
    	frequency = crystal * m;
    
    	while (fcco < 156000000)
    	{
    		fcco *= 2;
    		p++;								// find P which gives FCCO in the allowed range (over 156MHz)
    	}
    
    	PLLCFG = (m - 1) | (p << PLLCFG_PSEL_bit);	// set basic PLL parameters
    	pll_feed();
    	PLLCON = PLLCON_PLLE;					// enable PLL
    	pll_feed();
    	while (!(PLLSTAT & PLLSTAT_PLOCK));		// wait for PLL lock
    	PLLCON = PLLCON_PLLE | PLLCON_PLLC;		// connect PLL as the system clock
    	pll_feed();
    
    	APBDIV = APBDIV_APBDIV_1;				// set APB clock ratio to 1:1
    
    	return frequency;
    }
    
    /*------------------------------------------------------------------------*//**
    * \brief Initialize system
    * \details Enables the Fast GPIOs and ensures the vectors are taken from Flash
    *//*-------------------------------------------------------------------------*/
    
    static void system_init(void)
    {
    	SCS = SCS_GPIO0M;						// enable Fast I/O
    	MEMMAP = MEMMAP_MAP_FLASH;				// vectors in Flash
    }
    
    /*
    +=============================================================================+
    | ISRs
    +=============================================================================+
    */
    
    /******************************************************************************
    * END OF FILE
    ******************************************************************************/
    


    Różnica pomiędzy mikrokontrolerami LPC2103 i LPC2364 jest taka, że ten drugi posiada wewnętrzny rezonator RC, który po resecie jest skonfigurowany i taktuje CPU z częstotliwością 4Mhz. Jeśli zakomentuję procedurę uruchamiania pętli pll w pliku main, wówczas procesor miga diodą bardzo powoli (pracuje na wewnętrznym oscylatorze z częstotliwością 4MHz). Jeśli procedura startu pll jest odkomentowana nastaje cisza i procesor nie robi nic.

    Podejrzewam, że nie są skonfigurowane rejestry odpowiedzialne za wybór rezonatora, ale niestety jestem w armach początkujący i nie wiem jak się zabrać za konfigurację... Będę wdzięczny jeśli ktoś mi pomoże.
  • #2 10716225
    Electix
    Poziom 21  
    Posty: 462
    Pomógł: 46
    Ocena: 6
    Tak dobrze kombinujesz, powinieneś włączyć odpowiednie źródło sygnału taktującego. Za wybór tego źródła odpowiedzialny jest rejestr CLKSRCSEL. Po resecie jest tam wpisana wartość 0x00 czyli wybór wewnętrznego oscylatora RC. Aby wybrać zewnętrzny kwarc, musisz wpisać tam wartość 0x01. Natomiast sekwencję inicjalizacji PLL powinieneś wykonać według następującego algorytmu:
    Cytat:

    The following sequence must be followed step by step in order to have the PLL initialized
    an running:
    1. Disconnect the PLL with one feed sequence if PLL is already connected.
    2. Disable the PLL with one feed sequence.
    3. Change the CPU Clock Divider setting to speed up operation without the PLL, if
    desired.
    4. Write to the Clock Source Selection Control register to change the clock source.
    5. Write to the PLLCFG and make it effective with one feed sequence. The PLLCFG can
    only be updated when the PLL is disabled.
    6. Enable the PLL with one feed sequence.
    7. Change the CPU Clock Divider setting for the operation with the PLL. It's critical to do
    this before connecting the PLL.
    8. Wait for the PLL to achieve lock by monitoring the PLOCK bit in the PLLSTAT register,
    or using the PLOCK interrupt, or wait for a fixed time when the input clock to PLL is
    slow (i.e. 32 kHz). The value of PLOCK may not be stable when the PLL reference
    frequency (FREF, the frequency of REFCLK, which is equal to the PLL input
    frequency divided by the pre-divider value) is less than 100 kHz or greater than
    20 MHz. In these cases, the PLL may be assumed to be stable after a start-up time
    has passed. This time is 500 μs when FREF is greater than 400 kHz and 200 / FREF
    seconds when FREF is less than 400 kHz.
    9. Connect the PLL with one feed sequence.
    It's very important not to merge any steps above. For example, don't update the PLLCFG
    and enable the PLL simultaneously with the same feed sequence.


    Jest to cytat z manualu do Twojego µkontrolera. Warto z nim popracować...

    Pozdrowienia :)
  • #3 10717022
    Yaro126
    Poziom 20  
    Posty: 497
    Pomógł: 31
    Ocena: 43
    Postanowiłem uruchomić na sam początek taktowanie z zewnętrznego rezonatora bez uruchamiania pętli PLL. Z tego co udało mi się wyczytać m.in. z manuala wynika że po wpisaniu do rejestru CLCSRCSEL wartości 0x01 procesor powinien już pracować na zewnętrznym oscylatorze, niestety po wpisaniu tej wartości jest cisza... Nie ma żadnego przebiegu na oscylatorze taktującym. Czy ktoś już uruchamiał ten mikromontroler i wie jakie rejestry trzeba ustawić żeby zadziałał?

    Dodam że po ustawieniu na taktowanie z RTC (CLCSRCSEL=2) procesor działa i miga diodą według powyższego programu bardzo wolno...
  • Pomocny post
    #4 10717196
    Electix
    Poziom 21  
    Posty: 462
    Pomógł: 46
    Ocena: 6
    Sprawdź czy procedura nastaw PLL którą masz w swoim programie jest zgodna z procedurą którą Ci zacytowałem wyżej. Po resecie ten procek startuje z zegarem wewnętrznym IRC. Można softowo przełączyć na kwarc, albo na kwarc "zegarkowy" i rdzeń może pracować bez udziału PLL. Ale wymaga to odpowiednich nastaw. Poza tym sposób dobierania parametrów M i N dla PLL różni się od sposobu nastaw dla serii LPC21xx.

    Czy sam robiłeś płytkę? Jeśli tak, sprawdź czy zastosowałeś się do zaleceń odnośnie podłączania kwarców i odpowiednich do nich pojemności. Jaki to jest kwarc? Jaka ma częstotliwość? Czy mieści się w zalecanym zakresie?

    Jeżeli przeprowadziłeś dobrze procedurę nastawiania PLL i podpiąłeś zegar do rdzenia CCLKCFG a źle dobrałeś podziały M i N to mogłeś przetaktować w ten sposób rdzeń i też będzie się to kończyć zwiechą...
  • #5 10719306
    Yaro126
    Poziom 20  
    Posty: 497
    Pomógł: 31
    Ocena: 43
    Dziękuję za odpowiedzi w temacie. Udało mi się skonfigurować nareszcie pętlę PLL.

    Poniżej zamieszczam gdyby ktoś potrzebował funkcję do uruchamiania pętli PLL (funkcja nie jest mojego autorstwa)
    static void pll_start(void)
    {
    	if ( PLLSTAT & (1 << 25) ) {
    		PLLCON = 1;				/* Disconnect PLL output if PLL is in use */
    		PLLFEED = 0xAA; PLLFEED = 0x55;
    	}
    	PLLCON = 0;				/* Disable PLL */
    	PLLFEED = 0xAA; PLLFEED = 0x55;
    	CLKSRCSEL = 1;			/* Select main oscillator (11,0592MHz) as the PLL clock source */
    
    	PLLCFG = ((PLL_N - 1) << 16) | (PLL_M - 1);	/* Re-configure PLL */
    	PLLFEED = 0xAA; PLLFEED = 0x55;
    	PLLCON = 1;				/* Enable PLL */
    	PLLFEED = 0xAA; PLLFEED = 0x55;
    
    	while ((PLLSTAT & (1 << 26)) == 0);	/* Wait for PLL locked */
    
    	CCLKCFG = CCLK_DIV-1;	/* Select CCLK frequency (divide ratio of hclk) */
    	PLLCON = 3;				/* Connect PLL output to the sysclk */
    	PLLFEED = 0xAA; PLLFEED = 0x55;
    
    	MAMCR = 0;				/* Configure MAM with 0 wait operation */
    	MAMTIM = 3;
    	MAMCR = 2;
    
    }


    funkcja wymaga zdefiniowania następujących stałych:
    
    #define PLL_N		2UL						//odpowiednik parametru P w książce Lucjana Bryndzy
    #define PLL_M		6UL						//odpowiednik parametru M w książce Lucjana Bryndzy
    #define CCLK_DIV	1
    


    Aby mikrokontroler ruszył na zewnętrznym kwarcu należy ustawić w stan wysoki 5. bit rejestru SCS.
    Bit ten nazywa się OSCEN. Opis rejestru SCS znajduje się na stronie 42 manuala.

    I jeszcze bardzo ważna rzecz która wyszła w trakcie, a która długo nie pozwoliła mi dojść do tego czemu nie działają mi porty. Jeśli ktoś korzysta z wzoru projektu napisanego przez Freddiego Chopina dla LPC2103, to nie może używać szybkich portów - FIO. Na zewnętrznym kwarcu nie chcą działać. Szybkie porty uruchamia się w rejestrze SCS ustawiając bit 0 (GPIOM) w stan wysoki. Mimo ustawienia odpowiedniego bitu w tym rejestrze mikrokontroler nie reaguje jeśli próbujemy wymusić odpowiednie stany stosując np. FIO0SET lub FIO0CLR. Jeśli ktoś zna powód takiego stanu rzeczy, proszę o sugestie.

    Pozdrawiam
  • #6 10719571
    Electix
    Poziom 21  
    Posty: 462
    Pomógł: 46
    Ocena: 6
    A to dziwne, bo po ustawieniu 1 na pozycji 0 rejestru SCS, FPIO powinny śmigać. Pokaż co tam popisałeś w programie i jakie ustawienia porobiłeś...

    A może w rejestrze FIO0DIR nie ustawiłeś kierunku działania portu? Po resecie masz tam wpisane 0, a to konfiguruje piny jako wejścia. Ty potrzebujesz wyjść, więc musisz przestawić odpowiednie bity...
  • #7 10719668
    Yaro126
    Poziom 20  
    Posty: 497
    Pomógł: 31
    Ocena: 43
    Wygląda to następująco:

    Posiadam funkcję system init + zdefiniowane do niej stałe:

    Stałe:
    /*
    +-----------------------------------------------------------------------------+
    | SCS - System Control and Status flags register
    +-----------------------------------------------------------------------------+
    */
    
    #define SCS_GPIOM_bit						1
    #define SCS_GPIOM							(1 << SCS_GPIOM_bit)
    
    #define SCS_OSCEN_bit						5
    #define SCS_OSCEN                           (1 << SCS_OSCEN_bit)
    /*


    Funkcja system init:
    static void system_init(void)
    {
    	SCS |= (SCS_GPIOM | SCS_OSCEN);			    // włączenie FIO i zewnętrznego rezonatora
    	MEMMAP = MEMMAP_MAP_FLASH;				    // vectors in Flash
    }


    Ustawienie portów:
    #define LED_DIR								FIO0DIR	    ///< direction register of the port to which the LED is connected
    #define LED_SET								FIO0SET		///< "SET" register for the LED
    #define LED_CLR							    FIO0CLR		///< "CLR" register for the LED
    
    #define LED_pin								23			///< pin number of the LED
    #define LED									(1 << LED_pin)


    Kod programu:
    int main(void)
    {
    	volatile uint32_t count, count_max = 1000000;
    
    	system_init();
    	pll_start();
    
    	LED_DIR |= LED;
    
    	while (1)
    	{
    		for (count = 0; count < count_max; count++);	// delay
    		LED_SET |= LED;	// change LED state
    		for (count = 0; count < count_max; count++);	// delay
    		LED_CLR |= LED;	// change LED state
    	}
    }


    Wydaje mi się że wszytsko jest ok, chyba że się mylę.
  • #8 10719720
    Konto nie istnieje
    Konto nie istnieje  
  • #9 10719739
    Yaro126
    Poziom 20  
    Posty: 497
    Pomógł: 31
    Ocena: 43
    Faktycznie! ale byk... powinno być 0:) Dziękuję:)
  • #10 10719759
    Electix
    Poziom 21  
    Posty: 462
    Pomógł: 46
    Ocena: 6
    Piszesz:
    Cytat:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    A pole GPIOM w rejestrze SCS jest na pozycji 0, na pozycji 1 masz EMC_Reset_Disable. :) Zmień SCS_GPIOM_bit na 0 i powinno śmigać... :)
  • #11 10728216
    Yaro126
    Poziom 20  
    Posty: 497
    Pomógł: 31
    Ocena: 43
    Wszystko ładnie działa:)
    Pozdrawiam

Podsumowanie tematu

✨ Użytkownik miał problem z uruchomieniem pętli PLL w mikrokontrolerze LPC2364 w środowisku Eclipse, korzystając z projektu dla LPC2103. Po kilku próbach i wskazówkach od innych uczestników dyskusji, w tym dotyczących rejestru CLKSRCSEL oraz procedury inicjalizacji PLL, udało mu się skonfigurować PLL. Użytkownik podzielił się funkcją do uruchamiania pętli PLL oraz poprawnymi ustawieniami rejestrów, co pozwoliło na prawidłowe działanie mikrokontrolera.
REKLAMA