📄 16x32点阵.c
字号:
#include<reg51.h>
#include<intrins.h>
#include<font.h> //字库
#include<ds1302.h>
#include<ds18b20.h>
#define uchar unsigned char
#define uint unsigned int
#define light 180 //点阵亮度调节;视情况而定
void delayms(uint n); //(n)ms延时子程序
void delay(); //显示扫描延时
void DS1302_Initial (void); //初始化ds1302
void initTimer(void); //初始化定时器
void lie(); //列控制
void send8bit(unsigned int n); //发送字函数
void set_key(void); //SET键处理程序
void read_clockS(void); //时钟数据读取
void Set_time(unsigned char sel); //设置时间函数
void check_shijian(void); //读取时间
void load_shijian(void); //将待显示时间内容存至缓冲区
void check_wendu(void); //读取温度
void load_wendu(void); //将待显示温度内容存至缓冲区
void display(void); //显示子程序
sbit wendu=P3^4; //温度显示键(长按显示温度)
sbit SET=P3^2; //时间设定键
sbit ADD=P3^3; //时间调节键
sbit dat=P1^7; //595数据
sbit clock=P1^5; //595时钟信号
sbit so=P1^6; //595锁存信号
sbit gate1=P1^4; //154门控信号
uchar count,q=0; //标志位
uchar disbuf[64]; //显示缓冲区
uchar m,n,p,t; //缓冲区中间量
uchar min,hour; //定义时间映射全局变量
uchar dian1,dian2,dian3,dian4; //用于时间闪烁的冒号
uchar set_st=0; //调整选择标志0:正常走时;1:调时;2:调分
uchar set_key_st=0; //设置标志,为1则调用一次SET键处理
uchar add_key_st=0; //增加标志,为1则调用一次调时函数
uchar k=1; //秒闪烁及选中闪烁标志
uchar x,y,z; //时基
/**主函数**/
void main()
{
gate1=1; //关闭显示,防止花屏
delayms(500); //等待芯片复位,目的是稳定检测是否需要初始化
while(SET==0) //通电前按下SET键不放,接通电源时便初始化时间信息
{
DS1302_Initial();
}
initTimer(); //初始化定时器
TR0=1; //开启定时器0
ET0=1; //允许T0中断
EA=1; //开中断总开关
IT0=1; //开启外部中断0
EX0=1;
IT1=1; //开启外部中断1
EX1=1;
y=0; //系统时基清零
while(1)
{
while(set_key_st) //设置键按下
{
delayms(1);set_key();EX0=1;
}
if(set_st==1||set_st==2) //进入调时选中状态后如果长时间无调整则自动退出
{
if(z>=300){set_st=0;z=0;}
}
if(set_st==1||set_st==2)y=0; //系统时基清零
if(y<120||set_st==1||set_st==2)
{
check_shijian(); //读取时间信息
while(add_key_st&&set_st>0) //增加键按下
{
Set_time(set_st);EX1=1;
}
}
load_shijian(); //将待显示时间内容存至缓冲区准备显示
display(); //显示
while(wendu==0) //长按显示温度
{
check_wendu(); //读取温度信息
load_wendu(); //加载温度
display(); //显示
}
}
}
/**扫描延时(调节显示亮度)**/
void delay()/*延时子程序*/
{
unsigned int n;
for(n=0;n<light;n++);
}
/***(n)ms延时子程序**/
void delayms(uint n)
{
uchar i;
while(n--)
{
for(i=0;i<125;i++);
}
}
/*****初始化定时器*****/
void initTimer(void)
{
TMOD=0x1; //定时器0工作方式1
TH0=0xab;
TL0=0xff; //赋初值
}
/*****定时器0中断服务程序*****/
void time0(void) interrupt 1
{
TH0=0xab;
TL0=0xff; //重新赋初值
x++;y++;z++;
if(y>=160){y=0;} //系统时基、工作节拍控制
if(x>40){k=~k;x=0;} //0.5秒k取反一次,用于秒的冒号闪烁和调时选中闪烁
if(k==1) //控制秒冒号闪烁
{dian1=dian3=0x06;dian2=dian4=0x60;}
else
{dian1=dian3=0x00;dian2=dian4=0x00;}
}
/*****外部中断0服务程序*****/
void int0(void) interrupt 0
{
EX0=0;
set_key_st=1; //开启设置键标志
}
/*****外部中断1服务程序****/
void int1(void) interrupt 2
{
EX1=0;
add_key_st=1; //开启增加键标志
}
/****初始化DS1302*******/
void DS1302_Initial (void)
{
DS1302_w(0x8e,0x00); //允许写操作
DS1302_w(0x8c,0x09); //年 09
DS1302_w(0x8a,0x01); //星期一
DS1302_w(0x88,0x02); //月 2
DS1302_w(0x86,0x10); //日 16
DS1302_w(0x84,0x00); //小时
DS1302_w(0x82,0x00); //分钟
DS1302_w(0x80,0x00); //秒
DS1302_w(0x90,0xa5); //充电
DS1302_w(0x8e,0x80); //禁止写操作
}
/*****常用时钟数据读取*****/
void read_clockS(void)
{
hour = DS1302_r(0x85); //读取小时数据
min = DS1302_r(0x83); //读取分钟数据
/*在本电子钟中暂不需要读取以下信息,暂时屏蔽*/
// sec = DS1302_r(0x81); //读取秒数据
// day = DS1302_r(0x87); //读取日数据
// month= DS1302_r(0x89); //读取月数据
// week = DS1302_r(0x8b); //读取星期数据
// year = DS1302_r(0x8d); //读取年数据
}
/*****SET键处理程序*****/
void set_key(void)
{
if(SET==0){set_st++;z=0;}
if(set_st>2)set_st=0; //调整功能标志加一
set_key_st=0; //关闭设置键标志
}
/*****设置时间函数*****/
void Set_time(unsigned char sel) //引入调整选择标志
{
signed char address,item;
signed char max,mini;
if(sel==1) {address=0x84; max=23;mini=0;} //小时
if(sel==2) {address=0x82; max=59;mini=0;} //分钟
/*在本电子钟中暂不需要调整以下信息,暂时屏蔽*/
// if(sel==3) {address=0x80; max=0;mini=0;} //秒
// if(sel==4) {address=0x8c; max=99; mini=0;} //年
// if(sel==5) {address=0x88; max=12;mini=1;} //月
// if(sel==6) {address=0x86; max=31;mini=1;} //日
// if(sel==7) {address=0x8a; max=7;mini=1;} //星期
item=((DS1302_r(address+1))/16)*10 + (DS1302_r(address+1))%16;//读取1302某地址上的数值转换成10进制赋给item
if(ADD==0){item++;z=0;}
if(item>max) item=mini; //查看数值有效范围
if(item<mini) item=max;
DS1302_w(0x8e,0x00); //允许写操作
DS1302_w(address,(item/10)*16+item%10); //转换成16进制写入1302
DS1302_w(0x8e,0x80); //写保护,禁止写操作
add_key_st=0; //关闭增加键标志
}
/*****读取时间*****/
void check_shijian(void)
{
read_clockS(); //读取时间
m=hour>>4; //计算得到小时十位数字
n=hour&0x0f; //计算得到小时个位数字
p=min>>4; //计算得到分钟十位数字
t=min&0x0f; //计算得到分钟个位数字
}
/*****读取温度*****/
void check_wendu(void)
{
uchar i;
i=ReadTemperature()-5; //获取温度值并减去DS18B20的温漂误差
m=i/100; //计算得到十位数字
n=i/10-m*10; //计算得到个位数字
p=i-m*100-n*10; //计算得到小数位数字
}
/****将待显示时间内容存至缓冲区****/
void load_shijian(void)
{
uchar a;
if(set_st==1&&k==1) //调时,小时位闪烁,x的取反频率为闪烁频率
{
for(a=0;a<16;a++){disbuf[a]=0;}
for(a=16;a<32;a++){disbuf[a]=0;}
}
else
{
for(a=0;a<16;a++){disbuf[a]=shuzi[m*16+a];}
for(a=16;a<32;a++)
{
disbuf[a]=shuzi1[n*16+a-16];
if(a==30) disbuf[a]=dian1;
if(a==31) disbuf[a]=dian2;
}
}
if(set_st==2&&k==1) //调分,分钟位闪烁
{
for(a=32;a<48;a++){disbuf[a]=0;}
for(a=48;a<64;a++){disbuf[a]=0;}
}
else
{
for(a=32;a<48;a++)
{
disbuf[a]=shuzi2[p*16+a-32];
if(a==32) disbuf[a]=dian3;
if(a==33) disbuf[a]=dian4;
}
for(a=48;a<64;a++){ disbuf[a]=shuzi[t*16+a-48];}
}
}
/**将待显示温度内容存至缓冲区**/
void load_wendu(void)
{
uchar a;
for(a=0;a<16;a++)
{
if(m==0)disbuf[a]=0x00; //如果十位为0则不显示,目的在于消除前置0
else disbuf[a]=shuzi3[m*16+a]; //加载温度十位信息
}
for(a=16;a<32;a++)
{
disbuf[a]=shuzi3[n*16+a-16]; //加载温度个位信息
if(a==31) disbuf[a]=0x04;
}
for(a=32;a<48;a++){disbuf[a]=shuzi3[p*16+a-32];} //加载温度小数位信息
for(a=48;a<64;a++){disbuf[a]=fuhao[a-48];} //加载摄氏度符号
}
/****显示函数****/
void display(void)
{
unsigned char i;
count=0x00;
gate1=1;
for(i=1;i<=31;i+=2)
{
send8bit(i+32); //由于使用移位寄存74hc595,先发送一列的下半部分
send8bit(i-1+32); //后发送一列的上半部分,第2个字
send8bit(i); //由于使用移位寄存74hc595,先发送一列的下半部分
send8bit(i-1); //后发送一列的上半部分,第1个字。
so=0;
so=1; //产生上升沿锁存信号
lie(); //一个字的上半部分和下半部分发送完毕点燃该列。
delay(); //调用延时子程序
gate1=1; //关列显示
}
}
/**机内码发送子程序**/
void send8bit(unsigned int n)
{
for(q=0;q<8;q++)
{
dat=!((_cror_(disbuf[n],q))&0x01);//右移(7-q)位,从低位到高位取。即595发送,
clock=0;
clock=1; //寄存器时钟上跳沿,将一位数据存入移位寄存器。
}
}
/***列扫描***/
void lie()
{
gate1=0;//允许列选择
P1=count;
count++;
if(count==16)
{
count=0;
count++;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -