日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當(dāng)前位置:首頁(yè) > 嵌入式 > 嵌入式教程
[導(dǎo)讀]FS2410開(kāi)發(fā)板的S3C2410處理器具有117個(gè)多功能通用I/O(GPIO)端口管腳,包括GPIO 8個(gè)端口組,分別為GPA(23個(gè)輸出端口)、GPB(11個(gè)輸入/輸出端口)、GPC(16個(gè)輸入/輸出端口)、GPD(16個(gè)輸入/輸出端口)、GPE(16個(gè)輸入/輸出端口)、GPF(8個(gè)輸入/輸出端口)、GPH(11個(gè)輸入/輸出端口)。

11.3GPIO驅(qū)動(dòng)程序?qū)嵗?1.3.1GPIO工作原理

FS2410開(kāi)發(fā)板的S3C2410處理器具有117個(gè)多功能通用I/O(GPIO)端口管腳,包括GPIO8個(gè)端口組,分別為GPA(23個(gè)輸出端口)、GPB(11個(gè)輸入/輸出端口)、GPC(16個(gè)輸入/輸出端口)、GPD(16個(gè)輸入/輸出端口)、GPE(16個(gè)輸入/輸出端口)、GPF(8個(gè)輸入/輸出端口)、GPH(11個(gè)輸入/輸出端口)。根據(jù)各種系統(tǒng)設(shè)計(jì)的需求,通過(guò)軟件方法可以將這些端口配置成具有相應(yīng)功能(例如:外部中斷或數(shù)據(jù)總線)的端口。

為了控制這些端口,S3C2410處理器為每個(gè)端口組分別提供幾種相應(yīng)的控制寄存器。其中最常用的有端口配置寄存器(GPACON~GPHCON)和端口數(shù)據(jù)寄存器(GPADAT~GPHDAT)。因?yàn)榇蟛糠諭/O管腳可以提供多種功能,通過(guò)配置寄存器(PnCON)設(shè)定每個(gè)管腳用于何種目的。數(shù)據(jù)寄存器的每位將對(duì)應(yīng)于某個(gè)管腳上的輸入或輸出。所以通過(guò)對(duì)數(shù)據(jù)寄存器(PnDAT)的位讀寫,可以進(jìn)行對(duì)每個(gè)端口的輸入或輸出。

在此主要以發(fā)光二極管(LED)和蜂鳴器為例,討論GPIO設(shè)備的驅(qū)動(dòng)程序。它們的硬件驅(qū)動(dòng)電路的原理圖如圖11.4所示。

圖11.4LED(左)和蜂鳴器(右)的驅(qū)動(dòng)電路原理圖

在圖11.4中,可知使用S3C2410處理器的通用I/O口GPF4、GPF5、GPF6和GPF7分別直接驅(qū)動(dòng)LEDD12、D11、D10以及D9,而使用GPB0端口驅(qū)動(dòng)蜂鳴器。4個(gè)LED分別在對(duì)應(yīng)端口(GPF4~GPF7)為低電平時(shí)發(fā)亮,而蜂鳴器在GPB0為高電平時(shí)發(fā)聲。這5個(gè)端口的數(shù)據(jù)流方向均為輸出。

在表11.15中,詳細(xì)描述了GPF的主要控制寄存器。GPB的相關(guān)寄存器的描述與此類似,具體可以參考S3C2410處理器數(shù)據(jù)手冊(cè)。

表11.15 GPF端口(GPF0-GPF7)的主要控制寄存器

寄存器

地址

R/W

功能

初始值

GPFCON

0x56000050

R/W

配置GPF端口組

0x0

GPFDAT

0x56000054

R/W

GPF端口的數(shù)據(jù)寄存器

未定義

GPFUP

0x56000058

R/W

GPF端口的取消上拉寄存器

0x0

GPFCON

描述

GPF7

[15:14]

00=輸入01=輸出10=EINT711=保留

GPF6

[13:12]

00=輸入01=輸出10=EINT611=保留

GPF5

[11:10]

00=輸入01=輸出10=EINT511=保留

GPF4

[9:8]

00=輸入01=輸出10=EINT411=保留

GPF3

[7:6]

00=輸入01=輸出10=EINT311=保留

GPF2

[5:4]

00=輸入01=輸出10=EINT211=保留

GPF1

[3:2]

00=輸入01=輸出10=EINT111=保留

GPF0

[1:0]

00=輸入01=輸出10=EINT011=保留

GPFDAT

描述

GPF[7:0]

[7:0]

