嵌入式系统编程实验报告
系 别 电子科学与技术
专业班级 电子0802
学生姓名 指导教师 曹计昌 黄向宇
提交日期 20xx年11 月 7 日
一、实验目的
1学习 A D转换原理
2掌握 AD转换芯片的使用方法
3掌握不带有 AD 的 CPU 扩展 D/A 功能的主要方法
4了解AD 驱动程序加入内核的方法
二、实验内容
学习 AD 接口原理,了解实现 AD 系统对于系统的软件和硬件要求。阅读 芯片文档,掌握其使用方法。
三、实验环境
硬件:UP-TECH S2410/P270 DVP 嵌入式实验平台、PC 机 Pentium 500 以上, 硬盘 10G 以上。 软件:PC 机操作系统 REDHAT LINUX 9.0+MINICOM+ARM-LINUX 开发环境
四、 实验原理
GPIO驱动分析
Write,read,open,release四个函数与前边相同,只有基本操作和调试信息。Ioctl函数为GPIO口的控制函数,其代码如下:
ssize_t SIMPLE_GPIO_LED_ioctl (struct inode * inode ,struct file * file, unsigned int cmd, long ADta)
{
#ifdef OURS_GPIO_LED_DEBUG
printk ("SIMPLE_GPIO_LED_ioctl [ --kernel--]\n"); //调试信息 #endif
switch (cmd) //io控制,cmd为输入的命令
{
case LED_ON : {GPCR3 |= 0x1;break;}//通过修改寄存器控制GPIO口电平 case LED_OFF: {GPSR3 |= 0x1;break;}
default :
{printk ("lcd control : no cmd run
[ --kernel-- ]\n"); return (-EINVAL); //非法命令}
}
return 0;
}
操作结构体:
struct file_operations GPIO_LED_ctl_ops ={ open: SIMPLE_GPIO_LED_open, read: SIMPLE_GPIO_LED_read, write: SIMPLE_GPIO_LED_write, ioctl: SIMPLE_GPIO_LED_ioctl, release: SIMPLE_GPIO_LED_release,
};
建立操作映射,注册借口函数。为应用层提供统一的接口。
驱动模块必须具备两个函数,就是初始化函数和卸载函数,其声明为如下两句: module_init(pxa270_GPIO_LED_CTL_init);//加载模块时,系统调用 pxa270_GPIO_LED_CTL_init函数初始化模块
module_exit(cleanup_GPIO_LED_ctl);//系统将调用该函数来卸载模块
这是linux驱动模块必备的。
初始化函数如下:
static int __init pxa270_GPIO_LED_CTL_init(void)
{
int ret = -ENODEV; //初始化失败将返回次错误信息
//调试信息
#ifdef OURS_GPIO_LED_DEBUG
printk ("pxa270_GPIO_LED_CTL_init [ --kernel--]\n"); #endif
//调用HW_GPIO_LED_CTL_init函数完成初始化
ret = HW_GPIO_LED_CTL_init();
if (ret)
return ret;
return 0;
}
该函数通过调用HW_GPIO_LED_CTL_init函数实现初始化,该函数代码如下: static int __init HW_GPIO_LED_CTL_init(void)
{
int ret = -ENODEV;
printk("hhhhhhhhhhhhhhhhhhhhhhhhhhhhh\n\n");
showversion(); //显示版本信息
// init GPIO
//初始化输出端口
GPDR3 |= 0x00000001; // 设置输出端口模式
GPSR3 |= 0x00000001; // 关闭led灯
//调试信息,显示寄存器信息
#ifdef OURS_GPIO_LED_DEBUG
printk (" GPLR3=%x \n",GPLR3);
printk (" GPDR3=%x \n",GPDR3);
#endif
//注册设备
ret = devfs_register_chrdev(SIMPLE_GPIO_LED_MAJOR//主设备
号 ,"gpio_led_ctl", &GPIO_LED_ctl_ops//函数映射结构体);
if( ret < 0 )
{
printk (" pxa270: init_module failed with %d\n [ --kernel--]", ret);
return ret;
}
else
{
printk(" pxa270 gpio_led_driver register success!!! [ --kernel--]\n"); }
return ret;
}
模块卸载函数为cleanup_GPIO_LED_ctl,其代码实现如下:
static void __exit cleanup_GPIO_LED_ctl(void)
{
#ifdef OURS_GPIO_LED_DEBUG
printk ("cleanup_GPIO_LED_ctl [ --kernel--]\n");
#endif
//注销主设备号,释放设备
devfs_unregister_chrdev (SIMPLE_GPIO_LED_MAJOR, "gpio_led_ctl" );
}
测试函数:
通过调用ioctl函数实现对led灯的控制。
主函数实现如下:
int main(void)
{
int fd;
int ret;
char *i;
printf("\nstart gpio_led_driver test\n\n");
fd = open(DEVICE_NAME, O_RDWR);
//系统通过函数映射调用SIMPLE_GPIO_LED_open函数打开设备
printf("fd = %d\n",fd);
if (fd == -1)
{
printf("open device %s error\n",DEVICE_NAME);
}
else
{
//通过调用SIMPLE_GPIO_LED_ioctl函数控制led灯
//主循环
while(1)
{ ioctl(fd,LED_OFF);
sleep(1); // 修改sleep时间即可改变led灯点亮的时间,如 sleep(7)即灭7秒
ioctl(fd,LED_ON);
sleep(1);// sleep(5) 亮5秒
}
// close
ret = close(fd); //
printf ("ret=%d\n",ret);
printf ("close gpio_led_driver test\n");
}
return 0;
}// end main
通过该实验基本掌握了驱动模块的结构和一些函数的实现,如ioctl函数。
五、实验步骤
AD驱动实验
该模块需要ad模块的支持,所以初始化函数会相对比较复杂。不过初始化函数的结构依旧没有改变,同样是pxa270_AD_CTL_init函数通过调用HW_AD_CTL_init函数完成AD模块的初始化。
static int __init HW_AD_CTL_init(void)
{
int ret = -ENODEV;
showversion();
ad_ucb = ucb1x00_get();//获取AD模块的地址
//注册主设备号
ret = devfs_register_chrdev(ADCTL_MAJOR, "adctl",&adctl_ops);
if(ret<0)
{
printk("adctl init_module failed with %d\n [ --kernel--]",ret); return ret;
}
else
{
printk("adctl int_driver register success!!![ --kernel--]\n"); }
//注册AD模块,设定为字符模块
adctl_dev_handle = devfs_register( NULL, "ad_ctl",
DEVFS_FL_DEFAULT,ADCTL_MAJOR, 0, S_IFCHR, &adctl_ops, NULL);
return ret;
}
同理,卸载模块时就要同时注销主设备号和AD模块。所以,卸载函数改为: static void __exit cleanup_AD_ctl(void)
{
devfs_unregister( adctl_dev_handle );//注销AD模块
devfs_unregister_chrdev (ADCTL_MAJOR, "ad_ctl" );//注销主设备号
}
AD模块的控制由adctl_ioctl函数实现:
ssize_t adctl_ioctl (struct inode * inode ,struct file * file, unsigned int cmd, unsigned long arg)
{
int val;
#ifdef OURS_HELLO_DEBUG
// printk ("SIMPLE_HELLO_ioctl [ --kernel--]\n");
#endif
ucb0x00_adc_enable(ad_ucb);//使能AD转换
//读取AD转换后的数据,其中cmd指定转换通道
val = ucb0x00_adc_read(ad_ucb,cmd,0);
ucb0x00_adc_disable(ad_ucb);//停止AD转换
return UCB_ADC_ADT(val);//返回转换的数据
}
使用时调用ioctl函数便可以实现数据采集。
可以得到,测试文件的核心部分:
int val0,val1;
char *i;
ioctl(fd);//通过函数映射调用adctl_ioctl函数
/*
for(i=0;i<50;i++)
{
val = ioctl(fd,UCB_ADC_INP_AD0,0);
printf("val = %x\n", val);
usleep(200000);
}
*/
for(i=0;i<50;i++)
{
//通过函数映射调用adctl_ioctl函数读取通道1
val0 = ioctl(fd,UCB_ADC_INP_AD1,0);
usleep(100);//等待操作完成
//通过函数映射调用adctl_ioctl函数读取通道0
val1 = ioctl(fd,UCB_ADC_INP_AD0,0);
printf("val0 = %d\tval1=%d\n", val0,val1); usleep(500000);
}
测试函数其他部分与其他的测试文件相同
六、实验结果与分析
1、阅读理解源码
进入/arm2410cl/exp/basic/05_AD目录,使用 vi 编辑器或其他编辑器阅读理解源代码
2、编译应用程序
运行 make 产生 AD可执行文件 AD_main
[root@zxt /]# cd
/arm2410cl/exp/basic/05_AD/ [root@zxt
05_AD]# make
armv4l-unknown-linux-gcc -c -o AD_main.o
AD_main.c armv4l-unknown-linux-gcc AD_main.o
-o AD_main [root@zxt 05_AD]# ls
AD_main AD_main.c AD_main.o doc drivers Makefile s3c44b0-spi.h
3、下载调试
切换到 minicom 终端窗口,使用 NFS mount 开发主机的/arm2410cl 到/host 目录,然后进入 /host/exp/05_AD/drivers 目录,用 insmod s3c2410-exio.o 命令插入A D驱动,并用 lsmod 命令查看是否已经插入。
[/mnt/yaffs]cd /host/exp/basic/05_AD/[/host/exp/bas
[/host/exp/basic/05_AD/drivers]insmod
s3c2410-exio.o Using s3c2410-exio.o
[/host/exp/basic/05_AD/drivers]lsmod
Module
Size Used by Not tainted
2384
14104 0 (unused) 0 (unused) S3c2410-exio
i2c-tops2
注意:卸载模块可以使用 rmmod 命令,以本实验为例,卸载方法如下:
[/host/exp/basic/05_AD]rmmod s3c2410-exio
进入/host/exp/basic/05_AD目录,运行./AD_main,观察运行结果的正确性。在输 入 ./AD_main 后会出现下面的提示信息。
[/host/exp/basic/05_AD]./AD_main
Error parameter
Input as:
[~]./ad_main AD_id num
AD_id: select between 0
and 1 num: range 0.0 ~
4.096
这是由于我们没有指定参数造成的,它的格式为 ./AD_main [AD的 id 号] [数字],同 时还需要在 0.0~4.096V 之间来选择一个输出电压。下面的例子是用了开发板上的 AD并且 输出 1V 的电压,我们可以使用万用表对其进行测量。
[/host/exp/basic/05_AD]./AD_main 1
Current Voltage is 1.000000 v
南阳师范学院关于规范学生实验报告格式的通知
各学院:
为规范实验教学,迎接教学评估,对我校的实验报告格式作了规范,现把相关事项通知如下:
1、由于各院(系)之间存在学科和课程差异性,因此各学院可以根据学校提供的样本,结合学科和课程特点作适当调整。
2、各院(系)把调整后的实验报告格式报教务处实践考试科备查。
3、期末实验结束后,学生应按课程的将实验报告统一装订成册,由院(系)收回并统一归档保存。
4、实验报告由各院(系)统一印制。
教务处
20##年 月 日
附:1、南阳师范学院本科学生验证性实验报告(样本)
2、南阳师范学院本科学生综合性、设计性实验报告(样本)
南阳师范学院
本科学生实验报告
姓名____ _ 院(系)___ _
专业____ _ 班级____ _
实验课程名称_____ _______
指导教师及职称_________ _
开课时间 至_ 学年_ _学期
南阳师范学院
本科学生综合性、设计性
实验报告
姓名____ _ 学院____ _
专业____ _ 班级____ _
实验课程名称___________ _
指导教师及职称_________ _
开课学期 至_ 学年_ _学期
上课时间 年 月 日
南阳师范学院教务处编印
一、实验设计方案
二、实验报告
实验报告的书写是一项重要的基本技能训练。它不仅是对每次实验的总结,更重要的是它可以初步地培养和训练学生的逻辑归纳能力、综合分析能力…
数据库原理实验报告要求报告的主要内容一实验目的根据各实验项目的实验目的撰写具体在附件中给出二实验环境操作系统WindowsXP数据…
实验一:骨骼系统的观察骨骼系统由骨(成人206块)和骨连结组成,在骨连结处有软骨和韧带。全身的骨通过骨连结构成人体的支架,即骨骼。…
北京邮电大学世纪学院实验实习课程设计报告撰写格式与要求试行一实验报告格式要求1有实验教学手册按手册要求填写若无则采用统一实验报告封…
滁州市政府组织退耕还林(黑体,小二,1.5倍行距,段前段后0.5行)——5060451007范雪花(学号,TimesNewRoma…
滁州市政府组织退耕还林(黑体,小二,1.5倍行距,段前段后0.5行)——5060451007范雪花(学号,TimesNewRoma…
实验报告的书写是一项重要的基本技能训练。它不仅是对每次实验的总结,更重要的是它可以初步地培养和训练学生的逻辑归纳能力、综合分析能力…
附:实验报告格式模板有机合成综合实验报告实验名称姓名班级柜号实验日期室温一、实验目的1、…………………………………………2、…………
《ERP财务管理系统》实验报告(三)实验名称:固定资产系统(以下内容:字体小四,单倍行距。整篇报告至少5页,其中实验总结至少1页。…
2020学年第学期佛山职业技术学院食品营养与检测专业实验报告课程名称食品添加剂专业班级姓名学号所在组别同组成员实验地点实验时间实验…