【单片机自学笔记】(5):数据计算及存储误差、数组、Servo库、硬件模拟PWM控制伺服电机、8乘8点阵

 / C语言 /

数据计算及存储误差

104页中的一段程序

if(fabs(a)<=-6)

  printf(“is not a quadratic\n”)

其中fabs(a) 的意思是求a(a是浮点型数)的绝对值

由于disc(即b^2-4ac)是实数,而实数在计算和存储时会有一些微小的误差,因而不能直接判断“if(disc == )”。

转而要判别“(if(disc <= 1e-6))”即disc是否小于一个极小的数,小于这个数就直接当成0处理。

while和do…while

在循环体相同的条件下,当while后面的表达式第一次判断为“真”时,那么两种循环语句得到的结果是相同的。

当条件第一次判断就为“假”时,while可以一次也不执行循环体,而do…while则至少要执行一次循环体。

数组

定义一维数组

类型说明符 数组名[常量表达式]  

例:int a[10];

引用一维数组

数组名 [下标]

例:t = a[5]

定义二维数组

类型说明符 数组名[常量表达式][常量表达式]

例:int a[10][10];

引用二维数组

数组名[下标][下标]

例: a[5][5]

不管是行序号还是列序号都是从0起

字符数组

例:char c[5] = {‘c’,‘h’,‘i’,‘n’,‘a’};

C语言规定了空字符‘\0’作为“字符串结束的标志”

‘\0’是个空操作符,即它什么也不做

若想用新字符串代替原来的字符串,记得要在后面加多一个‘\0’,以免和原来的字符串连成一片。

格式符“%c”输入或输出一个字符

例:printf(“%c\n”, shuzu[i][j]); 

输出项是字符数组元素名

格式符“%s”输入或输出一个字符串

例printf(“%s\n”, shuzu);

输出项是字符数组名

scanf函数中的输入项如果是字符数组名,不要在加地址符&,因为在c语言中数组名代表该数组第一个元素的地址(或者说是数组的起始地址)

/ 51单片机 /

在KEIL5中新建项目时,如果没有找到Atmel要找到Microchip中的AT89C52

一些语句的实例:

sbit 变量名 = 地址名;

#define led P2          (后面不需要加分号)

typedef   固有的数据类型说明符  别名;

可以用别名来代替数据类型说明符

例如typedef  unsigned int u8;

u8 a1 = 0x12;

用keil5编程自定义delay函数的时候,并不知道实际会延时多长时间,需要自己设置断点,然后看运行delay前和运行后的时间,来确定实际时间(时间跟晶振有关)。

 

/ 伺服电机 /

Arduino引脚        舵机数据线

+5v                 红色线-VCC

DND                棕色线-GND

9(PWM)          橙色线-PWM控制信号

map()函数用来将某一数值从一个区间等比映射到一个新的区间

map(x, in_min, in_max, out_min, out_max);

Servo

Servo myservo    建立舵机对象myservo

电机名.attach(pin)   链接该舵机数据线的Arduino引脚

电机名.write(angle)    将舵机轴转到相应的角度位置

电机名.writeMicroseconds()

将微秒(US)值写入伺服系统,相应地控制轴。在标准伺服系统上,这将设置轴的角度。在标准伺服系统中,参数值1000是完全逆时针方向,2000是完全顺时针方向,1500是中间。但不同厂商的舵机可能会有些许差别,数值要相应改变。

Servo.read()    读取舵机当前角度

Servo.detach()    所有Servo变量均被脱离,9,10引脚可重新使用PWM功能

舵机的PWM控制

在arduino uno板子上有三个计时器(硬件)计时器0控制引脚5,6。计时器1控制引脚9,10。计时器2控制11,3。它通过软件模拟让这些引脚成为以PWM模式输出。

但是如果调用了Servo库后,会占用一个计时器,导致相应引脚的PWM功能就会失去作用。

所以如果不想引脚被Servo库占用,可以直接用硬件模拟PWM。

通常,伺服脉冲长度为1ms。因此需要用1Khz的频率驱动,这种操作很容易通过软件以几Mhz频率运行的输出上生成

最终可以达到用Arduino同时控制多达12个舵机。

即使不用3,5,6,9,10,11引脚,也一样可以通过硬件(计时器)模拟PWM,来控制伺服电机。只要向舵机发送一个1.5ms的脉冲,那么舵机输出轴就会转动到可转动角度中最中间的位置。

实验程序

实验结果

串口通讯

Serial.available()   

检查Arduino缓存中是否有数据等待传输,有几个字节数,改函数的返回值就是多少。

Serial.read() 读取缓存中的数据

/ 8乘8点阵 /

接线图

如果点阵的引脚情况不明确的话,可以用Arduino的3.3v和GND接口去一个个地测出来。

模拟I/O当数字I/O用

当要用Arduino直接控制8*8点阵的时候,可以直接把模拟输入引脚A0~A5当成是数字数字输入输出引脚14-19引脚来用(按照高低电平的方式读入或输出,A0-A5就等于是数字接口了,编程的时候可以直接写成14-19引脚

可以用digitalWrite也可以用analogWrite来控制模拟I/O

模拟输出:

analogWrite(pin, outputVal);

outputVal  在0~255之间对应0~5v

点阵控制

列(column)接高电平,行(row)接低电平

自定义亮单个灯的函数liang(只接了12个引脚6*6点阵)

 

通过“liang(5, 3);”即可达到点亮第五行第三列的led灯的效果

也可以配合loop函数里的嵌套for函数,达到逐个点亮的效果。

再利用视觉暂留现象(时间间隔很小),结合数组跟各种嵌套语句来达到点亮各种图案的效果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值