嵌入式系统学习报告.docx
《嵌入式系统学习报告.docx》由会员分享,可在线阅读,更多相关《嵌入式系统学习报告.docx(57页珍藏版)》请在冰豆网上搜索。
嵌入式系统学习报告
1.第一题
1.1设计目标
在Linux操作系统和ARM嵌入式实验系统环境下,分析linux下的键盘、LED驱动程序,编写一个应用程序,实现以下功能:
在ARM开发板上按下数字键1、2、3、4时,对应启动模拟量AIN0、AIN1、AIN2、AIN3采样,并把AD转换的结果从终端输出和LED显示。
显示格式:
通道号转换的电压值;例如:
2灭灭3.75
1.2设计思路
1.2.1驱动程序加载
针对我们这个实验,我们需要用到ADC0809芯片,LED显示数码管,小键盘。
为此,我们需要加载这三个对应的驱动程序,其驱动程序主要是设置一些寄存器的内容来确定端口的引脚输入输出方式以及键盘的扫描部分代码,LED控制显示函数等等。
1.2.2打开各个设备
在Linux系统下,各个设备都是通过文件来进行描述的,在这里我们利用open这个函数打开我们需要用到的LED,键盘,以及ADC0809芯片。
并且要由对应的出错处理。
1.2.3键盘扫描
驱动程序加载进去以后,我们运行可执行文件以后,代码就进入到了按键按下等待的代码中了。
对于用户而言,只是在键盘中按下了某个键,在计算机里,通过驱动得到按下的键值并通过read(fd_kb,&result_kb,1)函数把值赋给变量result_kb中(其中fd_kb为键盘的文件描述符)。
1.2.4A/D转换
当按下的键是我们要启动A/D转换的命令键的时候,就启动ADC0809芯片对应的通道进行数据转换,这里主要通过iotcl和read这两个函数实现,并把转化后的结果赋给result_ad这个变量。
然后利用voltage=5.0*result_ad/255.0这个公式得到电压值并赋给变量voltage。
1.2.5电压整数和其小数截取存放
整数部分容易截取,小数部分截取是这样的:
先让电压值乘以10,然后对其强制转化类型再对10求余。
具体的转化在这两条语句上面:
led[2]=led_map[(char)voltage];//截取电压的整数部分
led[0]=led_map[((char)(voltage*10))%10];//截取电压的小数部分
1.2.6LED数码管显示
我们按下键值的时候,比如说按下的是1数字键,怎样让LED显示为1呢?
换句话说,怎样实现1跟要在数码管上显示1的数据进行一一对应呢?
这样很容易让人想到数组,我们创建一个数组led_map[10],里面存放的是在LED上显示0-9多对应的数据,然后把我们按下的键值赋给这数组中的下标变量就可以实现一一对应了。
最后利用iotcl和write两个函数点亮对应的LED数码管。
1.2.7关闭各个设备
当我们不需要使用了的时候,我们必须利用close函数把工作的设备关闭掉。
1.3流程图
1.3.1主程序流程图
图1主程序流程图
1.3.2AD转换框图
图2AD转换框图
1.4编译与调试的步骤和方法
1.5执行结果图
2.第二题
2.1设计目标
写一个linux下的用户程序,在ARM开发板和PC机上实现以太网服务器,对每一个访问的客户端发一个欢迎通信信息,该服务器模型为并发服务器,选用异步I/O机制、多路复用I/O机制或信号驱动I/O模型。
2.2设计思路
首先分析以太网编程中TCP/IP和套接字接口的编程方法,掌握TCP/IP三次握手协议及socket的内涵。
然后,确定客户端和服务器的分工及程序设计,其中服务器则需要选择固定的模型(循环式或并发式),并选用I/O机制(阻塞式或异步),建立socket连接。
而客户端需要确定hostname,并在确立socket连接后输入要传输的字符。
2.3主程序流程图
2.4编译与调试的步骤和方法
2.5执行结果图
3.第三题
3.1设计目标
写linux下的用户程序,其中一个为父进程,它创建了另外2个子进程,这2个子进程通过某种IPC机制实现进程间通信。
要求分别在PC机上和在ARM开发板上测试实现。
IPC机制可选a)有名或无名管道、b)共享内存、c)信号或其它方法。
3.2设计思路
该题使用管道机制实现两个进程之间的通信。
管道是单向的、先进先出的、无结构的、固定大小的字节流;只能用于有亲缘关系进程间的通信。
首先建立一个管道用pipe()函数,随后建立一父进程和两个字进程用fork()函数,实现两个子进程间的通信。
其中一个子进程实现读read()操作。
另一个子进程实现写write()操作。
在服务器程序设计阶段,首先需要建立sockfd描述符,填充sockaddr结构,并将sockfd描述符捆绑到IP地址上;然后设置客户端最大连接数,通过阻塞式I/O机制建立通讯连接。
在客户端程序设计阶段,首先确定hostname,然后在确立socket连接后输入要传输的字符,实现基于TCP协议的套接字网络通信。
3.3主程序流程图
3.4运行结果
4.第四题
4.1设计目标
给你一个温度传感器DS1621芯片、三个发光二极管、面包板和导线,利用ARM嵌入式教学实验平台留有的扩展接口,设计接口电路并联线,编写驱动程序和应用程序实现温度的采集并能够根据温度高低来智能控制二极管亮灭的个数。
4.2设计思路
通过IIC总线的控制,设计DS1621驱动,设定温度变化范围,然后利用GPB0、GPB1、GBP9控制三个发光二极管,采用共阳极I/O输出数据进行亮灭。
4.3接口电路
4.4电路连线图
4.5主程序流程图
附录
第一题源程序
应用程序:
#include/*Stringfunctiondefinitions*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include"led_ioctl.h"
intmain()
{
intcount;
intfd_ad;
intfd_kb;
intfd_led;
intresult_kb=0;
intchannel;
intresult_ad=0;
intold_result_ad=0;
shorti=0;
shortj=0;
charled[6]={'\0',0x20,'\0',0x01,0x01,'\0'};/*thedatatobeputintoledsdirectly*/
charled_map[10]={0xde,0x50,0x9d,0x5d,0x53,0x4f,0xcf,0x58,0xdf,0x5f};/*0--9*/
charled_maph[10]={0xfe,0x70,0xbd,0x7d,0x73,0x6f,0xef,0x78,0xff,0x7f};/*0.--9.*/
floatvoltage=0.0;
fd_ad=open("/dev/adc0809",O_RDWR);
if(fd_ad<0)
{
perror("Can'topenadc0809device!
\n");
return-1;
}
fd_kb=open("/dev/keybd",O_RDONLY);
if(fd_kb<0)
{
perror("Can'topenkeyboarddevice!
\n");
return-1;
}
fd_led=open("/dev/led",O_WRONLY);
if(fd_led<0)
{
perror("Can'topenleddevice!
\n");
return-1;
}
while
(1)
{
/*readkeyboard*/
result_kb=0;
while(result_kb==0)
{
read(fd_kb,&result_kb,1);
}
/*ADtransforms*/
if(result_kb!
=led_map[1]&&result_kb!
=led_map[2]&&result_kb!
=led_map[3]&&result_kb!
=led_map[4])
{
printf("Presskeyerror!
\nPleasepress1or2or3or4.\n");
return0;
}
if(result_kb==led_map[1])
channel=0;
if(result_kb==led_map[2])
channel=1;
if(result_kb==led_map[3])
channel=2;
if(result_kb==led_map[4])
channel=3;
printf("channel=AIN%d\n",channel);
ioctl(fd_ad,channel,channel);/*selectthechannel1234-AIN0,AIN1,AIN2,AIN3*/
read(fd_ad,&result_ad,1);/*readtheA/Dtransformingresult*/
voltage=5.0*(float)result_ad/256.0;
printf("TheresultofA/Dtransformingis%fV\n",voltage);/*theresultwritetoscreen*/
printf("result_ad=%d\n\n",result_ad);
/*writetoledandprintonscreen*/
/*theformatoftheledisresult_kb--5.0*/
led[5]=result_kb;/*hasbeentransformedindriver*/
led[4]=0x00;
led[3]=0x00;
led[2]=led_maph[(char)voltage];
led[1]=led_map[((char)(voltage*10))%10];
led[0]=led_map[((char)(voltage*100))%10];
ioctl(fd_led,IOCTRL_LED_1);//lightthe1led:
led[0]
count=write(fd_led,led+0,1);
ioctl(fd_led,IOCTRL_LED_2);//lightthe2led:
led[1]
count=write(fd_led,led+1,1);
ioctl(fd_led,IOCTRL_LED_3);//lightthe3led:
led[2]
count=write(fd_led,led+2,1);
ioctl(fd_led,IOCTRL_LED_4);//lightthe4led:
led[3]
count=write(fd_led,led+3,1);
ioctl(fd_led,IOCTRL_LED_5);//lightthe5led:
led[4]
count=write(fd_led,led+4,1);
ioctl(fd_led,IOCTRL_LED_6);//lightthe6led:
led[5]
count=write(fd_led,led+5,1);
//sleep
(1);
}
return0;
}
ad驱动
adc0809.c
/*driver/char/adc0809.c
*thisisaadc0809chardevicedriver.
*Anyproblemplscontactsupport@
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include"adc0809_ioctl.h"
#defineADC0809_MAJOR231
/*definetheadc0809majornodeis231*/
#defineadc0809_sle(*(volatileunsignedlong*)ADC_GPACON)
#defineadc0809_sle_data(*(volatileunsignedlong*)ADC_GPADATA)
unsignedlongADC_GPACON,ADC_GPADATA;
unsignedlongADC_0,ADC_1,ADC_2,ADC_3,ADC_4,ADC_5,ADC_6,ADC_7;
//unsignedlongADC_DATA;
unsignedlongadc_write_addr;
unsignedlongadc_read_addr;
devfs_handle_tdevfs_adc;
voidadc0809_interrupt(int,void*,structpt_regs*);
intadc0809_open(structinode*,structfile*);
intadc0809_release(structinode*,structfile*);
intadc0809_ioctl(structinode*,structfile*,unsignedint,unsignedlong);
ssize_tadc0809_read(structfile*,char*,size_t,loff_t*);
ssize_tadc0809_write(structfile*,constchar*,size_t,loff_t*);
staticstructfile_operationsadc0809_fops={
ioctl:
adc0809_ioctl,
open:
adc0809_open,
read:
adc0809_read,
write:
adc0809_write,
release:
adc0809_release,
};
volatileunsignedlongdata;
unsignedlongaddr;
voidadc0809_interrupt(intirq,void*d,structpt_regs*regs)
{
/*clearinterruptregisterforINT2*/
//printk("**********************adc0809_interrupt*********************\n");
SRCPND&=(~0x00000004);//clearinterrupt(bit2)
INTPND=INTPND;
EINTPEND&=(~0x00000004);//bit2
//printk("interruptprocess!
\n");
//sleep
(1);
/*readadconverter'sresult*/
data=(*(volatileunsignedlong*)adc_read_addr);
}
/*
*Open/closecodeforrawIO.
*/
intadc0809_open(structinode*inode,structfile*filp)
{
//adc_read_addr=ADC_DATA;
printk("openok\n");
return0;
}
ssize_tadc0809_read(structfile*filp,char*buf,
size_tsize,loff_t*offp)
{
charkey;
key=data;
data=0;
if(key==0){
printk("adc0809_read:
havenodatatoread\n");
return0;
}
put_user(key,buf);
return1;
}
ssize_tadc0809_write(structfile*filp,constchar*buf,
size_tsize,loff_t*offp)
{
charkey;
if(get_user(key,buf))
return-EFAULT;
printk("adc0809_write:
adc_write_addr=0x%x;key=%c\n",adc_write_addr,key);
(*(volatileunsignedchar*)adc_write_addr)=key;
//put_user(key,buf);
return1;
}
//__ioremap
intadc0809_release(structinode*inode,structfile*filp)
{
printk("releaseok\n");
return0;
}
/*
*Dealwithioctlsagainsttheraw-devicecontrolinterface,tobind
*andunbindotherrawdevices.
*/
intadc0809_ioctl(structinode*inode,
structfile*flip,
unsignedintcommand,
unsignedlongarg)
{
interr=0;
switch(command){
caseIOCTRL_ADC_0:
adc_write_addr=ADC_0;
//printk("adc0809_ioctl:
adcaddr:
%x\n",adc_write_addr);
/*startcollectandconvert*/
(*(volatileunsignedchar*)adc_write_addr)=(char)arg;
udelay(1000);
return0;
caseIOCTRL_ADC_1:
adc_write_addr=ADC_1;
(*(volatileunsignedchar*)adc_write_addr)=(char)arg;
udelay(1000);
return0;
caseIOCTRL_ADC_2:
adc_write_addr=ADC_2;
(*(volatileunsignedchar*)adc_write_addr)=(char)arg;
udelay(1000);
return0;
caseIOCTRL_ADC_3:
adc_write_addr=ADC_3;
(*(volatileunsignedchar*)adc_write_addr)=(char)arg;
return0;
caseIOCTRL_ADC_4:
adc_write_addr=ADC_4;
(*(volatileunsignedchar*)adc_write_addr)=(char)arg;
return0;
caseIOCTRL_ADC_5:
adc_write_addr=ADC_5;
(*(volatileunsignedchar*)adc_write_addr)=(char)arg;
return0;
caseIOCTRL_ADC_6:
adc_write_addr=ADC_6;
(*(volatileunsignedchar*)adc_write_addr)=(char)arg;
return0;
caseIOCTRL_ADC_7:
adc_write_addr=ADC_7;
(*(volatileunsignedchar*)adc_write_addr)=(char)arg;
return0;
default:
err=-EINVAL;
}
//a