#include "stc15.h"
#include <intrins.h>
#include <stdio.h>
#include <absacc.h> typedef unsigned char u8;
typedef unsigned int u16;
typedef unsigned long u32;void WriteNbyte(u8 addr, u8 *p, u8 number);
void ReadNbyte( u8 addr, u8 *p, u8 number);
void WriteInt(u8 addr, int x); /* WordAddress,First Data Address,Byte lenth */
/****************************/
int ReadInt(u8 addr); /* WordAddress,First Data Address,Byte lenth */
void WriteFloat(u8 addr, float x) ; /* WordAddress,First Data Address,Byte lenth */
float ReadFloat(u8 addr); /* WordAddress,First Data Address,Byte lenth *///延时函数,位操作,选择支路573,LED操作刷新,ULN2003刷新,数码管的刷新
void delay1ms() //@11.0592MHz
{unsigned char i, j;_nop_();// i = 2;
// j = 199;i = 11;j = 190;do{while (--j);} while (--i);}void delayms(int n) //@11.0592MHz
{unsigned char i, j;int k;for(k=0;k<n;k++){delay1ms(); }
}//***************位操作,置1,清0,取反,判断
u8 bitSet(u8 temp,u8 pos)
{temp =temp |(1<<pos);return temp;
}
u8 bitReset(u8 temp,u8 pos)
{temp &=~(1<<pos);return temp;
}u8 bitTog(u8 temp,u8 pos)
{temp =temp ^(1<<pos);return temp;
}
u8 bitRead(u8 temp,u8 pos)
{u8 res;res =(temp>>pos) &0x01;return res;
}
//***************位操作,置1,清0,取反,判断//***************选择573
#define LEDY 1
#define SMGABCY 2
#define SMGCOMY 3
#define ULNY 4
#define NONE 5void xz573(u8 x)
{switch(x){case LEDY:P2=(P2&0x1F)|0x80; //Y4 1000 0000break;case SMGABCY:P2=(P2&0x1F)|0xe0; //Y7 1110 0000break;case SMGCOMY:P2=(P2&0x1F)|0xc0; //Y6 1100break;case ULNY:P2=(P2&0x1F)|0xa0; //Y5 1010break; case NONE:P2=P2&0x1F;break;}
}LED___________________---
//#define L1 0
//#define L2 1
//#define L3 2u8 u8LED=0xff;//void LEDonx(u8 i) //0
//{
// u8LED = bitReset(u8LED,i);
//}
//void LEDoffx(u8 i) //0
//{
// u8LED = bitSet(u8LED,i);
//}//void LEDtog(u8 i)
//{
// u8LED =bitTog(u8LED,i);
//}//u8 LEDRead(u8 i)
//{
// u8 sta;
// sta =bitRead(u8LED,i);
// return sta;
//}void LEDdis(u8 temp)
{//关闭所有的通道xz573(NONE);//刷新P0数据u8LED=temp;P0=u8LED;xz573(LEDY);xz573(NONE);
}*************蜂鸣器继电器
u8 u8ULN=0x00;//void JDQonx() //1
//{
// u8ULN = bitSet(u8ULN,4);
//}
//void JDQoffx() //0
//{
// u8ULN = bitReset(u8ULN,4);
//}//void FMQonx() //0
//{
// u8ULN = bitSet(u8ULN,6);
//}
//void FMQoffx() //0
//{
// u8ULN = bitReset(u8ULN,6);
//}void ULNdis(u8 temp)
{//关闭所有的通道xz573(NONE);//刷新P0数据u8ULN=temp;P0=u8ULN;xz573(ULNY);xz573(NONE);
}
//**********************************数码管,定时器动态扫描
//位码,段码,显示扫描,定时扫描,字符串翻译到LED8函数;
/************* 本地常量声明 **************/
u8 code t_display[]={ //标准字库,共阴极,比赛共阳,取反
// 0 1 2 3 4 5 6 7 8 9 A B C D E F0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
//black - H J K L N o P U t G Q r M y0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e,0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x46}; //0. 1. 2. 3. 4. 5. 6. 7. 8. 9. -1u8 code T_COM[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; //注意数码管的数据LED8[0]是不是对应TCOM[0]还是TCOM[8]
//u8 code T_COM[]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01}; //位码
/************* 本地变量声明 **************/
u8 LED8[8]; //显示缓冲
u8 display_index=0; //显示位索引
//bit B_1ms; //1ms标志
u8 SMGbuf[16];
/********************** 显示扫描函数 ************************/
//void DisplayScan(void)
//{
// Send_595(~T_COM[display_index]); //输出位码
// Send_595(t_display[LED8[display_index]]); //输出段码// P_HC595_RCLK = 1;
// P_HC595_RCLK = 0; //锁存输出数据
// if(++display_index >= 8) display_index = 0; //8位结束回0
//}
/********************** 显示扫描函数 ************************/
/********************** 显示扫描函数 ************************/
void DisplayScan(void)
{ //*******************************完善一下消隐,关闭位选,关闭段码,两个都要。实验发现仅仅关闭位选,不行,仅仅关闭段码可以消隐。//位取0,消隐// XBYTE [0xC000] = 0x00;
// xz573(NONE);
// P0=0x00;
// xz573(SMGCOMY);
// xz573(NONE);//段码
// XBYTE [0xE000] = LED8[display_index];xz573(NONE);P0=0xFF; //记得取反xz573(SMGABCY);xz573(NONE);//*******************************************************显示数据,位选,段选//位选择// XBYTE [0xC000] = T_COM[display_index];xz573(NONE);P0=T_COM[display_index]; xz573(SMGCOMY);xz573(NONE);//段码
// XBYTE [0xE000] = LED8[display_index];xz573(NONE);P0=LED8[display_index]; //记得取反xz573(SMGABCY);xz573(NONE);//锁存输出数据,这里是8个数码管if(++display_index >= 8) display_index = 0; //8位结束回0
}
//Pmmmm3.250000
void SMGconv()
{u8 i=0,j=0,temp=0;while(SMGbuf[i]!=0){switch(SMGbuf[i]){case '0':temp=~t_display[0];break;case '1':temp=~t_display[1];break;case '2':temp=~t_display[2];break;case '3':temp=~t_display[3];break;case '4':temp=~t_display[4];break;case '5':temp=~t_display[5];break;case '6':temp=~t_display[6];break;case '7':temp=~t_display[7];break;case '8':temp=~t_display[8];break;case '9':temp=~t_display[9];break;case 'A':temp=~0x77;break;case 'B':temp=~0x7C;break;case 'P':temp=~0x73;break;case '-':temp=~0x40;break;default:temp=0xFF;break;}if(SMGbuf[i+1]=='.'){temp &=0x7f;//0111 1111i++;}i++;LED8[j]=temp;j++;}
}//***********************按键操作
//int aaa=12;int longtime=0;
u8 longkeyflag=0;u8 key10ms=0;
u8 key10msflag=0;u8 keyRead1(void)
{u8 keyx=0;if(P30==0)keyx=7;else if(P31==0)keyx=6;else if(P32==0)keyx=5;else if(P33==0)keyx=4;return keyx;
}u8 keyRead4(void) //开发板
{u8 keyx=0;P44=0;P42=1;P35=1;P34=1;if(P30==0)keyx=7;else if(P31==0)keyx=6;else if(P32==0)keyx=5;else if(P33==0)keyx=4;P44=1;P42=0;P35=1;P34=1;if(P30==0)keyx=11;else if(P31==0)keyx=10;else if(P32==0)keyx=9;else if(P33==0)keyx=8;P44=1;P42=1;P35=0;P34=1;if(P30==0)keyx=15;else if(P31==0)keyx=14;else if(P32==0)keyx=13;else if(P33==0)keyx=12;P44=1;P42=1;P35=1;P34=0;if(P30==0)keyx=19;else if(P31==0)keyx=18;else if(P32==0)keyx=17;else if(P33==0)keyx=16;return keyx;
}u8 keyRead40(void) //仿真的,没有P4
{u8 keyx=0;P24=0;P22=1;P35=1;P34=1;if(P30==0)keyx=7;else if(P31==0)keyx=6;else if(P32==0)keyx=5;else if(P33==0)keyx=4;P24=1;P22=0;P35=1;P34=1;if(P30==0)keyx=11;else if(P31==0)keyx=10;else if(P32==0)keyx=9;else if(P33==0)keyx=8;P24=1;P22=1;P35=0;P34=1;if(P30==0)keyx=15;else if(P31==0)keyx=14;else if(P32==0)keyx=13;else if(P33==0)keyx=12;P24=1;P22=1;P35=1;P34=0;if(P30==0)keyx=19;else if(P31==0)keyx=18;else if(P32==0)keyx=17;else if(P33==0)keyx=16;return keyx;
}u8 tmp[8]={0,0,0,0,0,0,0,0};u8 second;u8 minute;u8 hour;
int intx=10;
float floatx=12.34;
void KeyProc()
{u8 keydown;u8 keyup;u8 keyx;static u8 keyold;if(key10msflag==1){key10msflag=0;}else return;//keyx=keyRead1();//仿真//keyx=keyRead40();//仿真keyx=keyRead4();//开发板keydown = keyx&(keyold^keyx);keyup =~keyx&(keyold^keyx);keyold=keyx;if(keydown){longtime=0;
//
// if(keydown==7)aaa=aaa+10;
// if(keydown==6)aaa=aaa-10;// sprintf(SMGbuf,"PPPPPP%2d",(unsigned int)aaa);
// SMGconv();}if(keyup){if(longkeyflag==0){if(keyup==7){// aaa=aaa+10;
// tmp[0] += 2;
// tmp[1] +=3;
// tmp[2] +=4;
// //
// sprintf(SMGbuf,"%2d-%2d-%2d",(unsigned int)tmp[0],(unsigned int)tmp[1],(unsigned int)tmp[2]);
// SMGconv();// sprintf(SMGbuf,"PPPPPP%2d",(unsigned int)aaa);
// SMGconv();//注意,写单个字节的时候,需要延时15毫秒以上,实验发现10ms以上合适,比赛发现不能正确读取的话,就改下延时
// WriteNbyte(0x00, &tmp[0], 1);delayms(5);
// WriteNbyte(0x01, &tmp[1], 1);delayms(5);
// WriteNbyte(0x02, &tmp[2], 1);delayms(5);intx=intx+2;WriteInt(0x00,intx);sprintf(SMGbuf,"PPPP%04d",(unsigned int)intx);SMGconv();}if(keyup==6){//aaa=aaa-10;// ReadNbyte(0x00, tmp, 3);delayms(15);//注意,读取单个字节的时候,需要延时15毫秒以上,实验发现10ms以上合适,比赛发现不能正确读取的话,就改下延时
// ReadNbyte(0x00, &tmp[0], 1);delayms(5);
// ReadNbyte(0x01, &tmp[1], 1);delayms(5);
// ReadNbyte(0x02, &tmp[2], 1);delayms(5);// second = tmp[0]+5;
// minute = tmp[1]+5;
// hour = tmp[2]+5;
// sprintf(SMGbuf,"%2d-%2d-%2d",(unsigned int)second,(unsigned int)minute,(unsigned int)hour);
// SMGconv();intx=ReadInt(0x00)+100;
// ReadNbyte(0x00, &tmp[0], 1);delayms(15);
// ReadNbyte(0x01, &tmp[1], 1);delayms(15);
// intx=tmp[0]<<8|tmp[1];sprintf(SMGbuf,"PPPP%04d",(unsigned int)intx);SMGconv();}if(keyup==5){floatx=floatx+0.01;WriteFloat(0x02,floatx);sprintf(SMGbuf,"PPPP%5.2f",floatx);SMGconv();}if(keyup==4){floatx=ReadFloat(0x02)+10;sprintf(SMGbuf,"PPPP%5.2f",floatx);SMGconv();}}else longkeyflag=0;
// sprintf(SMGbuf,"AAAAAA%2d",(unsigned int)keyup);
// SMGconv();}if(keyold &&(longtime>1000)){longtime=0;longkeyflag=1;if(keyold==7){//aaa=aaa+1;}if(keyold==6){//aaa=aaa-1;}//sprintf(SMGbuf,"BBBBBB%2d",(unsigned int)aaa);//SMGconv(); }}//float wendu=12.56;
//int sec=12;
int cnt1ms=0;
/* define constants */
#define FOSC 11059200L
#define T1MS (65536-FOSC/12/1000) //1ms timer calculation method in 12T mode
/********************** Timer0 1ms中断函数 ************************/
void timer0 (void) interrupt 1
{TL0 = T1MS; //仿真软件的传统51单片机需要重新设置定时初值TH0 = T1MS>>8; //设置定时初值
}/* Timer0 interrupt routine */
void tm1_isr() interrupt 3
{TL1 = T1MS; //reload timer1 low byteTH1 = T1MS >> 8; //reload timer1 high bytecnt1ms++;key10ms++;longtime++;if(key10ms==10){key10msflag=1;key10ms=0;}
//
// if(cnt1ms==1000) //边界处理
// {
// cnt1ms=0;
// sec++;
// if(sec==59)sec=0;
// }if(cnt1ms%300==0) //1ms的倍数{
// wendu+=0.01;
// if(wendu>25.5)
// wendu=5.2;}if(cnt1ms%20==0) //20ms的倍数{
// sprintf(SMGbuf,"PPPPP%03d",(unsigned int)sec);
// SMGconv();
//
// sprintf(SMGbuf,"P-AB%5.2f",wendu);
// SMGconv();KeyProc();//20ms读取一次按键}if(cnt1ms%2==0) //1ms的倍数{DisplayScan(); //1ms扫描显示一位 }
}//********************************************************main
void main()
{int i;LEDdis(0xff);//开机关闭LED灯ULNdis(0x00);//开机关闭继电器和蜂鸣器sprintf(SMGbuf," ");//熄灭数码管SMGconv();// AUXR &= 0x7F; //定时器时钟12T模式
// //TMOD &= 0xF0; //开发板设置定时器模式
// TMOD |= 0x01; //仿真Proteus设置定时器模式
// TL0 = T1MS; //设置定时初值
// TH0 = T1MS>>8; //设置定时初值
// TF0 = 0; //清除TF0标志
// TR0 = 1; //定时器0开始计时// ET0=1;//定时器0中断TMOD |= 0x10; //set timer1 as mode1 (16-bit)TL1 = T1MS; //initial timer1 low byteTH1 = T1MS >> 8; //initial timer1 high byteTR1 = 1; //timer1 start runningET1 = 1; //enable timer1 interruptintx=ReadInt(0x00);//开机读取数据int类型EA=1;//单片机总中断//i=ReadInt(0x00);while(1){}}#define SLAW 0xA0 //1010 0000
#define SLAR 0xA1 //1010 0001sbit SDA = P2^1; //定义SDA PIN5
sbit SCL = P2^0; //定义SCL PIN6///****************************开发板/
//void I2C_Delay(void) //for normal MCS51, delay (2 * dly + 4) T, for STC12Cxxxx delay (4 * dly + 10) T
//{
// u8 dly;
// // dly = 22059200 / 2000000UL; //按2us计算
// dly=5;
// while(--dly) ;
//}//******仿真
void I2C_Delay(void) //for normal MCS51, delay (2 * dly + 4) T, for STC12Cxxxx delay (4 * dly + 10) T
{int dly;// dly = 22059200 / 2000000UL; //按2us计算dly=10;while(--dly) ;
}/****************************/
void I2C_Start(void) //start the I2C, SDA High-to-low when SCL is high
{SDA = 1;I2C_Delay();SCL = 1;I2C_Delay();SDA = 0;I2C_Delay();SCL = 0;I2C_Delay();
} void I2C_Stop(void) //STOP the I2C, SDA Low-to-high when SCL is high
{SDA = 0;I2C_Delay();SCL = 1;I2C_Delay();SDA = 1;I2C_Delay();
}void S_ACK(void) //Send ACK (LOW)
{SDA = 0;I2C_Delay();SCL = 1;I2C_Delay();SCL = 0;I2C_Delay();
}void S_NoACK(void) //Send No ACK (High)
{SDA = 1;I2C_Delay();SCL = 1;I2C_Delay();SCL = 0;I2C_Delay();
}void I2C_Check_ACK(void) //Check ACK, If F0=0, then right, if F0=1, then error
{SDA = 1;I2C_Delay();SCL = 1;I2C_Delay();F0 = SDA;SCL = 0;I2C_Delay();
}/****************************/
void I2C_WriteAbyte(u8 dat) //write a byte to I2C
{u8 i;i = 8;do{if(dat & 0x80) SDA = 1;else SDA = 0;dat <<= 1;I2C_Delay();SCL = 1;I2C_Delay();SCL = 0;I2C_Delay();}while(--i);
}/****************************/
u8 I2C_ReadAbyte(void) //read A byte from I2C
{u8 i,dat;i = 8;SDA = 1;do{SCL = 1;I2C_Delay();dat <<= 1;if(SDA) dat++;SCL = 0;I2C_Delay();}while(--i);return(dat);
}/****************************/
void WriteNbyte(u8 addr, u8 *p, u8 number) /* WordAddress,First Data Address,Byte lenth *///F0=0,right, F0=1,error
{I2C_Start();I2C_WriteAbyte(SLAW);I2C_Check_ACK();if(!F0){I2C_WriteAbyte(addr);I2C_Check_ACK();if(!F0){do{I2C_WriteAbyte(*p); p++;I2C_Check_ACK();if(F0) break;}while(--number);}}I2C_Stop();
}/****************************/
void ReadNbyte(u8 addr, u8 *p, u8 number) /* WordAddress,First Data Address,Byte lenth */
{I2C_Start();I2C_WriteAbyte(SLAW);I2C_Check_ACK();if(!F0){I2C_WriteAbyte(addr);I2C_Check_ACK();if(!F0){I2C_Start();I2C_WriteAbyte(SLAR);I2C_Check_ACK();if(!F0){do{*p = I2C_ReadAbyte(); p++;if(number != 1) S_ACK(); //send ACK}while(--number);S_NoACK(); //send no ACK}}}I2C_Stop();
}/****************************/
void WriteInt(u8 addr, int x) /* WordAddress,First Data Address,Byte lenth */
{u8 MSB;u8 LSB;MSB=x>>8;LSB=x;WriteNbyte(addr, &MSB, 1);delayms(15);WriteNbyte(addr+1,&LSB, 1);delayms(15);
}/****************************/
int ReadInt(u8 addr) /* WordAddress,First Data Address,Byte lenth */
{u8 MSB;u8 LSB;int res;ReadNbyte(addr,&MSB,1); /* WordAddress,First Data Address,Byte lenth */delayms(15);ReadNbyte(addr+1,&LSB,1) ; /* WordAddress,First Data Address,Byte lenth */delayms(15);res=MSB*256+LSB;//注意,是乘以256,不是255//res=MSB<<8|LSB;//等价与上面的return res;
}
/***************************/
void WriteFloat(u8 addr, float x) /* WordAddress,First Data Address,Byte lenth */
{u8 f1;u8 f2;u8 f3;u8 f4;int y;y=x*100;f4=y%10;f3=y/10%10;f2=y/100%10;f1=y/1000%10;WriteNbyte(addr, &f1, 1);delayms(15);WriteNbyte(addr+1,&f2, 1);delayms(15);WriteNbyte(addr+2, &f3, 1);delayms(15);WriteNbyte(addr+3,&f4, 1);delayms(15);
}
//12.56
//1256
/***************************/
float ReadFloat(u8 addr) /* WordAddress,First Data Address,Byte lenth */
{u8 f1;u8 f2;u8 f3;u8 f4;int y;float res;//12.34=1234 1 2 3 4ReadNbyte(addr,&f1,1); /* WordAddress,First Data Address,Byte lenth */delayms(15);ReadNbyte(addr+1,&f2,1) ; /* WordAddress,First Data Address,Byte lenth */delayms(15);ReadNbyte(addr+2,&f3,1); /* WordAddress,First Data Address,Byte lenth */delayms(15);ReadNbyte(addr+3,&f4,1) ; /* WordAddress,First Data Address,Byte lenth */delayms(15);y=f1*1000+f2*100+f3*10+f4;res=(float)(y*0.01);return res;
}