每位對(duì)應(yīng)于相應(yīng)的端口,若端口用于輸入,則可以通過(guò)相應(yīng)的位讀取數(shù)據(jù);若端口用于輸出,則可以通過(guò)相應(yīng)的位輸出數(shù)據(jù);若端口用于其他功能,則其值無(wú)法確定。

GPFUP

描述

GPF[7:0]

[7:0]

0:向相應(yīng)端口管腳賦予上拉(pull-up)功能

1:取消上拉功能

為了驅(qū)動(dòng)LED和蜂鳴器,首先通過(guò)端口配置寄存器將5個(gè)相應(yīng)寄存器配置為輸出模式。然后通過(guò)對(duì)端口數(shù)據(jù)寄存器的寫操作,實(shí)現(xiàn)對(duì)每個(gè)GPIO設(shè)備的控制(發(fā)亮或發(fā)聲)。在下一個(gè)小節(jié)中介紹的驅(qū)動(dòng)程序中,s3c2410_gpio_cfgpin()函數(shù)和s3c2410_gpio_pullup()函數(shù)將進(jìn)行對(duì)某個(gè)端口的配置,而s3c2410_gpio_setpin()函數(shù)實(shí)現(xiàn)向數(shù)據(jù)寄存器的某個(gè)端口的輸出。

11.3.2GPIO驅(qū)動(dòng)程序

GPIO驅(qū)動(dòng)程序代碼如下所示:

/*gpio_drv.h*/

#ifndefFS2410_GPIO_SET_H

#defineFS2410_GPIO_SET_H

#include<linux/ioctl.h>

#defineGPIO_DEVICE_NAME"gpio"

#defineGPIO_DEVICE_FILENAME"/dev/gpio"

#defineLED_NUM4

#defineGPIO_IOCTL_MAGIC'G'

#defineLED_D09_SWT_IOW(GPIO_IOCTL_MAGIC,0,unsignedint)

#defineLED_D10_SWT_IOW(GPIO_IOCTL_MAGIC,1,unsignedint)

#defineLED_D11_SWT_IOW(GPIO_IOCTL_MAGIC,2,unsignedint)

#defineLED_D12_SWT_IOW(GPIO_IOCTL_MAGIC,3,unsignedint)

#defineBEEP_SWT_IOW(GPIO_IOCTL_MAGIC,4,unsignedint)

#defineLED_SWT_ON0

#defineLED_SWT_OFF1

#defineBEEP_SWT_ON1

#defineBEEP_SWT_OFF0

#endif/*FS2410_GPIO_SET_H*/

/*gpio_drv.c*/

#include<linux/config.h>

#include<linux/module.h>

#include<linux/moduleparam.h>

#include<linux/init.h>

#include<linux/kernel.h>/*printk()*/

#include<linux/slab.h>/*kmalloc()*/

#include<linux/fs.h>/*everything...*/

#include<linux/errno.h>/*errorcodes*/

#include<linux/types.h>/*size_t*/

#include<linux/mm.h>

#include<linux/kdev_t.h>

#include<linux/cdev.h>

#include<linux/delay.h>

#include<linux/device.h>

#include<asm/io.h>

#include<asm/uaccess.h>

#include<asm/arch-s3c2410/regs-gpio.h>

#include"gpio_drv.h"

staticintmajor=0;/*采用字符設(shè)備號(hào)的動(dòng)態(tài)分配*/

module_param(major,int,0);/*以參數(shù)的方式可以指定設(shè)備的主設(shè)備號(hào)*/

voids3c2410_gpio_cfgpin(unsignedintpin,unsignedintfunction)

{/*對(duì)某個(gè)管腳進(jìn)行配置(輸入/輸出/其他功能)*/

unsignedlongbase=S3C2410_GPIO_BASE(pin);/*獲得端口的組基地址*/

unsignedlongshift=1;

unsignedlongmask=0x03;/*通常用配置寄存器的兩位表示一個(gè)端口*/

unsignedlongcon;

unsignedlongflags;

if(pin<S3C2410_GPIO_BANKB)

{

shift=0;

mask=0x01;/*在GPA端口中用配置寄存器的一位表示一個(gè)端口*/

}

mask<<=(S3C2410_GPIO_OFFSET(pin)<<shift);

local_irq_save(flags);/*保存現(xiàn)場(chǎng),保證下面一段是原子操作*/

con=__raw_readl(base+0x00);

con&=~mask;

con|=function;

__raw_writel(con,base+0x00);/*向配置寄存器寫入新配置數(shù)據(jù)*/

local_irq_restore(flags);/*恢復(fù)現(xiàn)場(chǎng)*/

}

