基于C51的扩展系统结构的篮球记分器【包含IIC运用,DS1307,LCM12864】的课设作业

题目10:模拟篮球记分器(系统扩展结构)

设计语言:C

功能:模拟篮球比赛记分器,有比分显示,以及比赛开始、结束倒计时显示。

(1)在显示屏上显示篮球记分显示区

(2)蜂鸣器提醒开始、结束时间。响声不同

(3)键盘负责加分系统

硬件环境:单片机扩展系统,键盘,显示器,喇叭等

自检程序

LED自检

/*  已知是共阳管,所以只有当低电平才会点亮小灯泡,
    我们定义light初始为0xff,通过位移和for循环的
	配合使小灯泡产生流水灯的效果                 */
void led(){
	uchar light = 0xff; 
	uint i = 0;
	for(i = 0; i < 8; i++){
		light = light<<1;      //位移操作【左移】
		XBYTE[0x800c] = light; //片外总线选址传送数据
		delay(100);            //延时0.1s
	for(i = 0; i < 9; i++){
		XBYTE[0x800c] = light;
		light = (light<<1)+1;  //位移操作【左移】,想右补1
		delay(100);
	}
}

蜂鸣器自检

/*蜂鸣器自检程序,让蜂鸣器产生一定频率的声音,这里使50Hz*/
void sing(){
	unsigned int i = 0, j = 0;
	for(i = 0; i < 10){
		/*for循环100次,产生0.2s的响声*/
		for(j = 0; j < 100; j++){
			XBYTE[0x8018] = 0x01; //由电路图可知,高电平蜂鸣器不工作
			delay(1);
			XBYTE[0x8018] = 0x00; //低电平工作
			delay(1);
		}
		XBYTE[0x8018] = 0x01;
		delay(100);
	}
}

小键盘自检

void keys(){
	uchar key;
	uint i;
	/*通过死循环检查案件是否被按*/
	while(1){
		/*通过片外总线获取按键信息并赋予key*/
		key = XBYTE[0x8014];
		/*这里无视了独立键盘,但经过检查,独立键盘完好*/
		if(key < 0xfd)
		{	
			/*延时消抖*/
			delay(10);
			key = XBYTE[0x8014];
			/*再次确认*/
			if(key > 0xfd)
			{	
				/*点亮对应位置的LED*/
				XBYTE[0x800c] = key;
				while(key==0) key = XBYTE[0x8014];;
			}
		}
	}
}

LCD自检

分析

12864有两种工作模式。

  1. 文本工作模式

    整屏平均分成32个显示区(每个显示区是16*16点阵),每个显示区可显示一个中文,每个显示区可显示两个英文ASCII字符。

  2. 绘图工作模式

    整屏按水平方向每16个点分为一组,所以整屏共有8192/16=512组,每次可控制任意一组的16个点。图形显示坐标:水平方向 X—以字节单位,垂直方向 Y—以位为单位。

这里我们仅需要文本工作模式即可。

在这里插入图片描述

void checkbusy(){
    uchar read = XBYTE[8012];
    while((read & 0x80) == 0x80) read = XBYTE[8012];
}

void initLCD(){
  	writeCmd(0x30);  //选择基本指令操作
  	writeCmd(0x0c);  //显示开,关光标
  	writeCmd(0x01);  //清除LCD12864的显示内容
}

void writeCmd(uchar cmd){
	checkbusy();
	XBYTE[8010] = cmd;
}

void writeData(uchar dat){
    checkbusy();
	XBYTE[8011] = dat;
}

void SetWindow(uchar x, uchar y,uchar *word){
    uchar pos;
    uchar i=y;
    if(x == 0)     // 第一行的地址是80H
        x = 0x80;   
    else if(x == 1)  //第二行的地址是90H
        x = 0x90;  
    else if(x == 2)  //第三行的地址是88H
        x = 0x88; 
    else if(x == 3)  //第三行的地址是98H
        x = 0x98;
  
    pos = x + y;
    writeCmd(pos);  
    while(word[i]!='\0'){
        if(i<16){    //判断是否在本行的显示范围内
      		writeData(word[i]);
      		i++;
    	} 
  	}
}

  • writeCmd(0x01)在这里插入图片描述

  • writeCmd(0x0c)在这里插入图片描述

  • writeCmd(0x30)在这里插入图片描述

DS1307 程序自检

这里涉及到I2C的串口通信协议,所以我们还需要对协议有一个初步的认识,和代码补全.

DS1307简介

Ds1307是低功耗、IIC接口、日历和时钟数据,按BCD码存取的时钟/日历芯片。它提供秒、分、小时、星期、日期、月和年等时钟日历数据。

在使用中通常其他引脚已经接好了,所示如下:

在这里插入图片描述

所以我们进需要针对IIC协议对SDA和SCL进行操作即可。

这里是引脚图

在这里插入图片描述

随后我们对DS1307的寄存器进行简单的介绍:

在这里插入图片描述

IIC总线

接下来我们需要对IIC总线有个大致的了解,我们大致分为以下几个操作:

  • 初始总线
  • 发起起始信号
  • 发送数据
  • 应答
  • 发送终止信号
初始总线

首先是初始总线,在刚启动总线的时候,为了确保后续的稳定,我们通常会将SDA和SCL 置高。

发起起始信号

起始信号:当SCL为高期间,SDA由高到低的跳变;启动信号是一种电平跳变时序信号在这里插入图片描述

发送数据

SCL串行时钟的配合下,在SDA上逐位地串行传送每一位数据。数据的准备是在SCL的低电平,数据位的传输是上边沿触发。所以当SCL为高电平时SDA不可以变化。所以图像如下在这里插入图片描述
其中下面为SCL,上面为SDA。

应答位

发送器每发送一个字节,就在时钟脉冲9期间释放数据线,由接收器反馈一个应答信号,而应答有主机应答和从机应答。在这里插入图片描述

发送停止信号

停止信号:当SCL为高期间,SDA由低到高的跳变;停止信号也是一种电平跳变时序信号在这里插入图片描述

接下来稍微展示一下DS1307的读写过程:

在这里插入图片描述
在这里插入图片描述

#include<reg51.h>
#include<absacc.h>

#define uchar unsigned char
#define uint unsigned int
#define DS1307_ADDR 0xd0  // 定义一下ds1307的地址
 
typedef struct date{      // 定义变量别名
    uint hour;
    uint minute;
    uint second;
}date;

int count_down = 0;       // 用作倒计时的程序

sbit SCL = P1^0;          // 定义SCL引脚
sbit SDA = P1^1;          // 定义SDA引脚

void init(){              // 对I^C总线进行初始化
    SCL = 1;
    for(count_down = 0; count_down < 5; count_down++);
    SDA = 1;
    for(count_down = 0; count_down < 5; count_down++);
}
 
void start(){             // 发动起始信号
    SDA=1;
    for(count_down = 0; count_down < 5; count_down++);
    SCL=1;
    for(count_down = 0; count_down < 5; count_down++);
    SDA=0;
    for(count_down = 0; count_down < 5; count_down++);
	SCL=0;
}

void stop(){             // 发动停止信号
    SDA=0;
    for(count_down = 0; count_down < 5; count_down++);
    SCL=1;
    for(count_down = 0; count_down < 5; count_down++);
    SDA=1;
    for(count_down = 0; count_down < 5; count_down++);
	SCL = 0;
}

void send_byte(uchar byte){ // 传送数据【字节】
    uchar i;
    for(i = 0; i < 8; i++){
        SCL = 0;
        for(count_down = 0; count_down < 5; count_down++);
        if(byte & 0x80) SDA = 1;
        else            SDA = 0;
        for(count_down = 0; count_down < 5; count_down++);
        SCL = 1;
        for(count_down = 0; count_down < 5; count_down++);
        byte <<= 1;
    }
    SCL = 0;
    for(count_down = 0; count_down < 5; count_down++);
    SDA = 1;
    for(count_down = 0; count_down < 5; count_down++);
}

uchar read_byte(){      // 接受数据【字节】
    uchar dat, i;
    SCL = 0;
    for(count_down = 0; count_down < 5; count_down++);
    SDA = 1;
    for(count_down = 0; count_down < 5; count_down++);
    for(i = 0; i < 8; i++){
        dat <<= 1;
        SCL = 1;
        for(count_down = 0; count_down < 5; count_down++);
        if(SDA) dat = dat | 0x01;
        else    dat = dat & 0xfe;
        for(count_down = 0; count_down < 5; count_down++);
        SCL = 0;
        for(count_down = 0; count_down < 5; count_down++);
    }
	return dat;
}

bit Test_ACK(){          // 从机应答
	SDA = 0;
	for(count_down = 0; count_down < 5; count_down++);
    SCL = 1;
    for(count_down = 0; count_down < 5; count_down++);
    SCL = 0;
    for(count_down = 0; count_down < 5; count_down++);
    if(SDA){
        stop();
        return 0;
    }
    else return 1;
}

void Master_ACK(bit i)   // 主机应答
    SCL = 0;
    for(count_down = 0; count_down < 5; count_down++);
    if(i) SDA = 0;
    else SDA = 1;
    for(count_down = 0; count_down < 5; count_down++);
    SCL = 1;
    for(count_down = 0; count_down < 5; count_down++);
    SCL = 0;
    for(count_down = 0; count_down < 5; count_down++);
    SDA = 1;
    for(count_down = 0; count_down < 5; count_down++);
}

