【冉冰的成长日记004】
这届题挺简单的,前提是会555的情况下,估计当年考试的学长们心态都崩了,hhhh
我稍稍解释一下555定时器,先让TMOD =0x06,设为计数模式,然后给TH0和TL0值0xFF,,意思是每当有高低电平变化时就让定时器0里的HZ_flag++,定时器1计时1s然后将HZ_flag内的值赋给HZ显示出来。理解555的作用的话应该能明白我说的内容吧
赋两个链接,不懂的话看看吧
‘
555定时器,小蜜蜂老师课程(b站视频)
同上,视频内容的代码
下边这篇,是同届大佬写的,网站上有很多内容,可以看看
点开它,看看吧(点我点我)
看代码吧
#include<STC15F2K60S2.h>
#include<iic.h>
sbit S7=P3^0;
sbit S6=P3^1;
sbit S5=P3^2;
sbit S4=P3^3;
unsigned char code LED[]={0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90,0xFF ,0x8E, 0xC1,
0x40, 0x79, 0x24, 0x30, 0x19, 0x12, 0x02, 0x78, 0x00, 0x10
};//数码管
unsigned char LEDbuff[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }; //数码管缓冲区
unsigned long HZ=0,HZ_flag=0; //频率获取
unsigned int cnt_HZ=0,cnt_V=0,V=0;//中断计时,HZ表示当前频率
unsigned char AD=0; //AD获取
bit check_S7=1,check_S6=1,check_S5=1,check_S4=1,Display_flag=1,DAC_flag=0,LED_flag=1,LED_OF=0,SEG_flag=1;//check用来按键消抖
void Timer0Init(); //定时器0,1ms
void Timer1Init(); //定时器1,1ms
void Initial(); //模块初始化
void KEY(); //按键模块,包括S7.S6.S5.S4
void Display(); //数码管模块
void delay(unsigned int x); //延时函数
void DAC(); //电压计算
void main()
{
Timer0Init();
Timer1Init();
Initial(); //初始化函数
AD_Init(); //AD初始化
while(1)
{
if(cnt_V>=500)
{
cnt_V=0;
AD=AD_Get(); //AD值读取
delay(10); //延时一会,否则ad显示会乱跳
DAC_Init(AD); //dac输出
DAC();
}
Display();
KEY();
}
}
void delay(unsigned int x) //延时函数,ms单位
{
int X=0,Y=0;
for(X=0;X<x;X++)
{
for(Y=846;Y>0;Y--);
}
}
void Initial() //初始化函数
{
P2 = (P2&0x1F)|0x80;
P0 = 0xFF; //初始化LED
P2 = (P2&0x1F)|0xA0;
P0 = 0x00; //初始化继电器和蜂鸣器
P2 = (P2&0x1F)|0xC0;
P0 = 0xFF;
P2 = (P2&0x1F)|0xE0;
P0 = 0xFF; //初始化数码管
}
void Timer0Init(void) //计数
{
TMOD = 0x06;
TL0 = TH0 = 0xFF;
ET0 = 1;
TR0 = 1;
EA = 1;
}
void Timer1Init(void) //1毫秒@12.000MHz
{
// AUXR &= 0xBF; //定时器时钟12T模式
// TMOD &= 0x0F; //设置定时器模式
TL1 = 0x18; //设置定时初值
TH1 = 0xFC; //设置定时初值
TF1 = 0; //清除TF1标志
TR1 = 1; //定时器1开始计时
EA=1;
ET1 = 1;
}
void DAC()
{
if(DAC_flag==1)
{
DAC_Init(AD);
V = AD*2-10;
if(AD<=5) V=0;
}
if(DAC_flag==0) {V=200; DAC_Init(102);}
}
void Display_1() //频率显示界面
{
LEDbuff[7] = LED[11];
LEDbuff[6] = LED[10];
if(HZ>99999)
{LEDbuff[5] = LED[HZ/100000%10];
LEDbuff[4] = LED[HZ/10000%10];
LEDbuff[3] = LED[HZ/1000%10];
LEDbuff[2] = LED[HZ/100%10];
LEDbuff[1] = LED[HZ/10%10];
LEDbuff[0] = LED[HZ%10];}
if(HZ>9999&&HZ<99999)
{LEDbuff[5] =LED[10];
LEDbuff[4] = LED[HZ/10000%10];
LEDbuff[3] = LED[HZ/1000%10];
LEDbuff[2] = LED[HZ/100%10];
LEDbuff[1] = LED[HZ/10%10];
LEDbuff[0] = LED[HZ%10];}
if(HZ>999&&HZ<9999)
{LEDbuff[5] =LED[10];
LEDbuff[4] =LED[10];
LEDbuff[3] = LED[HZ/1000%10];
LEDbuff[2] = LED[HZ/100%10];
LEDbuff[1] = LED[HZ/10%10];
LEDbuff[0] = LED[HZ%10];}
if(HZ>99&&HZ<999)
{LEDbuff[5] =LED[10];
LEDbuff[4] =LED[10];
LEDbuff[3] =LED[10];
LEDbuff[2] = LED[HZ/100%10];
LEDbuff[1] = LED[HZ/10%10];
LEDbuff[0] = LED[HZ%10];}
if(HZ>9&&HZ<99)
{LEDbuff[5] =LED[10];
LEDbuff[4] =LED[10];
LEDbuff[3] =LED[10];
LEDbuff[2] =LED[10];
LEDbuff[1] = LED[HZ/10%10];
LEDbuff[0] = LED[HZ%10];
}
if(HZ<9)
{LEDbuff[5] =LED[10];
LEDbuff[4] =LED[10];
LEDbuff[3] =LED[10];
LEDbuff[2] =LED[10];
LEDbuff[1] = LED[10];
LEDbuff[0] = LED[HZ%10];
}
}
void Display_2() //电压显示界面
{
LEDbuff[7] = LED[12];
LEDbuff[6] = LED[10];
LEDbuff[5] = LED[10];
LEDbuff[4] = LED[10];
LEDbuff[3] = LED[10];
LEDbuff[2] = LED[V/100 + 13]; //其实可以用加0x80的方式点亮小数点,,,我写麻烦了
LEDbuff[1] = LED[V/10%10];
LEDbuff[0] = LED[V%10];
}
void Display_3()
{
LEDbuff[7] = LED[10];
LEDbuff[6] = LED[10];
LEDbuff[5] = LED[10];
LEDbuff[4] = LED[10];
LEDbuff[3] = LED[10];
LEDbuff[2] = LED[10];
LEDbuff[1] = LED[10];
LEDbuff[0] = LED[10];
}
void Display()
{
if(SEG_flag==1)
{ if(Display_flag==0) Display_1();
if(Display_flag==1) Display_2();}
if(SEG_flag==0) Display_3();
}
void LED_1()
{
if(LED_flag==1)
{
EA=0;
if(LED_OF==0&&DAC_flag==0) //电压模式,L1亮
{
if(V<150||(V>=250&&V<350))
{P2 = (P2&0x1F)|0x80;P0 = 0xFE;P2=0x00;}
if(V>=350||(V>=150&&V<250))
{P2 = (P2&0x1F)|0x80;P0 = 0xFA;P2=0x00;}
}
if(LED_OF==1) //频率模式,L2亮
{
if(HZ<1000||(HZ>=5000&&HZ<10000))
{P2 = (P2&0x1F)|0x80;P0 = 0xFD;P2=0x00;}
if(HZ>=10000||(HZ<=5000&&HZ>1000))
{P2 = (P2&0x1F)|0x80;P0 = 0xF5;P2=0x00;}
}
if(LED_OF==0&&DAC_flag==1) //电压模式,L1亮
{
if(V<150||(V>=250&&V<350))
{P2 = (P2&0x1F)|0x80;P0 = 0xEE;P2=0x00;}
if(V>=350||(V>=150&&V<250))
{P2 = (P2&0x1F)|0x80;P0 = 0xEA;P2=0x00;}
}
EA=1;
}
if(LED_flag==0)
{P2 = (P2&0x1F)|0x80;P0 = 0xFF;}
}
void KEY_S7()
{
if(S7 != check_S7)
{
if(check_S7==0)
{
SEG_flag = ~ SEG_flag;
}
check_S7 = S7;
}
}
void KEY_S6()
{
if(S6 != check_S6)
{
if(check_S6==0)
{
LED_flag = ~LED_flag;
}
check_S6=S6;
}
}
void KEY_S5()
{
if(S5 != check_S5)
{
if(check_S5==0)
{
DAC_flag = ~DAC_flag;
}
check_S5=S5;
}
}
void KEY_S4()
{
if(S4 != check_S4)
{
if(check_S4==0)
{
Display_flag = ~Display_flag;
LED_OF = ~LED_OF;
}
check_S4=S4;
}
}
void KEY()
{
KEY_S4();
KEY_S5();
KEY_S6();
KEY_S7();
}
void InterruptTimer0() interrupt 1
{
TL0 = TH0 = 0xFF;
HZ_flag++;
}
void InterruptTimer1() interrupt 3
{
static unsigned char i=0;
TL1 = 0x18; //设置定时初值
TH1 = 0xFC; //设置定时初值
switch(i)
{
case 0:P2 = 0xC0;P0=0x80;P2=0xE0;P0=LEDbuff[0];P2=0x00;i++;break;
case 1:P2 = 0xC0;P0=0x40;P2=0xE0;P0=LEDbuff[1];P2=0x00;i++;break;
case 2:P2 = 0xC0;P0=0x20;P2=0xE0;P0=LEDbuff[2];P2=0x00;i++;break;
case 3:P2 = 0xC0;P0=0x10;P2=0xE0;P0=LEDbuff[3];P2=0x00;i++;break;
case 4:P2 = 0xC0;P0=0x08;P2=0xE0;P0=LEDbuff[4];P2=0x00;i++;break;
case 5:P2 = 0xC0;P0=0x04;P2=0xE0;P0=LEDbuff[5];P2=0x00;i++;break;
case 6:P2 = 0xC0;P0=0x02;P2=0xE0;P0=LEDbuff[6];P2=0x00;i++;break;
case 7:P2 = 0xC0;P0=0x01;P2=0xE0;P0=LEDbuff[7];P2=0x00;i=0;break;
default : break;
}
cnt_V++;cnt_HZ++;
if(cnt_HZ>=1000){HZ=HZ_flag;cnt_HZ=0;HZ_flag=0;} //每1秒获取一次555定时器的变化频率
LED_1();
}
main.c
/*
程序说明: IIC总线驱动程序
软件环境: Keil uVision 4.10
硬件环境: CT107单片机综合实训平台 8051,12MHz
日 期: 2011-8-9
*/
#include<STC15F2K60S2.h>
#include "intrins.h"
#define DELAY_TIME 5
#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1
//总线引脚定义
sbit SDA = P2^1; /* 数据线 */
sbit SCL = P2^0; /* 时钟线 */
void IIC_Delay(unsigned char i)
{
do{_nop_();}
while(i--);
}
//总线启动条件
void IIC_Start(void)
{
SDA = 1;
SCL = 1;
IIC_Delay(DELAY_TIME);
SDA = 0;
IIC_Delay(DELAY_TIME);
SCL = 0;
}
//总线停止条件
void IIC_Stop(void)
{
SDA = 0;
SCL = 1;
IIC_Delay(DELAY_TIME);
SDA = 1;
IIC_Delay(DELAY_TIME);
}
//发送应答
void IIC_SendAck(bit ackbit)
{
SCL = 0;
SDA = ackbit; // 0:应答,1:非应答
IIC_Delay(DELAY_TIME);
SCL = 1;
IIC_Delay(DELAY_TIME);
SCL = 0;
SDA = 1;
IIC_Delay(DELAY_TIME);
}
//等待应答
bit IIC_WaitAck(void)
{
bit ackbit;
SCL = 1;
IIC_Delay(DELAY_TIME);
ackbit = SDA;
SCL = 0;
IIC_Delay(DELAY_TIME);
return ackbit;
}
//通过I2C总线发送数据
void IIC_SendByte(unsigned char byt)
{
unsigned char i;
for(i=0; i<8; i++)
{
SCL = 0;
IIC_Delay(DELAY_TIME);
if(byt & 0x80) SDA = 1;
else SDA = 0;
IIC_Delay(DELAY_TIME);
SCL = 1;
byt <<= 1;
IIC_Delay(DELAY_TIME);
}
SCL = 0;
}
//从I2C总线上接收数据
unsigned char IIC_RecByte(void)
{
unsigned char i, da;
for(i=0; i<8; i++)
{
SCL = 1;
IIC_Delay(DELAY_TIME);
da <<= 1;
if(SDA) da |= 1;
SCL = 0;
IIC_Delay(DELAY_TIME);
}
return da;
}
void AD_Init() //AD初始化
{
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(0x43);
IIC_WaitAck();
IIC_Stop();
}
unsigned char AD_Get() //AD获取
{
unsigned char temp=0;
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
temp = IIC_RecByte();
IIC_Stop();
return temp;
}
void DAC_Init(unsigned char dat) //DAC获取
{
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(0x43);
IIC_WaitAck();
IIC_SendByte(dat);
IIC_WaitAck();
IIC_Stop();
}
iic.c
#ifndef _IIC_H
#define _IIC_H
void IIC_Start(void);
void IIC_Stop(void);
bit IIC_WaitAck(void);
void IIC_SendAck(bit ackbit);
void IIC_SendByte(unsigned char byt);
unsigned char IIC_RecByte(void);
void AD_Init();
unsigned char AD_Get();
void DAC_Init(unsigned char dat);
#endif
iic.h
4.13修改DAC输出