JZ2440 베어 보드 개발 연습 # 3 - LED 개선 프로그램 (감시, 버튼, 시계)

이 운동은 LED의 프로그램을 개선한다

1. 모듈 형

첫째, 프로그램의 관련 정보를 등록합니다, 모듈 부문이 될 것이다 s3c2440.h을  , 레지스터에 후속 사용은 다른 기능을 계속 추가, 따라서 점차적으로 헤더 파일을 향상시킬 수 있습니다. 문서의 독립적으로 제공되는 동안 모듈 LED 모듈, 메인 기존 파일을 다음 모듈이 원하는 기능을 달성 할 수있는 메커니즘을 제공하기 위해 전화. (시작 파일이이 목록에없는, 아무런 차이가 없다.)

s3c2440.h
---------------------------------------
#ifndef __S3C2440_H
#define __S3C2440_H

#include <stdint.h>

/* GPIO */
#define GPFCON	(*((volatile uint32_t*)0x56000050))
#define GPFDAT	(*((volatile uint32_t*)0x56000054))

#endif

 

led.h
----------------------------------
#ifndef __LED_H
#define __LED_H

#include <stdint.h>

#define kLed1  4
#define kLed2  5
#define kLed3  6


void LedInitAll(void);
void SingleLedInit(const uint8_t ledn);
void SingleLedON(const uint8_t ledn);
void SingleLedOFF(const uint8_t ledn);

#endif
led.c
--------------------------------------
#include "led.h"

#include "s3c2440.h"

void LedInitAll(void)
{
	SingleLedInit(kLed1);
	SingleLedInit(kLed2);
	SingleLedInit(kLed3);
	SingleLedOFF(kLed1);
	SingleLedOFF(kLed2);
	SingleLedOFF(kLed3);
}


/* init the led gpio as a output pin */
void SingleLedInit(const uint8_t ledn)
{
	GPFCON &= ~(3 << ledn * 2);
	GPFCON |= (1 << ledn * 2);
}

void SingleLedON(const uint8_t ledn)
{
	GPFDAT &=~(1 << ledn);
}

void SingleLedOFF(const uint8_t ledn)
{
	GPFDAT |= 1 << ledn;
}


main.c
------------------------------------
#include <stdint.h>

#include "s3c2440.h"
#include "led.h"


void Delay(uint32_t time)
{
	while(time--);
}

int main()
{
	uint8_t led_now=kLed1;
	LedInitAll();
	while(1)
	{
		SingleLedOFF(led_now++);
		if(led_now > kLed3) { led_now =kLed1; }
		SingleLedON(led_now);
		Delay(100000);
	}

	
	
	return 0;
}

이 완료 경수의 기능은 세 가지 LED 조명의 효과를 끄십시오. 여기가 발생 (문제가 글로벌 변수 나 정적 변수를 정의하지 않은 경우 적절한 가이드 라인을 컴파일 할 링크 또는 스크립트가 없기 때문에, 분해 파일은 것, 경계 또는 오류의 rodata에서 DSS 세그먼트와 데이터 세그먼트를 표시 따라서 여기에서 제 대신 매크로를 사용하는 문제는 글로벌 변수 완료)를 정의한다.

 

2. 워치 독

그 이상의 시간을 위의 물 등을 발견 사용하여 프로그램을 실행하면 프로그램이 자동으로 재시작 실행, 거기에 감시 메커니즘의 S3C2440이며, 기본적으로 설정되어 있기 때문입니다, 필요 시간은 프로그램을 다시 시작 방지하기 위해 "개 먹이"것,이 프로그램은 하드웨어를 방지하는 방법입니다 우리가 그것을 끌 수있는, 교착 상태.

이는 물체의 감시를 달성하기 위해 0으로 감시 레지스터를 구성하는 칩 매뉴얼에 의해 얻을 수있다. 메인 함수 호출에 캡슐화 된 C 언어 후속 팽창 및 사용을 용이하게한다.

s3c2440.h
------------------------------
#ifndef __S3C2440_H
#define __S3C2440_H

#include <stdint.h>


/* WATCH DOG */
#define WTCON	(*((volatile uint32_t*)0x53000000))

/* GPIO */
#define GPFCON	(*((volatile uint32_t*)0x56000050))
#define GPFDAT	(*((volatile uint32_t*)0x56000054))




void WatchDogDisable(void);

#endif

s3c2440.c
-------------------------
#include "s3c2440.h"

void WatchDogDisable(void)
{
	WTCON = 0x0;
}

3. 키

동일한 LED 분석 먼저 개략 회로 키 핀을 발견하고 칩 매뉴얼에 제공된 관련된 GPIO 레지스터 차분 필요 입력으로 구성된 GPIO 핀의 핵심으로 발견.

도면은 버튼을 누르지 않은 경우 핀 풀업 저항, 즉, 핀이 높은, 낮은 눌러가는 것을 알 수있다.

그리고, 해당 핀은

EINT0 EINT2 EINT11 EINT19
GPF0 GPF2 GPG3 GPG11

다음과 같이 필요에 따라 모듈 형 패키지 키를 직접 :

