练习题目来自小蜜蜂老师微信公众号
一、按键长按短与短按
#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();
}
}