- 打卡等级:初来乍到
- 打卡总天数:1
- 最近打卡:2025-03-17 16:39:04
中级会员
- 积分
- 253
|
#include<STC15W408AS.H> //库文件
#include<intrins.h>
#define uchar unsigned char//宏定义无符号字符型
#define uint unsigned int //宏定义无符号整型
#define ADC_POWER 0x80 //ADC 电源控制位
#define ADC_FLAG 0x10 //ADC 转换结束标志位
#define ADC_START 0x08 //ADC 开始转换控制位
#define ADC_SPEEDLL 0x00 //210 个时钟周期转换一次
#define ADC_SPEEDL 0x20 //420 个时钟周期转换一次
#define ADC_SPEEDH 0x40 //630 个时钟周期转换一次
#define ADC_SPEEDHH 0x60 //840 个时钟周期转换一次
typedef unsigned char INT8U;
typedef unsigned int INT16U;
#define ENABLE_ISP 0x82 //系统工作时钟<20MHz 时,对IAP_CONTR 寄存器设置此值
#define WD1 0x5a //使用STC11xx系列单片机时,先写入0x5a,然写入0xa5
#define WD2 0xa5
char IAPAddr=0;
/********************************************************************
初始定义
*********************************************************************/
code uchar seg7code[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; //显示段码 数码管字跟
/********************************************************************
I/O定义
*********************************************************************/
bit ba=0,ba1=0,ba2=0,ba3=0,ba4=0,ba5=0,zs=0,k=0,z=0;
uchar smg2=0,y=0,s1=0,s2=0;
uint qian=0,bai=0,shi=0,ge=0,wendu=0,wendu1=0,wendu2=0,wendu3=0,wendu4=0,js=0,s3=0,s=0,s4=0;
sbit SO=P1^7;//
sbit CS=P5^4;
sbit SCK=P5^5;
sbit aj1=P3^1;
sbit aj2=P3^0;
sbit out=P3^4;
sbit L1=P3^5;//数码管位控制
sbit L2=P3^6;//数码管位控制
sbit L3=P3^7;//数码管位控制
sbit dp=P3^3;//小数点
bit kt=0,kt_1=0;
unsigned long Temp_3=0;
uchar trg=0,trg_1=0,cont=0,cont_1=0;
uchar ReadData=0,ReadData_1=0;
/********************************************************************
E2P函数
*********************************************************************/
union union_temp16
{
INT16U un_temp16;
INT8U un_temp8[2];
}my_unTemp16;
INT8U Byte_Read(INT16U add); //读一字节,调用前需打开IAP 功能
void Byte_Program(INT16U add, INT8U ch); //字节编程,调用前需打开IAP 功能
void Sector_Erase(INT16U add); //擦除扇区
void IAP_Disable(); //关闭IAP 功能
/*******************************************************************
* MAX6675读取程序
********************************************************************/
uint Re_Convert() //热电偶数据读取,返回温度
{ uchar i=0;
unsigned long Temp_2=0;
CS=1;
SCK=0;
_nop_();_nop_();
//这个_nop_()等效与汇编里面的NOP指令,也就是空一个机器周期,
//在51单片机中_nop_()等于空12个时钟周期【即一个机器周期】
CS=0;
for(i=0;i<16;i++)//16位数据读取
{
Temp_2<<=1;//向右移一位
_nop_();
SCK=1;//上升
if(SO==1){Temp_2=Temp_2|0x01;}
else Temp_2=Temp_2|0x00;
_nop_();
SCK=0;
_nop_();
}
CS=1; //读取完后对CS置1进行温度转换!MAX6675的转换时间是典型值:0.17s,最大值0.22s。
Temp_3=Temp_2;
Temp_2=Temp_2<<1; //向左移一位,取0-14位
Temp_2=Temp_2>>4; //向右移4位,取3-14位
Temp_2=(Temp_2*10)/4;//变换为温度值--每LSB代表0.25度,注意:在此处先乘了个10
// Temp_2=Temp_2&0x7fff;//去掉最后一位
// Temp_2=Temp_2>>3; //去掉前三位
// Temp_2=Temp_2*10/4;
Temp_2=Temp_2-50;//补偿温度
return(Temp_2);
}
/*******************************************************************
* 读取按键状态
********************************************************************/
void KeyRead()//读取按键IO口函数
{
ReadData = aj1^0xff; // 读取按键状态取反后赋值给ReadData
trg = ReadData & (ReadData ^ cont); //trg短按,每按下按键trg=1;抬手后为trg=0,长按为trg=0
cont = ReadData; //cont长按,长按cont=1,抬手后cont=0
ReadData_1 = aj2^0xff; // 读取按键状态取反后赋值给ReadData
trg_1 = ReadData_1 & (ReadData_1 ^ cont_1); //trg短按,每按下按键trg=1;抬手后为trg=0,长按为trg=0
cont_1 = ReadData_1; //cont长按,长按cont=1,抬手后cont=0
}
/*******************************************************************
* 按键
********************************************************************/
void key_1()
{
if(trg & 0x01) //短按
{
kt_1=0;
kt=1; //这是短按标志位,kt=1说明短按了
}
if((aj1!=0)&&(kt==1))//判断
{
z=1; // 选位标志位
y++; //选位
// out=1;
if(y==5)
{
s4=s;
z=0;
k=1;
y=0;
// s=s1+s2+s3;
}
kt=0;
} // 短按
}
void key_2()
{
if(trg_1 & 0x01) //短按
{
kt=0;
kt_1=1; //这是短按标志位,kt=1说明短按了
}
if((aj2!=0)&&(kt_1==1))//判断
{
if(y==1)
{
s1++;
if(s1>9)
{
s1=0;
}
}
if(y==2)
{
s2+=10;
if(s2>90)
{
s2=0;
}
}
if(y==3)
{
s3+=100;
if(s3>900)
{
s3=0;
}
}
kt_1=0;
} // 短按
}
/*******************************************************************
* 定时器配置
********************************************************************/
void ConfigTimer0(){
TMOD=0x01;//将定时器0,1都设置为模式1
TL0 = 0x66; //设置定时初值
TH0 = 0xFC; //设置定时初值1ms
TR0=1;//开启定时器0
ET0=1;//开定时器0的中断
EA=1;//开总中断
}
/*******************************************************************
* 显示
********************************************************************/
void led(uint date)
{
bai=date/100;
shi=date%100/10;
ge=date%10;
}
/*******************************************************************
* t0定时器
********************************************************************/
void timer0() interrupt 1
{
TL0 = 0x66; //设置定时初值1ms
TH0 = 0xFC; //设置定时初值
js++;
if(js==100){ba=1;}
if(js==400){ba1=1;}
if(js==700){ba2=1;}
if(js==1000){ba3=1;}
KeyRead(); //按键扫描
if(z==0){
smg2++;
}
else{
smg2=y;//让逐个显示位
}
switch(smg2){ //数码管扫描
/**************数码管-开始*****************/
case 1: P1=seg7code[ge];L3=1;L2=1;L1=0;dp=0;break;//从P2进P0出
case 2: P1=seg7code[shi];L3=1;L2=0;L1=1;if(zs==0){dp=0;}else{dp=1;}break;
case 3: P1=seg7code[bai]; L3=0;L2=1;L1=1;dp=0;break;
/**************数码管-结束*****************/
default: smg2=0;L3=1;L2=1;L1=1;break;
}
}
/********************************************************************
主函数
*********************************************************************/
void main()
{
P1M0 = 0xff; //设置强推挽和开漏模式
P1M1 = 0x80;
P3M0 = 0x08; //小数点使用
P3M1 = 0x00;
ConfigTimer0();
if(Byte_Read(0X0001)==0xff){s1=0;s2=0;s3=0;}//首次读取,如果读到0xFF说明没有存过数据,直接付给00值
else
{
s1=Byte_Read(0X0001);
s2=Byte_Read(0X0002);
s3=Byte_Read(0X0003);
}
s3=s3*100;
s2=s2*10;
s=s3+s2+s1;
while(1)
{
if(ba==1) {zs=0;wendu = Re_Convert();ba=0;}
if(ba1==1){zs=0;wendu1 = Re_Convert();ba1=0;}
if(ba2==1){zs=0;wendu2 = Re_Convert();ba2=0;}
if(ba3==1){zs=0;wendu3 = Re_Convert();wendu4 = ((wendu+wendu1+wendu2+wendu3)/40);ba3=0;js=0;}
if((y==0)&&(z==0))
{
if((Temp_3&0x04)==0){led(wendu4);}else{led(0);} //断线归0
}
if(y==1){zs=0;led(s1);}
if(y==2){zs=0;led(s2);}
if(y==3){zs=0;led(s3);}
if(y==4){zs=0;z=0;s=s1+s2+s3;led(s);}
if(wendu4>s4){out=0;}else{out=1;}
key_1();
key_2();
if(k==1)
{
Sector_Erase(0);
Byte_Program(0x0001,s1); //写入扇区
Byte_Program(0x0002,(s2/10)); //写入扇区
Byte_Program(0x0003,(s3/100)); //写入扇区
k=0;
}
}
}
//读一字节,调用前需打开IAP 功能,入口:DPTR = 字节地址,返回:A = 读出字节
INT8U Byte_Read(INT16U add)
{
IAP_DATA = 0x00;
IAP_CONTR = ENABLE_ISP; //打开IAP 功能, 设置Flash 操作等待时间
IAP_CMD = 0x01; //IAP/ISP/EEPROM 字节读命令
my_unTemp16.un_temp16 = add;
IAP_ADDRH = my_unTemp16.un_temp8[0]; //设置目标单元地址的高8 位地址
IAP_ADDRL = my_unTemp16.un_temp8[1]; //设置目标单元地址的低8 位地址
//EA = 0;
IAP_TRIG = WD1; //先送 WD1,再送WD2 到ISP/IAP 触发寄存器,每次都需如此
IAP_TRIG = WD2; //送完WD2 后,ISP/IAP 命令立即被触发起动
_nop_();
//EA = 1;
IAP_Disable(); //关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态,
//一次连续的IAP 操作完成之后建议关闭IAP 功能,不需要每次都关
return (IAP_DATA);
}
/*********************************************************************************************/
//字节编程,调用前需打开IAP 功能,入口:DPTR = 字节地址, A= 须编程字节的数据
void Byte_Program(INT16U add, INT8U ch)
{
IAP_CONTR = ENABLE_ISP; //打开 IAP 功能, 设置Flash 操作等待时间
IAP_CMD = 0x02; //IAP/ISP/EEPROM 字节编程命令
my_unTemp16.un_temp16 = add;
IAP_ADDRH = my_unTemp16.un_temp8[0]; //设置目标单元地址的高8 位地址
IAP_ADDRL = my_unTemp16.un_temp8[1]; //设置目标单元地址的低8 位地址
IAP_DATA = ch; //要编程的数据先送进IAP_DATA 寄存器
//EA = 0;
IAP_TRIG = WD1; //先送 WD1,再送WD2 到ISP/IAP 触发寄存器,每次都需如此
IAP_TRIG = WD2; //送完WD2 后,ISP/IAP 命令立即被触发起动
_nop_();
//EA = 1;
IAP_Disable(); //关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态,
//一次连续的IAP 操作完成之后建议关闭IAP 功能,不需要每次都关
}
/*********************************************************************************************
//擦除扇区, 入口:DPTR = 扇区地址 */
void Sector_Erase(uint addr)
{
IAP_CONTR = ENABLE_ISP; //打开IAP 功能, 设置Flash 操作等待时间
IAP_CMD = 3; //IAP/ISP/EEPROM 扇区擦除命令
// my_unTemp16.un_temp16 = add;
IAP_ADDRH = addr>>8; //设置目标单元地址的高8 位地址
IAP_ADDRL = addr; //设置目标单元地址的低8 位地址
IAP_TRIG = 0x5a; //先送 WD1,再送WD2 到ISP/IAP 触发寄存器,每次都需如此
IAP_TRIG = 0xa5; //送完WD2 后,ISP/IAP 命令立即被触发起动
_nop_();
//EA = 1;
IAP_Disable(); //关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态,
//一次连续的IAP 操作完成之后建议关闭IAP 功能,不需要每次都关
}
/*********************************************************************************************/
void IAP_Disable()
{
//关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态,
//一次连续的IAP 操作完成之后建议关闭IAP 功能,不需要每次都关
IAP_CONTR = 0; //关闭IAP 功能
IAP_CMD = 0; //清命令寄存器,使命令寄存器无命令,此句可不用
IAP_TRIG = 0; //清命令触发寄存器,使命令触发寄存器无触发,此句可不用
IAP_ADDRH = 0x80;
IAP_ADDRL = 0;
}
/*********************************************************************************************/
|
|