#include "at89x52.h"
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
uchar acLEDCS[]={0x1e,0x1d,0x1b,0x17}; /* 位选地址码,“0”有效,位选接的是P2口高4位 */
uchar code acLedSegCode[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c};/* 段码 */
uchar acLED[4]; /* 显示缓冲区 */
char cScanIndex; /* 位选指针0~3 */
uchar cKeyCode; /* 键值 */
uint nDelayKey; /* 键盘延时变量,为定时中断间隔时间的整数倍 */
uchar cKeySec; /* 按键长按几秒 */
bit bPush; /* 是否按键标志 */
char cMode; /* 显示方式变量,0~3对应4种方式 */
uint nTimer; /* 定时计数变量,为定时中断间隔时间的整数倍 */
/* 联合变量(大名2字节,小名2*1字节保存在同一物理空间),可用于定时器初值计算,控制中断周期 */
union UniT
{
uint T;
uchar t[2];
}idata uT;
uint freq = 50, duty = 500, nduty = 5;
/************************* 数码管显示函数 ***************************/
void display()
{
if(cMode == 0)
{
acLED[0] = 0x71; /* LED显示第1位 */
acLED[1] = 0x40;/* LED显示第2位 */
acLED[2] = acLedSegCode[freq/10%10]; /* LED显示第3位 */
acLED[3] = acLedSegCode[freq%10]; /* LED显示第4位 */
}
else if(cMode == 1)
{
acLED[0] = 0x5e; /* LED显示第1位 */
acLED[1] = acLedSegCode[duty / 100 % 10];/* LED显示第2位 */
acLED[2] = acLedSegCode[duty/10%10] | 0x80; /* LED显示第3位 */
acLED[3] = acLedSegCode[duty%10]; /* LED显示第4位 */
}
}
/******************** 按键处理程序 ******************/
void DisposeKEY()
{
switch(cKeyCode)
{
case 6: /* 例如:KeyADD */
if(cMode == 0 && freq<= 99)
freq++;
else if(cMode == 1 && duty < 999)
duty++;
break;
case 5: /* 例如:KeySUB */
if(cMode == 0 && freq)
freq--;
else if(cMode == 1 && duty)
duty--;
break;
case 3: /* 例如:KeyMode */
if(bPush==0)
{
cMode++;
cMode %= 2; /* 假设有4种显示状态 */
bPush = 1; /* 如果没松键就不会再改变显示方式 */
}
break;
}
display();
cKeyCode = 0;
nduty = duty / 5;
uT.T = 25-22118400/12/freq/200;
TL0 = uT.t[1];
TH0 = uT.t[0];
}
/************************** 主函数 *****************************/
void main(void)
{
/**************** 定时器初始化 *******************/
TMOD= 0x11;
TH1 = -18; /* 16位定时器,晶振22.1184M,22118400/12/256 = 7200 = 18*400 每秒钟溢出400次,每2.5ms中断一次*/
TR1 = 1;
ET1 = 1;
TR0 = 1;
ET0 = 1;
EA = 1; /* 开总中断 */
nduty = duty / 5;
uT.T = 25-22118400/12/freq/200;
TL0 = uT.t[1];
TH0 = uT.t[0];
display();
while(1)
{
if(cKeyCode)
{
DisposeKEY(); /* 响应按键操作 */
}
}
}
/****************** 多任务时序控制时钟中断 *********************/
void IntTimer() interrupt 3
{
TH1 = -18; /* 重装初值,保证每2.5ms中断一次*/
P0 = 0; // 清段选再送位选(消影)
P2_4 = 0;
//*************************中断次数计数******************
/*********************** 定时扫描独立按键 ************************/
if((P2 & 0x07) != 0x07) // 判断是否有按键动作,P22、P21、P20没有按键时为高电平(逻辑1)
{
nDelayKey++;
if((nDelayKey == 4 || nDelayKey % 128 == 0) && bPush == 0) // 延时削颤10ms,每160ms连加连减
{
cKeyCode = P2 & 0x07;// 取键值P20、P21、P22
}
if(nDelayKey % 400 == 0)
{ cKeySec++;
}
}
/***********************************************/
else // 松键,清按键相关变量
{
nDelayKey = 0;
cKeyCode = 0;
cKeySec = 0;
bPush = 0;
P2_4 = 1;
}
//*************************显示刷新******************
P2 = acLEDCS[cScanIndex]; /* 送位选数据 */
P0 = acLED[cScanIndex++]; /* 送显示数据,位选指针移位 */
cScanIndex &= 3; /* 位选指针回位 */
}
void IntTimer0() interrupt 1
{
TR0 = 0;
TL0 = uT.t[1];
TH0 = uT.t[0];
TR0 = 1;
nTimer++;
if(nTimer == nduty)
{
P2_7 = 0;
acLEDCS[0]=0x1e;
acLEDCS[1]=0x1d;
acLEDCS[2]=0x1b;
acLEDCS[3]=0x17;
}
if(nTimer == 200)
{
P2_7 = 1;
acLEDCS[0]=0x9e;
acLEDCS[1]=0x9d;
acLEDCS[2]=0x9b;
acLEDCS[3]=0x97;
nTimer = 0;
}
}
51单片机输出PWM波,可调频率、占空比
需积分: 0 90 浏览量
2024-04-30
21:09:29
上传
评论
收藏 67KB RAR 举报
ldtouzi
- 粉丝: 0
- 资源: 7
最新资源
- 部署yolov8的tensorrt模型支持检测分割姿态估计的C++源码+部署步骤.zip
- 以简单、易用、高性能为目标、开源的时序数据库,支持Linux及Windows, Time Series Database.zip
- python-leetcode面试题解之第198题打家劫舍-题解.zip
- python-leetcode面试题解之第191题位1的个数-题解.zip
- python-leetcode面试题解之第186题反转字符串中的单词II-题解.zip
- 一个基于python的web后端高性能开发框架,下载可用
- python-leetcode面试题解之第179题最大数-题解.zip
- python-leetcode面试题解之第170题两数之和III数据结构设计-题解.zip
- python-leetcode面试题解之第168题Excel表列名称-题解.zip
- python-leetcode面试题解之第167题两数之和II输入有序数组-题解.zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