日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

嵌入式学习4--混杂设备驱动

發(fā)布時間:2023/12/9 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 嵌入式学习4--混杂设备驱动 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

混雜設備驅動主要用于一些功能簡單的器件,將之整合到一起,major為10,minor一般為動態(tài)分配,其實實際的還是字符設備驅動。

比常規(guī)字符設備驅動更好的地方就是在于它簡化了編寫過程,將一些步驟整合到了一起,使代碼更加簡潔,可讀性更高,也便于維護和移植。

以下代碼為超聲波傳感器的驅動代碼

1.超聲波SRF05傳感器,在這里只用了Vcc、Trig、Echo、GND四個腳

A.Vcc 接5V電源

B.Trig接主板輸出端,主要是發(fā)送啟動信號

C.Echo接輸入端,主要檢測這個腳傳回來的值進行距離計算

D.GND接地

使用注意:如果帶電操作,一定要保證先接地,否則極易損壞器件

?

?

2.時序圖

A.觸發(fā)信號為至少維持20uS的高電平信號,需要控制Trig引腳來做啟動

B.模塊會發(fā)出8個40KHz的脈沖信號,并檢測回波

C.如果有回波,就輸出回響信號,回響信號會通過Echo引腳檢測,檢測到后做相應的處理

D.計算的公式為

?

3.以下為驅動代碼,Linux驅動代碼需要從下向上看

#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <mach/platform.h>
#include <linux/errno.h>
#include <linux/input.h>
#include <linux/cdev.h>
#include <linux/miscdevice.h>
#include <linux/gpio.h>
#include <asm/uaccess.h>

#define DEVICE_NAME "ultra_drv"
#define GPIOC_CFG_ULTRA_TRIG (PAD_GPIO_B + 28) ? ?//Trig引腳
#define GPIOC_CFG_ULTRA_ECHO (PAD_GPIO_B + 29) ?//Echo引腳

static int echo_data_in(void) ??
{
?? ?gpio_direction_input(GPIOC_CFG_ULTRA_ECHO); ?//設置為輸入引腳
?? ?return gpio_get_value(GPIOC_CFG_ULTRA_ECHO); ?//檢測當前電平
}

static int ultra_read_data(void)
{
?? ?unsigned int time_cnt = 0;
?? ?unsigned int distance = 0;
?? ?int ret = 0;
?? ?
?? ?ret = echo_data_in(); ? ? ? ? ? ? ? ? ? ?

?? ?if(ret){
?? ??? ?while(echo_data_in() && ((time_cnt++) < 50000)) ? ? ?//如果返回的是高電平代表有回波信號,開始記錄高電平持續(xù)時間
?? ??? ?{
?? ??? ??? ?udelay(10);
?? ??? ?}
?? ??? ?
?? ??? ?distance = ((time_cnt * 3) / 2); ?//當Echo拉低的時候,代碼測距完成,開始計算
?? ?}

?? ?return (distance);
}

int ultra_drv_open(struct inode *inode, struct file *filp)
{
?? ?printk("<4>" "ultra drv open\n");
?? ?
?? ?return 0;
}

ssize_t ultra_drv_read(struct file *filp, char __user *user_buf, size_t size, loff_t *offset)
{
?? ?int ret = 0;
?? ?unsigned int distance = 0;
?? ?
?? ?if(size != 4)
?? ??? ?return -EINVAL;
?? ?
?? ?gpio_direction_output(GPIOC_CFG_ULTRA_TRIG, 1); ?//啟動信號,控制Trig引腳拉高
?? ?udelay(20); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //至少維持10uS的高電平
?? ?gpio_set_value(GPIOC_CFG_ULTRA_TRIG, 0); ? ? ? ? ? ?//拉低Trig引腳,啟動成功
?? ?
?? ?distance = ultra_read_data(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//開始檢測Echo是否有回波信號
?? ?
?? ?ret = copy_to_user((int *)user_buf, &distance, sizeof(distance)); ?//將檢測到的距離copy到用戶空間,通過read讀取到
?? ?
?? ?return 0;
}

static struct file_operations ultra_drv_fops = { ? ? ?//文件操作集
?? ?.owner = THIS_MODULE,
?? ?.open ?= ultra_drv_open,
?? ?.read ?= ultra_drv_read
};

static struct miscdevice ultra_drv_miscdev = { ? //混雜設備
?? ?.minor = MISC_DYNAMIC_MINOR, ?//動態(tài)分配minor(此設備號)
?? ?.name ?= DEVICE_NAME, ? ? ? ? ? ? ? ? //設備名,使用open打開的就是這個名字
?? ?.fops ?= &ultra_drv_fops ? ? ? ? ? ? ? ? ? ? //文件操作集
};?

static int __init ultra_drv_init(void)
{
?? ?int ret = 0;
?? ?
?? ?gpio_free(GPIOC_CFG_ULTRA_TRIG); ? ? //野路子,避免內(nèi)核中已經(jīng)有功能使用該引腳,先釋放掉
?? ?
?? ?ret = gpio_request(GPIOC_CFG_ULTRA_TRIG, "ultra_drv"); ? ? ? //釋放后再申請給我們使用
?? ?if(ret < 0){
?? ??? ?printk("<4>" "gpio_request %s %d fail\n", DEVICE_NAME, GPIOC_CFG_ULTRA_TRIG);
?? ??? ?return ret;
?? ?}

?? ?ret = misc_register(&ultra_drv_miscdev); ? ? ? ?//注冊混雜設備
?? ?if(ret < 0){
?? ??? ?printk("<4>" "misc_register fail\n");
?? ??? ?return ret;
?? ?}
?? ?
?? ?printk("<4>" "ultra drv init\n");
?? ?
?? ?return 0;
}

static void __exit ultra_drv_exit(void)
{
?? ?gpio_free(GPIOC_CFG_ULTRA_TRIG);
?? ?
?? ?misc_deregister(&ultra_drv_miscdev);
?? ?
?? ?printk("<4>" "ultra drv exit\n");
}

module_init(ultra_drv_init);
module_exit(ultra_drv_exit);

MODULE_AUTHOR("ayl0521@sina.com"); ?//如有問題,可郵件探討
MODULE_DESCRIPTION("ultrasonic drv");
MODULE_LICENSE("GPL");

總結

以上是生活随笔為你收集整理的嵌入式学习4--混杂设备驱动的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。