/*LCD自检程序*/
void checkbusy(){
    uchar read = XBYTE[0x8012];
    while((read & 0x80) == 0x80) read = XBYTE[0x8012];
}

void writeCmd(uchar cmd){
	checkbusy();
	XBYTE[0x8010] = cmd;
}

void writeData(uchar dat){
    checkbusy();
	XBYTE[0x8011] = dat;
}

void SetWindow(uchar x, uchar y,uchar *word){
    uchar pos;
    uchar i=y;
    if(y < 4){
        if(x == 0) x = 0x80;      // 第一行的地址是80H
        else if(x == 1) x = 0x90; // 第二行的地址是90H
        else if(x == 2) x = 0x88; // 第三行的地址是88H
        else if(x == 3) x = 0x98; // 第三行的地址是98H
  
        pos = x + y;
        writeCmd(pos);  
        while(word[i]!='\0'){
            if(i<16){             //判断是否在本行的显示范围内
      		    writeData(word[i]);
      		    i++;
    	    } 
  	    }
    }
}

void initLCD(){
  	writeCmd(0x30);  //选择基本指令操作
  	writeCmd(0x0c);  //显示开,关光标
  	writeCmd(0x01);  //清除LCD12864的显示内容
}

void num2str(char* str, int num, int size){
    int i = size - 1;
    for(i = size - 1; i >= 0; i--){
        str[i] = num % 16 + '0';
        num /= 16;
    }
}
/*通过主函数调用*/
int main(){
	int j = 0;
  	bit ACK_flag;
	char seconds[] = "00";
	date demo;
	initLCD();
    init();
	
    start();
    send_byte(DS1307_ADDR+0);
    if(!Test_ACK()) ACK_flag = 1;
    send_byte(0x00);
    if(!Test_ACK()) ACK_flag = 1;
    send_byte(0x00);
    if(!Test_ACK()) ACK_flag = 1;
	send_byte(0x00);
    if(!Test_ACK()) ACK_flag = 1;
	send_byte(0x00);
    if(!Test_ACK()) ACK_flag = 1;
    stop();
//    for(count_down = 0; count_down < 5000; count_down++); // 延时1ms
	XBYTE[0x800c] = demo.second;
	for(j = 0; j < 2000; j++);
	num2str(seconds, demo.second, 2);
	SetWindow(0, 0, seconds);
    while(1){ 
		uint i = 0;
        char ch[] = "    00:00:00";
        char seconds[] = "00";
        char minutes[] = "00";
        char hours[] = "00";
		XBYTE[0x800c] = demo.second;
		for(i = 0; i < 5000; i++);
        start();
    	send_byte(DS1307_ADDR+0);
    	if(!Test_ACK()) ACK_flag = 1;
    	send_byte(0x00);
    	Master_ACK(0);
		stop();
    	start();
    	send_byte(DS1307_ADDR+1);
    	if(!Test_ACK()) ACK_flag = 1;
    	
        
		start();
    	send_byte(DS1307_ADDR+0);
    	if(!Test_ACK()) ACK_flag = 1;
    	send_byte(0x01);
    	Master_ACK(0);
		stop();
    	start();
    	send_byte(DS1307_ADDR+1);
    	if(!Test_ACK()) ACK_flag = 1;
    	demo.minute = read_byte();
    	Master_ACK(1);
    	stop();
		start();
    	send_byte(DS1307_ADDR+0);
    	if(!Test_ACK()) ACK_flag = 1;
    	send_byte(0x02);
    	Master_ACK(0);
		stop();
    	start();
    	send_byte(DS1307_ADDR+1);
    	if(!Test_ACK()) ACK_flag = 1;
    	demo.hour = read_byte();
    	Master_ACK(1);
    	stop();
		XBYTE[0x800c] = demo.second;
		for(i = 0; i < 20000; i++);
		num2str(seconds, demo.second, 2);
		num2str(minutes, demo.minute, 2);
		num2str(hours, demo.hour, 2);
		for(i = 0; i < 2; i++) ch[i+4] = hours[i];
		for(i = 0; i < 2; i++) ch[i+7] = minutes[i];
		for(i = 0; i < 2; i++) ch[i+10] = seconds[i];
		SetWindow(0, 0, ch);
    }
    return 0;
}

