嵌入式控制实验报告.docx
嵌入式控制系统及应用实验报告小组成员:912110200231.1最小系统设计一、实验目的(1)熟悉 Proteus 与 Keil for ARM 的使用;(2)掌握Proteus与Keil for ARM联合调试方法;(3)掌握嵌入式系统最小系统的设计与调试方法;(4)掌握嵌入式系统的仿真设计技术。二、实验内容本次实验利用电路仿真软件Proteus与嵌入式开发环境Keil for ARM进行嵌入式系统的仿真。在Proteus 中进行嵌入式系统最小系统的硬件电路设计,并在Keil for ARM中完成最小系统测试程序的编写和编译, 最后将编译成的可执行代码装载到嵌入式微处理器中进行电路的仿真运行。三、预备知识C语言的基础知识,Proteus与Keil for ARM软件的基本使用方法和设置。四、实验设备硬件:PC机(或笔记本电脑)软件:Windows xp以上操作系统,Proteus 7.8以上版本,Keil for ARM 3.0以上版本。五、实验步骤(1)安装 Proteus 及 Keil for ARM 软件(2)在Proteus中建立嵌入式最小系统电路XTAL1PD.mMMiPWMIXTAL2PC. I.'RCQPWMSPD_2ffiCL'CAPDJi PDjiEEWMAE.mENTI RSTPDJffiCKa>iCAPC.1PD.a'MISCQMATD.I PD.EMOSI&'CAPDi pa.zsELH'PWMarrra PD.BiT(D1iFWH4 Pa.9.'RxD1'PW M&rEN73 Pa.1WRT51i'CAP1Xl Pa.11.'CTS1iCAP1.1 Pa.IZfDSRIi'MATIjD IPD.13rtJTiRlJMAT1.1P0.14iDCD1irEINT1 PCL1 狗 1JEINT2PD. lai'EINTCL'MATD.ai'CAPDi PD.17iCAP 1 i'SCKi iMATIi PQ.I&'CAPl.a'MEOl po.ia'MATi.awoen POJa.MATI.l'SSELVEim pa.avpwfe&CAPij P022jCAPD.WMATOJ5 PD-23 PDJ4 PD25PD27/AllsniCAPD.1.'MATO.1 PDa?AIN1 iCAPD.2.'MATO2 PD.2S'AIN2jCAPD.l'MATO.3 Ptl.3D.,AJNl'EINTi,CAPD.DV3AP1.1&/TRACEPKTlipi.it/tiracepktiP1J&/TRACEPKT2PUS/TRACEPmP1.2&1RACESVNCV1BAP1.21.'WPESTA1DVI &P1.22rPIPESTATIVI &P1.23irP1PESTA12Pl.aTRACECLKVSSARLlPIJSEXIINDW5SAP1J&RTCKVSSP1-27/TOOVSSPhS-TDIVSSPITTCKVSSP1.30SVSSP1.31JTT腰EMLnJL图1.1.1嵌入式最小系统原理图(3)在Keil for ARM中编写最小系统测试程序测试程序源代码如下:#include<stdio.h>#include <LPC21xx.h>void delay()int i;int j;for(i=0;i<100;i+)for(j=0;j<1000;j+);int main(void)int i;IO0PIN=0;for(i=7;i<=10;i+) /*IO0DIR=1<<7I1<<8I1<<9I1<<10I;*/*IO0CLR=1<<7I1<<8I1<<9I1<<10I;*/IO0DIR=1<<i;IO0CLR=1<<i;delay();IO0DIR=1<<7I1<<8I1<<9I1<<10;IO0CLR=1<<7I1<<8I1<<9I1<<10;for(i=10;i<=7;i-)IO0SET=1<<i;(4)下载调试结果记录下图所示。1.2串行通信设计一、实验目的(1)掌握UART部件的使用与接口扩展方法;(2)掌握嵌入式系统的仿真设计技术。二、实验内容本次实验利用电路仿真软件Proteus与嵌入式开发环境Keil for ARM进行嵌入式系统的仿真。在Proteus 中进行嵌入式系统的UART接口硬件电路设计,并在Keil for ARM中完成串行通信程序的编写和编译,最 后将编译成的可执行代码装载到嵌入式微处理器中进行电路的仿真运行。三、预备知识C语言的基础知识,Proteus与Keil for ARM软件的基本使用方法和设置。四、实验设备硬件:PC机(或笔记本电脑)软件:Windows xp以上操作系统,Proteus 7.8以上版本,Keil for ARM 3.0以上版本。五、实验步骤(1)在Proteus中建立嵌入式系统电路图1.2.1 嵌入式系统原理图(2)在Keil for ARM中编写系统测试程序测试程序源代码如下:#include<LPC21xx.h>#include<stdio.h>char string="We are studentsn"int send(int ch)if(ch='n')while (!(UOLSR & 0x40); return (UOTHR=ch);void delay(void)unsigned volatile long i;for(i=0;i<400000;i+);void sendstr(char *p)while(*p!='0')send(*p+);int main (void)PINSEL0 = 0x0000005;U0LCR = 0x83;U0DLL = 122;U0LCR = 0x03;I00DIR = 0x000001;while (1)sendstr(string);delay();2.2多线程应用程序设计一、实验目的(1)了解多线程程序设计的基本原理。(2)学习pthread库函数的使用。二、实验内容熟悉几个重要的PTHREAD库函数的使用,掌握共享锁和信号量的使用方法。进入/arm2410s/exp/basic/02_pthread目录,运行make产生pthread程序,使用NFS方式连接开发主机进 行运行实验。三、预备知识有C语言基础掌握在Linux下常用编辑器的使用掌握Makefile的编写和使用掌握Linux下的程序编译与交叉编译过程。四、实验设备硬件:UP-NETARM2410-S嵌入式实验平台,PC机。软件:PC机操作系统REDHAT LINUX 9.0+ARM-LINUX开发环境。五、实验步骤(1) 编写并编译简单的多线程示例程序(2) 阅读源代及编译应用程序(3) 下载和调试(4) 在任意一个示例程序中,加入一个新的线程用于处理键盘的输入,并在按键为ESC时终止所有线程。该线程的流程图及关键代码如下。#include <studio.h>#include <studlib.h>#include <time.h>#include "pthread.h"#include <unistd.h>#define BUFFER_SIZE 16struct prodcons(int bufferBUFFER_SIZE;pthread_mutex_t lock;int reapdpos,writepos;pthread_cond_t notempty;pthread_cond_t notfull;void init(struct prodcons*b)pthread_mutex_init(&b->lock,NULL);pthread_cond_init(&b->notempty,NULL);pthread_cond_init(&b->notfull,NULL);b->reaapos=0;b->writepos=0; void put(struct prodcons*b,int data)pthread_mutex_lock(&b->lock);while(b->writepos+1)%BUFFER_SIZE=b->readpos) printf("wait for not fulln");pthread_cond_wait(&b->notfull,&b->lock);b->bufferb->writepos=data;b->writepos+;if(b->writepos>=BUFFER_SIZE)b->writepos=0;pthread_cond_signal(&b->notempty);pthread_mutex_unlock(&b->lock);int get(struct prodcons*b)int data;pthread_mutex_lock(&b->lock);while(b->writepos=b->readpos)printf("wait for not emptyn");pthread_cond_wait(&b->notempty,&b->lock);data=b->bufferb->readpos;b->readpos+;if(b->readpos>=BUFFER_SIZE)b->readpos=0;pthread_cond_signal(&b->notfull);pthread_mutex_unlock(&b->lock);return data;#define OVER(-1)struct prodcons buffer;void*producer(void*data)int n;for(n=0;n<1000;n+)printf("put->%dn");put(&buffer,n);usleep(1);put(&buffer,OVER);printf("producer stopped!n");return NULL; void*consumer(void*data)int d;while(1)usleep(1);d=get(&buffer);if(d=OVER)break;printf(" %d->getn",d);printf("consumer stopped!n");return NULL;void *th_me(pthread_t a,pthread_t b)char c;while(1)c=getchar();if(c=27)pthread_cancal(a);pthread_cancal(b);pthread_exit(0);int main(void)pthread_t th_a,th_b,th_c);void*retval;init(&buffer);pthread_create(&th_a,NULL,producer,0);pthread_create(&th_b,NULL,consumer,0);pthread_create(&th_c,NULL,th_me(th_a,th_b),0);pthread_join(&th_a,&retval);pthread_join(&th_b,&retval);pthread_join(&th_c,&retval);return 0;2.3 A/D接口实验一、实验目的了解在linux环境下对S3C2410芯片的8通道10位A/D的操作与控制。二、实验内容学习A/D接口原理,了解实现A/D系统对于系统的软件和硬件要求。阅读ARM芯片文档,掌握ARM的A/D相关寄存器的功能,熟悉ARM系统硬件的A/D相关接口。三、预备知识有C语言基础掌握在Linux下常用编辑器的使用掌握Makefile的编写和使用掌握Linux下的程序编译与交叉编译过程。四、实验设备硬件:UP-NETARM2410-S嵌入式实验平台,PC机。软件:PC机操作系统REDHAT LINUX 9.0+ARM-LINUX开发环境。五、实验步骤(1) 阅读理解源代码(2) 编译应用程序(3) 下载与调试(4) 实验结果如下:运行程序:/host/exp/basic/04_ad./ad终端显示:a0= 3.2968a1= 1.4438a2= 3.2968旋转电位器旋钮,再次运行程序终端显示:a0=2.7812a1=1.3406a2=3.2968旋转电位器旋钮,再次运行程序终端显示:a0=2.0174a1=1.1054a2=2.71032.5直流电机实验一、实验目的熟悉ARM本身自带的PWM,掌握相应寄存器的配置。Linux下编程实现ARM系统的PWM输出,从而控制直流电机。了解直流电机的工作原理,学会用软件的方法实现步进电机的脉冲分配。掌握带有PWM的CPU编程实现其相应功能的主要方法。二、实验内容学习直流电机的工作原理,了解实现电机转动对于系统的软件和硬件要求。学习ARM PWM的生成方 法。使用Redhat Linux 9.0操作系统环境及ARM编译器,编译直流电机的驱动模块和应用程序。运行程序, 实现直流电机的调速转动。三、预备知识C语言的基础知识、程序调试的基础知识和方法Linux的基本操作Linux关于module的必要知识。四、实验设备硬件:UP-NETARM2410-S嵌入式实验平台,PC机。软件:PC机操作系统REDHAT LINUX 9.0+ARM-LINUX开发环境。五、实验步骤(1) 编译直流电机模块(2) 编译应用程序(3) 下载调试实验结果如下:在未修改程序前,在运行程序后,发现显示电机实时转速不断在512到512r/s不断循环变化,此时调 节电位器旋钮是无法改变电机转速的。(4) 使用实验箱上的电位器旋钮控制直流电机的转速。流程图及关键代码如下。#include <studio.h>#include <string.h>#include <unistd.h>#include <sys/types.h>#include <sys/ipc.h>#include <sys/ioctl.h>#include <pthread.h>#include <fcntl.h>#include "s3c22410-adc.h”#define DCM_IOCTRL_SETPWM#define DCM_TCNTB0#define ADC_DEV "/dev/adc/0raw”static int adc_fd=-1;static int dcm_fd=-1;char *DCM_DEV="/dev/dcm/0raw”;static int init_ADdevice(void)if(adc_fd=open(ADC_DEVO_RDWR)<0) printf("Error opening %s adc devicen”,ADC_DEV); return -1;static int GetADresult(int channel)int PRESCALE=0XFF;int data=ADC_WRITE(channel,PRESCALE);write(adc_fd,&data,sizeof(data);read(adc_fd,&data,sizeof(data);return data;void Delay(int t)int i;for(;t>0;t-)for(i=0;i<400;i+);int main(int argc,char*argv)int setpwm=0;float d;int factor=DCM_TCNTB0/1024if(dcm_fd=open(DCM_DEVO_WRONGLY)<) printf("Error opening %s devicen,DCM_DEV); return 1;if(init_ADdevice()<0)printf("Error opening %s devicen");return -1;for(:)(d=(float)GetADresult(1)*3.3/1024.0;d=d*200;setpwm=d-330;if(setpwm=0)printf("DCmotor stoppedn");else if(setpwm<0)print("clockwisen");else printf("anticlockwishn");ioctl(dcm_fd,DCM_IOCRTL_SETPWM,setpwm*factor);Delay(500);/printf("setpwm=%dn”,setpwm);close(dcm_fd);return 0;程序分析:当电位为0V时,电机转速为0;当电位为3.3V时,电机转速达到最大。可以边旋转边显 示边显示瞬时转速。2.6步进电机实验一、实验目的了解直流电机和步进电机的工作原理学会Linux下用软件的方法实现步进电机的脉冲分配,用软件的方法代替硬件的脉冲分配器。二、实验内容学习步进电机的工作原理,了解实现电机转动对于系统的软件和硬件要求。学习ARM知识,要掌握 I/O的控制方法。Linux下编程实现ARM的四路I/O通道实现环形脉冲分配用于控制步进电机的转动。三、预备知识C语言的基础知识、程序调试的基础知识和方法Linux的基本操作Linux关于module的必要知识。四、实验设备硬件:UP-NETARM2410-S嵌入式实验平台,PC机。软件:PC机操作系统REDHAT LINUX 9.0+ARM-LINUX开发环境。五、实验步骤(1) 编译步进电机模块(2) 编译应用程序(3) 下载调试实验结果如下:在未修改程序前,运行程序后,步进电动机随意转动,旋转电位器旋钮无法控制步进电动机转动相 应的角度(4) 使用实验箱上的电位器旋钮控制步进电机转动相应的角度。流程图及关键代码如下。#include <studio.h>#include <string.h>#include <unistd.h>#include <sys/types.h>#include <sys/ipc.h>#include <sys/ioctl.h>#include <pthread.h>#include <fcntl.h>#include "s3c22410-adc.h”#define STEPMOTOR_IOCTRL_PHASE#define ADC_DEV "/dev/adc/0raw” static int adc_fd=-1; static int step_fd=-1;char *STEP_DEV="/dev/exio/0raw”;char stepdata=0x10,0x30,0x20,0x60,0x60,0x40,0xc0,0x80,0x90;void Delay(int t) int i;for(;t>0;t-)for(i=0;i<400;i+);static int init_ADdevice(void)if(adc_fd=open(ADC_DEVO_RDWR)<0)printf("Error opening %s adc devicen”,ADC_DEV);return -1; static int GetADresult(int channel) int PRESCALE=0XFF;int data=ADC_WRITE(channel,PRESCALE);write(adc_fd,&data,sizeof(data);read(adc_fd,&data,sizeof(data);return data;int main(int argc,char*argv)int t=0;int num1=0,num2=0;float d;if(step_fd=open(STEP_DEV,O_WRONGLY)<)printf("Error opening /dev/exio/0raw devicen");return 1;if(init_ADdevice()<0)return -1;for(:)d=(float)GetADresult(1)*3.3/1024.0;d=d*512.0*8.0/33;num2=d+0.5;if(num1>num2)for(;i>num2;i-)icotl(step_fd,STEPMOTOR_IOCRTL_PHASE,stepdatai%8);else if(num1<num2)for(;i<num2;i+)ioctl(step_fd,STEPMOTOR_IOCRTL_PHASE,stepdatai%8);num1=num2;Delay(100);close(step_fd);printf("Step motor start running!n");return0;