方波信号发生器
行至 359 行)
按键部分。按键 0-->频率千位加 1;按键 1-->频率千位减 1;按键 2-->频率百位加 1;按键 3-->频率百位减 1;
按键 4-->频率十位加 1;按键 5-->频率十位减 1;按键 6-->频率个位加 1;按键 7-->频率个位减 1;
按键 8-->占空比加 1;按键 9-->占空比减 1。
//软件去抖动
{
Tmp=P1^0x0f;
//按键后 f0 变成 XXXX0000,X 中有 1 个为 0,三个仍为 1;高 4 位转移到低 4 位并异或得到改变的值
switch(Tmp)
//判断按键发生于 0~3 列的哪一行 ,对 0~3 行分别加起始值 0,4,8,12
{
case 1 : KeyNo=0;break;
**输出: --
**功能描述:用数码管显示当前的频率值。采用动态扫描的显示方式
*****************************************************************/
void seg7leddisplay()
{
uchar i,temp;
P2=0xfe;
for(i=0;i<5;i++)
if(P0led[3]==0) P0led[3]=9;
else P0led[3]-=1;
break; case 8 :
if(DutyRatio==5)
//当没有按键按下时默认将按键值设定为 16(不存在的按键) //等待按键弹起,防止按一次键加多个值。缺陷:会造成按键时数码管闪烁一次 //有按键时执行按键操作 //频率的千位加 1,0->1->..->4->0 //频率的千位减 1,0->4->3->..->1->0 //频率的百位加 1,0->1->2->..->9->0 //频率的百位减 1,0->9->8->..->1->0 //频率的十位加 1,0->1->2->..->9->0 //频率的十位减 1,0->9->8->..->1->0 //频率的个位加 1,0->1->2->..->9->0 //频率的个位减 1,0->9->8->..->1->0 //占空比调节,加 1,1—>2->..->5->1
{
P0=0xff;
//数码管消隐
P2=_crol_(P2,1);
temp=P0led[i];
P0=DSY_CODE[temp]; delay_ms(1);
}
}
/****************************************************************
**函数名: keyscan() -----按键扫描函数
*****************************************************************/
void keyscan()
{
uchar Tmp;
P1=0x0f;
if((P1&0x0f)!=0x0f)
{
delay_ms(10);
if((P1&0x0f)!=0x0f)
/****************************************************************
** 程序:方波信号发生器
** 功能描述:基于 51 单片机的简易方波信号发生器。频率范围为 1Hz~5KHz 的方波发生器,
占空比 1~5 可调,可按键输入发生频率。
**设计硬件接口资源使用情况:
#include <reg52.h>
#include<intrins.h>
//调用该库可以使用_crol_()和_cror_()
#define uchar unsigned char
#define uint unsigned int
uchar P0led[]={1,0,0,0,1};
//P0led[]--频率及占空比数组。频率初始值为 1000Hz,P0led[0]->千位,
case 2 : KeyNo=4;break;
case 4 : KeyNo=8;break;
case 8 : KeyNo=12;break;
default : break;
//无键按下
}
P1=0xf0;
//高 4 位置 0,放入 4 行
Tmp=P1>>4^0x0f;
//按键后 0f 变成 0000XXXX,X 中一个为 0,3 个仍为 1,通过异或(^)把 3 个 1 变为 0,唯一的 0 变为 1
//P0led[1]->百位,P0led[2]->十位,
//P0led[3]->个位,P0led[4]->占空比
uchar KeyNo,DutyRatio;
//KeyNo--键值(取值 0~15,16 为无效态) ;DutyRatio--占空比(取值 1~5)
uint couter=0,set1HTH0,set1HTL0,set1LTH0,set1LTL0,set2TH0,set2TL0,couterH,couterL;
DutyRatio=1; else
DutyRatio+=1; P0led[4]=DutyRatio; break; case 9 : if(DutyRatio==1) DutyRatio=5; else DutyRatio-=1; P0led[4]=DutyRatio; break; default : break; } } }
for(;xms>0;xms--)
for(t=0;t<120;t++);
}
/****************************************************************
**函数名: seg7leddisplay()
**输入:
P0led[]---- 共 5 位,0~3,每位分别表示频率的千,百,十,个位值;4,占空比值
//串口方式 1
PCON=0;
//SMOD=0
REN=1;
//允许接收
TMOD= 0x20;
//定时器 1 定时方式 2
TH1= 0xfd;
//11.0592M 9600 波特率
TL1= 0xfd;
TR1= 1;
//启动定时器
} */
/****************************************************************
P0:数码管段码(8 位)。连接方式:P0^7~P0^0-->dp、g、f、e、d、c、b、a。
P1:4X4 矩阵按键。P0^0~P0^3-->行 0~行 3,P0^4~P0^7-->列 0-列 3。按键按下时为低电平。
P2:数码管位码(共八个共阳极数码管)。P2^0~P2^7-->S1~S7。注:本设计仅使用前五个数码管。
//共阳极数码管段码
{
0xc0, //0
0xf9, //1
0xa4, //2
0xb0, //3
0x99, //4
0x92, //5
0x82, //6
0xf8, //7
0x80, //8
0x90 //9
};
/****************************************************************
**函数名:delay_ms----延时函数
**输入:
xms----延时时间
**输出:
**功能描述:延时 x ms.
*****************************************************************/
void delay_ms(uint xms)
{
uint t;
//占空比调节,减 1,1—>5->4->..->2->1
/**************************************************************** **函数名:init()----程序初始化程序函数 **输入:
**输出:
P0led[]---- 共 4 位,0~3,每位分别表示频率的千,百,十,个位值
按键处理,按键扫描使用线反转法,有软件去抖动部分。按键按下一次执行一次按键操作,即是按键弹起
时才执行一次按键操作。
数码管显示。数码管为 8 位共阳极数码管。使用动态扫描法显示。
注:使用晶振为 12MHz
**作者:kach
**建立时间Biblioteka 2014.7.6*****************************************************************/
switch(Tmp)
//对 0~3 列分别加值 0,1,2,3
{ case 1 : KeyNo+=0;break; case 2 : KeyNo+=1;break; case 4 : KeyNo+=2;break; case 8 : KeyNo+=3;break; default: break;
} } } else KeyNo=16; P1=0x0f; while(P1!=0x0f); if(KeyNo!=16) { switch(KeyNo) { case 0 :