篮球记分器设计

流程图

总流程图
Created with Raphaël 2.2.0 Start 比赛开始 sw=独立键盘 sw == 0x00 home_page界面 比赛结束 sw == 0x01 score界面 yes no yes no
home_page流程图
Created with Raphaël 2.2.0 close界面开始 screen 场次 双方 总得分 球权 本节计时 本节时长 暂停 犯规 小键盘switch switch == 0x04 暂停【根据球权记录】 蜂鸣器提示暂停 比赛结束 switch == 0x08 犯规【根据球权记录】 蜂鸣器提示犯规 switch == 0x10 本节时常减少30 switch == 0x20 本节时常增加30 switch == 0x40 中场休息【下一小节】 蜂鸣器提示下一小节 switch == 0x80 比赛开始/结束 蜂鸣器提示开始结束 yes no yes no yes no yes no yes no yes
score流程图
Created with Raphaël 2.2.0 close界面开始 screen 总比分 第一小节比分 第二小节比分 第三小节比分 第四小节比分 小键盘switch switch == 0xfb 得 1 分 比赛结束 switch == 0xf7 得 1 分 switch == 0xef 得 1 分 switch == 0xdf 交换球权 yes no yes no yes no yes

code实现

总体代码展示

#include<reg51.h>
#include<absacc.h>