key.h
--------------------------------
#ifndef __KEY_H
#define __KEY_H

#include <stdint.h>

#define KEY_1 0
#define KEY_2 2
#define KEY_3 3
#define KEY_4 11


void AllKeyInit(void);
void SingleKeyInit(uint8_t keyn);
uint8_t Key1CheckDown(void);
uint8_t Key2CheckDown(void);
uint8_t Key3CheckDown(void);
uint8_t Key4CheckDown(void);

#endif
key.c
----------------------------------------

#include "key.h"

#include "s3c2440.h"

void AllKeyInit(void)
{
	SingleKeyInit(KEY_1);
	SingleKeyInit(KEY_2);
	SingleKeyInit(KEY_3);
	SingleKeyInit(KEY_4);
}

//config key as a input io
void SingleKeyInit(uint8_t keyn)
{
	switch(keyn)
	{
		case KEY_1:
		case KEY_2:
			GPFCON &= ~(3 << keyn*2);
			break;
		case KEY_3:
		case KEY_4:
			GPGCON &= ~(3 << keyn*2);
			break;
		default:
			break;
	}
}

uint8_t Key1CheckDown(void)
{
	return !(GPFDAT & (1 << KEY_1)); 
}

uint8_t Key2CheckDown(void)
{
	return !(GPFDAT & (1 << KEY_2));
}

uint8_t Key3CheckDown(void)
{
	return !(GPGDAT & (1 << KEY_3));
}

uint8_t Key4CheckDown(void)
{
	return !(GPGDAT & (1 << KEY_4));
}

따라서, 업데이트 된 등록 내용 s3c2440.h

#ifndef __S3C2440_H
#define __S3C2440_H

#include <stdint.h>


/* WATCH DOG */
#define WTCON	(*((volatile uint32_t*)0x53000000))

/* GPIO */
#define GPGCON	(*((volatile uint32_t*)0x56000060))
#define GPGDAT	(*((volatile uint32_t*)0x56000064))
#define GPGUP	(*((volatile uint32_t*)0x56000068))

#define GPFCON	(*((volatile uint32_t*)0x56000050))
#define GPFDAT	(*((volatile uint32_t*)0x56000054))
#define GPFUP	(*((volatile uint32_t*)0x56000058))


void WatchDogDisable(void);
void Delay(uint32_t time);

#endif

결합 된 LED 모듈, 추가 로직 부호 006은 버튼을 누르는 효과는 떨어져 해당 LED.

#include <stdint.h>

#include "s3c2440.h"
#include "led.h"
#include "key.h"


int main()
{
	WatchDogDisable();
	LedInitAll();
	AllKeyInit();

	while(1)
	{
		if(Key1CheckDown()){ SingleLedON(kLed1); }
		else { SingleLedOFF(kLed1); }
		
		if(Key2CheckDown()){ SingleLedON(kLed2); }
		else { SingleLedOFF(kLed2); }
		
		if(Key3CheckDown()){ SingleLedON(kLed3); }
		else { SingleLedOFF(kLed3); }
	}
}

그것은 타협 너무 전환 프로그램이기 때문에 여기에 매우 거친 방식으로,이 기능을 달성하기 위해.

4. 시계

기능 블록도보고 S3C2440 제 필요성, 주로 버스의 APB 버스 및 조성물의 연결된 주변 장치에 연결되어 상기 코어 프로세서 S3C2440 ARM920T, AHB 버스 디바이스에 의해, 도면에서 알 수있다. 도 시계를 참조하여, 시계 HCLK을 제공 AHB 버스 장치에서 볼 수있는 상기 PCLK가 제공 APB 버스 클럭 장치는 FCLK 코어 및 마스터 클럭 같은 ARM920T 프로세서를 제공 하였다.

 앞서 찾고 이것은 HCLK 및 PCLK FCLK이 결과를 분할하고, 상기 주파수 승산기를 통해 PLL에 의해 얻어진 외부 입력 클럭 FCLK 구했다. 클럭 입력은 발진기 또는 외부 클록 일 수있다. 다음과 같이 칩 설명서를 읽고, 당신이 찾을 수있는 관련 정보는 다음과 같습니다

OM 클럭 입력은 상기 클록 소스 입력으로 수정 오실레이터를 이용하여 기판 00을 직접 OM로 내려 오게되는 입력 신호, 즉,에 의해 선택되고, 수정 발진기는 12MHz의 온보드 마스터 클럭은 USB 클록 소스 클록을 사용한다.

우리는이 레지스터는 시스템을 개선 설정해야하므로 다음은 필요한 메모 MPLLCON 레지스터를 설정 한 후 MPLL의 출력이 이전 코드가 제공되지 않도록, 우리의 시스템 클럭을 실행하는 경우를 설명, 시스템 클럭은 매우 느리게,은 12MHz이다 속도.

 이 안정적인 전원 공급 장치의 용량 또는 지연 시간을 기다릴 필요가 있기 때문에 전원 기판 후, 시스템을 초기화 nRESET 신호 필요성, 시스템은 일정 기간 동안 신호 전력 nRESET 2 동안 1에 게재한다 칩 보장. 이 시스템 리셋 후, PLL은 우리가 설정해야하는 소프트웨어를 수정하는 경우이 시간에 실행을 시작, 그것은 clockdisable의 원인이됩니다 다음 시스템은 시스템이 안정되면, 잠금 시간이 경과, 정지, 시계가 정지, 시스템은 것입니다 우리는 4 FCLK 후 새로운 주파수도가 있음을 실행 클럭을 시작으로 설정. 이 단계는 PMS의 세트 MPLL, 결정 MPLL 곱셈 번호가 필요합니다.

