標(biāo)題:
單片機(jī)硬件的使用時(shí)間限制的程序 這里起拋磚引玉的作用 相當(dāng)于軟件狗 就是指定單片..
[打印本頁(yè)]
作者:
鐵牛單片機(jī)
時(shí)間:
2017-10-30 22:33
標(biāo)題:
單片機(jī)硬件的使用時(shí)間限制的程序 這里起拋磚引玉的作用 相當(dāng)于軟件狗 就是指定單片..
前兩天有客戶委托做一個(gè)項(xiàng)目。這個(gè)項(xiàng)目做好后。我的客戶也需要把東西交付給另外的公司。但是這個(gè)公司只付了百分之三十的訂金。說好交付產(chǎn)品時(shí)再付百分之六十。結(jié)果交付產(chǎn)品時(shí)卻沒有兌現(xiàn)承諾。
所以客戶要求我在程序里面加一個(gè)限制使用時(shí)間的子程序。如果三十天,或者九十天?蛻暨沒有打款。就不能用了。
想了幾天。寫了一段小程序。很好用。大家有需要的可以用一下。這里起一個(gè)拋磚引玉的作用。
//2017.9.30 帶狗測(cè)試。運(yùn)行一段時(shí)間后停止運(yùn)行
#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時(shí)鐘
sbit dio = P3^4; //IIC數(shù)據(jù)
sbit key_add = P3^2; //加按鍵
sbit key_sub = P3^3;
sbit JSQ_Sig = P3^1; //計(jì)數(shù)器脈沖信號(hào)
sbit JSQ_Relay= P3^0; //計(jì)數(shù)器繼電器返回信號(hào) 計(jì)數(shù)器計(jì)數(shù)到0后返回信號(hào)給電路板
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}; //共陽(yáng)數(shù)碼管
//測(cè)試地址
#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 延時(shí)
{
for(;i>0;i--)
_nop_();
}
///======================================
void I2CStart(void) //1637 開始
{
clk = 1;
dio = 1;
Delay_us(2);
dio = 0;
}
///=============================================
void I2Cask(void) //1637 應(yīng)答
{
clk = 0;
Delay_us(5); //在第八個(gè)時(shí)鐘下降沿之后延時(shí) 5us,開始判斷 ACK 信號(hào)
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) //寫一個(gè)字節(jié)
{
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) //按鍵檢測(cè)程序
{
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 地址自動(dòng)加 1 模式,44H 固定地址模式,本程序采用自加 1 模式
I2Cask();
I2CStop();
I2CStart();
I2CWrByte(0xc1);//設(shè)置首地址,
I2Cask();
for(i=0;i<6;i++)//地址自加,不必每次都寫地址
{
I2CWrByte(xsbcdbuf[bai]); //送數(shù)據(jù)
I2Cask();
I2CWrByte(xsbcdbuf[shi]); //送數(shù)據(jù)
I2Cask();
I2CWrByte(xsbcdbuf[ge]); //送數(shù)據(jù)
I2Cask();
I2CWrByte(xsbcdbuf[1]); //送數(shù)據(jù)
I2Cask();
I2CWrByte(xsbcdbuf[0]); //送數(shù)據(jù)
I2Cask();
I2CWrByte(xsbcdbuf[qian]); //送數(shù)據(jù)
I2Cask();
}
I2CStop();
I2CStart();
I2CWrByte(0x8b); //開顯示 ,八級(jí)亮度調(diào)制 88 89 8a 8b 8c 8d 8e 8f
I2Cask();
I2CStop();
}
///==============================================
void init() //定時(shí)器中斷初始化
{
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小時(shí)。測(cè)試時(shí)用1個(gè)小時(shí)算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) //脈沖信號(hào)來一次。計(jì)數(shù)器減1
{
count = 0;
number--;
IapEraseSector(IAP_ADDRESS);
IapProgramByte(IAP_ADDRESS,number);
dog_test();
if(number ==0)
{
number = 255;
}
}
while(dog_day>=1); //2天后停止運(yùn)行。實(shí)際上是2個(gè)小時(shí)。測(cè)試用小時(shí)代替天。
}
}
//===========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++;
}
/*----------------------------
軟件延時(shí)
----------------------------*/
void Delay(BYTE n)
{
WORD x;
while (n--)
{
x = 0;
while (++x);
}
}
/*----------------------------
關(guān)閉IAP
----------------------------*/
void IapIdle()
{
IAP_CONTR = 0; //關(guān)閉IAP功能
IAP_CMD = 0; //清除命令寄存器
IAP_TRIG = 0; //清除觸發(fā)寄存器
IAP_ADDRH = 0x80; //將地址設(shè)置到非IAP區(qū)域
IAP_ADDRL = 0;
}
/*----------------------------
從ISP/IAP/EEPROM區(qū)域讀取一字節(jié)
----------------------------*/
BYTE IapReadByte(WORD addr)
{
BYTE dat; //數(shù)據(jù)緩沖區(qū)
IAP_CONTR = ENABLE_IAP; //使能IAP
IAP_CMD = CMD_READ; //設(shè)置IAP命令
IAP_ADDRL = addr; //設(shè)置IAP低地址
IAP_ADDRH = addr >> 8; //設(shè)置IAP高地址
IAP_TRIG = 0x5a; //寫觸發(fā)命令(0x5a)
IAP_TRIG = 0xa5; //寫觸發(fā)命令(0xa5)
_nop_(); //等待ISP/IAP/EEPROM操作完成
dat = IAP_DATA; //讀ISP/IAP/EEPROM數(shù)據(jù)
IapIdle(); //關(guān)閉IAP功能
return dat; //返回
}
/*----------------------------
寫一字節(jié)數(shù)據(jù)到ISP/IAP/EEPROM區(qū)域
----------------------------*/
void IapProgramByte(WORD addr, BYTE dat)
{
IAP_CONTR = ENABLE_IAP; //使能IAP
IAP_CMD = CMD_PROGRAM; //設(shè)置IAP命令
IAP_ADDRL = addr; //設(shè)置IAP低地址
IAP_ADDRH = addr >> 8; //設(shè)置IAP高地址
IAP_DATA = dat; //寫ISP/IAP/EEPROM數(shù)據(jù)
IAP_TRIG = 0x5a; //寫觸發(fā)命令(0x5a)
IAP_TRIG = 0xa5; //寫觸發(fā)命令(0xa5)
_nop_(); //等待ISP/IAP/EEPROM操作完成
IapIdle();
}
/*----------------------------
扇區(qū)擦除
----------------------------*/
void IapEraseSector(WORD addr)
{
IAP_CONTR = ENABLE_IAP; //使能IAP
IAP_CMD = CMD_ERASE; //設(shè)置IAP命令
IAP_ADDRL = addr; //設(shè)置IAP低地址
IAP_ADDRH = addr >> 8; //設(shè)置IAP高地址
IAP_TRIG = 0x5a; //寫觸發(fā)命令(0x5a)
IAP_TRIG = 0xa5; //寫觸發(fā)命令(0xa5)
_nop_(); //等待ISP/IAP/EEPROM操作完成
IapIdle();
}
復(fù)制代碼
作者:
SJ-123
時(shí)間:
2020-2-7 10:15
這么好的貼咋沒人頂一個(gè)呢?
作者:
jvsoft
時(shí)間:
2020-2-7 11:52
很好的思路
作者:
xiaogan_gu
時(shí)間:
2020-2-9 20:29
這個(gè)不好用,別人要是付款了還得去給別人改,很麻煩。
時(shí)間到后產(chǎn)生一個(gè)隨機(jī)碼,機(jī)器鎖死,如果客戶付款了,讓他把隨機(jī)碼發(fā)過來,這邊用解碼算法算出密碼,讓客戶輸入設(shè)備就可以正常使用了。而且每臺(tái)設(shè)備產(chǎn)生的隨機(jī)碼不相同,密碼也就不一樣。以前用匯編寫過。
作者:
waas1987
時(shí)間:
2020-2-12 23:09
很好哦,
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1