s3c2440通过GPIO口控制三块74HC595的电路图为如下:
驱动为:
- /*************************************
- NAME:Con595.c
- 通过一个GPIO口来控制24个LED灯的明亮。
- *************************************/
- #include <linux/miscdevice.h>
- #include <linux/delay.h>
- #include <mach/regs-gpio.h>
- #include <mach/regs-gpioj.h>
- #include <mach/hardware.h>
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/init.h>
- #include <linux/mm.h>
- #include <linux/fs.h>
- #include <linux/types.h>
- #include <linux/delay.h>
- #include <linux/moduleparam.h>
- #include <linux/slab.h>
- #include <linux/errno.h>
- #include <linux/ioctl.h>
- #include <linux/cdev.h>
- #include <linux/string.h>
- #include <linux/list.h>
- #include <linux/pci.h>
- #include <asm/uaccess.h>
- #include <asm/atomic.h>
- #include <asm/unistd.h>
- #include <linux/gpio.h>
- //#undef DEBUG
- #define DEBUG
- #ifdef DEBUG
- #define DPRINTK(x...) {printk(x);}
- #else
- #define DPRINTK(x...) (void)(0)
- #endif
- #define DEFAULT 2
- #define ON 1
- #define OFF 0
- #define DEVICE_NAME "Control_595"
- unsigned int Current_LED_State =0xffffffff; //初始化全部都亮。
- /*=============================================================
- 函数名:OnOffLed
- 功能:对各个灯的控制。
- 参数:pin:表示第几个灯。范围0~23
- On_Off:表示灯的状态。
- ==============================================================*/
- static void OnOffLed(int pin,int On_Off)
- {
- int temp;
- int j;
- if(On_Off==0)
- {
- Current_LED_State |=1<<pin;//这是控制灯亮
- }
- else if(On_Off==1)
- {
- Current_LED_State &=~(1<<pin);//这是在控制灯暗
- }
- else if(On_Off==2 )
- {
- Current_LED_State=0xffffffff;
- }
- else if(On_Off==3)
- {
- Current_LED_State=0;
- }
- else
- {
- printk("Enter error!");
- }
- temp=j=0;
- DPRINTK("1:Current_LED_State:%04x\n",Current_LED_State);
- while(j<24)
- //(int j=0;j<24;j++)
- {
- temp = (Current_LED_State>>j) & 0x00000001;//这是把当前的一位取出来。
- DPRINTK("2-%d,bit-%d:Current_LED_State:%04x;\n",j,temp,Current_LED_State);
- //打开引脚SI的电平
- s3c2410_gpio_setpin(S3C2440_GPJ0,temp);//
- //SRCK产生一个脉冲,上升沿就把就移位。也就是说上升沿有效。
- s3c2410_gpio_setpin(S3C2440_GPJ2,0);
- udelay(200);//这是微秒级的。
- s3c2410_gpio_setpin(S3C2440_GPJ2,1);
- j++;
- }
- //到这里就控制RCK上升沿来把移位寄存器的数据移到数据寄存器。RCK一般保持正脉冲。
- s3c2410_gpio_setpin(S3C2440_GPJ1,0);
- udelay(200);
- s3c2410_gpio_setpin(S3C2440_GPJ1,1);
- }
- /*=============================================================
- 函数名:tq2440_gpio_ioctl().
- 功能:通过系统函数ioctl来设置那一个灯暗亮。
- 参数: cmd:是发送的命令。ON 表示亮,OFF表示暗。DEFAULT表示默认全部灯变亮。
- arg:表示那一个灯变亮。范围为0~23
- ==============================================================*/
- static int tq2440_gpio_ioctl(
- struct inode *inode,
- struct file *file,
- unsigned int cmd,
- unsigned int arg)
- {
- DPRINTK("enter to the ioctl\n");
- if (arg > 24)
- {
- return -EINVAL;
- }
- switch(cmd)
- {
- case ON:
- // 设置指定引脚的输出电平为0
- DPRINTK("ON\n");
- OnOffLed(arg,ON);
- return 0;
- case OFF:
- // 设置指定引脚的输出电平为1
- DPRINTK("OFF\n");
- OnOffLed(arg,OFF);
- return 0;
- case 3: //这个是低电平,也就是灯亮
- DPRINTK("3\n");
- OnOffLed(arg,3);
- return 0;
- case 4: //这是高电平,也就是灯亮
- DPRINTK("DEFAULT\n");
- OnOffLed(arg,2);
- return 0;
- default:
- return -EINVAL;
- }
- }
- static struct file_operations dev_fops = {
- .owner = THIS_MODULE,
- .ioctl = tq2440_gpio_ioctl,
- };
- static struct miscdevice misc = {
- .minor = MISC_DYNAMIC_MINOR,
- .name = DEVICE_NAME,
- .fops = &dev_fops,
- };
- /*=============================================================
- 函数名:dev_init();
- 功能:初始化连接74595和个引脚的初始化。分别有连接SIN ,SRCK RCK.
- ==============================================================*/
- static int __init dev_init(void)
- {
- int ret;
- s3c2410_gpio_cfgpin(S3C2440_GPJ0, S3C2440_GPJ0_OUTP);
- s3c2410_gpio_setpin(S3C2440_GPJ0, 1);
- s3c2410_gpio_cfgpin(S3C2440_GPJ1, S3C2440_GPJ1_OUTP);
- s3c2410_gpio_setpin(S3C2440_GPJ1, 1);
- s3c2410_gpio_cfgpin(S3C2440_GPJ2, S3C2440_GPJ2_OUTP);
- s3c2410_gpio_setpin(S3C2440_GPJ2, 1);
- /*===========================================================
- 以下是对ENIT5 ENIT6 ENTI7的初始化,这是对74595的管脚的使能
- =============================================================*/
- s3c2410_gpio_cfgpin(S3C2410_GPF(5), S3C2410_GPIO_OUTPUT);
- s3c2410_gpio_setpin(S3C2410_GPF(5), 0);
- s3c2410_gpio_cfgpin(S3C2410_GPF(6), S3C2410_GPIO_OUTPUT);
- s3c2410_gpio_setpin(S3C2410_GPF(6), 0);
- s3c2410_gpio_cfgpin(S3C2410_GPF(7), S3C2410_GPIO_OUTPUT);
- s3c2410_gpio_setpin(S3C2410_GPF(7), 0);
- OnOffLed(1,DEFAULT );
- ret = misc_register(&misc);
- printk(DEVICE_NAME" initialized\n");
- return ret;
- }
- static void __exit dev_exit(void)
- {
- misc_deregister(&misc);
- DPRINTK("unload!\n");
- }
- module_init(dev_init);
- module_exit(dev_exit);
- MODULE_LICENSE("GPL");
- MODULE_AUTHOR("Li");
- MODULE_DESCRIPTION("GPIO Control 74HC595");
测试代码为:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <linux/fs.h>
#include <errno.h>
#include <string.h>
#include"test595.h"
int main()
{
int fd,cmd,arg;
fd = open("/dev/Control_595", 0);
if (fd < 0)
{
perror("open ADC device !");
exit(1);
}
while (1)
{
printf("Please your led:(0~23).\n");
scanf("%d",&arg);
scanf("%d",&cmd);
printf("cmd:%d, arg:%d\n",cmd,arg);
//ioctl(fd,cmd,arg);
CONFIG_SW(fd,cmd,arg);
}return 0;
}