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);
}
}
}
} |