두 번째 단계는 FCLK은 PCLK의 HCLK 및 분할 요소에 제공이 필요하다. 최종 분주 수의 주파수 분할 계수는 다른 참조 프로그램 표에 따라 설정해야 할 원고의 나머지 항목을 알 수있다. 상한 및 PCLK HCLK 있다는 것을주의하는, 분주 비 요구 신중 FCLK 결정 후에 결정한다. HDIVN뿐만 비동기 모드로도 어셈블러 CPU 모드의 실시 예에서 요구하는 0이 아닌 경우 한편, 그렇지 않으면 CPU는 시스템 동작 클럭 HCLK로서 사용될 것이다.

 OR : 코 프로세서의 ORR, R1_nF 처리 용 MRC 및 MCR 명령어 R1_iA 참조 "ARM920T (계 1) 기술 참조 매뉴얼" ARM920T 비동기 모드로되도록, 두 개의 레지스터 제어를 제어하기위한 필요성을 알 수있다. 에서는  https://blog.csdn.net/shaodongju/article/details/51584576?locationNum=14&fps=1  상세한 설명이 이제 직접 수동 결론을 얻을 수있다 참조, 얻어진 어셈블리 코드 세그먼트이어야

mrc p15,0,r0,c1,c0,0
orr r0,r0,#0xc0000000
mcr p15,0,r0,c1,c0,0

등록 작업이 MPLL입니다

 여기에서 우리는 수동 (직접 확인 어렵고 부정확)에 값을 사례를 참조 할 필요가,

 동일한 분할 계수

 

 요약이 제공의 400MHz의 MPLL의 12MHz의 시스템 클럭 입력 주파수 분할한다 FCLK : HCLK : PCLK = 1 : 4 : 8, 즉 100MHz로 출력 HCLK, PCLK 출력의 50MHz. 다음 절차는 다음과 같습니다

s3c2440.h
---------------------------------------------
#ifndef __S3C2440_H
#define __S3C2440_H

#include <stdint.h>

/* CLOCK */
#define MPLLCON	 (*((volatile uint32_t*)0x4C000004))
#define UPLLCON	 (*((volatile uint32_t*)0x4C000008))

#define CLKDIVN	(*((volatile uint32_t*)0x4C000014))

/* WATCH DOG */
#define WTCON	(*((volatile uint32_t*)0x53000000))

/* GPIO */
#define GPGCON	(*((volatile uint32_t*)0x56000060))
#define GPGDAT	(*((volatile uint32_t*)0x56000064))
#define GPGUP	(*((volatile uint32_t*)0x56000068))

#define GPFCON	(*((volatile uint32_t*)0x56000050))
#define GPFDAT	(*((volatile uint32_t*)0x56000054))
#define GPFUP	(*((volatile uint32_t*)0x56000058))




void HardwareInitAll(void);
void Delay(uint32_t time);

#endif

s3c2440.c
---------------------------------------------
#include "s3c2440.h"


void Delay(uint32_t time)
{
	while(time--);
}

static void WatchDogDisable(void)
{
	WTCON = 0x0;
}

static void MPLLConfig(void)
{
	MPLLCON = ( 0x5c << 12) | ( 1 << 4 ) | ( 1 << 0 );
}

static void ClockDevideConfig(void)
{
	CLKDIVN = (2 << 1) | ( 1<< 0);
}

static void ChangeModeToAsynchronous(void)
{
	asm(
		"mrc p15,0,r0,c1,c0,0 \n\t"
		"orr r0,r0,#0xc0000000 \n\t"
		"mcr p15,0,r0,c1,c0,0 \n\t"
	);
}

void HardwareInitAll(void)
{
	WatchDogDisable();
	ChangeModeToAsynchronous();
	MPLLConfig();
	ClockDevideConfig();
}

main.c
------------------------------------------------
#include <stdint.h>

#include "s3c2440.h"
#include "led.h"

int main()
{
	HardwareInitAll();
	uint8_t led_now=kLed1;
	LedInitAll();
	while(1)
	{
		SingleLedOFF(led_now++);
		if(led_now > kLed3) { led_now =kLed1; }
		SingleLedON(led_now);
		Delay(100000);
	}
	return 0;
}

예를 들어 빛 물에서, 다음 시계를 수정, 400MHz의에서 시계가 명확하게 빛이 깜박 빠르게 관찰 할 수있다.

잠깐!

게시 19 개 원래 기사 · 원 찬양 7 · 전망 6926

추천

출처blog.csdn.net/G_METHOD/article/details/104271762