初学贴<1>: http://www.crystalradio.cn/thread-552316-1-1.html
初学贴<2>: http://www.crystalradio.cn/thread-552827-1-1.html
初学贴<2>续: http://www.crystalradio.cn/thread-553057-1-1.html
初学贴<3>函数的应用 http://www.crystalradio.cn/thread-553662-1-3.html
献给初学者的,仅作学习之用,写不好的请老鸟指出,但别喷,谢谢
献给初学者<4> 软件延时和软件延时法PWM回扫输出
一.目的:1. 通过传递不同形参值,打到修改延时时间的目的
验证方法:通过观察LED灯的亮灭交替闪烁的时间来确认;
2. 引申试验,通过设置传递不同形参值,以及输出高低电平的时间比例,达到输出脉冲的脉宽调节(PWM)的目的.
验证方法:
A.感性分析:通过观察LED灯的是否逐渐亮起后逐渐熄灭来确认;
B.定性分析: 用万用表直接测量输出的I/O 电压变化情况,应该看到逐渐变化的(变化速度与程序设置延时量有关)
二.硬件准备
51内核单片机最小系统(AT89S51/S52, STC89C51/C52/等等)一个,晶振12MHZ , LED一只,5V电源,下载线一根.
三.编译环境
请网上搜索KEIL软件下载后安装
二三歩不做细致说明了,切入正题.
1. 通过传递不同形参值,打到修改延时时间的目的
验证方法:通过观察LED灯的亮灭交替闪烁的时间来确认;
在 初学贴<3>函数的应用http://www.crystalradio.cn/thread-553662-1-3.html
中,我们知道:对于重复性的操作,我们可以把这部分功能独立成“模块”-------即函数的形式,需要用的时候,写上函数名和形参就可以了,函数把我们传递给它的数值(形参)作为输入变量,经过函数内部处理后,将结果返回(即输出)给调用它的语句.
本例中,为了让LED亮灭亮灭,实际上就是当I/O端口对地电压为高时,LED灭,端口对地电压为低时LED亮。
”
当LED点亮或者熄灭后,只要我们不作其它操作,机器也不断电,那么I/O的状态是有记忆的,继续保持这个状态不变,过一段时间后,如果我们想让LED状态改变,那么重写操作就可以了,这里“过一段时间后”的一段时间,就是我们要说的延时量.
由图二可知道,如果我们已经有了一个耗时为“t”延时函数,调用它并传参数为1时,CPU执行这个函数需要“t”时间,对于点亮灯的T0时间,它的时间是比较长的,可能大几倍甚至几百上千倍,我们打比方就说100倍吧,只要我们调用时传形参值为100,那么CPU运行耗时不就需要
100个单位的t时间吗?同理,假设灭灯的T1时间,它的时间是比较长的,可能大几倍甚至几百上千倍,我们打比方就说50倍吧,只要我们调用时传形参值为50,那么CPU运行耗时不就需要50个单位的t时间吗?以此类推..... 在这里,我们只需要调节函数形参值即可,不需要延时函数返回
啥结果,以此定义时返回值用空类型:void 自定义一个名为delpy的延时函数,形参变量为x,取值0-255
/* 延时功能函数--由x决定延时长度 */
void delpy (unsigned char x)
{
unsigned int i;
while( --x != 0)
{
for(i = 0; i < 500; i++); //t时间单位,修改常量20000位置的值,这个t时间单位的长短就不同了
}
}
在主函数main()里,我们尽管传参数就可以了,分别传100和50,LED所在端口电平置0置1即可。完整程序:
#include <AT89X51.H>
#define LED_A P1_1
/* 延时功能函数--由x决定延时长度 */
void delpy (unsigned char x)
{
unsigned int i;
while( --x != 0)
{
for(i = 0; i < 800; i++); //t时间单位
}
}
void main(void)
{
while(1)
{
// pwm_output();
LED_A=0;
delpy (100); //调用延时函数,并将100传给形参
LED_A=1;
delpy (50);
}
}
2. 引申试验,通过设置传递不同形参值,以及输出高低电平的时间比例,达到输出脉冲的脉宽调节(PWM)的目的.
验证方法:
A.感性分析:通过观察LED灯的是否逐渐亮起后逐渐熄灭来确认;
B.定性分析: 用万用表(最好是指针表)直接测量输出的I/O 电压变化情况,应该看到逐渐变化的(变化速度与程序设置延时量有关)
#include <AT89X51.H>
#define LED_A P1_1
#define LED_B P1_0
//* 延时功能函数--由d决定延时长度 */
void delpy (unsigned char x)
{
unsigned int i;
while( --x != 0)
{
for(i = 0; i < 2; i++); //t时间单位
}
}
/*****************************************************************************************
功 能:改变端口脉宽
入口参数:无
返 回 值:无
附 注:
周期255个单位,255级的脉宽调节, 脉宽从1/255递增到255/255, 然后逐渐递减到 1/255
改变端口的电压值,0-5V间变化
**************************************************************************************/
void pwm_output(void)
{unsigned char n,t=0;
for (n=254; n>0; n--) /*脉宽从1/255递增到254/255*/
{
LED_A = 0;
LED_B = 0;
t = ~t; /* t值取反 决定灯灭时的占空比,取反,相当于255-t */
delpy (t); //调用延时函数,并将数值传给形参
LED_A = 1;
LED_B = 1;
t = ~t; /* a值取反,还原 */
t++;/*改变占空比"t/255" */
delpy (t);
}
LED_A = 0;
LED_B = 0;; /* 灯全亮 使灯达到最亮 */
t= 0x00;
for (n=254; n>0; n--)/*脉宽从254/255递减到1/255*/
{
LED_A = 1;
LED_B = 1;;
t = ~t;
delpy (t);
LED_A = 0;
LED_B = 0;;
t = ~t;
t++;
delpy (t);
}
}
void main(void)
{
while(1)
{
pwm_output(); //调用脉宽控制输出函数
}
}
|