#include <stc15.h>
#include <intrins.h>
#include <stdio.h>
typedef unsigned char u8;
typedef unsigned int u16;
typedef unsigned long u32;
//函数声明
void delay1ms(); //@11.0592MHz
void delayms(int nms); //@11.0592MHz
//位函数
u8 bitSet(u8 x,u8 pos);
u8 bitReset(u8 x,u8 pos);
u8 bitRead(u8 x,u8 pos);
u8 bitToggle(u8 x,u8 pos);
//选择573函数
#define LEDY 0
#define SMGABCY 1
#define SMGCOMY 2
#define ULNY 3
#define NONE 4
void choose573(u8 x);
//LED驱动函数,
#define L1 0
#define L2 1
#define L3 2
#define LEDON 0
#define LEDOFF 1
u8 u8LED=0xff;
void LEDONx(u8 x);
void LEDOFFx(u8 x);
u8 LEDReadx(u8 x);
void LEDTOGx(u8 x);
void LEDdis(u8 x);
//继电器和蜂鸣器
u8 u8ULN=0x00;
void ULNdis(u8 x)
{
choose573(NONE);
u8ULN=x;
P0=u8ULN;
choose573(ULNY);
choose573(NONE);
}
void JDQON()
{
u8ULN=bitSet(u8ULN,4);
}
void JDQOFF()
{
u8ULN=bitReset(u8ULN,4);
}
void FMQON()
{
u8ULN=bitSet(u8ULN,6);
}
void FMQOFF()
{
u8ULN=bitReset(u8ULN,6);
}
//******************数码管
u8 SMGbuf[8];//显示缓冲
u8 display_index; //显示位索引
//位选择,和上面的数组倒过来,这样SMGbuf[0]对应位T_COM[0]数码管
u8 code T_COM[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; //位码
//u8 code T_COM[]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01}; //位码
char SMGtemp[20];//数码管转换中间变量,sprintf函数打印到这个缓冲区中。
//段码表,字库表
/************* 本地常量声明 **************/
u8 code t_display[]={ //标准字库,共阴极,记得取反就可以了。
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
0x3F,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 y
0x00,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. -1
//*********************************************复制stc-ISP里面试验箱的HC595驱动数码管的代码
/********************** 显示扫描函数 ************************/
void DisplayScan(void)
{
//位选
choose573(NONE);//关闭所有的通道
P0=T_COM[display_index];//选择位码
choose573(SMGCOMY);//选择位选COM通道,输出位码
choose573(NONE);//关闭通道
//消隐
P0=0xff;//段码0xFF,关闭段码熄灭数码管,消隐
choose573(SMGABCY);//选择段码通道,输出段码
//段码
P0=SMGbuf[display_index];//设置段码到P0口,
choose573(SMGABCY);//输出段码
choose573(NONE);//关闭所有的通道
//8个数码管
if(++display_index >= 8) display_index = 0; //8位结束回0
}
void SMGconv(void)
{
char i=0,j=0,temp;
while(SMGtemp[i]!=0) //缓冲区每次都会填入8个字符的sprintf,因此如果没数据会等于0x00;
{
switch(SMGtemp[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=~t_display[10];break;
case 'B':temp=~t_display[11];break;
case 'P':temp=~0x73;break;
case 'U':temp=~0x3E;break;
case '-':temp=~0x40;break;
default:temp=0xFF;break;
}
if(SMGtemp[i+1]=='.')//下一个等于小数点
{
temp&=0x7f;//将小数点
i++;//跳过一个小数点字符
}
i++;//不管有没有小数点,都加一个位置
SMGbuf[j]=temp;//将转换的数据,放到数码管段码缓冲区中;
j++;//记得这个加一
}
}
//**********************定时器的设置
#define FOSC 11059200L
//#define T1MS (65536-FOSC/1000) //1T模式
#define T1MS (65536-FOSC/12/1000) //12T模式
//-----------------------------------------------
u8 flag1s=0;
int cnt1ms=0;
/* Timer0 interrupt routine */
void tm0_isr() interrupt 1
{
static u8 i=0;
TL0 = T1MS; //初始化计时值
TH0 = T1MS >> 8;
cnt1ms++;
if(cnt1ms==1000)
{
cnt1ms=0;
flag1s=1;
}
//是2的倍数,cnt1ms%2==0,相当于2ms执行一次,这里是3个数码管,每个2ms那么就是6ms刷新率
//如果是8个数码管,那么可以cnt1ms%1==0,每8ms刷新一帧数据
if(cnt1ms%2==0)
{
DisplayScan();//2ms刷新一个字符,也可以%1==0,一个字符显示一个函数
}
}
//****************************8
void main()
{
float xx=2.54;
int yy=87;
int sec=20; //9999 9999
int ge,shi,bai;
u8 jiemian=0;
u8 i=0;
LEDdis(0xFF);//开机关闭LED
ULNdis(0x00);//开机关闭蜂鸣器和继电器
jiemian=3;
EA = 1;//单片机总中断EA打开
AUXR &= 0x7f; //定时器0为12T模式
//TMOD &= 0xF0; //设置定时器为模式0(16位自动重装载)
//TMOD &= 0xF1;//1111 0001
TMOD = 0x01;//1111 0001
TL0 = T1MS; //初始化计时值
TH0 = T1MS >> 8;
ET0 = 1; //使能定时器0中断
TR0 =1; //定时器0开始计时
while(1)
{
//*******************显示整数,注意%3u和%03u的区别
sprintf(SMGtemp,"A-B-P%03u",(unsigned int)yy);//不够3个字符宽度,用0代替
//sprintf(SMGtemp,"A-B--%3u",(unsigned int)yy);
SMGconv();
delayms(5000);
yy=yy+1;
if(yy==345)yy=65;
//*********************************************
//*******************显示
sprintf(SMGtemp,"B----%3.2f",xx);3个字符宽度,2个小数点
SMGconv();//转换到数码管显示缓冲区
delayms(5000);
xx=xx+0.01;
if(xx>=5)xx=2.57;
//*********************************************
}
}
//延时89s52,传统的
void delay1ms() //@11.0592MHz
{
unsigned char i, j;
_nop_();
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
void delayms(int nms) //@11.0592MHz
{
unsigned char i, j;
int m;
for(m=0;m<nms;m++)
{
_nop_();
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
}
//位操作
u8 bitSet(u8 x,u8 pos)
{
x=x|(1<<pos);
return x;
}
u8 bitReset(u8 x,u8 pos)
{
x=x&(~(1<<pos));
return x;
}
u8 bitRead(u8 x,u8 pos)
{
u8 y;
y=(x>>pos)&0x01;
return y;
}
u8 bitToggle(u8 x,u8 pos)
{
x=x^(1<<pos);
return x;
}
//选择573
//#define LEDY 0
//#define SMGABCY 1
//#define SMGCOMY 2
//#define ULNY 3
//#define NONE 4
void choose573(u8 x)
{
switch(x)
{
case LEDY:P2=P2&0x1F |0x80;break; //1000 0000
case SMGABCY:P2=P2&0x1F |0xe0;break; //1110 0000
case SMGCOMY:P2=P2&0x1F |0xc0;break; //1100 0000
case ULNY:P2=P2&0x1F |0xa0;break; //1010 0000
case NONE:P2=P2&0x1F;break; //0000 0000
}
}
//LED驱动
//u8 bitSet(u8 x,u8 pos);
//u8 bitReset(u8 x,u8 pos);
//u8 bitRead(u8 x,u8 pos);
//u8 bitToggle(u8 x,u8 pos);
void LEDONx(u8 x)
{
u8LED=bitReset(u8LED,x);
}
void LEDOFFx(u8 x)
{
u8LED=bitSet(u8LED,x);
}
u8 LEDReadx(u8 x)
{
return bitRead(u8LED,x);
}
void LEDTOGx(u8 x)
{
u8LED=bitToggle(u8LED,x);
}
void LEDdis(u8 x)
{
choose573(NONE);
u8LED= x;
P0=u8LED;
choose573(LEDY);
//delay1ms();
choose573(NONE);
}