#define uchar unsigned char
#define uint unsigned int
#define DS1307_ADDR 0xd0

int count_down = 0;

sbit SCL = P1^0;
sbit SDA = P1^1;
bit ACK_flag = 0;

typedef struct dat{
    uchar hour;
    uchar minute;
    uchar second;
}dat;

/*LCD相关函数*/
void checkbusy();                               // 查忙程序
void initLCD();                                 // LCD屏幕初始化
void writeCmd(uchar cmd);                       // 写入指令
void writeData(uchar dat);                      // 写入数据
void SetWindow(uchar x, uchar y,uchar *word);   // 包装使用

/*基础函数*/                              
void delay(int ms);                             // * 设置普通延时
uint read_key(uint key);                        // * 读入键值
int judge_key(int key);                         // * 判断键值
void buzzer(int time, int hz);                  // * 蜂鸣器控制
void process_show();                            // * 进程展示
void num2str(char* str, int num, int size);     // * 数字转字符串
void show_time(struct dat sj, int line);        // * 将时间展示到LCD
void pause_time();                              // * 设置暂停相关
void time_add(uint sec);                        // * 小节时间变化 

/*主界面相关函数*/
void pause(uint key);                           // * 暂停主函数
void pause_screen();                            // * 暂停函数屏幕
void judge_pause(int bol);                      // * 判断是否暂停,并执行
void judge_foul(int bol);                       // * 判断是否罚球,并执行
void processing();                              // * 设置进程
void match_stutes();                            // * 比赛状态函数【开始或结束】
void match_settlement();                        // * 比赛结束界面【未完成】

/*得分界面相关函数*/
void score(uint key);                           // * 得分主函数
void score_screen();                            // * 得分界面
void score_up(int n);                           // * 得分

/*I^C相关函数*/
void init();
void start();
void stop();
void waite();                                   // * 设置I^C相关延时
void send_byte(uchar byte);
uchar read_byte();
bit Test_ACK();
void Master_ACK(bit i);
void init_ds1307(uchar hour, uchar minute, uchar second); // * 初始化DS1307
struct dat read_ds1307(struct dat now_time);              // * 读入DS1307的值
struct dat time_c(struct dat now_time, struct dat b_time);// * 计算时间差
uint real_time(struct dat time1);                         // * 计算相对时间
void how();                                               // * 应答检测

