1.题目
2.重点代码
eeprom的写
由于eeprom连续写有延迟问题,所以需要加大约5ms的间隔,这里我使用了4ms
另外存放的数据过大的话,需要分开,例如频率要拆开分为高8位和低8位
if(flag_keep == 1)
{
if(flag_4ms)
{
flag_4ms = 0;
switch(index)
{
case 0:write_eeprom(H_volt,0x00);break;
case 1:write_eeprom(H_temper>>8,0x01);break;
case 2:write_eeprom(H_temper&0xff,0x02);break;
case 3:write_eeprom(H_fre>>8,0x03);break;
case 4:write_eeprom(H_fre&0xff,0x04);break;
}
index++;
if(index == 5)
{
index = 0;
flag_keep = 0;
}
}
}
eeprom的读
因为写入的数据是分开的,所以读出时记得整合起来,(转为无符号整形)高8位或运算低8位
void Read_Data()
{
H_volt = Read_eeprom(0x00);
H_temper = (uint)(Read_eeprom(0x01)<<8)|(Read_eeprom(0x02));
H_fre = (uint)(Read_eeprom(0x03)<<8)|(Read_eeprom(0x04));
}
长按键
长按键事件在中断里判断
首先判断按下时间是否超过0.8s,超过时进入长按时间,每隔200ms,增加一个阈值
否则计数清零,标志位置零
if(flag_s3_press == 1)
{
t3++;
if(t3 >= 400)
{
t3 = 0;
flag_long_press = 1;
}
if(flag_long_press == 1)
{
if(t3 >= 100)
{
t3 = 0;
valve++;
if(valve >= 50) valve = 1;
}
}
}
else
{
t3 = 0;
flag_long_press = 0;
}
3.代码
main.c
******************************************************************************
* 文件名:多功能测量仪表
* 描 述:
* 作 者:思索与猫
* 日 期: 19/5/18
* 备 注:
*
******************************************************************************
#include<stc15f2k60s2.h>
#include<sys.h>
unsigned char volt;
unsigned int fre,temper;
bit flag_keep,flag_warning;
void main()
{
static uchar index = 0;
CloseFucker();
Timer1Init(); //定时器配置
Timer0Init(); //计数器配置
pcf859_init();
valve = Read_eeprom(0x05); //读取阈值
while(1)
{
KeyDriver();
ShowNumber();
if(flag_ad == 1) //读取AD
{
flag_ad = 0;
volt = read_adc();
volt = volt*50/255;
if(volt >= valve) //判断是否超过阈值
{
flag_warning = 1;
}
else
{
flag_warning = 0;
}
}
if(flag_fre == 1) //测量频率
{
flag_fre = 0;
TR0 = 0;
fre = TH0*256+TL0;
fre = fre*2;
TH0 = 0;
TL0 = 0;
TR0 = 1;
}
if(flag_temp == 1) //测量温度(带小数)
{
flag_temp = 0;
temper = (uint)100*ReadTemp(); //一共四位,两位整数,两位小数
}
if(flag_keep == 1) //保存功能
{
if(flag_4ms) //每隔4ms写入一次eeprom
{
flag_4ms = 0;
switch(index)
{
case 0:write_eeprom(H_volt,0x00);break; //电压值
case 1:write_eeprom(H_temper>>8,0x01);break; //温度高8位
case 2:write_eeprom(H_temper&0xff,0x02);break; //温度低8位
case 3:write_eeprom(H_fre>>8,0x03);break; //频率高8位
case 4:write_eeprom(H_fre&0xff,0x04);break; //频率低8位
}
index++;
if(index == 5)
{
index = 0;
flag_keep = 0;
}
}
}
}
}
sys.c
#include<sys.h>
bit flag_ad = 1,flag_fre = 0,flag_temp = 0,flag_4ms = 0;
uchar led[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
bit flag_long_press;
void Timer0Init() // 计数器
{
TMOD = 0x04;
TL0 = 0;
TH0 = 0;
TF0 = 0;
TR0 = 1;
}
void Timer1Init() //2ms@12.000MHz
{
AUXR |= 0x40;
TMOD &= 0x0F;
TL1 = 0x40;
TH1 = 0xA2;
TF1 = 0;
TR1 = 1;
ET1 = 1;
EA = 1;
}
void Read_Data() //读取数据
{
H_volt = Read_eeprom(0x00);
H_temper = (uint)(Read_eeprom(0x01)<<8)|(Read_eeprom(0x02));
H_fre = (uint)(Read_eeprom(0x03)<<8)|(Read_eeprom(0x04));
}
void T1_time() interrupt 3
{
static uint ad_count,fre_count,temp_count,count_4ms,count_200ms,t3;
KeyScan();
Display();
if(++count_4ms >= 2)
{
count_4ms = 0;
flag_4ms = 1;
}
if(++ad_count >= 200) //400ms读取一次ad
{
ad_count = 0;
flag_ad = 1;
}
if(++fre_count >= 250) //500ms读取一次频率
{
fre_count = 0;
flag_fre = 1;
}
if(++temp_count >= 200) //400ms读取一次温度
{
temp_count = 0;
flag_temp = 1;
}
if(flag_warning == 1) //L8闪烁
{
if(++count_200ms >= 100)
{
count_200ms = 0;
ShowLed(led[7]|led[view]);
}
else
{
ShowLed(led[view]);
}
}
else if(flag_warning == 0)
{
ShowLed(led[view]);
}
if(flag_s3_press == 1) //长按键加阈值,长按1S加0.5
{
t3++;
if(t3 >= 400)
{
t3 = 0;
flag_long_press = 1;
}
if(flag_long_press == 1)
{
if(t3 >= 100)
{
t3 = 0;
valve++;
if(valve >= 50) valve = 1;
}
}
}
else
{
t3 = 0;
flag_long_press = 0;
}
}
void CloseFucker()
{
P2 = P2&0x1f|0xa0;
P0 = 0xaf;
P2 = P2&0x1f;
}
sys.h
#ifndef __SYS_H_
#define __SYS_H_
#include<stc15f2k60s2.h>
#include<onewire.h>
#include<iic.h>
typedef unsigned char uchar;
typedef unsigned int uint;
void Timer0Init();
void Timer1Init();
void Read_Data();
void CloseFucker();
void Display();
void ShowNumber();
void ShowLed(uchar led_dat);
void KeyDriver();
void KeyAction(uchar key_value);
void KeyScan();
extern uchar view;
extern uchar valve;
extern uchar led[];
extern bit H_mode,mode;
extern uchar volt,H_volt;
extern uint fre,temper,H_fre,H_temper;
extern bit flag_ad,flag_fre,flag_temp,flag_keep,flag_4ms,flag_warning;
extern bit flag_s3_press;
#endif
display.c
#include<sys.h>
uchar code duan[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F, //整数
0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF, //小数
0x00, //20black
0x40,0x3E,0x71,0x39,0x76,0x73};// 21-,22U,23F,24C,25H,26P
uchar disbuf[8];
uchar view = 0;
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[disbuf[index]];
P2 = P2&0x1f;
index++;
index &= 0x07;
}
void ShowNumber()
{
uint temp;
if(mode == 0)
{
if(view == 0) //电压显示界面
{
if(H_mode == 1)
{
temp = H_volt;
disbuf[0] = 25;
disbuf[1] = 22;
}
else
{
temp = volt;
disbuf[0] = 22;
disbuf[1] = 20;
}
disbuf[2] = 20;
disbuf[3] = 20;
disbuf[4] = 20;
disbuf[5] = 20;
disbuf[6] = temp/10+10;
disbuf[7] = temp%10;
}
else if(view == 1) //频率显示界面
{
if(H_mode == 1)
{
temp = H_fre;
disbuf[0] = 25;
disbuf[1] = 23;
}
else
{
temp = fre;
disbuf[0] = 23;
disbuf[1] = 20;
}
disbuf[2] = 20;
if(temp/10000 == 0)
{
disbuf[3] = 20;
}
else
{
disbuf[3] = temp/10000;
}
if(disbuf[3] == 20&&temp/1000%10 == 0)
{
disbuf[4] = 20;
}
else
{
disbuf[4] = temp/1000%10;
}
if(disbuf[4] == 20&&temp/100%10 == 0)
{
disbuf[5] = 20;
}
else
{
disbuf[5] = temp/100%10;
}
if(disbuf[5] == 20&&temp/10%10 == 0)
{
disbuf[6] = 20;
}
else
{
disbuf[6] = temp/10%10;
}
if(disbuf[6] == 20&&temp%10 == 0)
{
disbuf[7] = 20;
}
else
{
disbuf[7] = temp%10;
}
}
else if(view == 2) //温度显示界面
{
if(H_mode == 1)
{
temp = H_temper;
disbuf[0] = 25;
disbuf[1] = 24;
}
else
{
temp = temper;
disbuf[0] = 24;
disbuf[1] = 20;
}
disbuf[2] = 20;
disbuf[3] = 20;
disbuf[4] = temp/1000;
disbuf[5] = temp/100%10+10;
disbuf[6] = temp/10%10;
disbuf[7] = temp%10;
}
}
else if(mode == 1) //阈值显示界面
{
disbuf[0] = 26;
disbuf[1] = 20;
disbuf[2] = 20;
disbuf[3] = 20;
disbuf[4] = 20;
disbuf[5] = 20;
disbuf[6] = valve/10+10;
disbuf[7] = valve%10;
}
}
void ShowLed(uchar led_dat)
{
P2 = P2&0x1f|0x80;
P0 = ~led_dat;
P2 = P2&0x1f;
}
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] = {1, 2, 3, 4};
uchar H_volt;
uchar valve;
uint H_fre,H_temper;
bit H_mode = 0,mode = 0;
bit flag_s3_press;
void KeyDriver()
{
static uchar KeyBack[4] = {1, 1, 1, 1};
uchar i = 0;
for(i=0; i<4; i++)
{
if(KeySta[i] != KeyBack[i])
{
if(KeySta[i] == 0)
{
KeyAction(KeyCodeMap[i]);
}
KeyBack[i] = KeySta[i];
}
}
}
void KeyAction(uchar key_value)
{
if(key_value == 4) //设置按钮
{
mode = ~mode;
ShowLed(0x08);
}
if(mode == 0)
{
if(key_value == 1) //切换按钮
{
view++;
if(view >= 3) view = 0;
ShowLed(led[view]);
}
if(key_value == 2) //保存按钮
{
flag_keep = 1;
H_volt = volt;
H_fre = fre;
H_temper = temper;
}
if(key_value == 3) //回调按钮
{
Read_Data();
H_mode = ~H_mode;
}
}
else if(mode == 1)
{
if(key_value == 3) //增加阈值按钮
{
flag_s3_press = 1;
valve = valve+1;
if(valve >= 50) valve = 1;
write_eeprom(valve,0x05);
}
}
}
void KeyScan()
{
static uchar KeyBuf[4] = {0xff, 0xff, 0xff, 0xff};
uchar i = 0;
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<3; i++)
{
if(KeyBuf[i] == 0xff)
{
KeySta[i] = 1;
}
else if(KeyBuf[i] == 0x00)
{
KeySta[i] = 0;
}
else
{
if(flag_s3_press) //发生抖动,长按键取消
{
flag_s3_press = 0;
}
}
}
}
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;
}
float ReadTemp()
{
unsigned char low,high;
unsigned int temp;
float temper;
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&0x0f;
temp = temp<<8|low;
temper = temp*0.0625;
return temper;
}
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);
float ReadTemp();
#endif
iic.c
#include "iic.h"
void Delay5us() //@12.000MHz
{
unsigned char i;
_nop_();
_nop_();
i = 12;
while (--i);
}
void IIC_Start(void)
{
SDA = 1;
SCL = 1;
somenop;
SDA = 0;
somenop;
SCL = 0;
}
void IIC_Stop(void)
{
SDA = 0;
SCL = 1;
somenop;
SDA = 1;
}
void IIC_Ack(unsigned char ackbit)
{
if(ackbit)
{
SDA = 0;
}
else
{
SDA = 1;
}
somenop;
SCL = 1;
somenop;
SCL = 0;
SDA = 1;
somenop;
}
bit IIC_WaitAck(void)
{
SDA = 1;
somenop;
SCL = 1;
somenop;
if(SDA)
{
SCL = 0;
IIC_Stop();
return 0;
}
else
{
SCL = 0;
return 1;
}
}
void IIC_SendByte(unsigned char byt)
{
unsigned char i;
for(i=0;i<8;i++)
{
if(byt&0x80)
{
SDA = 1;
}
else
{
SDA = 0;
}
somenop;
SCL = 1;
byt <<= 1;
somenop;
SCL = 0;
}
}
unsigned char IIC_RecByte(void)
{
unsigned char da;
unsigned char i;
for(i=0;i<8;i++)
{
SCL = 1;
somenop;
da <<= 1;
if(SDA)
da |= 0x01;
SCL = 0;
somenop;
}
return da;
}
unsigned char Read_eeprom(unsigned char add)
{
unsigned char dat;
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(add);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0xa1);
IIC_WaitAck();
dat = IIC_RecByte();
IIC_WaitAck();
IIC_Stop();
return dat;
}
void write_eeprom(unsigned char dat,unsigned char add)
{
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(add);
IIC_WaitAck();
IIC_SendByte(dat);
IIC_WaitAck();
IIC_Stop();
}
void pcf859_init()
{
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(0x03);
IIC_WaitAck();
IIC_Stop();
}
unsigned char read_adc()
{
unsigned char dat;
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
dat = IIC_RecByte();
IIC_WaitAck();
IIC_Stop();
return dat;
}
iic.h
#ifndef _IIC_H
#define _IIC_H
#include "stc15f2k60s2.h"
#include "intrins.h"
#define somenop Delay5us()
#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1
sbit SDA = P2^1;
sbit SCL = P2^0;
void Delay5us();
void IIC_Start(void);
void IIC_Stop(void);
void IIC_Ack(unsigned char ackbit);
void IIC_SendByte(unsigned char byt);
bit IIC_WaitAck(void);
unsigned char IIC_RecByte(void);
unsigned char Read_eeprom(unsigned char add);
void write_eeprom(unsigned char dat,unsigned char add);
void pcf859_init();
unsigned char read_adc();
#endif