📄 file11.c
字号:
// 该信号源可以产生 多种波形,包括:占空比为1:1的方波,频率可调节(1 -- 50 Hz)
// 调制波,载波频率为1k,备调制频率 (1 -- 50 Hz)
// 高频信号 : 高电平 5V, 低电平 0V 频率 500K;
// 按键key3 选择 输出波形方式 1 ->载波(LED3亮,LED1指示输出)
// 2 -> 非载波(LED2亮,LED1指示输出);
// 按键key2 选择 输出频率
// 按键key1 启动\停止
#include <8051.h>
#define uchar unsigned char
#define uint unsigned int
#define key1 P3_3 //键盘定义
#define key2 P3_4
#define key3 P3_5
#define segdata P0 //数据 输出
#define sege P2_7 //显示 选中
#define segb P2_6 //位 选
#define segd P2_5 //段 选
uchar keyb();
// 这里定义的是数码管对应的字符字根
code uchar disbuf_u[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,
0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,
0x00,0x10,0x08,0x03,0x46,0x21,0x06,0x0e};
// ***************************************************************************
// 12M下的频率码表,每个数据分为三个字节,
// 第一个字节,定时器初值高8位
// 第二个字节,定时器初值低8位
// 第三个字节,倍数
// 用这三个信息来确定一个输出频率值
//1HZ ,
code uchar fretab12[] ={0,0,0,11,219,16};
code uchar freq12M[]={ 0,0,0, //起头,无效码
11,219,16,//频率1
11,218,8,//频率2
38,250,6,//频率3
11,217,4,//频率4
60,173,4,//频率5
38,249,3,//频率6
69,249,3,//频率7
11,214,2,//频率8
38,247,2,//频率9
60,170,2,//频率10
78,108,2,//频率11
93,56,2,//频率12
105,189,2,//频率13
116,120,2,//频率14
125,197,2,//频率15
11,209,1,//频率16
26,46,1,//频率17
38,242,1,//频率18
50,94,1,//频率19
60,165,1,//频率20
69,242,1,//频率21
78,103,1,//频率22
86,31,1,//频率23
93,51,1,//频率24
99,181,1,//频率25
105,184,1,//频率26
111,72,1,//频率27
116,115,1,//频率28
121,67,1,//频率29
125,192,1,//频率30
129,243,1,//频率31
133,227,1,//频率32
137,150,1,//频率33
141,18,1,//频率34
144,90,1,//频率35
147,116,1,//频率36
150,98,1,//频率37
153,42,1,//频率38
155,204,1,//频率39
158,77,1,//频率40
160,175,1,//频率41
162,244,1,//频率42
165,30,1,//频率43
167,46,1,//频率44
169,39,1,//频率45
171,10,1,//频率46
172,217,1,//频率47
174,148,1,//频率48
176,61,1,//频率49
177,213,1};//频率50
code uchar freq6M[]={ 0,0,0,//无效
3,251,31,//频率1
11,218,16,//频率2
19,64,11,//频率3
11,217,8,//频率4
32,198,7,//频率5
38,249,6,//频率6
32,196,5,//频率7
11,214,4,//频率8
38,247,4,//频率9
60,170,4,//频率10
19,58,3,//频率11
38,245,3,//频率12
55,166,3,//频率13
69,246,3,//频率14
82,92,3,//频率15
11,209,2,//频率16
26,46,2,//频率17
38,242,2,//频率18
50,94,2,//频率19
60,165,2,//频率20
69,242,2,//频率21
78,103,2,//频率22
86,31,2,//频率23
93,51,2,//频率24
99,181,2,//频率25
105,184,2,//频率26
111,72,2,//频率27
116,115,2,//频率28
121,67,2,//频率29
125,192,2,//频率30
3,230,1,//频率31
11,198,1,//频率32
19,44,1,//频率33
26,36,1,//频率34
32,180,1,//频率35
38,232,1,//频率36
44,196,1,//频率37
50,84,1,//频率38
55,152,1,//频率39
60,154,1,//频率40
65,94,1,//频率41
69,232,1,//频率42
74,60,1,//频率43
78,92,1,//频率44
82,78,1,//频率45
86,20,1,//频率46
89,178,1,//频率47
93,40,1,//频率48
96,122,1,//频率49
99,170,1//频率50
}; //最后面一个逗号去掉
struct botout {
uchar outh; //定时器常数 THO
uchar outl; //定时器常数 TLO
uchar count; //需要输出的次数
};
struct botout fcout; //这个是每个数据点的数据结构
static uint counts; //需要计数的次数
uchar fre; //用户设置的频率,不大于50
uchar flag; //波形选择 = 1调制波,否则方波
uchar start; //启动/停止标志
// 下面是定时器T0的中断服务程序
void ClockIrqHandler (void) interrupt 1{
TL0 = fcout.outl;
TH0 = fcout.outh;
if(counts) counts --; //如果没到定时时间,定时倍数减少一
else
{
if(start == 1) //这是启动/停止标志
{
if(flag == 1) //这个是调制/非调制标志
{
TR1 = ~TR1,P1_0 = ~TR1; //输出调制波
}
else P1_0 = ~P1_0,TR1 = 0; //输出方波
}else TR1=0,P1_0 = 1; //停止输出波形
counts = fcout.count; //重新送倍数
}
}
// 定时器T1中断服务程序
void TIMER1() interrupt 3{
TL1 = -1000%256;
TH1 = -1000/256;
P1_0 = ~P1_0; //p1.0输出
}
//*****************************************************************************
// 频率设置函数
void setfre(uchar fre)
{
uchar f;
f = fre*3;
fcout.outh = freq6M[f]; //根据给定频率值,查表求定时器高低初值和倍数
fcout.outl = freq6M[f+1] ;
fcout.count = freq6M[f+2];
}
//下面是延时程序。具体的延时时间不能通过表面程序看出,(为什么?)
//如果我们需要一个精密的延时程序,那么我们可以采用内嵌汇编代码的方式
void delay(uint ysz)
{
while(ysz--){};
}
//这里是显示子程序,入口参数为
// disseg -> 位选 可选范围 0-7 一共8个数码管
// disdata -> 段选 可选范围 0-31 一个32个字符
// 段选 0-15 16个字符 为 "0"->"F"
// 段选 16-31 16个字符 为 "0."->"F."
void display(uchar disseg,uchar disdata)
{
unsigned char dataf;
dataf = 1;
while(disseg)
{
dataf <<= 1;
disseg--;
}
sege = 0;
segdata = dataf; //这里首先把要显示的数据放到数据总线
segb = 1; //这里给出一个脉冲,数据送往位选端
segb = 0;
segdata = disbuf_u[disdata];
segd = 1; //这里给出一个脉冲,数据送往段选端
segd = 0;
delay(10);
segdata = 255;
segd = 1; //这里给出一个脉冲,数据送往段选端
segd = 0;
}
// 键盘程序,返回的结果是读得键盘对应的数据
uchar keyb()
{
uchar key,keytmp;
key1 = 1; //将输出线拉高
key2 = 1;
key3 = 1;
key = P3 ; //读回来
key = key & 0x38; //获得键盘结果
if(key == 56 ) return 0; //如果用户没有按键返回 0
else
{
keytmp = key;
delay(100); //判断是不是干扰
key = P3;
key = key & 0x38;
if (key != keytmp ) return 0; //是干扰,返回 0
else //不是干扰,等待用户释放按键
{
do{
key1 = 1; //输出拉高
key2 = 1;
key3 = 1;
key = P3 & 0x38; //读回来
P1_0 = ~P1_0; //如果用户不释放,闪烁 p1.0
}while(key != 56 ); //等待用户释放
P1_0 = 1; //用户释放以后,清除p1.0指示灯
switch(keytmp)
{
case 24: return 1;//返回用户按键结果
case 40: return 2;
case 48: return 3;
}
}
}
return 0;
}
void main()
{
uchar key;
P1 = 255; //关闭LED显示
P0 = 0; //关闭数码显示
P2 = 255; //
P3_7 = 0; //关闭蜂鸣器
counts = 0;
flag = 1 ; //调制波输出
fre = 1; // 初始化输出1HZ频率
start = 1;
TL0 = 255; //初值
TH0 = 255; //初值
TL1 = -1000%256;
TH1 = -1000/256;
TMOD = 1; // 定时器工作在方式0
ET0=1; // 允许定时器T0中断
EA =1; // 中断总允许
ET1 = 1; // 允许定时器1中断
setfre(fre);
TR0=1; //开启定时器
while(1)
{
key = keyb(); //取得键盘
if(key == 1) //用户按启动/停止功能键盘
{
start = ~start;
}else if(key == 2) //用户按频率选择功能键
{
if(fre>49) fre = 1;
else fre++;
setfre(fre); //设置频率值
}else if(key == 3) //用户按输出标志键
{
flag = ~flag;
if(flag==1) P1_2 = 1,P1_3=0;
else P1_2 = 0,P1_3 = 1;
}
if(flag==1) P1_2 = 1,P1_3=0;//显示标志位
else P1_2 = 0,P1_3 = 1;
display(0,fre%10); //显示个位
if(fre/10 !=0 ) //如果十位 = 0,不显示
{
display(1,fre/10);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -