今天继续学习开发板上的驱动程序,LED,即IO控制。板子CPU是S3C2410,很老的一块芯片了。
先看原理图:
再来看看相关IO的管脚控制器存器:
于是只须将GPACON的相关位清0,GPBCON的相关位设置为01 即可都配置为输出模式。
以下直接上驱动程序相关代码并做适当说明:
驱动代码
/* hardware access methods */
#define SNGS3C_REG_READ(x,result) ((result) = *(volatile unsigned int *)(x))
#define SNGS3C_REG_WRITE(x,data) (*((volatile unsigned int *)(x)) = (data))
#define SNGS3C_REG_AND(x, data) (*((volatile unsigned int *)(x)) &= (data))
#define SNGS3C_REG_OR(x, data) (*((volatile unsigned int *)(x)) |= (data))
#define SNGS3C_REG_XOR(x, data) (*((volatile unsigned int *)(x)) ^= (data))
// 访问硬件寄存器必须加上volatile关键字,以保证每次读写都是直接操作相关寄存器而不是中间缓存
//==============================================================================
// LED 灯IO口初始化
//==============================================================================
void Led_Init( void )
{
UINT32 dwValReg;
//RUN_LED---- GPA22 输出模式,指示开发板运行状态
SNGS3C_REG_READ( rGPACON, dwValReg );//GPA22-[22]
dwValReg = dwValReg & 0xFFBFFFFF;
SNGS3C_REG_WRITE( rGPACON, dwValReg );
//LED1-LED4---- GPB7-10 输出模式
SNGS3C_REG_READ( rGPBCON, dwValReg );//GPB7\8\9\10-[21:14]
dwValReg = dwValReg & 0xFFC03FFF;
dwValReg = dwValReg | 0x00154000;
SNGS3C_REG_WRITE( rGPBCON, dwValReg );
}
enum _LED_NAME_
{
ENUM_LED_LED0 = 0, // 指示灯编号
ENUM_LED_LED1,
ENUM_LED_LED2,
ENUM_LED_LED3,
ENUM_LED_MAXNO,
};
// 开关指定LED灯
void Led_OnOff( UINT8 byLedNo, BOOL bState )
{
UINT16 i;
switch(byLedNo)
{
case ENUM_LED_LED0: i = 1<<8; break;
case ENUM_LED_LED1: i = 1<<7; break;
case ENUM_LED_LED2: i = 1<<9; break;
case ENUM_LED_LED3: i = 1<<10;break;
default:
return;
}
if(bState)
SNGS3C_REG_AND(rGPBDAT, (~i));
else
SNGS3C_REG_OR(rGPBDAT, i);
}
// 运行状态指示灯,反转
void RunLed_Invert(void) //GPA22-[22]
{
UINT32 i;
i=1<<22;
SNGS3C_REG_XOR(rGPADAT, i); // 取反
// *(volatile UINT32 *)rGPADAT ^=i; // 取反
}
int Blink_Main( void )
{
UINT32 i=0;
BOOL j=0;
while( 1 )
{
RunLed_Invert(); // 运行状态指示灯反转
if(MenuDisp==3) // 触屏指定LED流水灯的时候,各灯依次点亮,依次熄灭
{
Led_OnOff(i++,j);
if(i>=4){ i=0;j=~j;}
}
else
{
for(i=0;i<4;i++)
Led_OnOff(i,0);
}
taskDelay(30);
}
}