|
/********************************************************
程序功能:用3个定时器产生3中不同频率的方波,用一个中断产生
3种不同频率的方波,用2个按键发出单脉冲波
接线说明:1MH的方波的发出端口为P3^0
100KHZ的方波的发出端口为P3^4
10KHZ的方波的发出端口为P3^5
1KHZ的方波的发出端口为P1^0
100HZ的方波的发出端口为P1^1
10HZ的方波的发出端口为P1^2
键盘的连接IO端口的P0^1和P0^2
单脉冲波的输出显示端口P0^3和P0^4
试验现象:不同的端口输出的频率,可以在示波器上看到6种不同频率的方波
日 期:2014/7/13
作 者:吴超
*********************************************************/
#include <reg51.h>
sfr AUXR = 0x8e; //特殊功能定时器
sfr INT_CLKO = 0x8f; //使能定时器
/*定时器2的各项参数定义*/
sfr T2H = 0xD6; //定时器2的高8位定义
sfr T2L = 0xD7; //定时器2的低8位定义
sfr IE2 = 0xAF; //定时器2的中断定义
sbit T0CLKO = P3^5; //定时器0的端口定义
sbit T1CLKO = P3^4; //定义器1的端口定义
sbit T2CLKO = P3^0; //定义器2的端口定义
/*通过定时器0的溢出中断输出1K 100HZ 10HZ的参数定义*/
sbit output_1K = P1^0; //定义1K方波的输出端口
sbit output_100HZ = P1^1; //定义100HZ方波的输出端口
sbit output_10HZ = P1^2; //定义10HZ方波的输出端口
unsigned int cunt_1K = 0; //1K方波的计数器
unsigned int cunt_100HZ = 0; //100HZ方波的计数器
unsigned int cunt_10HZ = 0; //10HZ方波的计数器
/*通过按键输出单脉冲的参数设置*/
sbit key = P0^0; //定义按键的端口为P0^0
char flag = 1; //定义变量flag,用于确定10ms进行一次按键扫描
sbit dmchong1 =P0^1; //定义单脉冲1输出端口
sbit dmchong2 =P0^2; //定义单脉冲2输出端口
char flag2 =0; //定义变量flag2,用于接收key_read函数的返回值
sbit led1 = P0^3; //定义变量led1,将led灯连接到端口P0^3
sbit led2 = P0^4; //定义变量led2,将led灯连接到端口P0^4
/****************************************************************
函数名:tm0_init()
函数功能:系统时钟的频率为12MHZ,机器周期=12/12MHZ=1us,将定时器0的时钟输出频率设为1MHZ
入口参数:无
返回参数:无
*****************************************************************/
void tm0_init()
{
INT_CLKO |= 0x01; //使能定时器0的时钟输出
AUXR |= 0x80; //定时器0为1T模式
TMOD = 0x00; //设置定时器0为工作模式0(16位自动重装)
TL0 = (65536-600)%256; //设置TL0的初始值(16进制)为0xFA TL0存放的是低8位的数值 最大能放255
TH0 = (65536-600)/256; //设置TH0的初始值(16进制)为0xFF
ET0 = 1; //定时器0中断开启
EA = 1; //全局中断开启
TR0 = 1; //打开定时器0
}
/****************************************************************
函数名:tm1_init()
函数功能:系统时钟的频率为12MHZ,将定时器1的时钟输出频率设为100KHZ
入口参数:无
返回参数:无
****************************************************************/
void tm1_init()
{
INT_CLKO |= 0x02; //使能定时器1的时钟输出
AUXR |= 0x40; //定时器1为1T模式
TMOD = 0x00; //设置定时器1为工作模式0(16位自动重装)
TL1 =(65536-60)%256; //设置定时器1的TH1的初始值(16进制)为0xC4
TH1 =(65536-60)/256; //设置定时器1的TL1的初始值(16进制)为0xFF
TR1 = 1; //开启定时器1
}
/***************************************************************
函数名:tm2_init()
函数功能:系统时钟的频率为12MHZ,将定时器2的时钟输出频率设为10KHZ
入口参数:无
返回参数:无
***************************************************************/
void tm2_init()
{
INT_CLKO |= 0x04; //使能定时器2的时钟输出
AUXR |= 0x04; //定时器2为1T模式
T2L = (65536-6)%256; //设置定时器T2L的初始值(16进制)为0xA8
T2H = (65536-6)/256; //设置定时器T2H的初始值(16进制)为0xFD
AUXR |= 0x10; //定时器2开始计时
}
/***********************************************************************
函数名:tm0_isr()
函数功能:定时器0的溢出中断函数,通过溢出中断,输出1KHZ 100HZ 10HZ的方波
入口参数:无
返回参数:无
************************************************************************/
void tm0_isr() interrupt 1 using 1
{
if(++cunt_1K == 10) //定时器0的频率周期是10KHZ,再除以10就是1KHZ的频率周期
{
output_1K = !output_1K; //1KHZ频率输出端口取反,输出频率
cunt_1K = 0; //计数器重置为0
}
if(++cunt_100HZ == 100)
{
output_100HZ = !output_100HZ; //100HZ频率输出端口取反
flag = 1;
cunt_100HZ = 0; //计数器重置为0
}
if(++cunt_10HZ == 1000)
{
output_10HZ = !output_10HZ; //10HZ频率输出端口取反
cunt_10HZ = 0; //计数器重置为0
}
}
/***************************************************************
函数名:key_read()
函数功能:扫描按键,用于按键的消抖
入口参数:无
返回参数:key_return
***************************************************************/
char key_read()
{
static char key_st = 0;
char key_return; //定义按键的返回值
char key_press; //定义字符型变量,用于存储I/O读到的数据
key_return = 0;
key_press = key; //读按键I/O口的电平
switch(key_st)
{
case 0:if(!key_press) //按键初始态
key_st=1;break; //按键被按下,状态转换到按键确认态
case 1:if(!key_press) //按键确认态
{
key_return = 1; //按键仍按下,按键确认输出为“1”
key_st=2; //状态转换到键释放态
}
else
key_st=0;break; //键已经抬起,转换到按键初始态
case 2:if(key_press)
key_st=0;break; //按键已经释放,转换到按键初始态
}
return key_return;
}
void main()
{
tm0_init(); //调用定时器0的函数,输出10KHZ的方波
tm1_init(); //调用定时器1的函数,输出100KHZ的方波
tm2_init(); //调用定时器2的函数,输出1MHZ的方波
led2 = 0; //将P0^3端口置0,使led2灯发亮
dmchong2 = 1; //将P0^2端口置1,是输出频率为1
while(1)
{
if(flag == 1) //100HZ方波进行的标志位,判断是否已进行了10ms
{
flag = 0; //将100HZ方波的标志位清零
flag2 = key_read(); //进行按键读取,flag2用于接收key_read()函数的返回值
if(flag2 == 1) //返回值如果是1,则按键按下
{
led1 =~led1; //将led1灯的端口取反(刚开始是1)
dmchong1 = ~dmchong1; //将dmchong1的输出端口取反(刚开始是0)
led2 = ~led2; //将led2灯的端口取反(刚开始是0)
dmchong2 = ~dmchong2; //将dmchomg2的输出端口取反(刚开始是1)
}
}
}
}
|
|