voids3c2410_gpio_pullup(unsignedintpin,unsignedintto)

{/*配置上拉功能*/

unsignedlongbase=S3C2410_GPIO_BASE(pin);/*獲得端口的組基地址*/

unsignedlongoffs=S3C2410_GPIO_OFFSET(pin);/*獲得端口的組內(nèi)偏移地址*/

unsignedlongflags;

unsignedlongup;

if(pin<S3C2410_GPIO_BANKB)

{

return;

}

local_irq_save(flags);

up=__raw_readl(base+0x08);

up&=~(1<<offs);

up|=to<<offs;

__raw_writel(up,base+0x08);/*向上拉功能寄存器寫入新配置數(shù)據(jù)*/

local_irq_restore(flags);

}

voids3c2410_gpio_setpin(unsignedintpin,unsignedintto)

{/*向某個(gè)管腳進(jìn)行輸出*/

unsignedlongbase=S3C2410_GPIO_BASE(pin);

unsignedlongoffs=S3C2410_GPIO_OFFSET(pin);

unsignedlongflags;

unsignedlongdat;

local_irq_save(flags);

dat=__raw_readl(base+0x04);

dat&=~(1<<offs);

dat|=to<<offs;

__raw_writel(dat,base+0x04);/*向數(shù)據(jù)寄存器寫入新數(shù)據(jù)*/

local_irq_restore(flags);

}

intgpio_open(structinode*inode,structfile*filp)

{/*open操作函數(shù):進(jìn)行寄存器配置*/

s3c2410_gpio_pullup(S3C2410_GPB0,1);/*BEEP*/

s3c2410_gpio_pullup(S3C2410_GPF4,1);/*LEDD12*/

s3c2410_gpio_pullup(S3C2410_GPF5,1);/*LEDD11*/

s3c2410_gpio_pullup(S3C2410_GPF6,1);/*LEDD10*/

s3c2410_gpio_pullup(S3C2410_GPF7,1);/*LEDD9*/

s3c2410_gpio_cfgpin(S3C2410_GPB0,S3C2410_GPB0_OUTP);

s3c2410_gpio_cfgpin(S3C2410_GPF4,S3C2410_GPF4_OUTP);

s3c2410_gpio_cfgpin(S3C2410_GPF4,S3C2410_GPF5_OUTP);

s3c2410_gpio_cfgpin(S3C2410_GPF4,S3C2410_GPF6_OUTP);

s3c2410_gpio_cfgpin(S3C2410_GPF4,S3C2410_GPF7_OUTP);

return0;

}

ssize_tgpio_read(structfile*file,char__user*buff,

size_tcount,loff_t*offp)

{/*read操作函數(shù):沒(méi)有實(shí)際功能*/

return0;

}

ssize_tgpio_write(structfile*file,constchar__user*buff,

size_tcount,loff_t*offp)

{/*write操作函數(shù):沒(méi)有實(shí)際功能*/

return0;

}

intswitch_gpio(unsignedintpin,unsignedintswt)

{/*向5個(gè)端口中的一個(gè)輸出ON/OFF值*/

if(!((pin<=S3C2410_GPF7)&&(pin>=S3C2410_GPF4))

&&(pin!=S3C2410_GPB0))

{

printk("Unsupportedpin");

return1;

}

s3c2410_gpio_setpin(pin,swt);

return0;

}

staticintgpio_ioctl(structinode*inode,structfile*file,

unsignedintcmd,unsignedlongarg)

{/*ioctl函數(shù)接口:主要接口的實(shí)現(xiàn)。對(duì)5個(gè)GPIO設(shè)備進(jìn)行控制(發(fā)亮或發(fā)聲)*/

unsignedintswt=(unsignedint)arg;

switch(cmd)

{

caseLED_D09_SWT:

{

switch_gpio(S3C2410_GPF7,swt);

}

break;

caseLED_D10_SWT:

{

switch_gpio(S3C2410_GPF6,swt);

}

break;

caseLED_D11_SWT:

{

switch_gpio(S3C2410_GPF5,swt);

}

break;

caseLED_D12_SWT:

{

switch_gpio(S3C2410_GPF4,swt);

}

break;

caseBEEP_SWT:

{

switch_gpio(S3C2410_GPB0,swt);

break;

}

default:

{

printk("Unsupportedcommandn");

break;

}

}

return0;

}

staticintgpio_release(structinode*node,structfile*file)

