㈠ 请问:单片机使用c语言编程,怎样控制led灯的完成亮度强弱变换
/*********************************************************************
模拟PWM输出控制灯的10个亮度级别
将定时器2溢出定为1/1200秒。每10次脉冲输出一个120HZ频率。
这每10次脉冲再用来控制高低电平的10个比值。
这样,在每个1/120秒的方波周期中,我们都可以改变方波的输出占空比,从而控制LED灯的10个级别的亮度。
*******************************************************************/
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
#include <reg52.h> //包括一个52标准内核的头文件
sbit P10 = P1^0; //要控制的LED灯
sbit K1= P3^2; //按键K1
uchar scale;//用于保存占空比的输出0的时间份额,总共10份
char code dx516[3] _at_ 0x003b;//这是为了仿真设置的
//模拟PWM输出控制灯的10个亮度级别
void main(void) // 主程序
{
uint n;
RCAP2H =0xF3; //赋T2的预置值,溢出1次是1/1200秒钟
RCAP2L =0x98;
TR2=1; //启动定时器
ET2=1; //打开定时器2中断
EA=1; //打开总中断
while(1) //程序循环
{ ;//主程序在这里就不断自循环,实际应用中,这里是做主要工作
for(n=0;n<50000;n++); //每过一会儿就自动加一个档次的亮度
scale++;
if(scale==10)scale=0;
}
}
//1/1200秒定时器2中断
timer2() interrupt 5
{
static uchar tt; //tt用来保存当前时间在一秒中的比例位置
TF2=0;
tt++;
if(tt==10) //每1/120秒整开始输出低电平
{
tt=0;
if(scale!=0) //这里加这一句是为了消除灭灯状态产生的鬼影
P10=0;
}
if(scale==tt) //按照当前占空比切换输出高电平
P10=1;
}
――――――――――――――――――
在主程序中,每延时一段时间,就自动换一个占空比,以使亮度自动变化,方便观察。
编译,运行,看结果。
可以看到,LED的亮度以每种亮度1秒左右不断变化,共有10个级别。
㈡ 关于51单片机做数码电压表时有段程序始终看不懂,请各位单片机高手们指点迷津
void也可以看成是数据类型,只是他是特殊的数据类型,这个类型就是“没有东西”。
比如一个函数
int a(int b){ }
表示函数的参数是int类型的,返回值是int类型的。如果没有返回值,也没有参数,就都把类型名称写成void,既然没有了,那么也就没有名称了,所以b也可以省了,便成了 void a(void) { }。
函数的定义是很基本的c语言知识,这个说起来很啰嗦,随便看书就能明白了。
void delay(void) 这个函数没什么特别意义,只是一个延时而已。因为单片机运行速度很快,数码管也不是恒定的点亮一个,而是动态扫描的,就是说,先点亮一个位,然后关闭,点亮另一个位。这个过程很快,由于视觉暂留作用,人眼只能看到所有的位都是同时亮的,这个原理和放电影一样,不过,如果点亮一个后,立即点亮另一个,会因为点亮时间太短,灯还没全亮就灭了(本人估计的,但应该也是这样),造成灯光太暗。所以要延时一下。
单片机的电源电压是5V,那么所有端口的承受电压就一定是5V,如果是3.3V单片机,就一定只能承受3.3V,所以测量量程一定是0 至 5V。如果实际测量量程远远小于这个范围,必须用放大器放大。如果量程大于这个范围,必须分压。
void convdata(unsigned char i)
这个 i 明显就是数模转换得到的结果,作为参数传递给这个函数处理。void以及函数参数等名词术语,说起来就是一本教科书的量,请自行看书,这是很基本的。
dis[0] = i/51 以及后面的两句,是一个数学问题。(dis[i]就是一个数组,这个不用多言)。
为什么是51呢?看他的注释“将0-255级换算成0.00-5.00的电压数值”。
也就是说,如果测得的电压是5V,那么数模转换的结果就是255,这是一个8位数的最大值,这个数模转换器的最大值就是8位,所以5V的电压转换得到就是255.
然后就可以照推了,如果测得的值是2.5V,那么得到的值就是255 / 2 = 127.5。也就是说,实际测得的值和这个转换值的关系是正比的,他们的比值就是 255 / 5 = 51 ,所以用测到的值去除以51,就得到实际值。明白了吗?如果这样说还不明白,那就没办法了~
然后,为什么后面又要搞那两条式子呢?这是因为,要把一个数值在数码管上显示出来,必须把一个数值上每一个位的数字单独处理给数码管显示。比如,上面除以51后,得到的数可能会有小数,比如1.45,那么要把这个数用数码管显示出来,就必须把 1、4、5和小数点都单独取出来。
以这个(i%51)*10/51*2为例:
i%51 , 是 i 除以 51 后的余数。这个数再除以51,再乘以10,再取整,就是第一个小数了。他这个式子把"乘以10"放在前面,是因为如果先除以51,那么因为i 和 51 都是int类型,结果也必将是int类型,没有小数,再乘以10也没意义了。至于后面为什么还要乘以2,这个还真不清楚,不过他这个dis数组是用来查表的,就是后面的tab[],要看他的表是怎么定义的。他第一个数没有乘以2,但是这个数和小数点的显示有关,可能不显示小数点的就要乘以2。
后面的求第二个小数,参照这个解释自己理解一下。
㈢ 单片机实现正弦波的C程序
在把PC上 用C语言 编写一个程序 生成 一个周期 正弦信号 的离散值
用一个字节 8位 表示
即 0 ~ 255 表示正弦 信号 -1 到 1之间的值
单片程序 把这组0 ~ 255的 数字 放在一个 数组里
用循环 向 某个 IO口输出 这个数组
IO口接 DAC数模转换 器