bit start_end = 0;                                    // * 开始结束检测
bit process_pause = 1;                                // * 暂停检测
int processgo = 0;                              // * 进程
int e_score[4] = {0}, c_score[4] = {0};         // * 小姐得分
int e_foul = 0, c_foul = 0;                     // * 罚球统计
int e_pause = 0, c_pause = 0;                   // * 暂停统计
bit ball = 0;                                         // * 球权
struct dat a_time;                                    // * 时间线
xdata struct dat start_time;
xdata struct dat whl_time;
xdata struct dat in_time;
xdata int judge;
xdata struct dat pause_t;
xdata struct dat pause_whl;

int main(){
    uint key = 0;
	initLCD();
    while(1){
		key = read_key(~key);
		if(key & 0x03 < 2) pause(key);
        switch(key & 0x03){
            case 0x00:
            case 0x01:pause(key); break; 
            default: score(key); break;
        } 
        a_time = read_ds1307(a_time);
		if(process_pause == 1 && real_time(a_time) > real_time(whl_time) && start_end == 1)	processing();
		if(process_pause == 0 && real_time(a_time) == real_time(whl_time) && start_end == 1) pause_time(); 				
        if(processgo > 7) match_stutes();
    }	
    return 0;
}

void pause(uint key){
	uint judge = judge_key(key);
    pause_screen();
    switch(judge){
        case 2: judge_pause(ball); break;
        case 3: judge_foul(ball); break;
        case 4: time_add(-30); break;
        case 5:	time_add(30); break;
        case 6: processing(); break;
        case 7: match_stutes(); break;
    }
}

void score(uint key){
	uint judge = judge_key(key);
    score_screen();
    if(process_pause & start_end){
        switch(judge){
            case 2: score_up(1); break;
            case 3: score_up(2); break;
            case 4: score_up(3); break;
            case 5: ball = !ball; break;
            default: break;
        }
    }
}

void delay(int ms){
    int i = 0;
    for(i = 0; i < 120 * ms; i++);
}

void checkbusy(){
    uchar read = XBYTE[0x8012];
    while((read & 0x80) == 0x80) read = XBYTE[0x8012];
}

void initLCD(){
  	writeCmd(0x30);
  	writeCmd(0x0c);
  	writeCmd(0x01);
}

void writeCmd(uchar cmd){
	checkbusy();
	XBYTE[0x8010] = cmd;
}

void writeData(uchar dat){
    checkbusy();
	XBYTE[0x8011] = dat;
}

void SetWindow(uchar x, uchar y,uchar *word){
    uchar pos;
    uchar i=y;
    if(y < 4){
        if(x == 0) x = 0x80;
        else if(x == 1) x = 0x90;
        else if(x == 2) x = 0x88;
        else if(x == 3) x = 0x98;
  
        pos = x + y;
        writeCmd(pos);  
        while(word[i]!='\0' && i < 16){
			writeData(word[i]);
      		i++;
  	    }
    }
}

uint read_key(uint key){
	uint temp = XBYTE[0x8014];
    if(temp != key){
        delay(10);
        if(temp == XBYTE[0x8014]){
			key = XBYTE[0x8014];			
            while(temp < 0xfc) temp = XBYTE[0x8014];
        }
    }
    return ~key;
}

int judge_key(int key){
    int index = 0, i;
    for(i = 2; i < 8; i++)
        index = (key >> i) & 0x01 ? i : index;
    return index;
}

void buzzer(int time, int hz){
    int i = 0, j = 0, k = 0;
    for(i = 0; i < time; i++)
        for(j = 0; j < hz; j++){
            XBYTE[0x8018] = 1;
            for(k = 0; k < 600/hz; k++);
            XBYTE[0x8018] = 0;
            for(k = 0; k < 600/hz; k++);
        }
		XBYTE[0x8018] = 1;
		delay(1);
}

void judge_pause(int bol){
    if(start_end & process_pause){
		process_pause = !process_pause;
		pause_t.hour = a_time.hour;
		pause_t.minute = a_time.minute;
		pause_t.second = a_time.second;
		init_ds1307(0x00, 0x00, 0x00);
		pause_whl.hour = whl_time.hour;
		pause_whl.minute = whl_time.minute;
		pause_whl.second = whl_time.second;
		whl_time.hour = 0;
		whl_time.minute = 0;
		whl_time.second = 15;
        bol ? c_pause++ : e_pause++;
        buzzer(1, 200);
    }
}

