这届省赛不难,但是是我第一次使用定时器扫描数码管和按键写程序,效果比Delay好太多,是真的好用!但出现的问题也会变多,其中主要是外设冲突问题。
目录
先来看看定时器扫描数码管
数码管显示
void display(void)
{
static uchar i=0;
P0=0xff;//消除鬼影
P2=(P2&0x1f)|0xe0;
P2=0;
P0=0x00;
P2=(P2&0x1f)|0xc0;
P0=dis_bit[i];
P2=0;
P0=0xff;
P2=(P2&0x1f)|0xe0;
P0=tab[dis_buf[i]];
P2=0;
if(++i==8)i=0;
}
显示定时器
void Timer0Init(void) //1毫秒@11.0592MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0xCD; //设置定时初值
TH0 = 0xD4; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
EA=1;
ET0=1;
}
void Tim0(void) interrupt 1
{
display();
if(++Key_flag==10)
{
Key_flag=0;
}
if(++smg_slow_down==70)//目的是减速,防止更新频率太快,导致外设显示冲突
{
smg_slow_down=0;
}
if(++led_slow_down==100)
{
led_slow_down=0;
}
}
独立按键
uchar Key_Read(void)
{
uchar Key_num,Key_value;
P3|=0x0f;//准双向口,先拉高
Key_num=P3&0x0f;
switch(Key_num)
{
case 0x0e: Key_value = 7; break;
case 0x0d: Key_value = 6; break;
case 0x0b: Key_value = 5; break;
case 0x07: Key_value = 4; break;
default: Key_value=0;break;
}
return Key_value;
}
void Key_isolated(void)
{
uchar Key_Temp,Key_Down,Key_Up;
static uchar Key_Old=0;
if(Key_flag)return;
Key_flag=1;
/****************消抖(网上有详细的教学)************/
Key_Temp=Key_Read();
Key_Down=Key_Temp&(Key_Temp^Key_Old);
Key_Up=~Key_Temp&(Key_Temp^Key_Old);
Key_Old=Key_Temp;
if(Key_Down)
{
switch(Key_Down)
{
case 7:
smg_flag=~smg_flag;
break;
case 6:
Led_mode=~Led_mode;
break;
case 5:
DA_flag=~DA_flag;
break;
case 4:
jiemian=~jiemian;
break;
default:break;
}
}
}
main.c
#include <stc15f2k60s2.h>
#include <iic.h>
#include <intrins.h>
code uchar tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,\
0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0xbf,0xff,0xc1,0x8e};
code uchar dis_bit[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};//位选
uchar dis_buf[]={11,11,11,11,11,11,11,11};//段选
void display(void);//显示函数
void Delayms(uint ms); //延时函数
void Allinit(void);//外设初始化函数
void Timer0Init(void);//定时器初始化
void Timer1Init(void);
uchar Key_Read(void);
void Key_isolated(void);
void smg_display(void);
void Led_Control(void);
uchar Key_flag=0;//独立按键减速
uchar smg_slow_down;//数码管减速
uchar led_slow_down;
bit jiemian=0;//界面切换
bit f_flag;//频率正反切换
bit DA_flag=0;
bit Led_mode;
bit smg_flag;
uint freq;//频率
uint Voltage;//电压
uint tt;//频率测量标志
uint time;//时间
uint zheng,fan,Newzheng,Newfan;//频率测量series
uchar AD;
void main(void)
{
Allinit();
Timer0Init();
Timer1Init();
dis_buf[0]=21;dis_buf[1]=21;dis_buf[2]=21;dis_buf[3]=21;dis_buf[4]=21;dis_buf[5]=21;dis_buf[6]=21;dis_buf[7]=21;
while(1)
{
smg_display();
Key_isolated();
Led_Control();
}
}
void Timer0Init(void) //1毫秒@11.0592MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0xCD; //设置定时初值
TH0 = 0xD4; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
EA=1;
ET0=1;
}
void Tim0(void) interrupt 1
{
display();
if(++Key_flag==10)
{
Key_flag=0;
}
if(++smg_slow_down==70)
{
smg_slow_down=0;
}
if(++led_slow_down==100)
{
led_slow_down=0;
}
tt++;
if(tt==969)
{
TR1=1;
}
else if(tt==999)
{
tt=0;
TR1=0;
time=(Newzheng+Newfan)*5;
freq=1000000/time;
}
}
void Timer1Init(void) //5微秒@11.0592MHz
{
AUXR |= 0x40; //定时器时钟1T模式
TMOD &= 0x0F; //设置定时器模式
TL1 = 0xC9; //设置定时初值
TH1 = 0xFF; //设置定时初值
TF1 = 0; //清除TF1标志
EA=1; //定时器1开始计时
ET1=1;
}
void Tim1(void) interrupt 3
{
if(P34==0)
{
fan++;
if(f_flag==1)
{
f_flag=0;
Newzheng=zheng;
zheng=0;
}
}
else if(P34==1)
{
zheng++;
if(f_flag==0)
{
f_flag=1;
Newfan=fan;
fan=0;
}
}
}
uchar Key_Read(void)
{
uchar Key_num,Key_value;
P3|=0x0f;//准双向口,先拉高
Key_num=P3&0x0f;
switch(Key_num)
{
case 0x0e: Key_value = 7; break;
case 0x0d: Key_value = 6; break;
case 0x0b: Key_value = 5; break;
case 0x07: Key_value = 4; break;
default: Key_value=0;break;
}
return Key_value;
}
void Key_isolated(void)
{
uchar Key_Temp,Key_Down,Key_Up;
static uchar Key_Old=0;
if(Key_flag)return;
Key_flag=1;
Key_Temp=Key_Read();
Key_Down=Key_Temp&(Key_Temp^Key_Old);
Key_Up=~Key_Temp&(Key_Temp^Key_Old);
Key_Old=Key_Temp;
if(Key_Down)
{
switch(Key_Down)
{
case 7:
smg_flag=~smg_flag;
break;
case 6:
Led_mode=~Led_mode;
break;
case 5:
DA_flag=~DA_flag;
break;
case 4:
jiemian=~jiemian;
break;
default:break;
}
}
}
void smg_display(void)
{
if(smg_slow_down)return;
smg_slow_down=1;
AD=IIC_Read(0x03);
Voltage=AD*1.96078431372549;
if(smg_flag==0)
{
if(jiemian==0)
{
if(DA_flag==0)
{
dis_buf[0]=22;dis_buf[1]=21;dis_buf[2]=21;dis_buf[3]=21;dis_buf[4]=21;
dis_buf[5]=200/100+10;dis_buf[6]=200%100/10;dis_buf[7]=200%10;
DA_Write(2*51);
}
else if(DA_flag==1)
{
dis_buf[0]=22;dis_buf[1]=21;dis_buf[2]=21;dis_buf[3]=21;dis_buf[4]=21;
dis_buf[5]=Voltage/100+10;dis_buf[6]=Voltage%100/10;dis_buf[7]=Voltage%10;
DA_Write(AD);
}
}
else if(jiemian==1)
{
dis_buf[0]=23;dis_buf[1]=21;
if(freq<10)
{
dis_buf[2]=21;dis_buf[3]=21;dis_buf[4]=21;dis_buf[5]=21;dis_buf[6]=21;dis_buf[7]=freq;
}
else if(freq>=10&&freq<100)
{
dis_buf[2]=21;dis_buf[3]=21;dis_buf[4]=21;dis_buf[5]=21;dis_buf[6]=freq/10;dis_buf[7]=freq%10;
}
else if(freq>=100&&freq<999)
{
dis_buf[2]=21;dis_buf[3]=21;dis_buf[4]=21;dis_buf[5]=freq/100;dis_buf[6]=freq%100/10;dis_buf[7]=freq%10;
}
else if(freq>=1000&&freq<10000)
{
dis_buf[2]=21;dis_buf[3]=21;dis_buf[4]=freq/1000;dis_buf[5]=freq%1000/100;dis_buf[6]=freq%100/10;dis_buf[7]=freq%10;
}
else if(freq>=10000&&freq<100000)
{
dis_buf[2]=21;dis_buf[3]=freq/10000;dis_buf[4]=freq%10000/1000;dis_buf[5]=freq%1000/100;dis_buf[6]=freq%100/10;dis_buf[7]=freq%10;
}
else if(freq>=100000)
{
dis_buf[2]=freq/100000;dis_buf[3]=freq%100000/10000;dis_buf[4]=freq%10000/1000;dis_buf[5]=freq%1000/100;dis_buf[6]=freq%100/10;dis_buf[7]=freq%10;
}
}
}
else if(smg_flag==1)
{
dis_buf[0]=21;dis_buf[1]=21;dis_buf[2]=21;dis_buf[3]=21;dis_buf[4]=21;dis_buf[5]=21;dis_buf[6]=21;dis_buf[7]=21;
}
}
void Led_Control(void)
{
if(led_slow_down)return;
led_slow_down=1;
P0=0xff;
if(Led_mode==0)
{
if(jiemian==0)
{
P2=(P2&0x1f)|0x80;
P0=P0&0xfe;P2=0;
}
else
{
P2=(P2&0x1f)|0x80;
P0=P0&0xfd;P2=0;
}
if(DA_flag==1)
{
if(Voltage<150||(Voltage>=250&&Voltage<350))
{
P2=(P2&0x1f)|0x80;
P0=P0|(~0xfb);P2=0;
}
else if((Voltage>=150&&Voltage<250)||(Voltage>=350))
{
P2=(P2&0x1f)|0x80;
P0=P0&0xfb;P2=0;
}
}
else if(DA_flag==0)
{
P2=(P2&0x1f)|0x80;
P0=P0&0xfb;P2=0;
}
if(freq<1000||(freq>=5000&&freq<10000))
{
P2=(P2&0x1f)|0x80;
P0=P0|(~0xf7);P2=0;
}
else if(freq>=1000&&freq<5000||(freq>=10000))
{
P2=(P2&0x1f)|0x80;
P0=P0&0xf7;P2=0;
}
if(DA_flag==0)
{
P2=(P2&0x1f)|0x80;
P0=P0|(~0xef);P2=0;
}
else
{
P2=(P2&0x1f)|0x80;
P0=P0&0xef;P2=0;
}
P2=0;
}
else if(Led_mode==1)
{
P2=(P2&0x1f)|0x80;
P0=0xff;P2=0;
}
}
void Allinit(void)
{
P2=(P2&0x1f)|0xa0;
P0=0x00;
P2=0;
P2=(P2&0x1f)|0x80;
P0=0xff;
P2=0;
P2=(P2&0x1f)|0xc0;
P0=0x00;
P2=0;
P2=(P2&0x1f)|0xf0;
P0=0xff;
P2=0;
}
void display(void)
{
static uchar i=0;
P0=0xff;//消除鬼影
P2=(P2&0x1f)|0xe0;
P2=0;
P0=0x00;
P2=(P2&0x1f)|0xc0;
P0=dis_bit[i];
P2=0;
P0=0xff;
P2=(P2&0x1f)|0xe0;
P0=tab[dis_buf[i]];
P2=0;
if(++i==8)i=0;
}
iic.c
#include <stc15f2k60s2.h>
#include <iic.h>
#include <intrins.h>
#define DELAY_TIME 5
sbit sda=P2^1;
sbit scl=P2^0;
//
static void I2C_Delay(unsigned char n)
{
do
{
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
}
while(n--);
}
//
void I2CStart(void)
{
sda = 1;
scl = 1;
I2C_Delay(DELAY_TIME);
sda = 0;
I2C_Delay(DELAY_TIME);
scl = 0;
}
//
void I2CStop(void)
{
sda = 0;
scl = 1;
I2C_Delay(DELAY_TIME);
sda = 1;
I2C_Delay(DELAY_TIME);
}
//
void I2CSendByte(unsigned char byt)
{
unsigned char i;
for(i=0; i<8; i++){
scl = 0;
I2C_Delay(DELAY_TIME);
if(byt & 0x80){
sda = 1;
}
else{
sda = 0;
}
I2C_Delay(DELAY_TIME);
scl = 1;
byt <<= 1;
I2C_Delay(DELAY_TIME);
}
scl = 0;
}
//
unsigned char I2CReceiveByte(void)
{
unsigned char da;
unsigned char i;
for(i=0;i<8;i++){
scl = 1;
I2C_Delay(DELAY_TIME);
da <<= 1;
if(sda)
da |= 0x01;
scl = 0;
I2C_Delay(DELAY_TIME);
}
return da;
}
//
unsigned char I2CWaitAck(void)
{
unsigned char ackbit;
scl = 1;
I2C_Delay(DELAY_TIME);
ackbit = sda;
scl = 0;
I2C_Delay(DELAY_TIME);
return ackbit;
}
void DA_Write(uchar dat)
{
I2CStart();
I2CSendByte(0x90);
I2CWaitAck();
I2CSendByte(0x40);
I2CWaitAck();
I2CSendByte(dat);
I2CWaitAck();
I2CStop();
}
iic.h
#ifndef _IIC_H
#define _IIC_H
#define uchar unsigned char
#define uint unsigned int
static void I2C_Delay(unsigned char n);
void I2CStart(void);
void I2CStop(void);
void I2CSendByte(unsigned char byt);
unsigned char I2CReceiveByte(void);
unsigned char I2CWaitAck(void);
void DA_Write(uchar dat);
#endif