一、按键控制LED亮度
具体任务:
采用按键控制LED1亮度。要求能在数码管上显示当前占空比,能够使用KEY1增加占空比,KEY2降低占空比。
代码:
#include <reg52.h>
//位定义
sbit LED1 = P2^4;
sbit KEY1 = P3^2;
sbit KEY2 = P3^3;
sbit SegmentG1 = P2^3;
sbit SegmentG2 = P2^2;
sbit SegmentG3 = P2^1;
sbit SegmentG4 = P2^0;
//定义变量
static unsigned int a ,b ,c ,d;
static unsigned char s_arrNumber[] = {0x03 , 0x9f , 0x25 , 0x0d , 0x99 , 0x49 , 0x41 , 0x1f , 0x01 , 0x09}; //?????????0-9
static unsigned int s_iCnt1 = 0; //s_iCnt1作为10ms计数变量,控制PWM周期
static unsigned int s_iCnt2 = 0; //s_iCnt1作为20ms计数变量,控制呼吸快慢
static unsigned int s_iDuty = 100; //s_iDuty作为占空比
static unsigned char s_iFlag = 0; //s_iFlag作为占空比增减标志,0减小,1增加
//定时器0配置函数
static void InitTimer0()
{
TMOD = 0x02; //工作模式2
TH0 = 0xFF; //高八位
TL0 = 0x9C; //低八位,定时100μs溢出
TR0 = 1; //打开定时器0
}
//中断初始化函数
static void InitInterrupt()
{
ET0 = 1; //定时器0 中断允许
EA = 1; //总中断允许
}
//延迟函数
static void DelayNms(int nms)
{
unsigned int i,j;
for(i = 0; i < nms; i++)
{
for(j = 0; j < 123; j++)
{
}
}
}
//主函数
void main()
{
InitInterrupt(); //配置中断
InitTimer0(); //配置定时器0
while (1)
{
//一直在显示可以放主函数里
a = s_iDuty / 1000; //显示千位(定义的整型所以自动忽略小数点后面的)
b = s_iDuty / 100; //显示百位
c = s_iDuty / 10; //显示十位
d = s_iDuty % 10; //显示个位
P0 = s_arrNumber[a];
SegmentG1 = 0;
DelayNms(1);
SegmentG1 = 1;
P0 = s_arrNumber[b];
SegmentG2 = 0;
DelayNms(1);
SegmentG2 = 1;
P0 = s_arrNumber[c];
SegmentG3 = 0;
DelayNms(1);
SegmentG3 = 1;
P0 = s_arrNumber[d];
SegmentG4 = 0;
DelayNms(1);
SegmentG4 = 1;
}
}
//中断服务函数
void Timer0_Handler () interrupt 1
{
//反复执行10ms计数(控制周期)
s_iCnt1++;
if(s_iCnt1 >= 100) //100*100μs=10ms
{
s_iCnt1 = 0;
}
//设置占空比调节标志
if(s_iDuty >= 100 && 1 == s_iFlag) //若占空比增大到100且当前标志为增加占空比
{
s_iFlag = 0; //设置标志为减小占空比
}
else if(0 == s_iDuty && 0 == s_iFlag) //若占空比减小到0且当前标志为减小占空比
{
s_iFlag = 1; //设置标志为增加占空比
}
//占空比调节
if(0 == s_iFlag) //若s_iFlag为0
{
s_iDuty--; //减小占空比
}
else if(1 == s_iFlag) //若s_iFlag为1
{
s_iDuty++; //增加占空比
}
//KEY1按键调节
if(0 == KEY1) //KEY1按下
{
DelayNms(50); //等50ms
if(0 == KEY1) //再次检测到KEY1按下
{
s_iDuty++; //增加占空比
}
}
//KEY2按键调节
if(0 == KEY2) //KEY2按下
{
DelayNms(50); //等50ms
if(0 == KEY2) //再次检测到KEY2按下
{
s_iDuty--; //减小占空比
}
}
if(s_iCnt1 <= s_iDuty) //控制LED开关
{
LED1 = 1; //关LED1
}
else
{
LED1 = 0; //开LED1
}
}
二、按键调整LED呼吸速度
具体任务:
采用按键调整LED1呼吸速度。要求能在数码管上显示 PWM占空比调整周期(单位:ms),能够使用KEY1降低调整周期,KEY2延长调整周期。
代码:
#include <reg52.h>
//位定义
sbit LED1 = P2^4;
sbit KEY1 = P3^2;
sbit KEY2 = P3^3;
sbit SegmentG1 = P2^3;
sbit SegmentG2 = P2^2;
sbit SegmentG3 = P2^1;
sbit SegmentG4 = P2^0;
//定义变量
int a ,b ,c ,d;
static unsigned char s_arrNumber[] = {0x03 , 0x9f , 0x25 , 0x0d , 0x99 , 0x49 , 0x41 , 0x1f , 0x01 , 0x09}; //?????????0-9
static unsigned int s_iCnt1 = 0; //s_iCnt1作为10ms计数变量,控制PWM周期
static unsigned int s_iCnt2 = 0; //s_iCnt1作为20ms计数变量,控制呼吸快慢
static unsigned int s_iDuty = 100; //s_iDuty作为占空比
static unsigned char s_iFlag = 0; //s_iFlag作为占空比增减标志,0减小,1增加
//定时器0配置函数
static void InitTimer0()
{
TMOD = 0x02; //工作模式2
TH0 = 0x9C; //高八位
TL0 = 0x9C; //低八位,定时100μs溢出
TR0 = 1; //打开定时器0
}
//中断初始化函数
static void InitInterrupt()
{
ET0 = 1; //定时器0 中断允许
EA = 1; //总中断允许
}
//延迟函数
static void DelayNms(int nms)
{
unsigned int i,j;
for(i = 0; i < nms; i++)
{
for(j = 0; j < 123; j++)
{
}
}
}
//主函数
void main()
{
InitInterrupt(); //配置中断
InitTimer0(); //配置定时器0
while (1)
{
//一直在显示可以放主函数里
a = s_iCnt2 / 1000; //显示千位
b = s_iCnt2 / 100; //显示百位
c = s_iCnt2 / 10; //显示十位
d = s_iCnt2 % 10; //显示个位
P0 = s_arrNumber[a];
SegmentG1 = 0;
DelayNms(1);
SegmentG1 = 1;
P0 = s_arrNumber[b];
SegmentG2 = 0;
DelayNms(1);
SegmentG2 = 1;
P0 = s_arrNumber[c];
SegmentG3 = 0;
DelayNms(1);
SegmentG3 = 1;
P0 = s_arrNumber[d];
SegmentG4 = 0;
DelayNms(1);
SegmentG4 = 1;
}
}
//中断服务函数
void Timer0_Handler () interrupt 1
{
//反复执行10ms计数(控制周期)
s_iCnt1++;
if(s_iCnt1 >= 100) //100*100μs=10ms
{
s_iCnt1 = 0;
}
//设置占空比调节标志
if(s_iDuty >= 100 && 1 == s_iFlag) //若占空比增大到100且当前标志为增加占空比
{
s_iFlag = 0; //设置标志为减小占空比
}
else if(0 == s_iDuty && 0 == s_iFlag) //若占空比减小到0且当前标志为减小占空比
{
s_iFlag = 1; //设置标志为增加占空比
}
//占空比调节
if(0 == s_iFlag) //若s_iFlag为0
{
s_iDuty--; //减小占空比
}
else if(1 == s_iFlag) //若s_iFlag为1
{
s_iDuty++; //增加占空比
}
//KEY1按键调节
if(0 == KEY1) //KEY1按下
{
DelayNms(50); //等50ms
if(0 == KEY1) //再次检测到KEY1按下
{
s_iCnt2++; //增加占空比周期
}
}
//KEY2按键调节
if(0 == KEY2) //KEY2按下
{
DelayNms(50); //等50ms
if(0 == KEY2) //再次检测到KEY2按下
{
s_iCnt2--; //减小占空比周期
}
}
if(s_iCnt1 <= s_iDuty) //控制LED开关
{
LED1 = 1; //关LED1
}
else
{
LED1 = 0; //开LED1
}
}