购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

1.2.2 简单的C语言程序

以一个简单的流水灯程序为例,了解一下AVR单片机C语言。

1.硬件电路

首先来看一个实例,这个例子的功能十分简单,就是让单片机的PA口的发光二极管(LED)灯按流水灯的形式进行闪烁,硬件电路如图 1-4 所示。

图 1-4 点亮P0 口LED灯电路

5V电源分别连接 8 只LED灯的正极,8 只LED灯的负极分别连接 8 个 1 kΩ限流电阻,然后再接到AVR单片机PB口。这样,当单片机的I/O口输出高电平时,LED两端都是高电平,LED不会导通,当I/O口输出低电平时,LED正向导通,同时也就发出光亮了。

这里解释一下LED灯上串联电阻大小的选择问题。我们知道,LED灯的工作电压为1.6~2.8V(一般为 2V),工作电流为 2~30mA(一般控制在 4~10mA),如果系统供电 V CC =5V,LED灯上串联的电阻为 1kΩ,并取LED灯上电压为 2V,那么,此时通过LED灯的电流则为(5V−2V)/1000Ω=3mA。如果需要提高亮度,需要增大LED灯的工作电流,当工作电流为 10mA时,则此时电阻应该选择(5V−2V)/10mA=300Ω,所以,LED灯的串联电阻一般在 0.3~1kΩ之间进行选择。

2.程序实现

8位流水灯源程序如下:

下面对这个程序进行简要的分析:

① 程序的第 1 行“#include <ioavr.h>”是“文件包含”,“文件包含”是指一个文件将另外一个文件的内容全部包含进来。所以,这里的程序虽然只有几行,但C编译器(如IAR软件)在处理的时候却要处理几十行或几百行。

② Delay_ms(500)的用途是延时,由于单片机执行指令的速度很快,如果不进行延时,灯亮之后马上就灭,灭了之后马上就亮,速度太快,人眼根本无法分辨。所以,需要进行适当的延时,这里采用自定义函数Delay_ms(500)实现延时,函数前面的void表示该延时函数没有返回值。

Delay_ms(500)函数是一个自定义函数,它不是由AVR编译器提供的,即不能在任何情况下编写这样一行程序以实现延时。如果在编写其他程序时写上这么一行,会发现编译通不过。注意观察本程序会发现,在使用Delay_ms(500)之前,已对Delay_ms(int k)函数进行了事先定义,因此,在主程序中才能采用Delay_ms(500)进行使用。

注意 :在延时函数Delay_ms(uint xms)定义中,参数xms称为“形式参数”(简称形参);而在调用延时函数Delay_ms(500)中,小括号里的数据“500”,这个“500”称为“实际参数”(简称实参)。参数的传递是单向的,即只能把实参的值传给形参,而不能把形参的值传给实参。另外,实参可以在一定范围内调整,这里的“500”表示延时时间为 0.5s,若为“1000”,则延时时间是 1000ms,即 1s。

③ AVR单片机的I/O口是标准的I/O口,I/O口的功能是负责实现CPU通过系统总线把I/O电路和外围设备联系在一起,标准的I/O口具有输入、输出、高阻 3 种状态,AVR单片机通过 3 个寄存器来控制I/O口的状态:输入和输出方向寄存器DDRx(x表示端口号,如DDRA表示端口A的方向寄存器)、输出寄存器PORTx、输入寄存器PINx。

在程序中,void port_init(void)是端口初始化函数,有两个语句:

● DDRB = 0xFF;的含义就是设置端口A为输出口。

● PORTA= 0xFF;的含义就是将端口A的输出寄存器设置为 0xFF,即让端口A的 8个I/O口全部输出高电平。

④ 在单片机程序中,首先在main主函数里对端口进行初始化,然后让程序进入一个while(1){}死循环中,这样保证程序一直运行。程序都是一步一步向下执行的,执行到程序的结尾就会停止,这时即使外界再有什么动作,单片机也不再响应了,加上死循环,那么程序就会一直在这个循环体中运行。如果在这个循环体中进行相应操作,程序就会很快检测到并给出响应。

在本例中,while(1){}死循环的功能轮流点亮PORTA口LED灯,使PORTA口的LED灯流动显示。 yOy0q+upcsBHflKDxh97EaQ91KM0dz9wX006pcLILiSsOcLL1NShAm3HGdUNOAV2

点击中间区域
呼出菜单
上一章
目录
下一章
×