void judge_foul(int bol){
    if(start_end & process_pause){
        bol ? c_foul++ : e_foul++;
        buzzer(1, 800);
    }
}

void processing(){
    processgo++;
    buzzer(3, 1000);
	init_ds1307(0x00, 0x00, 0x00);
    read_ds1307(a_time);
	whl_time.minute = 1;
    whl_time.second = 0;
    whl_time.hour   = 0;
}

void match_stutes(){
    int i = 0;
    if(start_end == 0){
        process_pause = 1;
        processgo = 1;
        e_foul = 0;
        c_foul = 0;
        e_pause = 0;
        c_pause = 0;
        for(i = 0; i < 4; i++){
            e_score[i] = 0;
            c_score[i] = 0;
        }
        init_ds1307(0x00, 0x00, 0x00);
        read_ds1307(a_time);
        whl_time.minute = 1;
        whl_time.second = 0;
        whl_time.hour   = 0;
    }
    else{
		match_settlement();
		process_pause = 0;
        processgo = 0;
	}
    start_end = !start_end;
    buzzer(5, 2000);
}

void pause_screen(){
    int j = 0;
    char epause[] = "00";
    char cpause[] = "00";
    char efoul[] = "00";
    char cfoul[] = "00";
    xdata char str1[] = "00暂停00";
	xdata char str2[] = "00罚球00";
    if(start_end == 1){
        num2str(epause, e_pause, 2);
        num2str(cpause, c_pause, 2);
        num2str(efoul, e_foul, 2);
        num2str(cfoul, c_foul, 2);
        process_show();
        if(ball == 0) SetWindow(1, 0, " 电子 vs 通信  O");
        else SetWindow(1, 0, "O 电子 vs 通信  ");
		show_time(a_time, 2);
   		show_time(whl_time, 3);
        for(j = 0; j < 2; j++) str1[0+j] = epause[j];
        for(j = 0; j < 2; j++) str1[6+j] = cpause[j]; 	  
        for(j = 0; j < 2; j++) str2[0+j] = efoul[j];
        for(j = 0; j < 2; j++) str2[6+j] = cfoul[j];
        SetWindow(2, 0, str1);
		SetWindow(3, 0, str2);
    }
}

void process_show(){
	uint j = 0;
	uint e_sum=0, c_sum=0;
	xdata char str1[] = " 000第01小节000 ";
	char esum[] = "000";
    char csum[] = "000";
	for(j = 0; j < 4; j++) e_sum += e_score[j];
	for(j = 0; j < 4; j++) c_sum += c_score[j];
    switch(processgo){
        case 1: str1[7] = '1'; break;
        case 3: str1[7] = '2'; break;
        case 5: str1[7] = '3'; break;
        case 7: str1[7] = '4'; break;
        default:str1[7] = '0';break;
    }
	XBYTE[0x800c] = e_sum;
	num2str(esum, e_sum, 3);
    num2str(csum, c_sum, 3);
	for(j = 0; j < 3; j++){
	 	str1[ 1+j] = esum[j];
		str1[12+j] = csum[j];
	 }
	SetWindow(0, 0, str1);
}

void num2str(char* str, int num, int size){
    int i = size - 1;
    for(i = size - 1; i >= 0; i--){
        str[i] = num % 10 + '0';
		num /= 10;
    }
}

void time_add(uint sec){
    sec = whl_time.hour * 3600 + whl_time.minute * 60 + whl_time.second + sec;
    whl_time.hour = sec / 3600;
    whl_time.minute = (sec % 3600) / 60;
    whl_time.second = sec % 60;
}

void score_screen(){ 
    int i = 0, j = 0;
    for(i = 0; i < 4 && start_end == 1; i++){
        char str_escore[] = "000";
        char str_cscore[] = "000";
        char str[] = "  000  --  000  ";
        num2str(str_escore, e_score[i], 3);
        num2str(str_cscore, c_score[i], 3);
        for(j = 0; j < 3; j++){
			str[ 2+j] = str_escore[j];
			str[11+j] = str_cscore[j];
		}
        SetWindow(i, 0, str);
    }
}

