完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
1、UNO R3的端口输出实验
1.1 实验介绍 对于单片机中最为经典的控制电路就是流水灯实验,流水灯也称作跑马灯,利用单片机的IO口输出高电平(HIGH)与低电平(LOW)进而控制外部电路中多个LED灯以不同时间频率的亮灭。在实验中使用UNO开发板控制外围电路中的6个LED灯,使其以1s的时间间隔依次亮起,其电路图如下所示: 1.2 核心代码 int Start= 2; int Num = 6; int Index = 0; void setup() { for (int i = Start; i < Start + Num; i ++) { pinMode(i, OUTPUT); } } void loop() { for (int i = Start; i < Start + Num; i ++) { digitalWrite(i, LOW); } digitalWrite(Start + Index, HIGH); Index = (Index + 1) % NUM; delay(1000); } 2、UNO R3的端口输入实验 2.1 实验介绍 对于Arduino UNO开发板的数字IO口不仅有输出高低电平的功能(如前一小节),同时其还可以读取外部电路的高电平(5V)以及低电平(0V)。需要注意的是UNO的读取范围需要满足其工作电压以及电流,因此很多不匹配的输入需要通过一定的电路将其转换成UNO可以识别的范围。其中最简单的实验就是对按键开关连接或断开状态的判断,当按压开关按下时,单片机读取的输入信号应为高电平;当开关断开是,输入信号为低电平。本实验使用按键控制板载LED灯的亮灭,其电路如下所示: 2.2 核心代码 int Led= 13; int Switch = 7; int Value = 0; void setup(){ pinMode(Led, OUTPUT); pinMode(Switch, INPUT); } void loop() { Value = digitalRead(Switch); if (HIGH == Value) { digitalWrite(Led, LOW); } else { digitalWrite(Led, HIGH); } } 3、步进电机实验 3.1 实验介绍 步进电机是一种将电脉冲信号转换成相应角位移或线位移的电动机。每当输入一个脉冲信号是,转子就转动一个角度或前进一步,其输出的角位移或线位移与输入的脉冲数成正比,转速与脉冲频率成正比。因此,步进电动机又被称为脉冲电动机。脉冲电机相对于其它电机最大的区别就是,其接收数字控制信号,因此使用单片机对其进行控制是非常方便的。本次实验使用的是五线四相型步进电机,其实物如下图中所示: 实验中还需要应用到的一个模块便是ULN2003步进电机驱动模块,它是一个大功率驱动芯片常用来驱动小型的五线四相电机,板载的LED灯可以指示步进电机的工作状态。IN1~IN4口连接于单片机的IO口,用以输出数字信号,通过模块将其转换为脉冲信号进而控制电机工作,其实物如下图中所示: 3.2 核心代码 int motor1=8; int motor2=9; int motor3=10; int motor4=11; void stepMotor(int thisStep); void ctlstepper(int whatSpeed,int steps); void setup() { // put your setup code here, to run once: pinMode(motor1,OUTPUT); pinMode(motor2,OUTPUT); pinMode(motor3,OUTPUT); pinMode(motor4,OUTPUT); } void loop() { // put your main code here, to run repeatedly: ctlstepper(800,20); } void ctlstepper(int whatSpeed,int steps) { int FX;//记录方向 int stepNumber=0;//记录运行到8拍的第几步 int stepsLeft=abs(steps);//记录运行步数,取绝对值 unsigned long stepDelay=60L*1000L/64/whatSpeed; //依据速度计算时间 long lastStepTime=0; //保存两步之间的时间 if(steps>0) { FX=1; } if(steps<0) { FX=0; } while(stepsLeft>0) { if(millis()-lastStepTime>=stepDelay) { lastStepTime=millis(); if(FX==1) { stepNumber++; if(stepNumber==64) { stepNumber=0; } } else { if(stepNumber==0) { stepNumber=64; } stepNumber--; } stepsLeft--; stepMotor(stepNumber%8); } } } void stepMotor(int thisStep) { switch(thisStep) { case 0: //1000 digitalWrite(motor1,HIGH); digitalWrite(motor2,LOW); digitalWrite(motor3,LOW); digitalWrite(motor4,LOW); break; case 1: //1100 digitalWrite(motor1,HIGH); digitalWrite(motor2,HIGH); digitalWrite(motor3,LOW); digitalWrite(motor4,LOW); break; case 2: //0100 digitalWrite(motor1,LOW); digitalWrite(motor2,HIGH); digitalWrite(motor3,LOW); digitalWrite(motor4,LOW); break; case 3: //0110 digitalWrite(motor1,LOW); digitalWrite(motor2,HIGH); digitalWrite(motor3,HIGH); digitalWrite(motor4,LOW); break; case 4: //0010 digitalWrite(motor1,LOW); digitalWrite(motor2,LOW); digitalWrite(motor3,HIGH); digitalWrite(motor4,LOW); break; case 5: //0011 digitalWrite(motor1,LOW); digitalWrite(motor2,LOW); digitalWrite(motor3,HIGH); digitalWrite(motor4,HIGH); break; case 6: //0001 digitalWrite(motor1,LOW); digitalWrite(motor2,LOW); digitalWrite(motor3,LOW); digitalWrite(motor4,HIGH); break; case 7: //1001 digitalWrite(motor1,HIGH); digitalWrite(motor2,LOW); digitalWrite(motor3,LOW); digitalWrite(motor4,HIGH); break; } } 4、超声波测距实验 4.1 实验介绍 超声波是振动频率高于20kHz的机械波,它具备频率高、波长短、绕射现象小、方向性好以及能够成为射线从而定向船舶的特点。超声波可以被使用到各种不同的场景中,超声波HC-SR04距离传感器模块就是其中的一种应用。HC-SR04模块性能稳定、测度距离精确,且使用简单。通过单片机的一个控制口向模块的发送口发送一个超过10us时间的高电平,就可以在模块接收口处对高电平输出的时间进行采集,最后通过一定的数学转换公式即可计算出所测量的距离值。 4.2 核心代码 int trigPin=3; float cm; void setup() { // put your setup code here, to run once: Serial.begin(9600); pinMode(echoPin,INPUT); pinMode(trigPin,OUTPUT); } void loop() { // put your main code here, to run repeatedly: digitalWrite(trigPin,LOW); delayMicroseconds(2); digitalWrite(trigPin,HIGH); delayMicroseconds(10);//延时微秒 digitalWrite(trigPin,LOW); cm=pulseIn(echoPin,HIGH)/58.0;//读取引脚上的高电平脉冲,最大脉冲时间间隔为60秒,并且把结果赋值给变量 cm=(int (cm*100.0))/100.0; Serial.println(cm); delay(100); } 5、LCD液晶显示实验 5.1 实验介绍 对于LCD1602液晶屏模块的详细介绍可以参见往期的文章,硬件电路的连接情况如下图中所示。在这个实验当中使用UNO开发板控制液晶屏上显示我们想要的字符,在Arduino中调用库函数 [tr]LCD1602VCCGNDV0RSR/W[/tr]
5.2 核心代码 #include const int Rs = 3, En = 5, D4 = 10 D5 = 11, D6 = 12, D7 = 13; LiquidCrystal lcd(Rs, EN, D4, D5, D6, D7); void setup() { lcd.begin(16, 2); lcd.print(“Hellow Arduino UNO!”); } void loop() { lcd.setCursor(0, 1); lcd.print( mills()/1000 ); } 6、传感器实验 6.1 温度采集实验 LM35是一种已经得到了广泛使用温度传感器,其用法简单,仅需要单片机的一个模拟口便可读取传感器采集到的模拟值,然后通过一定的数学公式将其转换为实际的温度。其硬件电路连接图与核心代码如下所示: 主要代码: void loop() { // put your main code here, to run repeatedly: Serial.println(analogRead(LM35)*4.9/10); delay(1000); } 6.2 RFID射频识别实验 本实验中使用RFID读卡器对电子标签进行识别,需要调用到 MFRC522库,这个库可以完成对RFID读卡器的一系列操作,其核心代码如下所示: #include #include #define SS_PIN 10 #define RST_PIN 9 MFRC522 mfrc522(SS_PIN,RST_PIN); void setup() { // put your setup code here, to run once: Serial.begin(9600); SPI.begin(); mfrc522.PCD_Init(); Serial.println("Scan PICC to see UID and tye..."); } void loop() { // put your main code here, to run repeatedly: if(!mfrc522.PICC_IsNewCardPresent())//如果不是新卡就返回 { return; } if(!mfrc522.PICC_ReadCardSerial())//选择卡片失败 { return; } mfrc522.PICC_DumpToSerial(&(mfrc522.uid)); } 6.3 红外实验 本实验中采用的是如下图中的红外遥控器,以及红外接收传感器。在发送端使用遥控器按下按键,通过红外接收传感器可以在UNO开发板所在的接收端受到相应的按键信息。 主要代码: #include #include //res.value为接收的值,recv.resume()接收下一个值 int recvPin=2; IRrecv recv(recvPin); decode_results res; void setup() { // put your setup code here, to run once: Serial.begin(9600); recv.enableIRIn(); } void loop() { // put your main code here, to run repeatedly: if(recv.decode(&res))//判断是否收到数据 { Serial.println(res); } } 6.4 感光灯实验 本实验采用一个LED灯以及一个光敏电阻来完成感光灯的实验,当光敏电阻感受到不同光强是其阻值会发生变化,通过UNO采集这个变化值,最后呈现在LED的亮度变化上。 主要代码: void loop() { val=analogRead(potpin); Serial.println(val); analogWrite(ledpin, val); delay(10); } 7、Arduino与Processing交互实验 7.1 实验介绍 Processing是一门开源编程语言和与之配套的的集成开发环境(IDE)的名称,其在电子艺术和视觉设计社区被用来教授编程基础,并运用与大量的新媒体和互动艺术作品中。在本次实验中,实现了Arduino通过串口控制Processing的相关操作。实现在Arduino UNO端利用A0模拟口读取声音传感器采集到的数据,然后通过串口发送到Processing客户端,最后将这些数据进行可视化的展示。 7.2 核心代码 Arduino端: int sensorPin=A0; int sensorValue=0; void setup() { // put your setup code here, to run once: pinMode(sensorPin,INPUT); Serial.begin(9600); } void loop() { // put your main code here, to run repeatedly: sensorValue=analogRead(sensorPin); Serial.println(sensorValue,DEC); } Processing端: import processing.serial.*; Serial myPort; public static final char HEADER='h'; //从串口读取信息的第一个字符校验符 public static final short LF=10; //每次从串口读取信息的长度 float vol; //声音变量 float offset=100; //正弦曲线0点向y轴移动的值 float scaleVal=35;//曲线振幅 float angleInc=PI/60;//角速度 float angle=0; float dx=0; //x轴偏移量 float under;//振幅的最小值 float high=200;//音量的最大值 String [] com; void setup() { //println(Serial.list());//获取当前可用串口列表 //com=Serial.list(); myPort=new Serial(this,"COM10",9600);//初始化myPort,读取第一个可用串口,比特率为9600 myPort.bufferUntil('n'); //从串行口读数据时遇到换行符则结束读取 size(600,200); noStroke(); frameRate(60); //每秒刷新60次 } void draw() { scaleVal=map(vol,under,high,0,100); background(204); fill(255,0,0); rect(20,20,20,20);//绘制一个矩形,鼠标单击时获取当前背景噪声,并以当前噪音为基准线 fill(0); for(int posx=0;posx<=width;posx++) { float posy=offset+(sin(angle-dx)*scaleVal); rect(posx,posy,1,1); angle+=angleInc; } dx+=0.05; angle=0; } void serialEvent(Serial myPort) { String message=myPort.readStringUntil(LF); if(message!=null){ String []data=message.split(",");//将字符串信息用逗号分隔 if(data[0].charAt(0)==HEADER){ if(data.length>1) { vol=Integer.parseInt(data[1]); if(high if(under>vol) vol=under; } } } } void mouseClicked() { if(mouseX<40&&mouseX>20) { if(mouseY<40&&mouseY>20) { under=vol; } } } 8、多线程库Scoop的使用 8.1 实验介绍 多线性,是指从软件或者硬件上实现多个线程并发执行的技术,也就是说单片机可以在同一时间执行多个线程,进而提升整体的处理性能。通过之前的实验掌握的主要是单片机的顺序编程,也就是说单片机是按照编写的代码一步一步执行,在这里就有一个先后的次序问题。但在有些情况我们需要在一段时间内执行多个功能,这个时候就需要用到了多线程库,因此在Arduino UNO开发板上实现多线程编程本质上是从软件而不是硬件上实现的。在使用这个库是,必须要在setup() 函数中调用mySccop.start()命令,同时还需要在loop()函数中调用yield()命令,关于对多线程创建人物的模板如代码中所示。 8.2 核心代码 #include #define led1 LED_BUILTIN defineTaskLoop(myTask1) //第一个线程函数(不需要初始化函数,将loop函数写在{}里) { Serial.println("hello from task1"); sleep(1000); } defineTask(myTask2) //第二个线程函数 void myTask2::setup() { trace("task2 setup"); pinMode(led1, OUTPUT); } void myTask2::loop() { Serial.println("led1 HIGH"); digitalWrite(led1, HIGH); sleepSync(500); Serial.println("led1 LOW"); digitalWrite(led1, LOW); sleepSync(500); } defineTimerRun(Timer1,100) //快速定义一个时钟,周期为100ms { if (Serial.available()) { char c = Serial.read(); Serial.print(c);Serial.println(" key pressed"); if (c=='a') myTask1.pause();//任务一暂停 if (c=='b') myTask1.resume();//任务一重启 } } void setup() { Serial.begin(57600); while (!Serial); mySCoop.start(); } void loop() { Serial.println("do whatever you want here also"); mySCoop.sleep(500); } |
|||||
|
|||||
只有小组成员才能发言,加入小组>>
2553 浏览 0 评论
1152浏览 2评论
750浏览 1评论
503浏览 0评论
269浏览 0评论
433浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-23 12:03 , Processed in 1.680305 second(s), Total 77, Slave 59 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号