{/*release操作函數(shù),熄滅所有燈和關(guān)閉蜂鳴器*/

switch_gpio(S3C2410_GPB0,BEEP_SWT_OFF);

switch_gpio(S3C2410_GPF4,LED_SWT_OFF);

switch_gpio(S3C2410_GPF5,LED_SWT_OFF);

switch_gpio(S3C2410_GPF6,LED_SWT_OFF);

switch_gpio(S3C2410_GPF7,LED_SWT_OFF);

return0;

}

staticvoidgpio_setup_cdev(structcdev*dev,intminor,

structfile_operations*fops)

{/*字符設(shè)備的創(chuàng)建和注冊(cè)*/

interr,devno=MKDEV(major,minor);

cdev_init(dev,fops);

dev->owner=THIS_MODULE;

dev->ops=fops;

err=cdev_add(dev,devno,1);

if(err)

{

printk(KERN_NOTICE"Error%daddinggpio%d",err,minor);

}

}

staticstructfile_operationsgpio_fops=

{/*gpio設(shè)備的file_operations結(jié)構(gòu)定義*/

.owner=THIS_MODULE,

.open=gpio_open,/*進(jìn)行初始化配置*/

.release=gpio_release,/*關(guān)閉設(shè)備*/

.read=gpio_read,

.write=gpio_write,

.ioctl=gpio_ioctl,/*實(shí)現(xiàn)主要控制功能*/

};

staticstructcdevgpio_devs;

staticintgpio_init(void)

{

intresult;

dev_tdev=MKDEV(major,0);

if(major)

{/*設(shè)備號(hào)的動(dòng)態(tài)分配*/

result=register_chrdev_region(dev,1,GPIO_DEVICE_NAME);

}

else

{/*設(shè)備號(hào)的動(dòng)態(tài)分配*/

result=alloc_chrdev_region(&dev,0,1,GPIO_DEVICE_NAME);

major=MAJOR(dev);

}

if(result<0)

{

printk(KERN_WARNING"Gpio:unabletogetmajor%dn",major);

returnresult;

}

gpio_setup_cdev(&gpio_devs,0,&gpio_fops);

printk("Themajorofthegpiodeviceis%dn",major);

return0;

}

staticvoidgpio_cleanup(void)

{

cdev_del(&gpio_devs);/*字符設(shè)備的注銷*/

unregister_chrdev_region(MKDEV(major,0),1);/*設(shè)備號(hào)的注銷*/

printk("Gpiodeviceuninstalledn");

}

module_init(gpio_init);

module_exit(gpio_cleanup);

MODULE_AUTHOR("David");

MODULE_LICENSE("DualBSD/GPL");

下面列出GPIO驅(qū)動(dòng)程序的測(cè)試用例:

/*gpio_test.c*/

#include<stdio.h>

#include<stdlib.h>

#include<unistd.h>

#include<fcntl.h>

#include<string.h>

#include<sys/types.h>

#include<sys/stat.h>

#include"gpio_drv.h"

intled_timer(intdev_fd,intled_no,unsignedinttime)

{/*指定LED發(fā)亮一段時(shí)間之后熄滅它*/

led_no%=4;

ioctl(dev_fd,LED_D09_SWT+led_no,LED_SWT_ON);/*發(fā)亮*/

sleep(time);

ioctl(dev_fd,LED_D09_SWT+led_no,LED_SWT_OFF);/*熄滅*/

}

intbeep_timer(intdev_fd,unsignedinttime)

{/*開(kāi)蜂鳴器一段時(shí)間之后關(guān)閉*/

ioctl(dev_fd,BEEP_SWT,BEEP_SWT_ON);/*發(fā)聲*/

sleep(time);

ioctl(dev_fd,BEEP_SWT,BEEP_SWT_OFF);/*關(guān)閉*/

}

intmain()

{

inti=0;

intdev_fd;

/*打開(kāi)gpio設(shè)備*/

dev_fd=open(GPIO_DEVICE_FILENAME,O_RDWR|O_NONBLOCK);

if(dev_fd==-1)

{

printf("Cann'topengpiodevicefilen");

exit(1);

}

while(1)

{

i=(i+1)%4;

led_timer(dev_fd,i,1);

beep_timer(dev_fd,1);

}

close(dev_fd);

return0;

}

具體運(yùn)行過(guò)程如下所示。首先編譯并加載驅(qū)動(dòng)程序:

$makeclean;make/*驅(qū)動(dòng)程序的編譯*/

$insmodgpio_drv.ko/*加載gpio驅(qū)動(dòng)*/

