1.1 AT24C02功能概述
24C02是一个2K Bit的串行EEPROM存储器,内部含有256个字节。在24C02里面有一个8字节的页写缓冲器。该设备的工作电压为1.8V到6.0V,芯片的第7引脚WP为写保护引脚,将该引脚接地允许正常的读写。
1.2 设备地址
同样AT24C02也是IIC通信在IIC总线上一次可以同时挂载8个该设备通过A0 A1 A2来进行设备的选择
设备地址可以分为固定地址和可编程两部分 其中固定地址为1010
可编程地址的A0 A1 A2在该平台默认接的低电平 所以进行写操作时地址为0xa0 进行读操作时地址为0xa1
1.3 读写操作中的应答信号
在写操作中,24C02每接收一个8位字节后会产生一个应答信号。在读操作中,24C02在发送一个8位数据后会释放SDA线并监视应答信号。一旦收到应答信号,将继续发送数据。如果主机没有发送应答信号,从机则停止发送数据且等待一个停止信号。
1.4 字节写操作
24C02接收完设备地址后,产生应答信号;然后接收8位内存字节地址,产生应答信号,接着接收一个8位数据,产生应答信号;最后主机发送停止信号,字节写操作结束
1.5 页写操作
24C02有一个8字节的页写缓冲器,也就是说可以一次连续写入8个字节到缓冲器,然后由缓冲器一次性写到EEPROM。页写操作初始化与字节写操作相同,只是主机不会在写完第一个数据后就发送停止信号,而是在24C02应答后,接着发送7个数据。
需要注意的是,24C02接收到每个数据后,其字节地址的低3位会自动加1,高位地址不变,维持在当前页内。当内部产生的字节地址到达该页边界时,随后的数据将写入该页的页首,先前的写入的数据将会被覆盖
1.6 当前地址读操作
24C02内部的地址寄存器会保存着上次读/写操作最后一个地址加1的值。只要芯片有电,该地址就一直保存着。如果上次读/写操作的地址为N,那么当前地址读操作就从N+1开始。当读到最后一个字节(即255处),地址会回转到0
1.7 字节读操作
主机首先发送起始信号,接着发送设备地址和它想要读取的数据内存字节地址,执行一个伪写操作。在24C02应答主机之后,主机重新发送起始信号和从设备地址,进行读操作。24C02响应并发送应答信号,然后输出所要求的一个8位字节数据。主机接收完这个8位数据后,产生一个“非应答”信号,最后发送停止条件,字节读操作结束。
1.8 连续读操作
在24C02发送完一个8位字节数据之后,主机产生一个应答信号来响应,告知24C02要求读取更多的数据,直到读完最后一个数据,主机向24C02发送一个“非应答”信号,然后发送一个停止信号,结束此操作。
/********************************************
Date:2022-1-14
Author:小殷同学
Learn From:B 站小蜜蜂老师
*********************************************/
#include "reg52.h"
#include "iic.h"
unsigned char dat1 = 0;
unsigned char dat2 = 0;
unsigned char dat3 = 0;
//共阳数目管段码
//0-f 0xbf代表 -
unsigned char code SMG_Duan[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E,0xbf};
//---------------------------------简单延时函数-------------------------
void Delay(unsigned int t)
{
while(t--);
}
//-------------------------------74HC138初始化---------------------------
void Init_74HC138(unsigned char n)
{
switch(n)
{
case 4:P2 = P2| 0x1f; P2 = 0x80; break;
case 5:P2 = P2| 0x1f; P2 = 0xa0; break;
case 6:P2 = P2| 0x1f; P2 = 0xc0; break;
case 7:P2 = P2| 0x1f; P2 = 0xe0; break;
case 0:P2 = P2| 0X1f; P2 = 0x00; break; //所有锁存器都不选择
}
}
//----------------------------------系统初始化---------------------------
void InitSystem(void)
{
Init_74HC138(5);
P0 = 0x00; //关闭继电器与蜂鸣器
Init_74HC138(4);
P0 = 0xff; //关闭led
}
//---------------------------------数码管安位显示--------------------------
void SMG_DisplayBit(unsigned char pos ,unsigned char dat)
{
Init_74HC138(6);
P0 = 0x01 << pos ;//位选
Init_74HC138(7);
P0 = dat; //段码
}
//-------------------------------关闭所有数码管---------------------------
void SMG_CLOSEALL(unsigned char dat)
{
Init_74HC138(6);
P0 = 0xff; //选中所有数码管
Init_74HC138(7);
P0 = dat; //关闭
}
//----------------------------时间显示函数----------------------------
void Time_Display(void)
{
SMG_DisplayBit(0,SMG_Duan[dat1/10]);
Delay(100);
SMG_DisplayBit(1,SMG_Duan[dat1%10]);
Delay(100);
SMG_DisplayBit(2,SMG_Duan[16]);
Delay(100);
SMG_DisplayBit(3,SMG_Duan[dat2/10]);
Delay(100);
SMG_DisplayBit(4,SMG_Duan[dat2%10]);
Delay(100);
SMG_DisplayBit(5,SMG_Duan[16]);
Delay(100);
SMG_DisplayBit(6,SMG_Duan[dat3/10]);
Delay(100);
SMG_DisplayBit(7,SMG_Duan[dat3%10]);
Delay(100);
SMG_CLOSEALL(0xff);
Delay(100);
}
//---------------------------------24C02写操作-----------------------------
void Write_24C02(unsigned char addr,unsigned char dat)
{
IIC_Start(); //IIC总线起始信号
IIC_SendByte(0xa0); //24C02的写设备地址
IIC_WaitAck(); //等待从机应答
IIC_SendByte(addr); //内存字节字节
IIC_WaitAck(); //等待从机应答
IIC_SendByte(dat); //写入目标数据
IIC_WaitAck(); //等待从机应答
IIC_Stop(); //IIC总线停止信号
}
//---------------------------------24C02读操作-----------------------------
unsigned char Read_24C02(unsigned char addr)
{
unsigned char temp; //存储读取数据
IIC_Start(); //IIC总线起始信号
IIC_SendByte(0xa0); //24C02的写设备地址
IIC_WaitAck(); //等待从机应答
IIC_SendByte(addr); //内存字节字节
IIC_WaitAck(); //等待从机应答
IIC_Start(); //IIC总线起始信号
IIC_SendByte(0xa1); //24C02的读设备地址
IIC_WaitAck(); //等待从机应答
temp = IIC_RecByte(); //读取数据
IIC_SendAck(1); //非应答信号
IIC_Stop(); //IIC总线停止信号
return temp;
}
//--------------------------------24C02读写操作--------------------------
void Read_Write_24C02(void)
{
dat1 = Read_24C02(0x01);
dat2 = Read_24C02(0x03);
dat3 = Read_24C02(0x05);
dat1 += 1;
dat2 += 1;
dat3 += 1;
if(dat1 > 10)
{
dat1 = 0;
}
if(dat2 > 20)
{
dat2 = 0;
}
if(dat3 > 30)
{
dat3 = 0;
}
Write_24C02(0x01,dat1);
Delay(200);
Write_24C02(0x03,dat2);
Delay(200);
Write_24C02(0x05,dat3);
Delay(200);
}
void main(void)
{
InitSystem();
Read_Write_24C02();
while(1)
{
Time_Display();
}
}
#include "reg52.h"
#include "iic.h"
/********************************************
Date:2022-1-15
Author:小殷同学
Learn From:B 站小蜜蜂老师
*********************************************/
//led 灯定义
sbit L1 = P0^0;
sbit L2 = P0^1;
sbit L3 = P0^2;
sbit L4 = P0^3;
sbit L5 = P0^4;
sbit L6 = P0^5;
sbit L7 = P0^6;
sbit L8 = P0^7;
unsigned char Rd1 = 0; //记录光敏实时数值
unsigned char Rd1_old = 0; //记录历史光敏值
unsigned char Level = 0; //记录灯光实时等级
unsigned char Level_old = 0; //记录灯光历史等级
//按键定义
sbit S4 = P3^3;
sbit S5 = P3^2;
//共阳数目管段码
//0-f 0xbf代表 -
unsigned char code SMG_Duan[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E,0xbf};
//---------------------------------简单延时函数-------------------------
void Delay(unsigned int t)
{
while(t--);
}
//-------------------------------74HC138初始化---------------------------
void Init_74HC138(unsigned char n)
{
switch(n)
{
case 4:P2 = P2| 0x1f; P2 = 0x80; break;
case 5:P2 = P2| 0x1f; P2 = 0xa0; break;
case 6:P2 = P2| 0x1f; P2 = 0xc0; break;
case 7:P2 = P2| 0x1f; P2 = 0xe0; break;
case 0:P2 = P2| 0X1f; P2 = 0x00; break; //所有锁存器都不选择
}
}
//----------------------------------系统初始化---------------------------
void InitSystem(void)
{
Init_74HC138(5);
P0 = 0x00; //关闭继电器与蜂鸣器
Init_74HC138(4);
P0 = 0xff; //关闭led
}
//---------------------------------数码管安位显示--------------------------
void SMG_DisplayBit(unsigned char pos ,unsigned char dat)
{
Init_74HC138(6);
P0 = 0x01 << pos ;//位选
Init_74HC138(7);
P0 = dat; //段码
}
//-------------------------------关闭所有数码管---------------------------
void SMG_CLOSEALL(unsigned char dat)
{
Init_74HC138(6);
P0 = 0xff; //选中所有数码管
Init_74HC138(7);
P0 = dat; //关闭
}
//----------------------------光敏数据读取函数----------------------------
void Read_Rd1_Data()
{
IIC_Start(); //IIC起始信号
IIC_SendByte(0x90); //写入设备地址
IIC_WaitAck(); //等待应答
IIC_SendByte(0x01); //写入通道 AIN1
IIC_WaitAck(); //等待应答
IIC_Stop(); //IIC停止信号
IIC_Start(); //IIC起始信号
IIC_SendByte(0x91); //读取设备地址
IIC_WaitAck(); //等待应答
Rd1 = IIC_RecByte(); //读取数据
IIC_SendAck(1); //非应答
IIC_Stop(); //IIC停止信号
}
//--------------------------------光敏等级Led控制---------------------------
/*
等级1:255 <= 光照数据 < 200,L1点亮。
等级2:200 <= 光照数据 < 150,L1~L2点亮。
等级3:150 <= 光照数据 < 100,L1~L4点亮。
等级4:100 <= 光照数据 < 50,L1~L6点亮。
等级5:50 <= 光照数据 < 0,L1~L8点亮。
*/
void Led_Level_Tackle(void)
{
Init_74HC138(4);
Read_Rd1_Data();
if(Rd1 > 200 && Rd1 <= 250)
{
//L1 = 0;
P0 = 0xfe;
Level = 5;
}
else if(Rd1 > 150 && Rd1 <= 200)
{
//L1 = L2 = 0;
P0 = 0xfc;
Level = 4;
}
else if(Rd1 > 100 && Rd1 <= 150)
{
//L1 = L2 = L3 = L4 = 0;
P0 = 0xf0;
Level = 3;
}
else if(Rd1 > 50 && Rd1 <= 100)
{
//L1 = L2 = L3 = L4 = L5 = L6 = 0;
P0 = 0xc0;
Level = 2;
}
else if(Rd1 > 0 && Rd1 <= 50)
{
//L1 = L2 = L3 = L4 = L5 = L6 = L7 = L8 = 0;
P0 = 0x00;
Level = 1;
}
}
//----------------------------------24c02写操作-----------------------------
void Write_24C02(unsigned char addr,unsigned char dat)
{
IIC_Start(); //IIC起始信号
IIC_SendByte(0xa0); //发送设备地址 写操作
IIC_WaitAck(); //等待应答
IIC_SendByte(addr); //发送写单元地址
IIC_WaitAck(); //等待应答
IIC_SendByte(dat); //发送目标数据
IIC_WaitAck(); //等待应答
IIC_Stop(); //IIC停止信号
}
//----------------------------------24c02读操作-------------------------------
unsigned char Read_24C02(unsigned char addr)
{
unsigned char temp; //接收数据变量
IIC_Start(); //IIC起始信号
IIC_SendByte(0xa0); //发送设备地址 写操作
IIC_WaitAck(); //等待应答
IIC_SendByte(addr); //发送写单元地址
IIC_WaitAck(); //等待应答
IIC_Start(); //IIC起始信号
IIC_SendByte(0xa1); //发送设备地址 读操作
IIC_WaitAck(); //等待应答
temp = IIC_RecByte(); //接收数据
IIC_SendAck(1); //非应答
IIC_Stop(); //IIC停止信号
return temp ; //返回数据
}
//----------------------------------数码管数据显示---------------------------
void SMG_Dispaly_New_Data(void)
{
SMG_DisplayBit(0,SMG_Duan[16]);
Delay(200);
SMG_DisplayBit(1,SMG_Duan[Level]);
Delay(200);
SMG_DisplayBit(2,SMG_Duan[16]);
Delay(200);
SMG_DisplayBit(3,0xff);
Delay(200);
SMG_DisplayBit(4,0xff);
Delay(200);
SMG_DisplayBit(5,SMG_Duan[Rd1/100]);
Delay(200);
SMG_DisplayBit(6,SMG_Duan[Rd1/10%10]);
Delay(200);
SMG_DisplayBit(7,SMG_Duan[Rd1%10]);
Delay(200);
}
//显示旧值
void SMG_Dispaly_Old_Data(void)
{
SMG_DisplayBit(0,SMG_Duan[16]);
Delay(200);
SMG_DisplayBit(1,SMG_Duan[Level_old]);
Delay(200);
SMG_DisplayBit(2,SMG_Duan[16]);
Delay(200);
SMG_DisplayBit(3,0xff);
Delay(200);
SMG_DisplayBit(4,0xff);
Delay(200);
SMG_DisplayBit(5,SMG_Duan[Rd1_old/100]);
Delay(200);
SMG_DisplayBit(6,SMG_Duan[Rd1_old/10%10]);
Delay(200);
SMG_DisplayBit(7,SMG_Duan[Rd1_old%10]);
Delay(200);
}
//---------------------------------------按键读写操作------------------------
//按下S4按键将当前的灯光控制等级和光敏电阻的数据保存到存储器24C02的0x01和0x02内存单元中。
// 按下S5按键时,读取存储在24C02的历史数据并显示在数码管上,松开S5按键后,恢复显示实时数据。
void Key_Tackle(void)
{
if(S4 == 0)
{
Delay(20);
if(S4 == 0)
{
Write_24C02(0x01,Level); //写入灯光等级
Delay(200);
Write_24C02(0x02,Rd1); //写入光敏数值
while(S4 == 0)
{
SMG_Dispaly_New_Data(); //实时数据显示
}
}
}
if(S5 == 0)
{
Delay(20);
if(S5 == 0)
{
Level_old = Read_24C02(0x01); //读取灯光等级
Delay(200);
Rd1_old = Read_24C02(0x02); //读取光敏数值
while(S5 == 0)
{
SMG_Dispaly_Old_Data(); //历史数据显示
}
}
}
}
//-------------------------------------主函数----------------------------------
void main(void)
{
InitSystem(); //系统初始化
while(1)
{
Led_Level_Tackle(); //灯光等级获取
SMG_Dispaly_New_Data(); //数码管实时显示
Key_Tackle(); //按键切换
}
}
#include "regx52.h"
#include "absacc.h"
sbit S7 = P3^0;
sbit S4 = P3^3;
unsigned char pwm = 0;
unsigned char pwm_duty = 0;
unsigned char times = 0;
unsigned char led_go = 0;
unsigned char stat_go = 0;
unsigned char stat = 0;
unsigned char key_puse = 0;
unsigned char code SMG_duanma[18]=
{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,
0x88,0x80,0xc6,0xc0,0x86,0x8e,0xbf,0x7f};
void DelaySMG(unsigned int t)
{
while(t--);
}
void DisplaySMG_Bit(unsigned char pos, unsigned char value)
{
XBYTE[0xE000] = 0xff;
XBYTE[0xC000] = 0x01 << pos;
XBYTE[0xE000] = value;
}
void Display_Info(unsigned char pos, unsigned char duty)
{
DisplaySMG_Bit(0, SMG_duanma[pos]);
DelaySMG(500);
DelaySMG(500);
DisplaySMG_Bit(6, SMG_duanma[duty / 10]);
DelaySMG(500);
DisplaySMG_Bit(7, SMG_duanma[duty % 10]);
DelaySMG(500);
DisplaySMG_Bit(0, 0xff);
DisplaySMG_Bit(6, 0xff);
DisplaySMG_Bit(7, 0xff);
}
void Init_Timer0()
{
TMOD = 0x01;
TH0 = (65535 - 1000) / 256;
TL0 = (65535 - 1000) % 256;
ET0 = 1;
EA = 1;
TR0 = 1;
}
void Service_Timer0() interrupt 1
{
TH0 = (65535 - 1000) / 256;
TL0 = (65535 - 1000) % 256;
if(stat_go == 0)
{
XBYTE[0x8000] = 0xe7;
return;
}
pwm++;
if(pwm <= pwm_duty)
{
XBYTE[0x8000] = ~(0x01 << stat);
}
else if(pwm <= 10)
{
XBYTE[0x8000] = 0xff;
}
else
{
XBYTE[0x8000] = ~(0x01 << stat);
pwm = 0;
if(key_puse == 0)
{
times++;
}
}
}
void LED_Control()
{
if(times == 5)
{
times = 0;
if(led_go == 0)
{
pwm_duty = pwm_duty + 1;
if(pwm_duty == 11)
{
pwm_duty = 10;
led_go = 1;
}
}
else if(led_go == 1)
{
pwm_duty = pwm_duty - 1;
if(pwm_duty == 255)
{
pwm_duty = 0;
led_go = 0;
if(stat_go == 1)
{
stat++;
if(stat == 8)
{
stat = 0;
}
}
else if(stat_go == 2)
{
stat--;
if(stat == 255)
{
stat = 7;
}
}
}
}
}
}
void Scan_Keys()
{
if(S4 == 0)
{
DelaySMG(100);
if(S4 == 0)
{
while(S4 == 0)
{
key_puse = 1;
}
key_puse = 0;
stat_go++;
if(stat_go == 3)
{
stat_go = 1;
}
}
}
if(S7 == 0)
{
DelaySMG(100);
if(S7 == 0)
{
while(S7 == 0)
{
key_puse = 1;
Display_Info(stat + 1, pwm_duty * 10);
}
key_puse = 0;
}
}
}
void Init_System()
{
XBYTE[0xA000] = 0xff;
XBYTE[0xA000] = 0x00;
XBYTE[0xE000] = 0xff;
XBYTE[0xC000] = 0xff;
Init_Timer0();
}
void main()
{
Init_System();
while(1)
{
LED_Control();
Scan_Keys();
}
}
#include "reg52.h"
#include "intrins.h"
/********************************************
Date:2022-1-19
Author:小殷同学
Base Learn From:B 站小蜜蜂老师
*********************************************/
sbit TX = P1^0;
sbit RX = P1^1;
unsigned int Time = 0;
unsigned int dis = 0;
#define somenop() {_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();}
//共阳数目管段码
unsigned char month = 0; //定义一个变量让其变化显示
//0-f 0xbf代表 -
unsigned char code SMG_Duan[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E,0xbf};
//---------------------------------简单延时函数-------------------------
void delay(unsigned int t)
{
while(t--);
}
void Delay12us() //@12.000MHz 延时12us
{
unsigned char i;
_nop_();
_nop_();
i = 33;
while (--i);
}
//-------------------------------74HC138初始化---------------------------
void Init_74HC138(unsigned char n)
{
switch(n)
{
case 4:P2 = P2| 0x1f; P2 = 0x80; break;
case 5:P2 = P2| 0x1f; P2 = 0xa0; break;
case 6:P2 = P2| 0x1f; P2 = 0xc0; break;
case 7:P2 = P2| 0x1f; P2 = 0xe0; break;
case 0:P2 = P2| 0X1f; P2 = 0x00; break; //所有锁存器都不选择
}
}
//----------------------------------系统初始化---------------------------
void InitSystem(void)
{
Init_74HC138(5);
P0 = 0x00; //关闭继电器与蜂鸣器
Init_74HC138(4);
P0 = 0xff; //关闭led
}
//---------------------------------数码管安位显示--------------------------
void SMG_DisplayBit(unsigned char pos ,unsigned char dat)
{
Init_74HC138(6);
P0 = 0x01 << pos ;//位选
Init_74HC138(7);
P0 = dat; //段码
}
//-------------------------------关闭所有数码管----------------------
void SMG_CLOSEALL(unsigned char dat)
{
Init_74HC138(6);
P0 = 0xff; //选中所有数码管
Init_74HC138(7);
P0 = dat; //关闭
}
void SMG_Display_Dynamic(void)
{
SMG_DisplayBit(0,0xff);
delay(200);
SMG_DisplayBit(1,0xff);
delay(200);
SMG_DisplayBit(2,0xff);
delay(200);
SMG_DisplayBit(3,0xff);
delay(200);
SMG_DisplayBit(4,0xff);
delay(200);
SMG_DisplayBit(5,SMG_Duan[dis/100]);
delay(200);
SMG_DisplayBit(6,SMG_Duan[dis/10%10]);
delay(200);
SMG_DisplayBit(7,SMG_Duan[dis%10]);
delay(200);
SMG_CLOSEALL();
delay(200);
}
//--------------------------------------发出声波----------------------------------
void SendWave(void)
{
unsigned char i;
for(i = 0; i < 8;i++)
{
TX = 1;
somenop();
TX = 0;
somenop();
}
}
//------------------------------------超声波测距----------------------------------
void Ultrasonic_Dis(void)
{
TMOD &= 0x0f; //定时器1模式0 13位最大值8192
TH1 = 0x00;
TL1 = 0x00;
TF1 = 0; //溢出标志位
TR1 = 0;
SendWave(); //发送声波信号
TR1 = 1;//启动定时
while(RX == 1 && TF1 == 0); //等待超声波信号返回或者等到测量超出范围 返回RX = 0
TR1 = 0;//停止计时
if(TF1 == 1) //溢出了还没有返回信号
{
TF1 = 0;
dis = 999;
}
else
{
//接收到了返回信号 将定时时间合成16位
Time = (TH1 << 8) | TL1; //总时间
//dis = ((Time / 10) * 17) / 100 + 3;
dis = Time * 0.0172;
}
}
//------------------------------------------------------------------------------------
void Delay_SMG( unsigned char t)
{
while(t--)
{
SMG_Display_Dynamic();
}
}
void main(void)
{
InitSystem();
while(1)
{
Ultrasonic_Dis();
Delay_SMG(50);
}
}
#include "reg52.h"
#include "iic.h"
/*****************************************************
*第十三届省赛模拟
*Date:2022-3-27
*Author:小殷
*****************************************************/
//独立按键定义
sbit S7 = P3^0;
sbit S6 = P3^1;
sbit S5 = P3^2;
sbit S4 = P3^3;
//LED定义
sbit LED1 = P0^0;
sbit LED2 = P0^1;
sbit LED3 = P0^2;
sbit LED4 = P0^3;
sbit LED5 = P0^4;
unsigned int Frequent = 0 ,f_data = 0,count = 0,count_flag = 0; //频率相关变量
unsigned int Period = 0; //周期
unsigned int Voltage_Rd1 = 0,Voltage_Rb2 = 0,Voltage = 0; //电压
unsigned int old_voltage = 0,old_frequent = 0;
unsigned char led_flag = 0; //0 代表开启 1 代表关闭
unsigned char channel = 1,interface = 1 ; //通道编号 和显示界面
unsigned char time_flag = 0; //1s标志
unsigned char s7_press = 0,s_count = 0,s7_mode = 0; //按键长按下标志 ,计时变量 模式切换
unsigned char code smg_data[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xbf,0xff};
unsigned char code smg_data_dot[] = {0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
unsigned char led[] = {0xfe,0xfd,0xfb,0xf7,0xef,0xff,0xff,0xff}; //led
void SMG_Display_V(void);
void SMG_Display_F(void);
void SMG_Display_T(void);
/**********************简单延时**********************/
void delay(unsigned char t)
{
while(t--);
}
void delay_smg(unsigned char t)
{
while(t--)
{
if(interface == 1)
{
SMG_Display_F();
}
else if(interface == 2)
{
SMG_Display_T();
}
else if(interface == 3)
{
SMG_Display_V();
}
}
}
/**********************锁存器操作********************/
void Init_74HC138(unsigned char n)
{
switch(n)
{
case 4:P2 = (P2 & 0x1f) | 0x80;break;
case 5:P2 = (P2 & 0x1f) | 0xa0;break;
case 6:P2 = (P2 & 0x1f) | 0xc0;break;
case 7:P2 = (P2 & 0x1f) | 0xe0;break;
case 0:P2 = (P2 & 0x1f) | 0x00;break;
}
}
/*********************数码管安位操作*******************/
void SMG_DisplayBit(unsigned char pos,unsigned char dat)
{
Init_74HC138(6);
P0 = (0x01 << pos);
Init_74HC138(7);
P0 = dat;
Init_74HC138(0);
}
/*************************关闭所有数码管***************/
void SMG_Close(void)
{
Init_74HC138(6);
P0 = 0xff;
Init_74HC138(7);
P0 = 0xff;
Init_74HC138(0);
}
/**********************系统初始化**********************/
void Init_System(void)
{
Init_74HC138(4);
P0 = 0xff;
Init_74HC138(5);
P0 = 0x00;
Init_74HC138(0);
}
/***********************数码管功能显示******************/
void SMG_Display_F(void)
{
SMG_DisplayBit(0,0x8e); // F ->0111 0001 0x8e
delay(200);
if(Frequent > 999999)
{
SMG_DisplayBit(1,smg_data[Frequent/1000000]);
delay(200);
}
if(Frequent > 99999)
{
SMG_DisplayBit(2,smg_data[Frequent/100000%10]);
delay(200);
}
if(Frequent > 9999)
{
SMG_DisplayBit(3,smg_data[Frequent/10000%10]);
delay(200);
}
if(Frequent > 999)
{
SMG_DisplayBit(4,smg_data[Frequent/1000%10]);
delay(200);
}
if(Frequent > 99)
{
SMG_DisplayBit(5,smg_data[Frequent /100%10]);
delay(200);
}
if(Frequent > 9)
{
SMG_DisplayBit(6,smg_data[Frequent /10%10]);
delay(200);
}
SMG_DisplayBit(7,smg_data[Frequent %10]);
delay(200);
SMG_Close();
}
/*****************************周期显示***********************/
void SMG_Display_T(void)
{
Period = 1.0/Frequent *1000000;
SMG_DisplayBit(0,0xc8); // >0001 0011 0xc8
delay(200);
if(Period > 999999)
{
SMG_DisplayBit(1,smg_data[Period/1000000]);
delay(200);
}
if(Period > 99999)
{
SMG_DisplayBit(2,smg_data[Period/100000%10]);
delay(200);
}
if(Period > 9999)
{
SMG_DisplayBit(3,smg_data[Period/10000%10]);
delay(200);
}
if(Period > 999)
{
SMG_DisplayBit(4,smg_data[Period/1000%10]);
delay(200);
}
if(Period > 99)
{
SMG_DisplayBit(5,smg_data[Period /100%10]);
delay(200);
}
if(Period > 9)
{
SMG_DisplayBit(6,smg_data[Period /10%10]);
delay(200);
}
SMG_DisplayBit(7,smg_data[Period %10]);
delay(200);
SMG_Close();
}
/*******************************电压显示**********************/
void SMG_Display_V(void)
{
SMG_DisplayBit(0,0xc1); // >1000 0011 0xc8
delay(200);
SMG_DisplayBit(1,0xbf); // -
delay(200);
SMG_DisplayBit(2,smg_data[channel]);
delay(200);
SMG_DisplayBit(3,0xff);
delay(200);
SMG_DisplayBit(4,0xff);
delay(200);
SMG_DisplayBit(5,smg_data_dot[Voltage/100]);
delay(200);
SMG_DisplayBit(6,smg_data[Voltage/10%10]);
delay(200);
SMG_DisplayBit(7,smg_data[Voltage%10]);
delay(200);
SMG_Close();
delay(200);
}
/******************************定时器初始化******************/
void Init_Timer(void)
{
TMOD = 0x16; //定时器0计数 定时器1 计时
TH0 = 0xff;
TL0 = 0xff;
TH1 = (65535-50000)/256; //50ms
TL1 = (65535-50000)%256;
ET0 = 1;
ET1 = 1;
TR0 = 1;
TR1 = 1;
EA = 1;
}
unsigned char Read_RD1(void)
{
unsigned char temp = 0;
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(0x01); //光敏通道
IIC_WaitAck();
IIC_Stop();
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
temp = IIC_RecByte();
IIC_SendAck(1);
IIC_Stop();
return temp;
}
unsigned char Read_RD2(void)
{
unsigned char temp = 0;
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(0x03); //电位器通道
IIC_WaitAck();
IIC_Stop();
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
temp = IIC_RecByte();
IIC_SendAck(1);
IIC_Stop();
return temp;
}
/***************************按键处理*************************/
void KeyScans(void)
{
if(S4 == 0)
{
delay_smg(20);
if(S4 == 0)
{
while(S4 == 0); //等待按键松开
if(interface == 1)
{
interface = 2;
SMG_Display_F();
}
else if(interface == 2)
{
interface = 3;
SMG_Display_T();
}
else if(interface == 3)
{
interface = 1;
SMG_Display_V();
}
}
}
if(S5 == 0)
{
delay_smg(20);
if(S5 == 0)
{
while(S5 == 0); //等待按键松开
if(channel == 1)
{
channel = 3;
}
else if(channel == 3)
{
channel = 1;
}
}
}
if(S6 == 0)
{
delay_smg(20);
if(S6 == 0)
{
while(S6 == 0); //等待按键松开
old_voltage = Voltage ; //保存旧值
}
}
if(S7 == 0)
{
delay_smg(20);
if(S7 == 0)
{
s7_press = 0; //按键按下标志
s_count = 0;
while(S7 == 0); //等待按键松开
if(s7_press == 1) //长按
{
if(s7_mode == 0) //模式切换变量 第一次长按关闭Led功能 再次长按打开led功能
{
s7_mode = 1;
led_flag = 1; //关闭led功能
}
else if(s7_mode == 1)
{
s7_mode = 0;
led_flag = 0; //打开led功能
}
}
else //短按
{
old_frequent = Frequent; //保存旧值
}
}
}
}
/************************Led操作函数*************************/
void Led_Running(void)
{
if(led_flag == 0)
{
Init_74HC138(4); //选通Y4 进行LED 控制
//通道3的实时电压数据大于缓存电压数据,指示灯L1点亮,否则熄灭
if(Voltage > old_voltage )
{
//P0 = led[0];
LED1 = 0;
}
else
{
LED1 = 1;
}
//实时频率值大于缓存频率数据,指示灯L2点亮,否则熄灭
if(Frequent > old_frequent )
{
//P0 = led[1];
LED2 = 0;
}
else
{
LED2 = 1;
}
//处于频率界面,指示灯L3点亮,否则熄灭
if(interface == 1)
{
//P0 = led[2];
LED3 = 0;
}
else
{
LED3 = 1;
}
//处于周期界面,指示灯L4点亮,否则熄灭。
if(interface == 2)
{
//P0 = led[3];
LED4 = 0;
}
else
{
LED4 = 1;
}
//处于电压界面,指示灯L5点亮,否则熄灭
if(interface == 3)
{
//P0 = led[4];
LED5 = 0;
}
else
{
LED5 = 1;
}
}
else if(led_flag == 1)
{
P0 = 0xff;
Init_74HC138(4);
}
//Init_74HC138(0);
}
/****************************主函数**************************/
void main(void)
{
Init_System();
Init_Timer();
while(1)
{
KeyScans();
switch(interface)
{
case 1:SMG_Display_F();break;
case 2:SMG_Display_T();break;
case 3:SMG_Display_V();break;
}
if(interface == 3)
{
switch(channel)
{
case 1: Voltage_Rd1 = Read_RD1();
Voltage = ( Voltage_Rd1/255.0 *5*100);//将其扩大100倍方便显示
break;
case 3: Voltage_Rb2 = Read_RD2();
Voltage = ( Voltage_Rb2/255.0 *5*100);//将其扩大100倍方便显示
break;
}
}
Led_Running();
}
}
void Server_Timer0() interrupt 1
{
f_data++;
}
void Server_Timer1() interrupt 3
{
TH1 = (65535-50000)/256; //50ms
TL1 = (65535-50000)%256;
count++;
s_count++;
if(count == 20) //1s
{
Frequent = f_data;
f_data = 0;
count = 0;
}
//长按计时
if(s_count == 20)
{
s7_press = 1; //到达1s s7press 置1
}
}
#include "reg52.h"
#include "iic.h"
/**************************************
*第十三届蓝桥杯单片机省赛模拟
*Date:2022-3-29
*Author:小殷
***************************************/
sfr P4 = 0xc0;
sbit H1 = P3^0;
sbit H2 = P3^1;
sbit H3 = P3^2;
sbit H4 = P3^3;
sbit L1 = P3^4;
sbit L2 = P3^5;
sbit L3 = P4^2;
sbit L4 = P4^4;
sbit LED1 = P0^0;
sbit LED2 = P0^1;
unsigned char s_press = 0,s_count = 0; //按键按下标志位和计时
unsigned char count = 0,led_flag = 0; //计时 led标志位
unsigned int count_value = 0,count_value2 = 0;//按键值 和保存值
unsigned char interface = 1; //界面
//数码管段码
unsigned char code smg_data[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,
0x82,0xF8,0x80,0x90,0xbf,0xff};
//1简单延时
void delay(unsigned int t)
{
while(t--);
}
//操作锁存器
void Init_74HC138(unsigned char channel)
{
switch(channel)
{
case 4:P2 = (P2 & 0x1f) | 0x80;break; //Y4
case 5:P2 = (P2 & 0x1f) | 0xa0;break; //Y5
case 6:P2 = (P2 & 0x1f) | 0xc0;break; //Y6
case 7:P2 = (P2 & 0x1f) | 0xe0;break; //Y7
case 0:P2 = (P2 & 0x1f) | 0x00;break; //不选通任何一个
}
P2 = (P2 & 0x1f) | 0x00;
}
//数码管安位操作
void SMG_DisplayBit(unsigned char pos,unsigned char dat)
{
P0 = (0x01 << pos);
Init_74HC138(6);
P0 = dat;
Init_74HC138(7);
}
//操作所有数码管
void SMG_All(unsigned char dat)
{
P0 = 0xff;
Init_74HC138(6);
P0 = dat;
Init_74HC138(7);
}
//显示数码管数据 累加和减的数据
void SMG_Display_Data1(void)
{
//0001 0001 ->0x88
SMG_DisplayBit(0,0x88);
delay(200);
// SMG_DisplayBit(0,0xff);
SMG_DisplayBit(1,0xff);
delay(200);
SMG_DisplayBit(2,0xff);
delay(200);
SMG_DisplayBit(3,0xff);
delay(200);
SMG_DisplayBit(4,0xff);
delay(200);
//3位数码管来显示键值
if(count_value > 99)
{
SMG_DisplayBit(5,smg_data[count_value/100]);
delay(200);
}
if(count_value > 9)
{
SMG_DisplayBit(6,smg_data[count_value/10%10]);
delay(200);
}
SMG_DisplayBit(7,smg_data[count_value%10]);
delay(200);
SMG_All(0xff);
delay(200);
}
//系统初始化
void Init_System(void)
{
P0 = 0xff;
Init_74HC138(4);
P0 = 0x00;
Init_74HC138(5);
SMG_All(0xff);
}
//回显数据显示
void SMG_Display_Data2(void)
{
//1001 0001 ->0x89
SMG_DisplayBit(0,0x89);
delay(200);
// SMG_DisplayBit(0,0xff);
SMG_DisplayBit(1,0xff);
delay(200);
SMG_DisplayBit(2,0xff);
delay(200);
SMG_DisplayBit(3,0xff);
delay(200);
SMG_DisplayBit(4,0xff);
delay(200);
//3位数码管来显示键值
if(count_value > 99)
{
SMG_DisplayBit(5,smg_data[count_value2/100]);
delay(200);
}
if(count_value > 9)
{
SMG_DisplayBit(6,smg_data[count_value2/10%10]);
delay(200);
}
SMG_DisplayBit(7,smg_data[count_value2%10]);
delay(200);
SMG_All(0xff);
delay(200);
}
//EEPROM写操作
void Write_AT24C02(unsigned char addr,unsigned char dat)
{
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(addr);
IIC_WaitAck();
IIC_SendByte(dat);
IIC_WaitAck();
IIC_Stop();
}
//读操作
unsigned char Read_AT24C02(unsigned char addr)
{
unsigned int temp = 0;
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(addr);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0xa1);
IIC_WaitAck();
temp = IIC_RecByte();
IIC_SendAck(1);
IIC_Stop();
return temp;
}
void Key_Scan(void)
{
H3 = 0;
H1 = H2 = H4 = 1;
L1 = L2 = L3 = L4 = 1;
//S9 回显
if(L3 == 0)
{
delay(20);
if(L3 == 0)
{
while(L3 == 0){
if(interface == 1)
{
interface = 2; //界面切换
SMG_Display_Data1();
}
else if(interface == 2)
{
interface = 1;
SMG_Display_Data2();
}
}
}
}
//S5 减
else if(L4 == 0)
{
delay(20);
if(L4 == 0)
{
while(L4 == 0)
{
SMG_Display_Data1();
}
//在计数界面下进行键值的减
if(interface == 1)
{
count_value--;
}
}
}
H4 = 0;
H1 = H2 = H3 = 1;
L1 = L2 = L3 = L4 = 1;
//S8 存储
if(L3 == 0)
{
delay(20);
if(L3 == 0)
{
//每次按下时将计时和标志位清零
s_press = 0;
s_count = 0;
while(L3 == 0)
{
SMG_Display_Data1();
}
if(s_press == 1) //长按标志
{
count_value = 0; //计数清零
}
//短按
else
{
if(interface == 1)
{
//count_value2 = count_value; //保存当前值
Write_AT24C02(0x00,count_value);
}
}
}
}
//S4 加
else if(L4 == 0)
{
delay(20);
if(L4 == 0)
{
while(L4 == 0)
{
SMG_Display_Data1();
}
//在计数界面下 进行键值的累加
if(interface == 1)
{
count_value++;
}
}
}
}
//dac数据
void Read_DAC(float dat)
{
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(0x43);
IIC_WaitAck();
IIC_SendByte(dat);
IIC_WaitAck();
IIC_Stop();
}
//电压显示
void Voltage_Tackle(void)
{
//为5非0 整数倍 DAC->4 ELSE DAC ->1
if((count_value % 5)== 0)
{
Read_DAC(204); //数字转模拟 0-5 ->0-255
//5/255 = 4/x 4x51 = 204
}
else
{
Read_DAC(51);
}
}
void Led_Tackle(void)
{
if(interface == 1)
{
LED1 = 0;
}
else
{
LED1 = 1;
}
if(count_value > count_value2)
{
if(led_flag == 0)
{
LED2 = 0;
}
else if(led_flag == 1)
{
LED2 = 1;
}
}
Init_74HC138(4);
}
void Init_Timer(void)
{
TMOD = 0x01;
TH0 = (65535-50000)/256; //50ms
TL0 = (65535-50000)%256;
ET0 = 1;
TR0 = 1;
EA = 1;
}
//主函数
void main(void)
{
Init_System();
Init_Timer();
while(1)
{
Key_Scan();
switch(interface)
{
case 1:SMG_Display_Data1();break;
case 2:
count_value2 = Read_AT24C02(0x00);
SMG_Display_Data2();break;
}
Led_Tackle();
Voltage_Tackle();
}
}
void Server_Timer0() interrupt 1
{
TH0 = (65535-50000)/256; //50ms
TL0 = (65535-50000)%256;
count++;
s_count++;
if(count == 4) //0.2s 开启led标志位
{
count = 0;
if(led_flag == 0)
{
led_flag = 1;
}
else if(led_flag == 1)
{
led_flag = 0;
}
}
if(s_count == 40) //定时2s
{
s_press = 1; //长按标志位置1 代表已进入长按模式
}
}
一、灯闪烁与数码管计数
#include "reg52.h"
sbit LED1 = P0^0;
sbit LED2 = P0^1;
sbit LED8 = P0^7;
unsigned char led_stat = 0xff;
unsigned char value1 = 0,value2 = 0;
unsigned char code smg_data[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8, 0x80,0x90};
void SMG_Display_Data(void);//1.简单延时
void delay(unsigned int t)
{
while(t--);
}
void Delay_s(unsigned int t)
{
while(t--)
{
SMG_Display_Data(); //在延时期间保持数码管刷新
}
}
//2.锁存器初始化
void Init_74HC138(unsigned char channel)
{
switch(channel)
{
case 4:P2 = (P2 & 0x1f) | 0x80;break;//Y4输出0,LED控制
case 5:P2 = (P2 & 0x1f) | 0xa0;break;//Y5输出0,蜂鸣器和继电器控制
case 6:P2 = (P2 & 0x1f) | 0xc0;break; //Y6输出0,数码管位选
case 7:P2 = (P2 & 0x1f) | 0xe0;break;//Y7输出0,数码管段码
case 0:P2 = (P2 & 0x1f) | 0x00;break;//所有锁存器不选择
}
P2 = (P2 & 0x1f) | 0x00;//所有锁存器不选择
}
//3.数码管安位操作
void SMG_DisplayBit(unsigned char pos,unsigned char dat)
{
P0 = (0x01 << pos); //数码管的段位
Init_74HC138(6);
P0 = dat; //数码管显示内容
Init_74HC138(7);
}
//4.操作所有数码管
void SMG_All(unsigned char dat)
{
P0 = 0xff; //数码管的段位
Init_74HC138(6);
P0 = dat; //数码管显示内容
Init_74HC138(7);
}
//5.系统初始化
void Init_System(void)
{
P0 = 0xff; //关闭所有led
Init_74HC138(4);
P0 = 0x00; //关闭蜂鸣器和继电器
Init_74HC138(5);
SMG_All(0xff); //关闭所有数码管
}
//6.数码管数据显示
void SMG_Display_Data(void)
{
SMG_DisplayBit(0,smg_data[value1]);
delay(200);
SMG_DisplayBit(1,0xff);
delay(200);
SMG_DisplayBit(2,0xff);
delay(200);
SMG_DisplayBit(3,0xff);
delay(200);
SMG_DisplayBit(4,0xff);
delay(200);
SMG_DisplayBit(5,0xff);
delay(200);
SMG_DisplayBit(6,smg_data[value2/10]);
delay(200);
SMG_DisplayBit(7,smg_data[value2%10]);
delay(200);
SMG_All(0xff);
delay(200);
}
//7.led操作
void Led_Tackle(void)
{
led_stat &= ~0x80; //led8电亮
P0 = led_stat;
Init_74HC138(4);
Delay_s(200);
led_stat |= 0x80; //熄灭
P0 = led_stat;
Init_74HC138(4);
Delay_s(200);
value2++;
if(value2 == 100)
{
value2 = 0;
}
//led1 和led2 灯同时翻转
if((led_stat & 0x03) == 0x03)
{
led_stat &= ~0x03;
}
else
{
led_stat |= 0x03;
}
P0 = led_stat;
Init_74HC138(4);
value1++;
if(value1 > 9)
{
value1 = 0;
}
}
void main(void)
{
Init_System();
while(1)
{
Led_Tackle();
SMG_Display_Data();
}
}
二、24C02基本读写操作
#include "reg52.h"
#include "iic.h"
unsigned char dat1,dat2,dat3;
unsigned char code smg_data[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8, 0x80,0x90};
//1.简单延时
void delay(unsigned int t)
{
while(t--);
}
//2.锁存器操作
void Init_74HC138(unsigned char n)
{
switch(n)
{
case 4:P2 = (P2 & 0x1f) | 0x80;break;
case 5:P2 = (P2 & 0x1f) | 0xa0;break;
case 6:P2 = (P2 & 0x1f) | 0xc0;break;
case 7:P2 = (P2 & 0x1f) | 0xe0;break;
case 0:P2 = (P2 & 0x1f) | 0x00;break;
}
P2 = (P2 & 0x1f) | 0x00;
}
//3.数码管安位操作
void SMG_DisplayBit(unsigned char pos,unsigned char dat)
{
P0 = (0x01 << pos);
Init_74HC138(6);
P0 = dat;
Init_74HC138(7);
}
//关闭所有数码管
void SMG_Close(void)
{
P0 = 0xff;
Init_74HC138(6);
P0 = 0xff;
Init_74HC138(7);
}
//4.系统初始化
void Init_System(void)
{
Init_74HC138(0);
P0 = 0x00;
Init_74HC138(5);
P0 = 0xff;
Init_74HC138(4);
}
//5.数码管数据显示
void SMG_Display_Data(void)
{
SMG_DisplayBit(0,smg_data[dat1/10]);
delay(200);
SMG_DisplayBit(1,smg_data[dat1%10]);
delay(200);
SMG_DisplayBit(2,0xbf);
delay(200);
SMG_DisplayBit(3,smg_data[dat2/10]);
delay(200);
SMG_DisplayBit(4,smg_data[dat2%10]);
delay(200);
SMG_DisplayBit(5,0xbf);
delay(200);
SMG_DisplayBit(6,smg_data[dat3/10]);
delay(200);
SMG_DisplayBit(7,smg_data[dat3%10]);
delay(200);
SMG_Close();
delay(200);
}
//6.at24c02数据写
void AT24C02_Write(unsigned char addr,unsigned char dat)
{
IIC_Start(); //起始信号
IIC_SendByte(0xa0); //EEPROM的写设备地址
IIC_WaitAck(); //等待从机应答
IIC_SendByte(addr); //内存单元地址
IIC_WaitAck(); //等待从机应答
IIC_SendByte(dat); //内存写入数据
IIC_WaitAck(); //等待从机应答
IIC_Stop(); //停止信号
}
//7.at24c02数据读
unsigned char AT24C02_Read(unsigned char addr)
{
unsigned char tmp = 0;
//首先,进行一个伪写操作
IIC_Start(); //起始信号
IIC_SendByte(0xa0); //EEPROM的写设备地址
IIC_WaitAck(); //等待从机应答
IIC_SendByte(addr); //内存单元地址
IIC_WaitAck(); //等待从机应答
//然后,开始字节读操作
IIC_Start(); //起始信号
IIC_SendByte(0xa1); //EEPROM的读设备地址
IIC_WaitAck(); //等待从机应答
tmp = IIC_RecByte(); //读取内存中的数据
IIC_SendAck(1); //产生非应答信号
IIC_Stop(); //停止信号
return tmp;
}
//8.数据处理
void Read_Write_Data(void)
{
//先读取数据
dat1 = AT24C02_Read(0x01);
dat2 = AT24C02_Read(0x03);
dat3 = AT24C02_Read(0x05);
dat1 = dat1 +1;
dat2 = dat2 +2;
dat3 = dat3 + 3 ;
if( dat1 > 10)
{
dat1 = 0;
}
if(dat2 > 20)
{
dat2 = 0;
}
if(dat3 > 30)
{
dat3 = 0;
}
//将数据写回去
AT24C02_Write(0x01,dat1);
delay(1000);
AT24C02_Write(0x03,dat2);
delay(1000);
AT24C02_Write(0x05,dat3);
delay(1000);
}
void main(void)
{
Init_System();
Read_Write_Data();
while(1)
{
SMG_Display_Data();
}
}
三、24C02存储按键触发次数
#include "iic.h"
#include "reg52.h"
sbit S6 = P3^1;
sbit S5 = P3^2;
sbit S4 = P3^3;
unsigned char s4_value = 0,s5_value = 0,s6_value = 0;
unsigned char code smg_data[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8, 0x80,0x90};
//1.简单延时
void delay(unsigned int t)
{
while(t--);
}
//2.锁存器初始化
void Init_74HC138(unsigned char channel)
{
switch(channel)
{
case 4:P2 = (P2 & 0x1f) | 0x80;break;
case 5:P2 = (P2 & 0x1f) | 0xa0;break;
case 6:P2 = (P2 & 0x1f) | 0xc0;break;
case 7:P2 = (P2 & 0x1f) | 0xe0;break;
case 0:P2 = (P2 & 0x1f) | 0x00;break;
}
P2 = (P2 & 0x1f) | 0x00;
}
//3.数码管安位操作
void SMG_DisplayBit(unsigned char pos,unsigned char dat)
{
P0 = (0x01 << pos);
Init_74HC138(6);
P0 = dat;
Init_74HC138(7);
}
//4.操作所有数码管
void SMG_All(unsigned char dat)
{
P0 = 0xff;
Init_74HC138(6);
P0 = dat;
Init_74HC138(7);
}
//5.系统初始化
void Init_System(void)
{
P0 = 0xff;
Init_74HC138(4);
P0 = 0x00;
Init_74HC138(5);
SMG_All(0xff);
}
//6.数码管显示数据
void SMG_Display_Data(void)
{
SMG_DisplayBit(0,smg_data[s4_value/10]);
delay(200);
SMG_DisplayBit(1,smg_data[s4_value%10]);
delay(200);
SMG_DisplayBit(2,0xbf);
delay(200);
SMG_DisplayBit(3,smg_data[s5_value/10]);
delay(200);
SMG_DisplayBit(4,smg_data[s5_value%10]);
delay(200);
SMG_DisplayBit(5,0xbf);
delay(200);
SMG_DisplayBit(6,smg_data[s6_value/10]);
delay(200);
SMG_DisplayBit(7,smg_data[s6_value%10]);
delay(200);
SMG_All(0xff);
delay(200);
}
//7.at24c02写数据
void AT24C02_Write(unsigned char addr,unsigned char dat)
{
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(addr);
IIC_WaitAck();
IIC_SendByte(dat);
IIC_WaitAck();
IIC_Stop();
}
//8.at24c04读数据
unsigned char AT24C02_Read(unsigned char addr)
{
unsigned char temp = 0;
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(addr);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0xa1);
IIC_WaitAck();
temp = IIC_RecByte();
IIC_SendAck(1);
IIC_Stop();
return temp;
}
//9.系统上电后,先从24C04存储器的0x00、0x01和0x02这三个地址单元读取数据
void AT24C02_Data_Init(void)
{
s4_value = AT24C02_Read(0x00);
delay(1000);
s5_value = AT24C02_Read(0x01);
delay(1000);
s6_value = AT24C02_Read(0x02);
delay(1000);
}
//10.按键控制
void Key_Scans(void)
{
if(S4 == 0)
{
delay(20);
if(S4 == 0)
{
while(S4 == 0);
s4_value++;
if(s4_value > 13)
{
s4_value = 0;
}
AT24C02_Write(0x00,s4_value);
}
}
if(S5 == 0)
{
delay(20);
if(S5 == 0)
{
while(S5 == 0);
s5_value++;
if(s5_value > 13)
{
s5_value = 0;
}
AT24C02_Write(0x01,s5_value);
}
}
if(S6 == 0)
{
delay(20);
if(S6 == 0)
{
while(S6 == 0);
s6_value++;
if(s6_value > 13)
{
s6_value = 0;
}
AT24C02_Write(0x02,s6_value);
}
}
}
void main(void)
{
Init_System();
AT24C02_Data_Init();
while(1)
{
SMG_Display_Data() ;
Key_Scans();
}
}
四、采样可变电阻电压与光敏电阻电压
#include "iic.h"
#include "reg52.h"
sbit S4 = P3^3;
unsigned char channel = 1;
unsigned int adc_value = 0,adc_volt = 0;
unsigned char code smg_data[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8, 0x80,0x90};
unsigned char code smg_dot[] ={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
//1.简单延时
void delay(unsigned int t)
{
while(t--);
}
//2.锁存器初始化
void Init_74HC138(unsigned char channel)
{
switch(channel)
{
case 4:P2 = (P2 & 0x1f) | 0x80;break;
case 5:P2 = (P2 & 0x1f) | 0xa0;break;
case 6:P2 = (P2 & 0x1f) | 0xc0;break;
case 7:P2 = (P2 & 0x1f) | 0xe0;break;
case 0:P2 = (P2 & 0x1f) | 0x00;break;
}
P2 = (P2 & 0x1f) | 0x00;
}
//数码管安位操作
void SMG_DisplayBit(unsigned char pos,unsigned char dat)
{
P0 = (0x01 << pos);
Init_74HC138(6);
P0 = dat;
Init_74HC138(7);
}
//操作所有数码管
void SMG_All(unsigned char dat)
{
P0 = 0xff;
Init_74HC138(6);
P0 = dat;
Init_74HC138(7);
}
//系统初始化
void Init_System(void)
{
P0 = 0xff;
Init_74HC138(4);
P0 = 0x00;
Init_74HC138(5);
SMG_All(0xff);
}
//数码管数据显示
void SMG_Display_Data(void)
{
SMG_DisplayBit(0,0xbf);
delay(200);
SMG_DisplayBit(1,smg_data[channel]);
delay(200);
SMG_DisplayBit(2,0xbf);
delay(200);
SMG_DisplayBit(3,0xff);
delay(200);
SMG_DisplayBit(4,0xff);
delay(200);
SMG_DisplayBit(5,smg_dot[adc_volt/100]);
delay(200);
SMG_DisplayBit(6,smg_data[adc_volt/10%10]);
delay(200);
SMG_DisplayBit(7,smg_data[adc_volt%10]);
delay(200);
SMG_All(0xff);
delay(200);
}
//PCF8591数据读取
void PCF8591_Read_Data(unsigned char channel)
{
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
if(channel == 1)
{
IIC_SendByte(0x01);
}
else if(channel == 3)
{
IIC_SendByte(0x03);
}
IIC_WaitAck();
IIC_Stop();
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
adc_value = IIC_RecByte();
IIC_SendAck(1);
IIC_Stop();
adc_volt = adc_value * (5.0/255)*100; //扩大100倍方便显示
}
//按键操作
void Key_Tackle(void)
{
if(S4 == 0)
{
delay(20);
if(S4 == 0)
{
while(S4 == 0)
{
if(channel == 1)
{
channel = 3;
}
else if(channel == 3)
{
channel = 1;
}
PCF8591_Read_Data(channel);
SMG_Display_Data();
}
}
}
}
//主函数
void main(void)
{
Init_System();
while(1)
{
Key_Tackle();
PCF8591_Read_Data(channel);
SMG_Display_Data();
}
}
一、按键长按短与短按
#include "reg52.h"
//定义S4按键
sbit S4 = P3^3;
unsigned char t_count = 0,s_press = 0,value =28; //计时,按键长按标志,数值
unsigned char code smg_data[18]={0xc0,0xf9,
0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,
0x88,0x80,0xc6,0xc0,0x86,0x8e,0xbf,0x7f}; //段码
//简单延时
void delay(unsigned int t)
{
while(t--);
}
//锁存器初始化
void Init_74HC138(unsigned char channel)
{
switch(channel)
{
case 4:P2 = (P2 & 0x1f) | 0x80;break;
case 5:P2 = (P2 & 0x1f) | 0xa0;break;
case 6:P2 = (P2 & 0x1f) | 0xc0;break;
case 7:P2 = (P2 & 0x1f) | 0xe0;break;
case 0:P2 = (P2 & 0x1f) | 0x00;break;
}
P2 = (P2 & 0x1f) | 0x00;
}
//操作所有数码管
void SMG_All(unsigned char dat)
{
P0 = 0xff;
Init_74HC138(6);
P0 = dat;
Init_74HC138(7);
}
//数码管安位操作
void SMG_DisplayBit(unsigned char pos,unsigned char dat)
{
P0 = (0x01 << pos);
Init_74HC138(6);
P0 = dat;
Init_74HC138(7);
}
//数码管显示数据
void SMG_Display_Data(void)
{
SMG_DisplayBit(0,0xff);
delay(200);
SMG_DisplayBit(1,0xff);
delay(200);
SMG_DisplayBit(2,0xff);
delay(200);
SMG_DisplayBit(3,0xff);
delay(200);
SMG_DisplayBit(4,0xff);
delay(200);
SMG_DisplayBit(5,0xff);
delay(200);
SMG_DisplayBit(6,smg_data[value/10]);
delay(200);
SMG_DisplayBit(6,0xff);
delay(200);
SMG_DisplayBit(7,smg_data[value%10]);
delay(200);
SMG_DisplayBit(7,0xff);
SMG_All(0xff);
delay(200);
}
//系统初始化
void Init_System(void)
{
P0 = 0xff;
Init_74HC138(4);
P0 = 0x00;
Init_74HC138(5);
SMG_All(0xff);
}
//按键处理
void Key_Scan(void)
{
if(S4 == 0)
{
delay(20);
if(S4 == 0)
{
//这里一定注意要将标志位和计时清零
s_press = 0;
t_count = 0;
while(S4 == 0)
{
SMG_Display_Data();
}
if(s_press == 1) //长按模式
{
value = 0;
}
else //短按模式
{
value++;
if(value > 99)
{
value = 0;
}
}
}
}
}
//定时器初始化
void Init_Timer(void)
{
TMOD = 0x01;
TH0 =(65535-10000)/256; //10ms
TL0 =(65535-10000)%256;
ET0 = 1;
TR0 = 1;
EA = 1;
}
//主函数
void main(void)
{
Init_System();
Init_Timer();
while(1)
{
Key_Scan();
SMG_Display_Data();
}
}
//定时器中断处理
void Server_Timer0() interrupt 1
{
TH0 = (65535-10000)/256;
TL0 = (65535-10000)%256;
t_count++;
if(t_count == 100) //1s
{
s_press = 1; //长按标志
}
}
二、采样光敏与可调电阻电压
#include "reg52.h"
#include "iic.h"
unsigned char rd1_value = 0,rd2_value = 0; //光敏与电阻采样变量
unsigned int smg_value1 = 0,smg_value2 =0; //数码管显示
//不带小数点段码
unsigned char code smg_data[18]={0xc0,0xf9,
0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,
0x88,0x80,0xc6,0xc0,0x86,0x8e,0xbf,0x7f};
//带小数点段码
unsigned char code smg_data_dot[10]={0x40,0x79,
0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
//简单延时
void delay(unsigned int t)
{
while(t--);
}
//锁存器初始化
void Init_74HC138(unsigned char channel)
{
switch(channel)
{
case 4:P2 = (P2 & 0x1f) | 0x80;break;
case 5:P2 = (P2 & 0x1f) | 0xa0;break;
case 6:P2 = (P2 & 0x1f) | 0xc0;break;
case 7:P2 = (P2 & 0x1f) | 0xe0;break;
case 0:P2 = (P2 & 0x1f) | 0x00;break;
}
P2 = (P2 & 0x1f) | 0x00;
}
//数码管安位操作
void SMG_DisplayBit(unsigned char pos,unsigned char dat)
{
P0 = (0x01 << pos);
Init_74HC138(6);
P0 = dat;
Init_74HC138(7);
}
//操作所有数码管
void SMG_All(unsigned char dat)
{
P0 = 0xff;
Init_74HC138(6);
P0 = dat;
Init_74HC138(7);
}
//数码管数据显示
void SMG_Display_V(void)
{
//光敏电压显示
SMG_DisplayBit(0,smg_data_dot[smg_value1/100]);
delay(200);
SMG_DisplayBit(0,0xff);
delay(200);
SMG_DisplayBit(1,smg_data[smg_value1/10%10]);
delay(200);
SMG_DisplayBit(1,0xff);
delay(200);
SMG_DisplayBit(2,smg_data[smg_value1%10]);
delay(200);
SMG_DisplayBit(2,0xff);
delay(200);
SMG_DisplayBit(3,0xff);
delay(200);
SMG_DisplayBit(4,0xff);
delay(200);
//电阻电压显示
SMG_DisplayBit(5,smg_data_dot[smg_value2/100]);
delay(200);
SMG_DisplayBit(5,0xff);
SMG_DisplayBit(6,smg_data[smg_value2/10%10]);
delay(200);
SMG_DisplayBit(6,0xff);
delay(200);
SMG_DisplayBit(7,smg_data[smg_value2%10]);
delay(200);
SMG_DisplayBit(7,0xff);
delay(200);
SMG_All(0xff);
delay(200);
}
//读取光敏数据
void Read_AD1(void)
{
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(0x01);
IIC_WaitAck();
IIC_Stop();
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
rd1_value = IIC_RecByte();
IIC_SendAck(1);
IIC_Stop();
smg_value1 = rd1_value * (5.0/255) * 100;
}
//读取电阻数据
void Read_AD2(void)
{
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(0x03);
IIC_WaitAck();
IIC_Stop();
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
rd2_value = IIC_RecByte();
IIC_SendAck(1);
IIC_Stop();
smg_value2 = rd2_value * (5.0/255) * 100;
}
//系统初始化
void Init_System(void)
{
P0 = 0xff;
Init_74HC138(4);
P0 = 0x00;
Init_74HC138(5);
SMG_All(0xff);
}
//主函数
void main(void)
{
Init_System();
while(1)
{
Read_AD1();
Read_AD2();
SMG_Display_V();
}
}
三、基于PCF8591的DAC模拟电压输出
#include "reg52.h"
#include "iic.h"
sbit S4 = P3^3; //引脚定义
unsigned char mode = 1; //输出模式
unsigned int volt_value = 0,ad_value = 0; //数码管显示电压、采样变量
//不带小数点段码
unsigned char code smg_data[18]={0xc0,0xf9,
0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,
0x88,0x80,0xc6,0xc0,0x86,0x8e,0xbf,0x7f};
//带小数点段码
unsigned char code smg_data_dot[10]={0x40,0x79,
0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
//简单延时
void delay(unsigned int t )
{
while(t--);
}
//锁存器初始化
void Init_74HC138(unsigned char channel)
{
switch(channel)
{
case 4:P2 = (P2 & 0x1f) | 0x80;break;
case 5:P2 = (P2 & 0x1f) | 0xa0;break;
case 6:P2 = (P2 & 0x1f) | 0xc0;break;
case 7:P2 = (P2 & 0x1f) | 0xe0;break;
case 0:P2 = (P2 & 0x1f) | 0x00;break;
}
P2 = (P2 & 0x1f) | 0x00;
}
//数码管安位操作
void SMG_DisplayBit(unsigned char pos,unsigned char dat)
{
P0 = (0x01 << pos);
Init_74HC138(6);
P0 = dat;
Init_74HC138(7);
}
//操作所有数码管
void SMG_All(unsigned char dat)
{
P0 = 0xff;
Init_74HC138(6);
P0 = dat;
Init_74HC138(7);
}
//数码管数据显示
void SMG_Display_Data(void)
{
SMG_DisplayBit(0,0xbf);
delay(200);
SMG_DisplayBit(0,0xff);
delay(200);
SMG_DisplayBit(1,smg_data[mode]);
delay(200);
SMG_DisplayBit(1,0xff);
delay(200);
SMG_DisplayBit(2,0xbf);
delay(200);
SMG_DisplayBit(2,0xff);
delay(200);
SMG_DisplayBit(3,0xff);
delay(200);
SMG_DisplayBit(4,0xff);
delay(200);
SMG_DisplayBit(5,smg_data_dot[volt_value/100]);
delay(200);
SMG_DisplayBit(5,0xff);
delay(200);
SMG_DisplayBit(6,smg_data[volt_value/10%10]);
delay(200);
SMG_DisplayBit(6,0xff);
delay(200);
SMG_DisplayBit(7,smg_data[volt_value%10]);
delay(200);
SMG_DisplayBit(7,0xff);
delay(200);
SMG_All(0xff);
delay(200);
}
//PCF8591数据读取
void Read_ADC(void)
{
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(0x43);
IIC_WaitAck();
IIC_Stop();
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
ad_value = IIC_RecByte();
IIC_SendAck(1);
IIC_Stop();
volt_value = ad_value * (5.0/255)* 100;
}
void Read_DAC(float dat)
{
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(0x43);
IIC_WaitAck();
IIC_SendByte(dat);
IIC_WaitAck();
IIC_Stop();
}
//系统初始化
void Init_System(void)
{
P0 = 0xff;
Init_74HC138(4);
P0 = 0x00;
Init_74HC138(5);
SMG_All(0xff);
}
//按键处理
void Key_Scans(void)
{
if(S4 == 0)
{
delay(20);
if(S4 == 0)
{
while(S4 == 0)
{
SMG_Display_Data();
}
if(mode == 1)
{
mode = 2;
}
else if(mode == 2)
{
mode = 3;
}
else if(mode == 3)
{
mode = 1;
}
}
}
}
//主函数
void main(void)
{
Init_System();
while(1)
{
Key_Scans();
switch(mode)
{
case 1:Read_DAC(102);volt_value = 2*100;break;
case 2:Read_DAC(204);volt_value = 4*100;break;
case 3:Read_ADC();Read_DAC(ad_value);break;
}
SMG_Display_Data();
}
}
#include "reg52.h"
#include "iic.h"
sbit S6 = P3^1;
sbit S5 = P3^2;
sbit S4 = P3^3;
unsigned int adc_volt = 0,volt = 0; //采集电压 和数码管显示变量
unsigned int param_volt = 300,alarm_count = 0;//电压参数 、计数参数
unsigned char alarm_flag = 0,flash_flag = 0;//报警标志 、闪烁标志
unsigned char led_stat = 0xff; //led状态
unsigned int t_count = 0;//计时
unsigned char interface = 0; //界面切换
unsigned char code smg_data[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80};
unsigned char code smg_data_dot[]={0xc0-0x80,0xf9-0x80,0xa4-0x80,0xb0-0x80,0x99-0x80,0x92-0x80,0x82-0x80,0xf8-0x80,0x80-0x80};
void delay(unsigned int t)
{
while(t--);
}
void Init_74HC138(unsigned char channel)
{
switch(channel)
{
case 4:P2 = (P2 & 0x1f) | 0x80;break;
case 5:P2 = (P2 & 0x1f) | 0xa0;break;
case 6:P2 = (P2 & 0x1f) | 0xc0;break;
case 7:P2 = (P2 & 0x1f) | 0xe0;break;
case 0:P2 = (P2 & 0x1f) | 0x00;break;
}
P2 = (P2 & 0x1f) | 0x00;
}
void SMG_All(unsigned char dat)
{
P0 = 0xff;
Init_74HC138(6);
P0 = dat;
Init_74HC138(7);
}
void SMG_DisplayBit(unsigned char pos,unsigned char dat)
{
P0 = (0x01 << pos);
Init_74HC138(6);
P0 = dat;
Init_74HC138(7);
}
void Read_ADC(void)
{
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(0x03);
IIC_WaitAck();
IIC_Stop();
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
adc_volt = IIC_RecByte();
IIC_SendAck(1);
IIC_Stop();
//数据处理
volt = adc_volt * (5.0/255)*100;
}
void SMG_Display_Data(void)
{
SMG_DisplayBit(1,0xff);
delay(200);
SMG_DisplayBit(2,0xff);
delay(200);
SMG_DisplayBit(3,0xff);
delay(200);
SMG_DisplayBit(4,0xff);
delay(200);
if(interface == 0)
{
//U 1000 0011 0xc1
SMG_DisplayBit(0,0xc1);
delay(200);
SMG_DisplayBit(5,smg_data_dot[volt/100]);
delay(200);
SMG_DisplayBit(6,smg_data[volt/10%10]);
delay(200);
SMG_DisplayBit(7,smg_data[volt%10]);
delay(200);
}
else if(interface == 1)
{
//P 0011 0001 0x8c
SMG_DisplayBit(0,0x8c);
delay(200);
SMG_DisplayBit(5,smg_data_dot[param_volt/100]);
delay(200);
SMG_DisplayBit(6,smg_data[param_volt/10%10]);
delay(200);
SMG_DisplayBit(7,smg_data[param_volt%10]);
delay(200);
}
else if(interface == 2)
{
//S
SMG_DisplayBit(0,0x92);
delay(200);
SMG_DisplayBit(5,0xff);
delay(200);
if(alarm_count > 9)
{
SMG_DisplayBit(6,smg_data[alarm_count/10]);
delay(200);
}
SMG_DisplayBit(7,smg_data[alarm_count%10]);
delay(200);
}
SMG_All(0xff);
delay(200);
}
void Key_Scans(void)
{
//S4界面切换
if(S4 == 0)
{
delay(20);
if(S4 == 0)
{
while(S4 == 0)
{
SMG_Display_Data();
}
if(interface == 0)
{
interface = 1;
}
else if(interface == 1)
{
interface = 2;
}
else if(interface == 2)
{
interface = 0;
}
}
}
//电压参数减0.5v每次
if(S5 == 0)
{
delay(20);
if(S5 == 0)
{
while(S5 == 0)
{
SMG_Display_Data();
}
if(interface == 1)
{
param_volt -= 50; //扩大100倍 分别显示处理
if(param_volt == 0)//边界处理
{
//减到最小值后 变成最大
param_volt = 500;
}
}
}
}
//电压参数加0.5v每次
if(S6 == 0)
{
delay(20);
if(S6 == 0)
{
while(S6 == 0)
{
SMG_Display_Data();
}
if(interface == 1)
{
param_volt += 50; //扩大100倍 分别显示处理
if(param_volt == 500)//边界处理
{
//加到最大值后变成最小值
param_volt = 0;
}
}
}
}
}
void Led_Tackle(void)
{
if(volt < param_volt)
{
if(alarm_flag == 0)
{
alarm_flag = 1; //报警标志
}
}
else
{
alarm_flag = 0;
flash_flag = 0;
t_count = 0;
alarm_count = 0;
led_stat |= 0xff;
P0 = led_stat;
Init_74HC138(4);
}
}
void Init_Timer(void)
{
TMOD = 0x01;
TH0 = (65535-50000)/256;
TL0 = (65535-50000)%256;
ET0 = 1;
TR0 = 1;
EA = 1;
}
void Init_System(void)
{
P0 = 0xff;
Init_74HC138(4);
P0 = 0x00;
Init_74HC138(5);
SMG_All(0xff);
}
void main(void)
{
Init_System();
Init_Timer();
while(1)
{
Read_ADC();
Key_Scans();
SMG_Display_Data();
Led_Tackle();
}
}
void Server_Timer0() interrupt 1
{
TH0 = (65535-50000)/256;
TL0 = (65535-50000)%256;
//启动报警
if(alarm_flag == 1)
{
t_count++;
if(t_count % 20 == 0) //1s
{
//还未到达最值计数值
if(alarm_count != 99)
{
alarm_count++;
}
//秒闪标志
if(flash_flag == 1)
{
if(led_stat & 0x80 == 0x80)
{
led_stat &= (~0x80); //点亮L8
}
else
{
led_stat |= 0x80; //熄灭L8
}
}
}
if(t_count > 120) //超过6s
{
led_stat &= (~0x07); //点亮L1 L2 L 3
flash_flag = 1;
}
else if(t_count > 80) //超过4s
{
led_stat &= (~0x03);
}
else if(t_count > 40) //超过2s
{
led_stat &= (~0x01); //L1亮
}
else
{
led_stat = 0xff;//关闭LED
}
P0 = led_stat;
Init_74HC138(4);
}
}
#include "reg52.h"
#include "iic.h"
sbit S5 = P3^2;
sbit S4 = P3^3;
unsigned int temp = 0;
unsigned char led_stat = 0xff; //led 状态
unsigned char adc_volt= 0,old_volt = 0; //电压采集
unsigned int volt = 0; //数码管显示电压
unsigned char old_grade = 0,grade = 0; //灯光等级
//0-9 段码
unsigned char code smg_data[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80};
//0.-9.段码
unsigned char code smg_data_dot[]={0xc0-0x80,0xf9-0x80,0xa4-0x80,0xb0-0x80,0x99-0x80,0x92-0x80,0x82-0x80,0xf8-0x80,0x80-0x80};
//简单延时
void delay(unsigned int t)
{
while(t--);
}
//锁存器初始化
void Init_74HC138(unsigned char channel)
{
switch(channel)
{
case 4:P2 = (P2 & 0x1f) | 0x80;break;
case 5:P2 = (P2 & 0x1f) | 0xa0;break;
case 6:P2 = (P2 & 0x1f) | 0xc0;break;
case 7:P2 = (P2 & 0x1f) | 0xe0;break;
case 0:P2 = (P2 & 0x1f) | 0x00;break;
}
P2 = (P2 & 0x1f) | 0x00;
}
//操作所有数码管
void SMG_All(unsigned char dat)
{
P0 = 0xff;
Init_74HC138(6);
P0 = dat;
Init_74HC138(7);
}
//数码管安位操作
void SMG_DisplayBit(unsigned char pos,unsigned char dat)
{
P0 = (0x01 << pos);
Init_74HC138(6);
P0 = dat;
Init_74HC138(7);
}
//数码管数据显示
void SMG_Display_V(void)
{
SMG_DisplayBit(0,0xbf);
delay(200);
SMG_DisplayBit(1,smg_data[grade]);
delay(200);
SMG_DisplayBit(2,0xbf);
delay(200);
SMG_DisplayBit(3,0xff);
delay(200);
SMG_DisplayBit(4,0xff);
delay(200);
SMG_DisplayBit(5,smg_data_dot[volt/100]);
delay(200);
SMG_DisplayBit(6,smg_data[volt/10%10]);
delay(200);
SMG_DisplayBit(7,smg_data[volt%10]);
delay(200);
SMG_All(0xff);
delay(200);
}
//读取光敏通道电压
void Read_ADC(void)
{
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(0x01);
IIC_WaitAck();
IIC_Stop();
SMG_Display_V();
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
adc_volt = IIC_RecByte();
IIC_SendAck(1);
IIC_Stop();
//数据处理
volt = adc_volt * (5.0/255)*100;
SMG_Display_V();
}
//灯光控制
void Led_Working(void)
{
Read_ADC();
//等级0 全部灯熄灭
if(volt <= 500 && volt > 450)
{
grade = 0;
led_stat = 0xff;
}
//等级1 L1 点亮
else if(volt <= 450 && volt > 400)
{
grade = 1;
led_stat = 0xfe;
}
//等级2 L1-L2 亮
else if(volt <= 400 && volt > 350)
{
grade = 2;
led_stat = 0xfc;
}
//等级3 L1-L3 亮
else if(volt <= 350 && volt > 300)
{
grade = 3;
led_stat = 0xf8;
}
//等级4 L1-L4 点亮
else if(volt <= 300 && volt > 250)
{
grade = 4;
led_stat = 0xf0;
}
//等级5 L1- L5 亮
else if(volt <= 250 && volt > 200)
{
grade = 5;
led_stat = 0xe0;
}
//等级6 L1-L6 亮
else if(volt <= 200 && volt > 150)
{
grade = 6;
led_stat = 0xc0;
}
//等级7 L1-L7 亮
else if(volt <= 150 && volt > 100)
{
grade = 7;
led_stat = 0x80;
}
//等级8 L1-L8 亮
else if(volt <= 50 && volt > 0)
{
grade = 8;
led_stat = 0x00;;
}
P0 = led_stat;
Init_74HC138(4);
}
//AT24C02处理
void Write_AT24C02(unsigned char addr,unsigned char dat)
{
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(addr);
IIC_WaitAck();
IIC_SendByte(dat);
IIC_WaitAck();
IIC_Stop();
}
//读AT24C02
unsigned int Read_AT24C02(unsigned char addr)
{
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(addr);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0xa1);
IIC_WaitAck();
temp = IIC_RecByte();
IIC_SendAck(1);
IIC_Stop();
return temp;
}
//保存当前数据
void Save_To_24C02(void)
{
Write_AT24C02(0x01,grade);
SMG_Display_V();
Write_AT24C02(0x02,volt);
SMG_Display_V();
}
//读取历史数据
void Read_From_24c02(void)
{
old_grade = Read_AT24C02(0x01);
delay(500);
old_volt = Read_AT24C02(0x02);
delay(500);
grade = old_grade;
volt = old_volt;
}
//按键处理
void Key_Scans(void)
{
if(S4 == 0)
{
delay(20);
if(S4 == 0)
{
Save_To_24C02();
while(S4 == 0)
{
Led_Working();
}
}
}
if(S5 == 0)
{
delay(20);
if(S5 == 0)
{
//关闭所有灯光
led_stat = 0xff;
P0 = led_stat;
Init_74HC138(4);
//读取数据
Read_From_24c02();
while(S5 == 0)
{
SMG_Display_V();
}
}
}
}
//系统初始化
void Init_System(void)
{
P0 = 0xff;
Init_74HC138(4);
P0 = 0x00;
Init_74HC138(5);
SMG_All(0xff);
}
//主函数
void main(void)
{
Init_System();
while(1)
{
Led_Working();
Key_Scans();
}
}
#include "reg52.h"
#include "iic.h"
/******************************************************************
*第十三届蓝桥杯省赛软件部分实现 *
*Author:小殷童鞋 *
*Date:2022-12-13 *
*******************************************************************/
sbit S4 = P3^3;
sbit S5 = P3^2;
sbit S6 = P3^1;
sbit S7 = P3^0;
unsigned int f_count = 0,count = 0,period = 0; //频率 显示频率 周期变量
unsigned char Rd_Data = 0,Rd_Volt = 0, channel = 1; //通道模拟数据 电压 和通道变量
unsigned char interface = 1; //界面
unsigned int old_volt = 0,old_f = 0; //缓存电压和频率
unsigned char long_press_flag = 0,t_count = 0,press_count = 0; //长按标志 计时 长按次数变量
unsigned char led_flag = 1,led_status = 0xff,old_led_status = 0xff;//led启动标志 led状态 led旧状态变量
//共阳
unsigned char code SMG_Duan[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E,0xbf}; //数码管段码
unsigned char code smg_dot[] ={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10}; //带小数点
//简单延时
void delay(unsigned int t)
{
while(t--);
}
//744HC138初始化
void Init_74HC138(unsigned char dat)
{
switch(dat)
{
case 4:P2 = (P2 & 0x1f) | 0x80;break;
case 5:P2 = (P2 & 0x1f) | 0xa0;break;
case 6:P2 = (P2 & 0x1f) | 0xc0;break;
case 7:P2 = (P2 & 0x1f) | 0xe0;break;
case 0:P2 = (P2 & 0x1f) | 0x00;break;
}
P2 = (P2 & 0x1f) | 0x00;
}
//数码管按位操作
void SMG_DisplayByBit(unsigned char pos,unsigned char dat)
{
P0 = (0x01 << pos);
Init_74HC138(6);
P0 = dat;
Init_74HC138(7);
}
//操作所有数码管
void Controal_All_SMG(unsigned char dat)
{
P0 = 0xff;
Init_74HC138(6);
P0 = dat;
Init_74HC138(7);
}
//数码管数据显示频率
void SMG_Display_Frequent(void)
{
SMG_DisplayByBit(0,SMG_Duan[15]);
delay(200);
if(count > 999999)
{
SMG_DisplayByBit(1,SMG_Duan[count/1000000]);
delay(200);
}
if(count > 99999)
{
SMG_DisplayByBit(2,SMG_Duan[count/100000%10]);
delay(200);
}
if(count > 9999)
{
SMG_DisplayByBit(3,SMG_Duan[count/10000%10]);
delay(200);
}
if(count > 999)
{
SMG_DisplayByBit(4,SMG_Duan[count/1000%10]);
delay(200);
}
if(count > 99)
{
SMG_DisplayByBit(5,SMG_Duan[count/100%10]);
delay(200);
}
if(count > 9)
{
SMG_DisplayByBit(6,SMG_Duan[count/10%10]);
delay(200);
}
SMG_DisplayByBit(7,SMG_Duan[count%10]);
delay(200);
Controal_All_SMG(0xff);
delay(200);
}
//周期显示
void SMG_Display_Period(void)
{
SMG_DisplayByBit(0,~0x37);
delay(200);
if(count > 999999)
{
SMG_DisplayByBit(1,SMG_Duan[period/1000000]);
delay(200);
}
if(count > 99999)
{
SMG_DisplayByBit(2,SMG_Duan[period/100000%10]);
delay(200);
}
if(count > 9999)
{
SMG_DisplayByBit(3,SMG_Duan[period/10000%10]);
delay(200);
}
if(count > 999)
{
SMG_DisplayByBit(4,SMG_Duan[period/1000%10]);
delay(200);
}
if(count > 99)
{
SMG_DisplayByBit(5,SMG_Duan[period/100%10]);
delay(200);
}
if(count > 9)
{
SMG_DisplayByBit(6,SMG_Duan[period/10%10]);
delay(200);
}
SMG_DisplayByBit(7,SMG_Duan[period%10]);
delay(200);
Controal_All_SMG(0xff);
delay(200);
}
//PCF8591电压采集
void PCF8591_Volt_Rd1(unsigned char channel)
{
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
if(channel == 1)
{
IIC_SendByte(0x01); //光敏
}
else if(channel == 3)
{
IIC_SendByte(0x03); //电压
}
IIC_WaitAck();
IIC_Stop();
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
Rd_Data = IIC_RecByte();
IIC_SendAck(1);
IIC_Stop();
Rd_Volt = Rd_Data * (5.0/255) * 100; //扩大100倍方便显示
}
//数码管电压显示数据
void SMG_Display_Volt(void)
{
SMG_DisplayByBit(0,~0x3e);
delay(200);
SMG_DisplayByBit(1,0xbf);
delay(200);
SMG_DisplayByBit(2,SMG_Duan[channel]); //通道编号
delay(200);
SMG_DisplayByBit(3,0xff);
delay(200);
SMG_DisplayByBit(4,0xff);
delay(200);
SMG_DisplayByBit(5,smg_dot[Rd_Volt/100]); //电压
delay(200);
SMG_DisplayByBit(6,SMG_Duan[Rd_Volt/10%10]);
delay(200);
SMG_DisplayByBit(7,SMG_Duan[Rd_Volt%10]);
delay(200);
Controal_All_SMG(0xff);
delay(200);
}
//按键控制
void Key_Scans(void)
{
if(S4 == 0)
{
delay(20);
if(S4 == 0)
{
while(S4 == 0)
{
//在按键一直按下时 避免数码管熄灭 根据相应的界面显示相应的数据
if(interface == 1)
{
SMG_Display_Frequent();
}
else if(interface == 2)
{
SMG_Display_Period();
}
else if(interface == 3)
{
SMG_Display_Volt();
}
}
if(interface == 1)
{
interface = 2;
}
else if(interface == 2)
{
interface = 3;
}
else if(interface == 3)
{
interface = 1;
}
}
}
if(interface == 3)
{
//S5通道切换
if(S5 == 0)
{
delay(20);
if(S5 == 0)
{
while(S5 == 0)
{
PCF8591_Volt_Rd1(channel);
SMG_Display_Volt();
}
if(channel == 1)
{
channel = 3;
}
else if(channel == 3)
{
channel = 1;
}
}
}
}
//S6缓存channel 电压
if(S6 == 0)
{
delay(20);
if(S6 == 0)
{
t_count = 0;
long_press_flag = 0;
while(S6 == 0)
{
//在按键一直按下时 避免数码管熄灭 根据相应的界面显示相应的数据
if(interface == 1)
{
SMG_Display_Frequent();
}
else if(interface == 2)
{
SMG_Display_Period();
}
else if(interface == 3)
{
SMG_Display_Volt();
}
if(long_press_flag == 1) //长按
{
if(press_count == 0)
{
press_count = 1;
led_flag = 0; //禁用LED 全部熄灭
old_led_status = led_status; //缓存Led状态
P0 = 0xff;
Init_74HC138(4);
}
else if(press_count == 1)
{
//恢复LED功能
press_count = 0;
led_status = old_led_status; //将缓存的LED状态重新赋值给led_status
led_flag = 1; //启用LED功能
}
}
else{
if(channel == 3)
{
old_volt = Rd_Volt;
}
}
}
}
}
//S7缓存频率
if(S7 == 0)
{
delay(20);
if(S7 == 0)
{
while(S7 == 0)
{
//在按键一直按下时 避免数码管熄灭 根据相应的界面显示相应的数据
if(interface == 1)
{
SMG_Display_Frequent();
}
else if(interface == 2)
{
SMG_Display_Period();
}
else if(interface == 3)
{
SMG_Display_Volt();
}
}
old_f = count; //将实时采集的频率count的值缓存到old_f变量中
}
}
}
//定时器初始化
void Init_Timer(void)
{
TMOD = 0x16; //定时器0计数 定时器1定时
TH0 = 0xff;
TL0 = 0xff;
TH1 = (65535 - 50000)/256; //高八位50ms
TL1 = (65535 - 50000)%256;
ET0 = 1;
ET1 = 1;
TR0 = 1;
TR1 = 1;
EA = 1;
}
//系统初始化
void Init_System(void)
{
Init_74HC138(0);
Controal_All_SMG(0xff);
P0 = 0xff;
Init_74HC138(4);
P0 = 0x00;
Init_74HC138(5);
}
//主函数
void main(void)
{
Init_System(); //系统初始化
Init_Timer(); //定时器初始化
while(1)
{
PCF8591_Volt_Rd1(channel);
Key_Scans();
switch(interface)
{
case 1:SMG_Display_Frequent();break;
case 2:SMG_Display_Period();break;
case 3:SMG_Display_Volt();break;
}
if(led_flag == 1)
{
if(old_volt < Rd_Volt) //L1 open
{
led_status = 0xfe; //0111 1111
}
if(old_f < count)
{
led_status &= 0xfd; //1011 1111
}
if(interface == 1)
{
led_status &= 0xfb; //1101 1111
}
if(interface == 2)
{
led_status &= 0xf7; //1110 1111
}
if(interface == 3)
{
led_status &= 0xef; //1111 0111
}
P0 = led_status;
Init_74HC138(4);
}
}
}
void Timer0_Server() interrupt 1
{
f_count++;
}
void Timer1_Server() interrupt 3
{
static unsigned char t = 0;
TH1 = (65535 - 50000)/256; //高八位50ms
TL1 = (65535 - 50000)%256;
t++;
t_count++;
if(t == 20) //1s
{
count = f_count;
period = (1.0/count) * 1000000;
f_count = 0;
t = 0;
}
if(t_count >= 20) //超过或等于1s
{
long_press_flag = 1;
}
}