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;
}

これは、3つの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モジュール、追加のロジックコードmain.cの、ボタンを押すの効果は、オフに対応する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バス装置によって、図から分かります。図のクロックを参照しながら、クロックPCLKによって提供HCLK、APBバスクロック装置を提供AHBバスデバイスから見ることができる、FCLKは、マスタークロックとしてコアとARM920Tプロセッサに提供されます。

 今後、それがPCLKによって発見されたとHCLK FCLKは、結果を分割し、周波数逓倍器を通じてPLLによって得られた外部入力クロックFCLK。クロック入力は、発振器または外部クロックであってもよいです。次のようにチップのマニュアルを読んで、あなたは見つけることができる関連情報は次のとおりです。

OMクロック入力は、クロックソース入力として、水晶発振器を用いて基板00を直接OMにプルダウンされた入力ソース、すなわちによって選択され、水晶発振器は12MHzのあるオンボードマスタークロックは、USBクロックソースのクロックを使用しています。

我々はシステムを改善し、このレジスタを設定する必要がありますので、以下のレジスタを設定した後に必要なノートのMPLLCON場合を説明した私たちの前のコードが提供されていないので、MPLLの出力は、私たちのシステムクロックを実行すると、システムクロックは、非常に遅く、12MHzでありますスピード。

 安定した電力供給のためのストレージキャパシタ又はAの遅延時間を待つ必要があるため、パワーボードの後に、システムをリセットNRESET信号の必要性は、システムは、しばらくの間、信号電力nRESETの2つつ1に、実行を開始しますチップ保証。2システムリセット後、PLLは、我々はそれが設定されていることをソフトウェアを変更する場合は、この時点で実行を開始、それはclockdisableの原因となります、クロックが停止され、その後、システムは、システムが安定している場合、停止され、ロック時間は、システムの意志を通過しました私たちは、FCLKが4後に新たな周波数の図であることを、クロックが動作を開始する設定しました。このステップは、PMSのセットMPLL、決定MPLLの逓倍数に必要とされます。

第二のステップは、FCLKはPCLKとHCLKの分割要素に提供が必要です。最終の分周数で分周率とは異なる参照し、プログラムはこのテーブルに従って設定する必要があり、元の文書の残りの項目は、注目することができます。上限PCLKとHCLKがあることに注意することは、分周比を注意深くFCLKを決定した後に決定される必要があります。そうでない場合、CPUは、システム動作クロックHCLKとして使用され、非同期モードにCPUモードアセンブラの実施形態によって必要とされる一方、HDIVNは、0ではありません。

 MRCおよびMCRコプロセッサの処理のための指示、ORR、R1_nF:OR:R1_iAリファレンス「ARM920T(改訂1)テクニカルリファレンスマニュアルには、」 ARM920Tが非同期モードになっているので、こと、2つのレジスタ制御を制御する必要性を見ることができます。 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、すなわち、出力HCLK 100MHzの、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