2018年做無線通訊下位機測試的例程
保證好用,新手可以參考
/*無線通訊從機板74HC164串口輸出測試***/
/*2018 8 20 21:00 PAST CODE674 1-99*/
/***按鍵設置從機地址EEPROM 存儲 ***/
#include <REG52.H>
#include <intrins.H>
#define uint unsigned int
#define uchar unsigned char
uchar code tab[10]={0X03,0X9F,0X25,0X0D,0X99,0X49,0X41,0X1F,0X01,0X09};
#define CMD_IDLE 0 //空閑模式
#define CMD_READ 1 //IAP字節讀命令
#define CMD_PROGRAM 2 //IAP字節編程命令
#define CMD_ERASE 3 //IAP扇區擦除命令
#define ENABLE_IAP 0x82 //if SYSCLK<20MHz
#define IAP_ADDRESS 0x0000 //EEPROM首地址
typedef unsigned char BYTE;
typedef unsigned int WORD;
uchar kcounter,kstatus; //按鍵計數標志 按鍵狀態標志
uchar v; /*從機號*/
int count;
int time=0;
sbit OUT1=P1^3; /****輸出***/
sbit CLK=P1^1;
sbit SDA=P1^0;
sbit KEY_ADD=P3^6;
sbit KEY_DEC=P3^7;
sbit KEY_SET=P1^4;
sbit KEY_ENTER=P3^3;
void delay(uint k); /****延時****/
void timer0() interrupt 1
{
TH0=0X53;
TL0=0X32;
time++;
if(time==2)
{
count++;
time=0;
}
}
/*------------------------------------------*/
void delay(uint t)
{
uint i,j;
for(i=0;i<t;i++)
for(j=0;j<10;j++);
}
/*---------------延時子程序----------------*/
void delay1 (uint ms)
{
uint i,j;
for(i=0;i<ms;i++)
for(j=0;j<1000;j++)
;
}
/*----關閉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 val=IapReadByte(IAP_ADDRESS+1);
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();
}
/*-----------------------------------------*/
void red_eeprom(void)
{
uchar t_data,b_data; //
t_data=IapReadByte(IAP_ADDRESS); //十位
b_data=IapReadByte(IAP_ADDRESS+1); //個位
v=t_data*10+b_data;
}
/***************************************/
void write_eeprom(uchar dat)
{
uchar Tdata,Bdata; //
Tdata=dat/10;
Bdata=dat-Tdata*10;
IapEraseSector(IAP_ADDRESS); //扇區擦除
IapProgramByte(IAP_ADDRESS,Tdata); /*寫入十位*/
IapProgramByte(IAP_ADDRESS+1,Bdata);/*寫入小數*/
}
/*------------------------------------------*/
void ind_light_disp(uchar buff) //點亮哪一位就置1
{
uchar j,sbuff;
bit s;
sbuff=buff;
for(j=0;j<8;j++) //移動8位
{
s=sbuff&0x01; //位變量等于緩沖區最低位
if(s==1) //最低位等于1
{
CLK=0; //此處與下面的CLK = 1結合產生一個上升沿
SDA=0;
CLK=1;
}
else
{
CLK=0;
SDA=1;
CLK=1;
}
delay(10);
sbuff=sbuff>>1; //右移一次
}
delay(10);
}
/*------------------------------------------*/
void display(uchar val)
{
uchar ss; /*緩沖*/
ss=(tab[(val%100)/10]); /*十位*/
ind_light_disp(ss);
ss=(tab[val%10]); /*個位*/
ind_light_disp(ss);
}
/******************************************/
void key_reset()
{
kcounter=0; //計數器歸零
kstatus=0; //狀態計數器歸零
delay1(50);
}
/******************************************/
void Key_ValAdd()
{
kcounter++; //按鍵計數器加一
kstatus++; //按鍵狀態標志加一
delay1(50);
}
/******************************************/
void Key_Clear()
{
kcounter++; //按鍵計數器加一
kstatus=0; //按鍵狀態標志歸零
}
/*------------------主循環程序----------------*/
void main( ) /*主程序開始*/
{ /**加一**/
SCON=0X00;
ES=0;
AUXR=0X80; //STC系列的1T 設置
TMOD=0X01;
TH0=0X53;
TL0=0X32;
EA=1;
ET0=1;
TR0=1;
P1=255;
red_eeprom();
display(v);
while(1)
{
key_reset();
if(!KEY_ADD) //脈沖系數加
{
for(;kcounter<5;) //按鍵循環5次
{
if(!KEY_ADD) //按鍵低電平
{
Key_ValAdd(); //按鍵低電平 計數器加一狀態標志加一
}
else if(~!KEY_ADD) //按鍵高電平
{
Key_Clear(); //按鍵計數器加一 狀態標志歸零
}
}
if(kstatus>=3) /*按鍵狀態標志大于等于3為有效值*/
{
v++;
if(v>99)
v=0;
write_eeprom(v);
display(v);
delay1(50);
}
}
key_reset();
if(!KEY_DEC) //脈沖系數加
{
for(;kcounter<5;) //按鍵循環5次
{
if(!KEY_DEC) //按鍵低電平
{
Key_ValAdd(); //按鍵低電平 計數器加一狀態標志加一
}
else if(~!KEY_DEC) //按鍵高電平
{
Key_Clear(); //按鍵計數器加一 狀態標志歸零
}
}
if(kstatus>=3) /*按鍵狀態標志大于等于3為有效值*/
{
v-=1;
if(v<1)
v=99;
write_eeprom(v);
display(v);
delay1(50);
}
}
}
} |