标题:
用单片机做一个带存储一功能的秒表,现在程序有点问题,可以正常计... 求帮助
[打印本页]
作者:
rocky13
时间:
2019-5-3 18:50
标题:
用单片机做一个带存储一功能的秒表,现在程序有点问题,可以正常计... 求帮助
#include "reg52.h"
typedef unsigned int u16; //对数据类型进行声明定义
typedef unsigned char u8;
void delay(); //短暂延时
void start(); //开始信号
void stop(); //停止信号
void respons(); //应答
void init(); //初始化 两条线都拉高
void write_byte(u8); //写一个字节
u8 read_byte(); //读一个字节,带带返回值的函数
void write_add(u8,u8);//写入 指定地址 数据
u8 read_add(u8); //读出 指定地址 数据
u8 fanye=0; //定义外部中断1 存数次数标志位,翻页次数
u8 gg=0; //定义存第几数 ,翻到第几个数
u16 cc=0; //定义定时器0溢出次数
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
sbit int0=P3^2; //外部中断0,端口
sbit int1=P3^3; //外部中断1,端口
sbit scl=P1^3; //时钟线
sbit sda=P1^4; //数据线
u8 code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//显示0~F的值
u8 ssec,sec,min;
u8 DisplayData[8];
u8 qc=0; //定义长按外部中断0 取出保存的数
u8 zant=0; //暂停开始标志位,外部中断0控制
/*******************************************************************************
* 函 数 名 : delay
* 函数功能 : 延时函数,i=1时,大约延时10us
*******************************************************************************/
void delay(u16 i)
{
while(i--);
}
/*******************************************************************************
* 函 数 名 : Timer0Init
* 函数功能 : 定时器0初始化
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void Timer0Init()
{
TMOD|=0X01;//选择为定时器0模式,工作方式1,仅用TR0打开启动。
TH0=0Xd8; //给定时器赋初值,定时10ms
TL0=0Xf0;
ET0=1;//打开定时器0中断允许
EA=1;//打开总中断
TR0=1;//打开定时器
}
/*******************************************************************************
* 函 数 名 : DigDisplay
* 函数功能 : 数码管动态扫描函数,循环扫描8个数码管显示
*******************************************************************************/
void DigDisplay()
{
u8 i;
for(i=0;i<8;i++)
{
switch(i) //位选,选择点亮的数码管,
{
case(7):
LSA=0;LSB=0;LSC=0; break;//显示第0位
case(6):
LSA=1;LSB=0;LSC=0; break;//显示第1位
case(5):
LSA=0;LSB=1;LSC=0; break;//显示第2位
case(4):
LSA=1;LSB=1;LSC=0; break;//显示第3位
case(3):
LSA=0;LSB=0;LSC=1; break;//显示第4位
case(2):
LSA=1;LSB=0;LSC=1; break;//显示第5位
case(1):
LSA=0;LSB=1;LSC=1; break;//显示第6位
case(0):
LSA=1;LSB=1;LSC=1; break;//显示第7位
}
P0=DisplayData[i];//发送段码
delay(100); //间隔一段时间扫描
P0=0x00;//消隐
}
}
/*************************延时********************************/
void delayms(u16 x) //延时函数
{
u16 p,q;
for(p=x;p>0;p--)
for(q=110;q>0;q--);
}
void datapros()
{
DisplayData[0]=smgduan[ssec%10];
DisplayData[1]=smgduan[ssec/10];
DisplayData[2]=0x40;
DisplayData[3]=smgduan[sec%10];
DisplayData[4]=smgduan[sec/10];
DisplayData[5]=0x40;
DisplayData[6]=smgduan[min%10];
DisplayData[7]=smgduan[min/10];
}
/*******************外部中断0*******************/
void wbzd0()interrupt 0
{
u8 p=0; //判断按键按下的时间
delayms(20); //消抖
if(int0==0)
{
while(!int0&&p<250) //最多按25秒
{ p++;
delayms(100);}
if(p>15) //长按2秒 调出数据,
{
qc=1; //主程序开始 读eeprom数据
TR0=0; //停止定时器工作
}
else // 低于两秒
{
zant=~zant;
TR0=zant; //来回反转实现定时器0的启停
}
}
}
void wbzd1()interrupt 2
{
delayms(20); //消抖
if(int1==0)
{
fanye=1; //主程序进入存数据,后跳出,直到下次按键按下
gg++; //用于判断存数据位,和读数据位,在不同的位置实现的功能不同
if(gg==5)
{gg=1;}
while(!int1); //按键不松,程序不往下执行
}
}
void T0_time()interrupt 1 //八位自动装填
{
cc++;
if(cc>=400) //0.1秒到来
{
cc=0;
ssec++;
}
}
/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void main()
{
Timer0Init(); //定时器0初始化
while(1)
{ IT0=1; //外部0低电平触发
EX0=1; //开外部中断0
IT1=1; //外部1低电平触发
EX1=1; //开外部中断1
ET0=1; //开定时器0
EA=1; // 开总中断
IP=0x04; //外部1优先
datapros();
DigDisplay();
/**************************按键处理*************************/
if(fanye==1) //存数据 判断外部中断1是否按下
{
switch(gg) //通过gg的值“按第几下”,存到不同的位置
{
case 1:
init();
write_add(0x01,DisplayData[0]);
init();
write_add(0x02,DisplayData[1]);
init();
write_add(0x03,DisplayData[2]);
init();
write_add(0x04,DisplayData[3]);
init();
write_add(0x05,DisplayData[4]);
init();
write_add(0x06,DisplayData[5]);
break;
/* case 2:
init();
write_add(0x03,num0);
init();
write_add(0x04,num1);
break;
case 3:
init();
write_add(0x05,num0);
init();
write_add(0x06,num1);
break;
case 4:
init();
write_add(0x07,num0);
init();
write_add(0x08,num1);
break; */
}
fanye=0; //退出存数,直到下次外部中断1到来
}
if(qc==1) //判断外部中断0长按键 开始读存进EEPROM的数据
{
while(1)
{
switch(gg) //通过判断外部中断1,按键次数gg实现翻页功能
{ //因为又进入到现在这个大循环 所以外部中断1中的
case 1: //fanye=1;不能在返回上面控制 存第几个数据了,相当与无用
init();
DisplayData[0]=read_add(0x01);
init();
DisplayData[1]=read_add(0x02);
init();
DisplayData[2]=read_add(0x03);
init();
DisplayData[3]=read_add(0x04);
init();
DisplayData[4]=read_add(0x05);
init();
DisplayData[5]=read_add(0x06);
break;
/*case 2:
init();
num0=read_add(0x03);
init();
num1=read_add(0x04);
break;
case 3:
init();
num0=read_add(0x05);
init();
num1=read_add(0x06);
break;
case 4:
init();
num0=read_add(0x07);
init();
num1=read_add(0x08);
break; */
}
/*mb[0]=num1%10; //秒表个位
mb[1]=num1/10; //秒表十位
mb[2]=num0; */
//display(num0,num1); //程序将在此一直判断gg,实现翻页,显示存的数据
} //若想再次计数,按下单片机的RST复位键,程序重头执行
}
}
}
/*******************************************************************************
* 函 数 名 : void Timer0() interrupt 1
* 函数功能 : 定时器0中断函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void Timer0() interrupt 1
{
TH0=0Xd8; //给定时器赋初值,定时10ms
TL0=0Xf0;
ssec++;
if(ssec>=100) //1s
{
ssec=0;
sec++;
if(sec>=60)
{
sec=0;
min++;
if(min>=60)
{
min=0;
}
}
}
}
/*void delay2()
{;;} */
void start() //开始信号
{
sda=1;
delay2();
scl=1;
delay2();
sda=0;
delay2();
}
void stop() //停止信号
{
sda=0;
delay2();
scl=1;
delay2();
sda=1;
delay2();
}
void respons() //应答
{
u8 i;
scl=1;
delay2();
while((sda==1)&&(i<250)) //防止一直没有收到应答,程序停止
{i++;}
scl=0;
delay2();
}
void init() //初始化 两条线都拉高
{
sda=1;
delay2();
scl=1;
delayms(1); //加延时,否则用不了
}
void write_byte(u8 date) //写一个字节
{
u8 i,temp;
temp=date;
for(i=0;i<8;i++)
{
temp=temp<<1;
scl=0;
delay2();
sda=CY; //最高位移入PSW寄存器中CY位中
delay2(); //将CY中的值赋给sda
scl=1;
delay2();
}
scl=0;
delay2();
sda=1;
delay2();
}
u8 read_byte() //读一个字节,带带返回值的函数
{
u8 i,k;
scl=0;
delay2();
sda=1;
delay2();
for(i=0;i<8;i++)
{
scl=1;
delay2();
k=(k<<1)|sda; //将K左移一位后与sda进行或运算,
scl=0; //依次把8个位放入一个字节中来完成接收
delay2();
}
return k; //返回值为k
}
void write_add(u8 address,u8 date) //写入 指定地址 数据
{
start();
write_byte(0xa0); //接下来为写操作
respons();
write_byte(address); //送入地址
respons();
write_byte(date); //写入数据
respons();
stop();
delayms(1); //加延时,否则用不了
}
u8 read_add(u8 address) //读出 指定地址 数据
{
u8 date;
start();
write_byte(0xa0); //接下来为写操作
respons();
write_byte(address); //送入地址 ,下面读数据的地址
respons();
start();
write_byte(0xa1); //接下来为读操作 存储器发送数据
respons();
date=read_byte(); //把SDA数据线上的数据用date存
stop();
return date;
delayms(1); //加延时,
}
复制代码
作者:
jhczy
时间:
2019-5-3 23:47
楼主,请问要帮助解决什么问题?
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1