zoukankan      html  css  js  c++  java
  • s3c2440的GPIO驱动

    S3C2440包含有130多个通用的GPIO,同时这些端口也拥有一些复用功能(ADC输入),有部分端口只能输入,有部分端口只能输出,今天我们来看看如何设置一个GPIO的输出电平以及如何获取一个端口的GPIO电平

     

    GPIO进行操作分为以下几步

    1.       功能设置,GPXCON寄存器,针对于2440addr.h,分别为

    rGPACON, rGPBCON, rGPCCON, rGPDCON, rGPECON, rGPFCON, rGPGCON, rGPHCON, rGPJCON

    通过设置不同的值来选着不同的功能,输入,输出,复用,

    2.       数据读写,GPXDAT寄存器,在输入模式下,dat寄存器相应位代表相应引脚的当前电平,在输出模式下, dat寄存器相应位代想要设置的相应电平

    (,2440addr.h中的寄存器前面都有一个小写r开头).

    3.       内部上拉寄存器GPXUP寄存器,可以设置相应位的内部上拉是否打开

    设置好这三位之后,GPIO就可以正常操作了

     

    以下是GPIO输出LED,使用GPB5-GPB8

     

    Led.c

     

    #include "led.h"
    
    
    
    void LedInit(void)
    {
    	//GPB 01为输出模式,先清零寄存器为00
    	rGPBCON &= ~((3<<10)|(3<<12)|(3<<14)|(3<<16));//10 b5 12 b6 14 b7 16 b8
    	//设置相应寄存器为01
    	rGPBCON |= ((1<<10)|(1<<12)|(1<<14)|(1<<16));
    	//禁止上拉,因为是输出
    	rGPBUP &= ~((1<<5)|(1<<6)|(1<<7)|(1<<8));
    	//设置初始化为1 led处于熄灭状态
    	rGPBDAT |= ((1<<5)|(1<<6)|(1<<7)|(1<<8));
    }
    
    void LedSet(u8 ch,u8 value)
    {
    	switch(ch)
    	{
    	case 0:
    		if(value)rGPBDAT |= (1<<5);
    		else rGPBDAT &= ~(1<<5);
    		break;
    	case 1:
    		if(value)rGPBDAT |= (1<<6);
    		else rGPBDAT &= ~(1<<6);
    		break;
    	case 2:
    		if(value)rGPBDAT |= (1<<7);
    		else rGPBDAT &= ~(1<<7);
    		break;
    	case 3:
    		if(value)rGPBDAT |= (1<<8);
    		else rGPBDAT &= ~(1<<8);
    		break;
    	}
    }
    
    
    


    Led.h

     

    #ifndef __LED_H
    #define __LED_H
    #include "2440addr.h"
    #include "def.h"
    
    void LedInit(void);
    
    void LedSet(u8 ch,u8 value);
    
    
    
    #endif
    


    以下是GPIO输入按键检测,使用GPIOF 0 1 2 4

     

    Key.c

     

    #include "key.h"
    
    u8 keyValue = 0;
    
    void KeyInit(void)
    {
    	rGPFCON &=~((3<<2)|(3<<8)|(3<<4)|(3<<0));	//对GPFCON[10:17]清零
    	rGPFUP &=~((1<<1)|(1<<4)|(1<<2)|(1<<0));	//设置上拉功能
    	rGPFDAT |=(1<<1)|(1<<4)|(1<<2)|(1<<0);	//设定初始值
    }
    
    //按键按下,相关端口为0,没有按键按下时,不会自动清零,会保持最后一次的状态,需要用户自己去清零
    u8 GetKeyValue(void)
    {
    	u32 temp = rGPFDAT;
    	if(!(temp & (1<<0)))	//如果相关端口为0
    	{
    		keyValue = KEY_UP;
    		return keyValue;
    	}
    	if(!(temp & (1<<1)))
    	{
    		keyValue = KEY_DOWN;
    		return keyValue;
    	}
    	if(!(temp & (1<<2)))
    	{
    		keyValue = KEY_LEFT;
    		return keyValue;
    	}
    	if(!(temp & (1<<4)))
    	{
    		keyValue = KEY_RIGHT;
    		return keyValue;
    	}
    	return 0;
    }
    


    Key.h

     

    #ifndef __KEY_H
    #define __KEY_H
    
    #include "2440addr.h"
    #include "def.h"
    
    
    //按键全部上拉
    //key1 对应 F1
    //key2 对应 F4
    //key3 对应 F2
    //key4 对应 F0
    
    #define KEY_UP		1
    #define KEY_DOWN	2
    #define KEY_LEFT	3
    #define KEY_RIGHT	4
    
    extern u8 keyValue;
    
    void KeyInit(void);
    
    u8 GetKeyValue(void);
    
    
    
    
    #endif
    
    


     

     

     

     

  • 相关阅读:
    Leetcode 16.25 LRU缓存 哈希表与双向链表的组合
    Leetcode437 路径总和 III 双递归与前缀和
    leetcode 0404 二叉树检查平衡性 DFS
    Leetcode 1219 黄金矿工 暴力回溯
    Leetcode1218 最长定差子序列 哈希表优化DP
    Leetcode 91 解码方法
    Leetcode 129 求根到叶子节点数字之和 DFS优化
    Leetcode 125 验证回文串 双指针
    Docker安装Mysql记录
    vmware虚拟机---Liunx配置静态IP
  • 原文地址:https://www.cnblogs.com/dengxiaojun/p/4279422.html
Copyright © 2011-2022 走看看