标题:
单片机硬件的使用时间限制的程序 这里起抛砖引玉的作用 相当于软件狗 就是指定单片..
[打印本页]
作者:
铁牛单片机
时间:
2017-10-30 22:33
标题:
单片机硬件的使用时间限制的程序 这里起抛砖引玉的作用 相当于软件狗 就是指定单片..
前两天有客户委托做一个项目。这个项目做好后。我的客户也需要把东西交付给另外的公司。但是这个公司只付了百分之三十的订金。说好交付产品时再付百分之六十。结果交付产品时却没有兑现承诺。
所以客户要求我在程序里面加一个限制使用时间的子程序。如果三十天,或者九十天。客户还没有打款。就不能用了。
想了几天。写了一段小程序。很好用。大家有需要的可以用一下。这里起一个抛砖引玉的作用。
//2017.9.30 带狗测试。运行一段时间后停止运行
#include<reg52.h>
#include<intrins.h>
#include <stc15f102w.h>
typedef unsigned char BYTE;
typedef unsigned int WORD;
//定义端口
//sbit led = P3^4; //LED指示灯
sbit clk = P3^5; //IIC时钟
sbit dio = P3^4; //IIC数据
sbit key_add = P3^2; //加按键
sbit key_sub = P3^3;
sbit JSQ_Sig = P3^1; //计数器脉冲信号
sbit JSQ_Relay= P3^0; //计数器继电器返回信号 计数器计数到0后返回信号给电路板
unsigned char number;
unsigned char qian,bai,shi,ge,count,dog,dog_sec,dog_min,dog_hour,dog_day;
unsigned char code xsbcdbuf[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77}; //共阳数码管
//测试地址
#define IAP_ADDRESS 0x0200
void Delay(BYTE n);
void IapIdle();
BYTE IapReadByte(WORD addr);
void IapProgramByte(WORD addr, BYTE dat);
void IapEraseSector(WORD addr);
///=======================================
void Delay_us(unsigned int i) //nus 延时
{
for(;i>0;i--)
_nop_();
}
///======================================
void I2CStart(void) //1637 开始
{
clk = 1;
dio = 1;
Delay_us(2);
dio = 0;
}
///=============================================
void I2Cask(void) //1637 应答
{
clk = 0;
Delay_us(5); //在第八个时钟下降沿之后延时 5us,开始判断 ACK 信号
while(dio);
clk = 1;
Delay_us(2);
clk=0;
}
///========================================
void I2CStop(void) // 1637 停止
{
clk = 0;
Delay_us(2);
dio = 0;
Delay_us(2);
clk = 1;
Delay_us(2);
dio = 1;
}
///=========================================
void I2CWrByte(unsigned char oneByte) //写一个字节
{
unsigned char i;
for(i=0;i<8;i++)
{
clk = 0;
if(oneByte&0x01) //低位在前
{
dio = 1;
}
else
{
dio = 0;
}
Delay_us(3);
oneByte=oneByte>>1;
clk=1;
Delay_us(3);
}
}
///================================================
unsigned char ScanKey(void) //按键检测程序
{
if(key_add == 0) //按键加
{
Delay_us(10);
if(key_add==0)
{
number = number+5;
IapEraseSector(IAP_ADDRESS);
IapProgramByte(IAP_ADDRESS,number);
while(!key_add); //等待按键松手
}
}
if(key_sub == 0) //按键减
{
Delay_us(10);
if(key_sub==0)
{
number = number-5;
IapEraseSector(IAP_ADDRESS);
IapProgramByte(IAP_ADDRESS,number);
while(!key_sub); //等待按键松手
}
}
}
///================================================
void jisuan()
{
qian = number/1000;
bai = number%1000/100;
shi = number%1000%100/10;
ge = number%10;
}
void SmgDisplay(void) //写显示寄存器
{
unsigned char i;
I2CStart();
I2CWrByte(0x40); // 40H 地址自动加 1 模式,44H 固定地址模式,本程序采用自加 1 模式
I2Cask();
I2CStop();
I2CStart();
I2CWrByte(0xc1);//设置首地址,
I2Cask();
for(i=0;i<6;i++)//地址自加,不必每次都写地址
{
I2CWrByte(xsbcdbuf[bai]); //送数据
I2Cask();
I2CWrByte(xsbcdbuf[shi]); //送数据
I2Cask();
I2CWrByte(xsbcdbuf[ge]); //送数据
I2Cask();
I2CWrByte(xsbcdbuf[1]); //送数据
I2Cask();
I2CWrByte(xsbcdbuf[0]); //送数据
I2Cask();
I2CWrByte(xsbcdbuf[qian]); //送数据
I2Cask();
}
I2CStop();
I2CStart();
I2CWrByte(0x8b); //开显示 ,八级亮度调制 88 89 8a 8b 8c 8d 8e 8f
I2Cask();
I2CStop();
}
///==============================================
void init() //定时器中断初始化
{
TMOD = 0x01; //set timer0 as mode1 (16-bit)
TL0 = (65536-50000)%256; //initial timer0 low byte
TH0 = (65536-50000)/256; //initial timer0 high byte
TR0 = 1; //timer0 start running
ET0 = 1; //enable timer0 interrupt
EA = 1; //open global interrupt switch
count = 0;
number = 200;
dog_sec = 0;
dog_min = 0;
dog_hour = 0;
}
///==============================================
void dog_test()
{
dog_sec++;
if(dog_sec == 60) //60s钟让狗加1
{
dog_sec = 0;
dog_min++;
if(dog_min ==60)
{
dog_min=0;
dog_hour++;
if(dog_hour ==24) //正常是24小时。测试时用1个小时算1天。
{
dog_hour=0;
dog_day++;
IapEraseSector(0x0000);
IapProgramByte(0x0000,dog_day);
}
}
}
}
void main(void)
{
unsigned char keydate;
init(); //初始化
dog_day = IapReadByte(0x0000);
number = IapReadByte(IAP_ADDRESS);
while(1)
{
jisuan();
SmgDisplay();
ScanKey();
if(count == 20) //脉冲信号来一次。计数器减1
{
count = 0;
number--;
IapEraseSector(IAP_ADDRESS);
IapProgramByte(IAP_ADDRESS,number);
dog_test();
if(number ==0)
{
number = 255;
}
}
while(dog_day>=1); //2天后停止运行。实际上是2个小时。测试用小时代替天。
}
}
//===========end==================================
/* Timer0 interrupt routine */
void tm0_isr() interrupt 1 using 1
{
TL0 = (65536-50000)%256; //reload timer0 low byte
TH0 = (65536-50000)/256; //reload timer0 high byte
count++;dog++;
}
/*----------------------------
软件延时
----------------------------*/
void Delay(BYTE n)
{
WORD x;
while (n--)
{
x = 0;
while (++x);
}
}
/*----------------------------
关闭IAP
----------------------------*/
void IapIdle()
{
IAP_CONTR = 0; //关闭IAP功能
IAP_CMD = 0; //清除命令寄存器
IAP_TRIG = 0; //清除触发寄存器
IAP_ADDRH = 0x80; //将地址设置到非IAP区域
IAP_ADDRL = 0;
}
/*----------------------------
从ISP/IAP/EEPROM区域读取一字节
----------------------------*/
BYTE IapReadByte(WORD addr)
{
BYTE dat; //数据缓冲区
IAP_CONTR = ENABLE_IAP; //使能IAP
IAP_CMD = CMD_READ; //设置IAP命令
IAP_ADDRL = addr; //设置IAP低地址
IAP_ADDRH = addr >> 8; //设置IAP高地址
IAP_TRIG = 0x5a; //写触发命令(0x5a)
IAP_TRIG = 0xa5; //写触发命令(0xa5)
_nop_(); //等待ISP/IAP/EEPROM操作完成
dat = IAP_DATA; //读ISP/IAP/EEPROM数据
IapIdle(); //关闭IAP功能
return dat; //返回
}
/*----------------------------
写一字节数据到ISP/IAP/EEPROM区域
----------------------------*/
void IapProgramByte(WORD addr, BYTE dat)
{
IAP_CONTR = ENABLE_IAP; //使能IAP
IAP_CMD = CMD_PROGRAM; //设置IAP命令
IAP_ADDRL = addr; //设置IAP低地址
IAP_ADDRH = addr >> 8; //设置IAP高地址
IAP_DATA = dat; //写ISP/IAP/EEPROM数据
IAP_TRIG = 0x5a; //写触发命令(0x5a)
IAP_TRIG = 0xa5; //写触发命令(0xa5)
_nop_(); //等待ISP/IAP/EEPROM操作完成
IapIdle();
}
/*----------------------------
扇区擦除
----------------------------*/
void IapEraseSector(WORD addr)
{
IAP_CONTR = ENABLE_IAP; //使能IAP
IAP_CMD = CMD_ERASE; //设置IAP命令
IAP_ADDRL = addr; //设置IAP低地址
IAP_ADDRH = addr >> 8; //设置IAP高地址
IAP_TRIG = 0x5a; //写触发命令(0x5a)
IAP_TRIG = 0xa5; //写触发命令(0xa5)
_nop_(); //等待ISP/IAP/EEPROM操作完成
IapIdle();
}
复制代码
作者:
SJ-123
时间:
2020-2-7 10:15
这么好的贴咋没人顶一个呢?
作者:
jvsoft
时间:
2020-2-7 11:52
很好的思路
作者:
xiaogan_gu
时间:
2020-2-9 20:29
这个不好用,别人要是付款了还得去给别人改,很麻烦。
时间到后产生一个随机码,机器锁死,如果客户付款了,让他把随机码发过来,这边用解码算法算出密码,让客户输入设备就可以正常使用了。而且每台设备产生的随机码不相同,密码也就不一样。以前用汇编写过。
作者:
waas1987
时间:
2020-2-12 23:09
很好哦,
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1