|

楼主 |
发表于 2022-7-2 15:59:25
|
显示全部楼层
#include <reg51.h> // 定义8x51暂存器之标头档,P2-17~19
#include <intrins.h>
#define SEG P1 // 定义七节显示器接至Port 2
//#define SCANP P3 // 定义扫瞄线接至Port 1
sbit LED=P5^5; // 声明LED接至P0.7
#define uint unsigned int
#define uchar unsigned char
/*声明T0计时相关声明*/ // THx TLx 计算参考
#define count_M1 500 // T0(MODE 1)之计量值,0.05s
#define TH_M1 (65536-count_M1)/256// T0(MODE 1)计量高8位元
#define TL_M1 (65536-count_M1)%256// T0(MODE 1)计量低8位元
int count_T0=0; // 计算 T0中断次数
/*声明T1扫瞄相关声明*/
//#define count_M2 500 // T1(MODE 2)之计量值,0.25ms
//#define TH_M2 (65536-count_M2)/256 // T1(MODE 2)自动载入计量
//#define TL_M2 (65536-count_M2)%256 // T1(MODE 2)计数量
//uchar count_T1=0; // 计算 T1中断次数
/* 声明七节显示器驱动信号阵列(共阳) */
// 0 1 2 3 4 5 6 7 8 9
char code TAB[]={ 0x8a, 0xef, 0x96, 0xa6, 0xe3,0x22, 0x82, 0xee, 0x82, 0xa2, //数字0-4
0xdf, 0xdf, 0xdf, 0xdf, 0xdf,0xff, 0xff, 0xdf, 0xdf, 0xdf,
0xa8,
}; //数字5-9
uchar disp[4]; // 声明显示区阵列初始显示00
sbit P00=P3^2;//正转
sbit P01=P3^4;//反转
sbit P02=P3^5;//按下
sbit LS138A=P2^7; //
sbit LS138B=P2^6;
sbit led1=P2^5;
/* 声明基本变量 */
char seconds; // 秒数
char bianma,shijian,gonglv; // 编码器数值
char i,b;
bit a=1,panduan=1;
uint fen,aa,bb;
void delay(unsigned int cnt)//10为1ms
{
unsigned char i;
for(;cnt>0;cnt--)
for(i=0;i<111;i++);
}
/****************特殊功能寄存器声明****************/
sfr ISP_DATA = 0xc2;
sfr ISP_ADDRH = 0xc3;
sfr ISP_ADDRL = 0xc4;
sfr ISP_CMD = 0xc5;
sfr ISP_TRIG = 0xc6;
sfr ISP_CONTR = 0xc7;
void cc(uint addr);
void xcx(uint addr,uchar dat);
uchar dcx(uint addr);
void Q0();
void bianmaqi(void);
//==主程序================================
main() // 主程序开始
{
//char panduan;
IE=0x8a; // 1000 1010,启用TF0、TF1中断(6-4页)
TMOD=0x20; // 0010 0000,T1采mode 2、T0采mode 0 16位自动重装
TH0=TH_M1; TL0=TL_M1;// 设置T0计数量高8位元、低8位元
TR0=1; // 启动T0(7-7页)
T2H=0x9e; T2L=0x58;// 设置T2自动载入值、计数量
AUXR=0X10; // 允许定时器2运行,12分频
IE2=0X04; // 启动T2 ET2=1
P2M0=0xc0;
P2M1=0x00;
shijian= dcx(0x0001);
gonglv= dcx(0x0005);
while(1)
{
if(b==5&a==0)
{ EA=0;
SEG=0XFF;
cc(0x0000);
xcx(0x0001,shijian) ;
xcx(0x0005,gonglv) ;
panduan=1;
EA=1;
a=1;}
if(P02==0)
{ delay(30);
while(P02==0);
panduan=~panduan;
if(panduan==0)
b=0;
}
if(panduan==0)
{ bianmaqi();
shijian=bianma;
seconds=shijian*5;
if(shijian>16)
shijian=0;
if(shijian<0)
shijian=16;
if(b==5)
panduan=1;
}
else
{ bianmaqi();
seconds=bianma;
gonglv=bianma;
if(gonglv>99)
gonglv=0;
if(gonglv<0)
gonglv=99;//
}
} } // 主程序结束
//== T0中断子程序- 计算并显示秒数 ==================
void T0_1s(void) interrupt 1 // T0中断子程序开始
{// TH0=TH_M1; TL0=TL_M1; // 设置T0计数量高8位元、低8位元
if (++count_T0==2000) // 若中断20次,即0.05x20=1秒
{ count_T0=0; // 重新计次
b++; // 秒数加1
fen++;
if (b>5) // 若超过5秒
b=5; // 秒数归0,重新开始
if(fen==1800)
{ fen=0;
shijian=shijian-1; //
} // i
} // i
disp[1]=(seconds/10); // 填入十位数显示区
disp[0]=(seconds%10); // 填入个位数显示区
SEG=0xff;
switch(i)
{
case 0:LS138A=0; LS138B=1; break;
case 1:LS138B=0; LS138A=1; break;
}
SEG=TAB[disp[i]];
i++;
if(i==2)
{
i=0;
}
}
// T0中断子程序结束
//===T1中断子程序 - 扫瞄 =========================
void T1_8ms(void) interrupt 12 // T1中断子程序开始
{
bb++;
if(bb==100)
bb=0;
// LED=~LED;;
// }
if(shijian>0)
{ if(gonglv>bb)
{ LED=0;
led1=0;
}
{ if(gonglv<bb)
{ // if叙述结束(超过60秒)
LED=1;
led1=1; } // if叙述结束(中断20次)
} }
else
{
LED=1;
led1=1;
fen=0;
}
}
//if (++aa==10) // 若中断20次,即0.05x20=1秒
// { aa=0; // 重新计次
void cc(uint addr)
{
// 打开 IAP 功能(ISP_CONTR.7)=1:允许编程改变Flash, 设置Flash操作等待时间
// 0x83(晶振<5M) 0x82(晶振<10M) 0x81(晶振<20M) 0x80(晶振<40M)
ISP_CONTR = 0x81;
ISP_CMD = 0x03;
ISP_ADDRL = addr; // 用户可以对"Data Flash/EEPROM区"进行扇区擦除 ISP_ADDRL = addr; // ISP/IAP操作时的地址寄存器低八位,
ISP_ADDRH = addr>>8; // ISP/IAP操作时的地址寄存器高八位。
//EA =0;
ISP_TRIG = 0x5a;
ISP_TRIG = 0xa5; // 在ISPEN(ISP_CONTR.7)=1时,对ISP_TRIG先写入5a, ISP_TRIG = 0xB9; // 再写入B9h,ISP/IAP命令才会生效。
_nop_();
Q0(); // 关闭ISP/IAP
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数:写一字节
入口:addr = 扇区单元地址 , dat = 待写入数据
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void xcx(uint addr,uchar dat)
{
ISP_CONTR = 0x81;
ISP_CMD = 0x02; // 用户可以对"Data Flash/EEPROM区"进行字节编程 ISP_ADDRL = addr;
ISP_ADDRL = addr;
ISP_ADDRH = addr>>8;
ISP_DATA = dat; // 数据进ISP_DATA
// EA = 0;
ISP_TRIG = 0x5a;
ISP_TRIG = 0xa5;
_nop_();
Q0(); // 关闭ISP/IAP
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数:读一字节
入口:addr = 扇区单元地址
出口:dat = 读出的数据
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
uchar dcx(uint addr)
{
uchar dat;
ISP_CONTR = 0x81;
ISP_CMD = 0x01; // 用户可以对"Data Flash/EEPROM区"进行字节读 ISP_ADDRL = addr;
ISP_ADDRL = addr;
ISP_ADDRH = addr>>8;
//EA = 0;
ISP_TRIG = 0x5a;
ISP_TRIG = 0xa5;
_nop_();
dat = ISP_DATA; // 取出数据
Q0(); // 关闭ISP/IAP
return dat;
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数:关闭ISP/IAP操作
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void Q0()
{
ISP_CONTR = 0; // 关闭IAP功能
ISP_CMD = 0; // 待机模式,无ISP操作
ISP_TRIG = 0; // 关闭IAP功能, 清与ISP有关的特殊功能寄存器
ISP_ADDRH=0x80;
ISP_ADDRL =0;
}
void bianmaqi(void)
{ if(panduan==0)
bianma=shijian;
else
bianma=gonglv;
if(!P00) //如果p0.0口变为低电平
{
delay(20); //延时
if(!P00) //如果p0.0还是低电平
{
while(!P00); //等待p0.0变成高电平
while(P01); //等待p0.1变成低电平
delay(20); //延时
while(P01); //如果p0.1还是低电平
while(!P01); //等待p0.1变成高电平
bianma+=1; //计数加1
a=0;
b=0;
}}
if(!P01)
{
delay(20);
if(!P01)
{
while(!P01);
while(P00);
delay(20);
while(P00);
while(!P00);
bianma-=1;
a=0;
b=0;
}
} }
|
打赏
-
查看全部打赏
|