void score_up(int n){
	XBYTE[0x800c] = 0xfd;
    if(start_end & process_pause){		
        if(ball == 0)e_score[processgo /2] += n;
        else c_score[processgo /2] += n;
    }
}

void init(){
    SCL = 1;
    waite();
    SDA = 1;
    waite();
}
 
void start(){
    SDA=1;
    waite();
    SCL=1;
    waite();
    SDA=0;
    waite();
	SCL=0;
}

void stop(){
    SDA=0;
    waite();
    SCL=1;
    waite();
    SDA=1;
    waite();
	SCL=0;
}

void send_byte(uchar byte){
    uchar i;
    for(i = 0; i < 8; i++){
        SCL = 0;
        waite();
        if(byte & 0x80) SDA = 1;
        else            SDA = 0;
        waite();
        SCL = 1;
        waite();
        byte <<= 1;
    }
    SCL = 0;
    waite();
    SDA = 1;
    waite();
}

uchar read_byte(){
    uchar dat, i;
    SCL = 0;
    waite();
    SDA = 1;
    waite();
    for(i = 0; i < 8; i++){
        dat <<= 1;
        SCL = 1;
        waite();
        if(SDA) dat = dat | 0x01;
        else    dat = dat & 0xfe;
        waite();
        SCL = 0;
        waite();
    }
	return dat;
}

bit Test_ACK(){
	SDA = 0;
	waite();
    SCL = 1;
    waite();
    SCL = 0;
    waite();
    if(SDA){
        stop();
        return 0;
    }
    else return 1;
}

void Master_ACK(bit i){
    SCL = 0;
    waite();
    if(i) SDA = 0;
    else SDA = 1;
    waite();
    SCL = 1;
    waite();
    SCL = 0;
    waite();
    SDA = 1;
    waite();
}

void init_ds1307(uchar hour, uchar minute, uchar second){
    init();
    start();
    send_byte(DS1307_ADDR+0);
    how();
    send_byte(0x00);
    how();
    send_byte(second);
    how();
	send_byte(minute);
    how();
	send_byte(hour);
    how();
    stop();
}

struct dat read_ds1307(struct dat now_time){
    start();
    send_byte(DS1307_ADDR+0);
    how();
    send_byte(0x00);
    Master_ACK(0);
	stop();
    start();
    send_byte(DS1307_ADDR+1);
    how();
	now_time.second = BCD2num(read_byte());
	Master_ACK(1);
   	stop();
	start();
    send_byte(DS1307_ADDR+0);
    how();
    send_byte(0x01);
    Master_ACK(0);
	stop();
    start();
    send_byte(DS1307_ADDR+1);
    how();
    now_time.minute = BCD2num(read_byte());
    Master_ACK(1);
    stop();	
	start();
    send_byte(DS1307_ADDR+0);
    how();
    send_byte(0x02);
    Master_ACK(0);
	stop();
    start();
    send_byte(DS1307_ADDR+1);
    how();
    now_time.hour = BCD2num(read_byte());
    Master_ACK(1);
    stop();
	return now_time;
}

void show_time(struct dat sj, int line){
    int i = 0;
    char ch[] = "        00:00:00";
    char now[] = "00";
    num2str(now, sj.hour, 2);
    for(i = 0; i < 2; i++) {
        ch[9+i] = now[i];
        now[i] = '0';
    }
    num2str(now, sj.minute, 2);
    for(i = 0; i < 2; i++) {
        ch[11+i] = now[i];
        now[i] = '0';
    }
    num2str(now, sj.second, 2);
    for(i = 0; i < 2; i++) {
        ch[14+i] = now[i];
        now[i] = '0';
    }
    SetWindow(line, 0, ch);
}

char BCD2num(char b){
	int num = 0;
	num = b/16;
	num = num*10+b%16;
	return num;
}

uint real_time(struct dat time1){
	return time1.hour*3600 + time1.minute*60 + time1.second;
}

void waite(){
    for(count_down = 0; count_down < 5; count_down++);
}

void pause_time(){
	init_ds1307(pause_t.hour, pause_t.minute, pause_t.second);
	read_ds1307(a_time);
	whl_time.hour = pause_whl.hour;
	whl_time.minute = pause_whl.minute;
	whl_time.second = pause_whl.second;
	process_pause = !process_pause;
}

void how(){
	if(!Test_ACK()) ACK_flag = 1;
} 

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值