/*无线通讯语言模块测试·PAST 2019 12 28 L298 CODE1871**/
#include <REG52.H>
#include <intrins.H>
#include "stdio.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;
sbit INTPUT=P1^2;
sbit MD0MD1=P3^2;
bit Warning;
uchar Counter;
void delay(uint k); /****延时****/
uchar DAT2=0;
bit Receive_Flag;
/*------------------------------------------*/
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<200;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(5);
}
/******************************************/
void Key_ValAdd()
{
kcounter++; //按键计数器加一
kstatus++; //按键状态标志加一
delay1(5);
}
/******************************************/
void Key_Clear()
{
kcounter++; //按键计数器加一
kstatus=0; //按键状态标志归零
}
/*------------初始化串口---------------------*/
void InitUart()
{
SCON=0X50; //8位数据,可变波特率
AUXR|=0x01; //串口1选择定时器2为波特率发生器
AUXR|=0X04; //定时器2时钟为Fosc,即1T
T2L=0XE0; //设置定时器处置 110592》9600
T2H=0XFE; //设置定时器处置 110592》9600
AUXR|=0X10; //启动定时器2
TI=1;
EA=1;
}
/*--------UART 中断服务程序----Buff=SBUF---------------*/
void Uart() interrupt 4 using 1
{
if(RI)
{
DAT2=SBUF; //数组下标位置的数据等于j
RI=0; //
Receive_Flag=1; //接收数据标志置一
}
}
/*------------------主循环程序----------------*/
void main( ) /*主程序开始*/
{ /**加一**/
AUXR=0X80; //STC系列的1T 设置
TMOD=0X01;
InitUart(); //初始化串口
ES=1;
Receive_Flag=0; //接收到数据标志置零
P1=255;
red_eeprom();
display(v);
MD0MD1=0; //
Warning=0; //报警标志等于0
Counter=0; //报警计数器等于0
// printf("报警标志");
printf("<Z>5");
printf("<V>2");
printf("<S>3");
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(10);
}
}
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(10);
}
}
key_reset();
if(!KEY_SET) //数据发送
{
for(;kcounter<5;) //按键循环5次
{
if(!KEY_SET) //按键低电平
{
Key_ValAdd(); //按键低电平 计数器加一状态标志加一
}
else if(~!KEY_SET) //按键高电平
{
Key_Clear(); //按键计数器加一 状态标志归零
}
}
if(kstatus>=3) /*按键状态标志大于等于3为有效值*/
{
display(2);
printf("不喝酒就没得朋友可是只要偶一喝酒就喝倒一代朋友人生真的很矛盾");
// printf("Please input up,dowm,high:\r\n");
OUT1=0;
delay1(2000);
delay1(2000);
OUT1=1;
display(9);
}
}
}
}