完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
原理图
ADC的基础adc 的基础是从10_0000开始,大小0x10000。PMUCRUFF75_0000 , 大小0x10000。明天的每个月至 ADC 的5 次接近 ADC 类型是模拟接近 ADC 的类型。例如,很宽的尺寸至应用16位,具有这些类型的工业通用特性、小尺寸等特性。 /,采样率等。由于 ADC 实际上次执行的是一种近距搜索搜索算法,该内部电路在数兆赫兹信号 (MHz) 时,因此,ADC 的频率是多少的几倍。分之一。 这些 SAR ADC 和扬声器、主要扬声器、扬声器以及周围是 SAR ADC 与更多的小尺寸的集成功能。需要哪些、需要比较单元(如 DAC),整体系统整体的精确度。 RK3399Pro [tr] NameOffsetSizeResetValueDescription [/tr]
最后转换ADC的数字值,通过获取这个数字值。 地址:Operational Base + offset (0x0000) 该寄存器包含A/D转换后的数据。 [tr]BitAttrReset 值描述[/tr]
通过这个需要的模数是否在进行转换。 地址:Operational Base + offset (0x0004)A/D 转换器的状态寄存器。 [tr]BitAttrReset 值描述[/tr]
控制决定是否开始进行模数转换。 地址:运算基+偏移量(0x0008)A/D转换器的控制寄存器。 [tr]BitAttrReset 值描述[/tr]
地址:Operational Base + offset (0x000c)delay between power up and start command [tr]BitAttrReset ValueDescription[/tr]
CRU_CLKSEL_CON26时钟 配置 Address: Operational Base + offset (0x0168)内部时钟选择和分频寄存器 26 [tr]BitAttrReset ValueDescription[/tr]
操作流程 adc转换步骤:
函数入口函数 配置ADC的CTRL寄存器。 static int __init gec3399_adc_init(void) { int ret; printk(KERN_INFO "gec3399_adc_initn"); //第一步:注册杂项设备 ret = misc_register(&miscdev); if(ret < 0){ printk("misc driver register errorn"); goto misc_register_err; } //第二步:内存映射 SARADC_BASE = ioremap(0xFF100000,0x1000); if(SARADC_BASE == NULL){ printk("SARADC_BASE ioremap errorn"); ret = -EFAULT; goto SARADC_ioremap_err; } //第三步:CLK地址内存映射 CRU_CLKSEL_BASE = ioremap(0xFF760000,0x1000); if(SARADC_BASE == NULL){ printk(" CRU_CLKSEL_BASE ioremap errorn"); ret = -EFAULT; goto CRU_ioremap_err; } //第四步:内存地址初始化 SARADC_DATA = SARADC_BASE + 0x0000; SARADC_STAS = SARADC_BASE + 0x0004; SARADC_CTRL = SARADC_BASE + 0x0008; CRU_CLKSEL_CON26 = CRU_CLKSEL_BASE + 0x0168; writel(readl(SARADC_CTRL)&~(1<<3),SARADC_CTRL); //关闭ADC writel(readl(CRU_CLKSEL_CON26)&~(0xFF<<8),CRU_CLKSEL_CON26); writel(readl(CRU_CLKSEL_CON26)|(0xFF<<8),CRU_CLKSEL_CON26); //设置分频因子 return 0; CRU_ioremap_err: iounmap(SARADC_BASE); SARADC_ioremap_err: misc_deregister(&miscdev); misc_register_err: return ret; //返回错误的原因 } 杂项设备 static struct miscdevice miscdev = { .minor = MISC_DYNAMIC_MINOR, .name = "adc_drv", .fops = &gec3399_adc_fops, }; 文件操作集 static const struct file_operations gec3399_adc_fops = { .owner = THIS_MODULE, .unlocked_ioctl = gec3399_adc_ioctl, .read = gec3399_adc_read, }; ADC通道设备 static long gec3399_adc_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { switch(cmd) { case GEC3399_ADC_SET_CHANNEL: writel(readl(SARADC_CTRL)&~(7<<0),SARADC_CTRL); //清零操作 writel(readl(SARADC_CTRL)|(arg<<0),SARADC_CTRL); //选择通道 } return 0; } ADC值获取 static ssize_t gec3399_adc_read(struct file *file, char __user *buf,size_t nbytes, loff_t *ppos) { int ret; int timr_out = 10000; unsigned int value = 100; writel(readl(SARADC_CTRL)|(1<<3),SARADC_CTRL); //启动ADC mdelay(20); //等待启动完毕 writel(readl(SARADC_STAS)|1,SARADC_STAS); while((((readl(SARADC_STAS)&1)==1)&&(timr_out--))); if(timr_out == 0) { printk(KERN_INFO "timr out errotn"); } writel(readl(SARADC_CTRL)&~(1<<3),SARADC_CTRL); //关闭ADC value = readl(SARADC_DATA)&0x3ff; //读取数据 ret = copy_to_user((void*)buf,&value,4); if(ret < 0) { printk(KERN_INFO "copy_to_user errotn"); return -1; } return 0; } 测试代码 #include #include #include #include #include #include #include #define GEC3399_ADC_SET_CHANNEL _IO('A',1) int main(void) { int fd; int ret; float tmp; unsigned int voltage = 0; //第一步:打开ADC设备节点 fd = open("/dev/adc_drv", O_RDWR); if(fd < 0) { perror("open adc driver"); return -1; } while(1) { //第二步:打开ADC通道0 ret = ioctl(fd,GEC3399_ADC_SET_CHANNEL,0); if(ret<0) { perror("ioctl adc driver "); } //第三步:读取ADC通道0的值 ret = read(fd,&voltage,4); if(ret<0) { perror("read adc driver "); } if(voltage==0) continue; //printf("voltage = %dn",voltage); tmp=(float)voltage; printf("ADC 0 voltage = %0.2fn",(tmp/1024)*1.8); usleep(500*1000);//0.5s //第四步:打开ADC通道1 ret = ioctl(fd,GEC3399_ADC_SET_CHANNEL,1); if(ret<0) { perror("ioctl adc driver "); } //第五步:读取ADC通道1的值 ret = read(fd,&voltage,4); if(ret<0) { perror("read adc driver "); } if(voltage==0) continue; //printf("voltage = %dn",voltage); tmp=(float)voltage; printf("ADC 1 voltage = %0.2fn",(tmp/1024)*1.8); usleep(500*1000);//0.5s } close(fd); return 0; } 编写Makefile文件 obj-m += adc_drv.o KERNELDIR:=/file/RK3399Pro/rk3399pro_git_repo/kernel PWD:=$(shell pwd) default: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules test: aarch64-linux-gnu-gcc adc_test.c -o adc_test clean: rm -rf *.o *.order .*.cmd *.ko *.mod.c *.symvers *.tmp_versions 测试步骤 编译源码 在ubuntu中输入: make 得到驱动目标文件adc_drv.ko 输入: make test 得到测试目标文件:adc_test 加载驱动 在开发板命令终端输入: insmod adc_drv.ko 执行测试程序 在开发板命令终端输入: chmod 777 adc_test ./adc_test 实验现象 读取ADC的模数转换值。 |
||||
|
||||
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
2104 浏览 1 评论
synopsys 的design ware:DW_fpv_div,浮点数除法器,默认32位下,想提升覆盖率(TMAX),如果用功能case去提升覆盖率呢?
2735 浏览 1 评论
RK3588 GStreamer调试四路鱼眼摄像头四宫格显示报错
5514 浏览 1 评论
【飞凌嵌入式OK3576-C开发板体验】RKNN神经网络-YOLO图像识别
254 浏览 0 评论
【飞凌嵌入式OK3576-C开发板体验】SSH远程登录网络配置及CAN通讯
1336 浏览 0 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-28 23:33 , Processed in 0.488659 second(s), Total 70, Slave 54 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号