【嵌入式】非操作系統下GPIO口控制器及LED燈編程

GPIO控制器

概述

S3C6410 共有 187 根 IO 口,分成 17 個 PORT,每根 IO 口可以被用在輸入引腳線、輸出引腳線和其它功能引腳線使用,可以通過每個端口自帶的控制寄存器進行功能配置。在這裏插入圖片描述
在這裏插入圖片描述

內部架構

  • GPIO控制器掛在APB總線,屬於低速設備。
  • 控制器包括寄存器文件相應的功能電路組成,通過寄存器可以控制功能電路按照用戶的方式進行工作。
  • 整個控制器包括 alive-part , off-part 兩個部分, 區別在於sleep mode 時是否有電源供應,在 alive-part 時有電源供給,所以其端口可用作 wake –up 喚醒信號
    在這裏插入圖片描述

端口寄存器

GPIO控制寄存器

  • 功能 – 配置相應端口的功能

在這裏插入圖片描述

GPIO數據寄存器

  • 數據寄存器每個bit位對應相應端口的IO線
  • 如果該IO線被用做輸入口引腳,該bit位隨着引腳線電平的變化而變化(其對應值爲0或者1);
  • 如果該IO線被用作輸出口引腳,則該bit位值爲1時,外面對應引腳線爲高電平(一般爲3.3v左右),則該bit位值爲0時,外面對應引腳線爲低電平(一般爲略大於0V)

在這裏插入圖片描述

GPIO上拉寄存器

  • 該寄存器可以對 arm 一些特殊io做上拉或下拉處理,這在一些場合是非常有用的,避免了在pcb上加上拉或下拉電阻,能夠簡化外部電路設計

在這裏插入圖片描述

非操作系統LED燈閃爍

開發步驟

  1. 看懂硬件圖
  2. 編寫驅動
  3. 編寫應用程序
  4. 使用工具
  5. 系統調試
    在這裏插入圖片描述

開發板上二極管

在這裏插入圖片描述

讀電路圖

S3C6410芯片手冊

在這裏插入圖片描述

程序框架

  • 彙編
;asses.s內容
	AREA Init, CODE READONLY
	ENTRY
_start
        B Main
	END
  • 編寫應用程序
// ledapp.c
void main()
{
	ledconfig();
	for()
	{
		ledon();delay();
	  	ledoff();delay();
	}
}
  • 編寫驅動
// leddrv.c
void ledconfig()
{
	……
}
void ledon()
{
	……
}
void ledoff()
{
	……
}

驅動編寫示例 leddrv.c

  • 配置M口M1引腳爲輸出口
#define rGPMCON  *((volatile int *) 0x7f008820 )
void ledconfig()
	tmp= rGPMCON;		//讀出端口寄存器值
	tmp &=! (0xF<<4);	//把bit4~7清0
	tmp |= (1<<4);		//把bit4~7寫入0x1值
	rGPMCON = tmp;		//寫回到端口寄存器
}
  • 點亮
    配置M口M1輸出低電平
#define rGPMDAT  *((volatile int *) 0x7f008824 )
void ledon()
{
	tmp= rGPMDAT;		//讀出端口寄存器值
	tmp &=! (0x1<<1);	//把bit1清0
	tmp |= (0<<1);		//把bit1寫入0x0值
	rGPMDAT = tmp;		//寫回到端口寄存器
}
  • 熄滅
    配置M口M1輸出高電平
void ledoff()
{
	tmp= rGPMDAT;		//讀出端口寄存器值
	tmp &=	! (0x1<<1);	//把bit1清0
	tmp |= (1<<1);		//把bit1寫入0x1值
	rGPMDAT = tmp;		//寫回到端口寄存器
}

課後作業

編寫一個在非操作系統LED燈閃爍的程序,要求
1)控制GPM2和GPM4端口;
2)寫出驅動程序和應用程序。

剛開始嵌入式,對於硬件方面有很多不理解,不過這不影響我編程。
在這裏插入圖片描述

答案如下:

  • 驅動程序 leddrv.c
//  leddrv.c
#define rGPMCON  *((volatile int *) 0x7f008820 )
// 控制GPM2和GPM4端口
void ledconfig(){
	tmp= rGPMCON;		//讀出端口寄存器值
	tmp &=! (0xF<<8);	//把bit8~11清0
	tmp |= (1<<8);		//把bit8~11寫入0x1值
	tmp &=! (0xF<<16);	//把bit16~19清0	
	tmp |= (1<<16);		//把bit16~19寫入0x1值
	// 這裏再提供一種簡便寫法,完全等價上面四行、
	// tmp &= !(0xF<<8 | 0xF<<16);
	// tmp |== (1<<8 | 1 <<16);
	rGPMCON = tmp;		//寫回到端口寄存器
}
#define rGPMDAT  *((volatile int *) 0x7f008824 )
void ledon()
{
	tmp= rGPMDAT;		//讀出端口寄存器值
	tmp &= !(0x1<<2);	//把bit2清0
	tmp |= (0<<2);		//把bit2寫入0x0值
	tmp &= !(0x1<<4);	//把bit4清0
	tmp |= (0<<4);		//把bit4寫入0x0值
	// 這裏再提供一種簡便寫法,完全等價上面四行
	// tmp &= !(0x1<<2 | 0x1<<4);
	// tmp |= (0<<2 | 0<<4)
	rGPMDAT = tmp;		//寫回到端口寄存器
}
void ledoff()
{
	tmp= rGPMDAT;		//讀出端口寄存器值
	tmp &= !(0x1<<2);	//把bit2清0
	tmp |= (1<<2);		//把bit2寫入0x1值
	tmp &= !(0x1<<4);	//把bit4清0
	tmp |= (1<<4);		//把bit4寫入0x1值
	// 這裏再提供一種簡便寫法,完全等價上面四行
	// tmp &= !(0x1<<2 | 0x1<<4);
	// tmp |= (1<<2 | 1<<4)
	rGPMDAT = tmp;		//寫回到端口寄存器
}
  • 應用程序 ledapp.c
// leadapp.c
void delay(){ // 停止一段時間
	for( i=0;i<1000;i++)
		for( j=0;j<1000;j++);
}
void main()
{
	ledconfig(); // 配置驅動
	while(1)
	{
		ledon();delay();
		ledoff();delay();
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章