题目
这里初次使用sys.h封装系统使用
关于外部变量注意:
c/c++语言中有很多地方要用到extern,但是如果没有真正的了解它的意义,会给编程带来很大的麻烦,为了使大家少走弯路,特祥细的说明一下。
对于比较小的程序,一般只有一个c文件和一个头文件,全局变量我们通常会直接定义在c文件中,在程序之前加int i定义。如果要在头文件中定义有以下两种方法:用extern来声明:extern int i;这一句只是对变量i进行声明,在c文件的程序之前必须加上int i进行定义。extern int i=0;这一句声明和定义都做了。
对于大一点的程序,有很多c文件和头文件,这个时候全局变量就必须在头文件中声明(不需要初始化),然后在一个c文件中定义(该初始化的要初始化)。如果在头文件中定义,则编译的时候会出现重复定义的错误。如果只有头文件中声明就会出现没有定义有警告。
*** ERROR L104: MULTIPLE PUBLIC DEFINITIONS
SYMBOL: K
MODULE: 222.obj (222)
出现上述错误则是因为变量k重复定义,把你的头文件中的变量定义前加extern(只是变量声明不用初始化),再在某一个你要调用该变量的c文件的程序之前再定义(注意第一个调用的c文件要负责附带初始化该变量,其他调用的c文件就不需要初始化过程啦)
关于按键:
这里用了定时扫描独立按键,详细说明在这里: 定时扫描独立键盘
代码:
main.c
******************************************************************************
* 文件名:温度记录器
* 描 述:
* 作 者:思索与猫
* 日 期: 19/3/15
* 备 注:
*
******************************************************************************
#include<stc15f2k60s2.h>
#include<sys.h>
uchar temp_range[10]; //使用数组,温度[10]
uchar index = 0; //索引
uchar mode = 0; //模式
bit t_flag = 0; //读取温度标志位
void main()
{
CloseFucker();
Timer0Init();
while(1)
{
if(mode == 1&&t_flag == 1) //读取温度
{
t_flag = 0;
temp_range[index] = ReadTemp(); //一个一个赋值
index++;
if(index >= 10) //采集到10个温度index复位,进入模式2
{
mode = 2;
light = 1; //L1闪烁
index = 0;
}
}
ShowTable(); //显示数码管
KeyDriver(); //键盘驱动
}
}
sys.h
#ifndef __SYS_H_
#define __SYS_H_
typedef unsigned char uchar;
typedef unsigned int uint;
#include<stc15f2k60s2.h>
#include<onewire.h>
#include<ds1302.h>
//初始化
void CloseFucker();
void Timer0Init();
//显示
void ShowTable();
void Display();
void ShowLed(uchar led_dat);
//按键
void KeyScan();
void KeyDriver();
void KeyAction(uchar temp);
//外部变量
extern uchar temp_range[];
extern uchar interval[];
extern uchar length;
extern uchar index;
extern uchar shi,fen,miao;
extern uchar mode;
extern bit t_flag;
extern bit smg_flag;
extern bit led_flag;
extern bit light;
#endif
sys.c
#include<sys.h>
bit smg_flag;
bit led_flag;
bit light;
void CloseFucker()
{
P2 = P2&0x1f|0xa0;
P0 = 0xaf;
P2 = P2&0x1f;
}
void Timer0Init() //2ms@12.000MHz
{
AUXR |= 0x80;
TMOD &= 0xF0;
TL0 = 0x40;
TH0 = 0xA2;
TF0 = 0;
TR0 = 1;
ET0 = 1;
EA = 1;
}
void T0_time() interrupt 1
{
static int count = 0, t_count = 0;
TL0 = 0x40;
TH0 = 0xA2;
KeyScan();
Display();
if(++count >= 500) //1S
{
smg_flag = ~smg_flag;
led_flag = ~led_flag;
count = 0;
t_count++;
}
if(mode == 1&&t_count >= length) //经过length秒,扫描一次温度
{
t_count = 0;
t_flag = 1;
}
else if(mode != 1)
{
t_count = 0;
t_flag = 0;
}
if(mode == 2&&light == 1) //控制LED灯
{
if(led_flag == 1) //闪烁
{
ShowLed(0xfe);
}
else if(led_flag == 0)
{
ShowLed(0xff);
}
}
else if(light == 0) //全灭
{
ShowLed(0xff);
}
}
key.c
#include<sys.h>
sbit Key_In_1 = P3^0;
sbit Key_In_2 = P3^1;
sbit Key_In_3 = P3^2;
sbit Key_In_4 = P3^3;
uchar KeySta[4] = {1, 1, 1, 1};
uchar KeyCodeMap[4] = {7, 6, 5, 4};
void KeyDriver()
{
uchar i = 0;
static uchar keyback[4] = {1, 1, 1, 1};
for(i=0; i<4; i++)
{
if(KeySta[i] != keyback[i])
{
if(KeySta[i] == 1)
{
KeyAction(KeyCodeMap[i]);
}
keyback[i] = KeySta[i];
}
}
}
void KeyAction(uchar key_value) //按键
{
static uchar i = 0;
if(mode == 0) //模式0情况下
{
if(key_value == 4) //按下S4,切换温度间隔扫描时间
{
i++;
i &= 0x03;
length = interval[i];
}
else if(key_value == 5) //按下S5,进入模式1
{
mode = 1;
index = 0;
SetTime(23, 59, 50); //开始计时
}
}
if(mode == 2) //模式2情况下
{
if(key_value == 6) //按下s6,L1灭,显示温度
{
light= 0;
index++;
if(index >= 10)
{
index = 0;
}
}
if(key_value == 7) //按下S7,回到模式0
{
mode = 0;
index = 0;
i = 0;
}
}
}
void KeyScan()
{
uchar i = 0;
static KeyBuf[4] = {0xff, 0xff, 0xff, 0xff};
KeyBuf[0] = (KeyBuf[0]<<1)|Key_In_1;
KeyBuf[1] = (KeyBuf[1]<<1)|Key_In_2;
KeyBuf[2] = (KeyBuf[2]<<1)|Key_In_3;
KeyBuf[3] = (KeyBuf[3]<<1)|Key_In_4;
for(i=0; i<8; i++)
{
if(KeyBuf[i] == 0x00)
{
KeySta[i] = 0;
}
else if(KeyBuf[i] == 0xff)
{
KeySta[i] = 1;
}
else
{
;
}
}
}
display.c
#include<sys.h>
uchar code duan[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00,0x40}; //10black,11-
uchar Table[8];
uchar length = 1;
uchar interval[] = {1, 5, 30, 60};
uchar shi,fen,miao;
void Display()
{
static uchar index = 0;
P2 = P2&0x1f|0xe0;
P0 = 0xff;
P2 = P2&0x1f;
P2 = P2&0x1f|0xc0;
P0 = 1<<index;
P2 = P2&0x1f;
P2 = P2&0x1f|0xe0;
P0 = ~duan[Table[index]];
P2 = P2&0x1f;
index++;
index &= 0x07;
}
void ShowTable()
{
if(mode == 0) //模式0界面
{
Table[0] = 10;
Table[1] = 10;
Table[2] = 10;
Table[3] = 10;
Table[4] = 10;
Table[5] = 11;
Table[6] = length/10;
Table[7] = length%10;
}
else if(mode == 1) //模式1界面
{
miao = Ds1302_Single_Byte_Read(0x81);
Ds1302_Single_Byte_Write(0x00,0x00);
fen = Ds1302_Single_Byte_Read(0x83);
Ds1302_Single_Byte_Write(0x00,0x00);
shi = Ds1302_Single_Byte_Read(0x85);
Ds1302_Single_Byte_Write(0x00,0x00);
Table[0] = shi/16;
Table[1] = shi%16;
Table[3] = fen/16;
Table[4] = fen%16;
Table[6] = miao/16;
Table[7] = miao%16;
if(smg_flag == 1)
{
Table[2] = 11;
Table[5] = 11;
}
else if(smg_flag == 0)
{
Table[2] = 10;
Table[5] = 10;
}
}
else if(mode == 2) //模式2界面
{
Table[0] = 11;
Table[1] = index/10;
Table[2] = index%10;
Table[3] = 10;
Table[4] = 10;
Table[5] = 11;
Table[6] = temp_range[index]/10;
Table[7] = temp_range[index]%10;
}
}
void ShowLed(uchar led_dat) //显示LED灯
{
P2 = P2&0x1f|0x80;
P0 = led_dat;
P2 = P2&0x1f;
}
onewire.h
#ifndef _ONEWIRE_H
#define _ONEWIRE_H
#include "stc15f2k60s2.h"
#define OW_SKIP_ROM 0xcc
#define DS18B20_CONVERT 0x44
#define DS18B20_READ 0xbe
sbit DQ = P1^4;
void Delay_OneWire(unsigned int t);
void Write_DS18B20(unsigned char dat);
bit Init_DS18B20(void);
unsigned char Read_DS18B20(void);
unsigned char ReadTemp(); //读取温度
#endif
onewire.c
#include "onewire.h"
void Delay_OneWire(unsigned int t)
{
t *= 12;
while(t--);
}
bit Init_DS18B20(void)
{
bit initflag = 0;
DQ = 1;
Delay_OneWire(12);
DQ = 0;
Delay_OneWire(80);
DQ = 1;
Delay_OneWire(10);
initflag = DQ;
Delay_OneWire(5);
return initflag;
}
void Write_DS18B20(unsigned char dat)
{
unsigned char i;
for(i=0;i<8;i++)
{
DQ = 0;
DQ = dat&0x01;
Delay_OneWire(5);
DQ = 1;
dat >>= 1;
}
Delay_OneWire(5);
}
unsigned char Read_DS18B20(void)
{
unsigned char i;
unsigned char dat;
for(i=0;i<8;i++)
{
DQ = 0;
dat >>= 1;
DQ = 1;
if(DQ)
{
dat |= 0x80;
}
Delay_OneWire(5);
}
return dat;
}
unsigned char ReadTemp()
{
unsigned char temp;
unsigned char low,high;
Init_DS18B20();
Write_DS18B20(0xcc);
Write_DS18B20(0x44);
Delay_OneWire(200);
Init_DS18B20();
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);
Delay_OneWire(200);
low = Read_DS18B20();
high = Read_DS18B20();
temp = high<<4;
temp |= (low&0xf0)>>4;
return temp;
}
ds1302.h
#ifndef __DS1302_H__
#define __DS1302_H__
#include<stc15f2k60s2.h>
#include<intrins.h>
/********************************************************************/
sbit SCK=P1^7;
sbit SD=P2^3;
sbit RST=P1^3;
/********************************************************************/
#define RST_CLR RST=0
#define RST_SET RST=1
#define SDA_CLR SD=0
#define SDA_SET SD=1
#define SDA_R SD
#define SCK_CLR SCK=0
#define SCK_SET SCK=1
/********************************************************************/
#define ds1302_sec_addr 0x80
#define ds1302_min_addr 0x82
#define ds1302_hr_addr 0x84
#define ds1302_date_addr 0x86
#define ds1302_month_addr 0x88
#define ds1302_day_addr 0x8A
#define ds1302_year_addr 0x8C
#define ds1302_control_addr 0x8E
#define ds1302_charger_addr 0x90
#define ds1302_clkburst_addr 0xBE
extern void Write_Ds1302_Byte(unsigned char dat);
extern unsigned char Read_Ds1302_Byte(void);
extern void Ds1302_Single_Byte_Write(unsigned char addr, unsigned char dat);
extern unsigned char Ds1302_Single_Byte_Read(unsigned char addr);
void SetTime(unsigned char shi, unsigned char fen, unsigned char miao); //设置时分秒
#endif
ds1302.c
#include "ds1302.h"
void Write_Ds1302_Byte(unsigned char dat)
{
unsigned char i;
SCK = 0;
for (i=0;i<8;i++)
{
if (dat & 0x01)
{
SDA_SET;
}
else
{
SDA_CLR;
}
SCK_SET;
SCK_CLR;
dat = dat >> 1;
}
}
unsigned char Read_Ds1302_Byte(void)
{
unsigned char i, dat=0;
for (i=0;i<8;i++)
{
dat = dat >> 1;
if (SDA_R)
{
dat |= 0x80;
}
else
{
dat &= 0x7F;
}
SCK_SET;
SCK_CLR;
}
return dat;
}
void Ds1302_Single_Byte_Write(unsigned char addr, unsigned char dat)
{
RST_CLR;
SCK_CLR;
RST_SET;
addr = addr & 0xFE;
Write_Ds1302_Byte(addr);
Write_Ds1302_Byte(dat);
RST_CLR;
}
unsigned char Ds1302_Single_Byte_Read(unsigned char addr)
{
unsigned char temp;
RST_CLR;
SCK_CLR;
RST_SET;
addr = addr | 0x01;
Write_Ds1302_Byte(addr);
temp=Read_Ds1302_Byte();
RST_CLR;
return temp;
}
void SetTime(unsigned char shi, unsigned char fen, unsigned char miao)
{
Ds1302_Single_Byte_Write(0x8e,0x00);
Ds1302_Single_Byte_Write(0x80,(miao/10)*16+miao);
Ds1302_Single_Byte_Write(0x82,(fen/10)*16+fen);
Ds1302_Single_Byte_Write(0x84,(shi/10)*16+shi);
Ds1302_Single_Byte_Write(0x8e,0x80);
}