$cat/proc/devices/*通過(guò)這個(gè)命令可以查到gpio設(shè)備的主設(shè)備號(hào)*/

$mknod/dev/gpioc2520/*假設(shè)主設(shè)備號(hào)為252,創(chuàng)建設(shè)備文件節(jié)點(diǎn)*/

然后編譯并運(yùn)行驅(qū)動(dòng)測(cè)試程序:

$arm-linux-gcc–ogpio_testgpio_test.c

$./gpio_test

運(yùn)行結(jié)果為4個(gè)LED輪流閃爍,同時(shí)蜂鳴器以一定周期發(fā)出聲響。

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

LED驅(qū)動(dòng)電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: 驅(qū)動(dòng)電源

在工業(yè)自動(dòng)化蓬勃發(fā)展的當(dāng)下,工業(yè)電機(jī)作為核心動(dòng)力設(shè)備,其驅(qū)動(dòng)電源的性能直接關(guān)系到整個(gè)系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動(dòng)勢(shì)抑制與過(guò)流保護(hù)是驅(qū)動(dòng)電源設(shè)計(jì)中至關(guān)重要的兩個(gè)環(huán)節(jié),集成化方案的設(shè)計(jì)成為提升電機(jī)驅(qū)動(dòng)性能的關(guān)鍵。

關(guān)鍵字: 工業(yè)電機(jī) 驅(qū)動(dòng)電源

LED 驅(qū)動(dòng)電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個(gè)照明設(shè)備的使用壽命。然而,在實(shí)際應(yīng)用中,LED 驅(qū)動(dòng)電源易損壞的問(wèn)題卻十分常見(jiàn),不僅增加了維護(hù)成本,還影響了用戶體驗(yàn)。要解決這一問(wèn)題,需從設(shè)計(jì)、生...

關(guān)鍵字: 驅(qū)動(dòng)電源 照明系統(tǒng) 散熱

根據(jù)LED驅(qū)動(dòng)電源的公式,電感內(nèi)電流波動(dòng)大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關(guān)鍵字: LED 設(shè)計(jì) 驅(qū)動(dòng)電源

電動(dòng)汽車(EV)作為新能源汽車的重要代表,正逐漸成為全球汽車產(chǎn)業(yè)的重要發(fā)展方向。電動(dòng)汽車的核心技術(shù)之一是電機(jī)驅(qū)動(dòng)控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機(jī)驅(qū)動(dòng)系統(tǒng)中的關(guān)鍵元件,其性能直接影響到電動(dòng)汽車的動(dòng)力性能和...

關(guān)鍵字: 電動(dòng)汽車 新能源 驅(qū)動(dòng)電源

在現(xiàn)代城市建設(shè)中,街道及停車場(chǎng)照明作為基礎(chǔ)設(shè)施的重要組成部分,其質(zhì)量和效率直接關(guān)系到城市的公共安全、居民生活質(zhì)量和能源利用效率。隨著科技的進(jìn)步,高亮度白光發(fā)光二極管(LED)因其獨(dú)特的優(yōu)勢(shì)逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

關(guān)鍵字: 發(fā)光二極管 驅(qū)動(dòng)電源 LED

LED通用照明設(shè)計(jì)工程師會(huì)遇到許多挑戰(zhàn),如功率密度、功率因數(shù)校正(PFC)、空間受限和可靠性等。

關(guān)鍵字: LED 驅(qū)動(dòng)電源 功率因數(shù)校正

在LED照明技術(shù)日益普及的今天,LED驅(qū)動(dòng)電源的電磁干擾(EMI)問(wèn)題成為了一個(gè)不可忽視的挑戰(zhàn)。電磁干擾不僅會(huì)影響LED燈具的正常工作,還可能對(duì)周圍電子設(shè)備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來(lái)解決L...

關(guān)鍵字: LED照明技術(shù) 電磁干擾 驅(qū)動(dòng)電源

開(kāi)關(guān)電源具有效率高的特性,而且開(kāi)關(guān)電源的變壓器體積比串聯(lián)穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機(jī)重量也有所下降,所以,現(xiàn)在的LED驅(qū)動(dòng)電源

關(guān)鍵字: LED 驅(qū)動(dòng)電源 開(kāi)關(guān)電源

LED驅(qū)動(dòng)電源是把電源供應(yīng)轉(zhuǎn)換為特定的電壓電流以驅(qū)動(dòng)LED發(fā)光的電壓轉(zhuǎn)換器,通常情況下:LED驅(qū)動(dòng)電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: LED 隧道燈 驅(qū)動(dòng)電源
關(guān)閉