目录
第十三届国赛有难度,重难点就是定时器冲突,而且非常矛盾,用多了变量在定时器中断里面也会出错,频率测量,超声波,pwm波,当然数码管也可以动态扫描,而常用的定时器只有0、1、2,所以要合理的分配定时器。
首先看一下题目中的N-MOTOR电机驱动(输出pwm波)在哪:
如上图,J3排针第六个,其引脚为573的out6,也就是0x20;
接下来主程序:
main.c
#include <stc15f2k60s2.h>
#include <iic.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define somenop {_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();}
sbit TX=P1^0;
sbit RX=P1^1;
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,0x8e,0x89,0x88,0x8c};
code uchar dis_bit[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
uchar dis_buf[]={11,11,11,11,11,11,11,11};
uint freq;
uchar para_freq=90;//后面×100再比较
uchar jiemian;
uchar para;
uchar shidu;
uchar para_shidu=40;
uint distance;
uint i;
uchar para_distance=6;//后面×10再比较
uchar count;
uchar dis_count=0;
bit f_flag=0;
bit d_flag=0;
bit cm=0;
bit hz=0;
bit led_flag;
bit count_flag=0;
bit k1_flag;
uint Newzheng,Newfan,fan,zheng,time,intr;
bit pwm_flag;
void Allinit(void);
void display(void);
void Delayms(uint ms);
void display_jiemian(void);
void keyscan(void);
void Timer0Init(void);
void Timer1Init(void);
void sonic(void);
void send_wave(void);
void led_kz(void);
void pwm(void);
void DA_output(void);
void jdq_kz(void);
void Timer2Init(void);
void main(void)
{
Allinit();
Timer0Init();
Timer1Init();
Timer2Init();
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)
{
shidu=AD_Read(0x03)*0.39;
keyscan();
DA_output();
led_kz();
jdq_kz();
pwm();
display_jiemian();
display();
}
}
void display_jiemian(void)
{
if(jiemian==0)//频率界面显示
{
if(freq>99&&hz==0)
{
dis_buf[0]=22;dis_buf[1]=21;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>99&&hz==1)
{
dis_buf[0]=22;dis_buf[1]=21;dis_buf[2]=21;dis_buf[3]=21;dis_buf[4]=21;
dis_buf[5]=21;dis_buf[6]=freq/1000+10;dis_buf[7]=freq%1000/100;
}
if(freq>999&&hz==0)
{
dis_buf[0]=22;dis_buf[1]=21;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>999&&hz==1)
{
dis_buf[0]=22;dis_buf[1]=21;dis_buf[2]=21;dis_buf[3]=21;
dis_buf[4]=21;dis_buf[5]=21;dis_buf[6]=freq/1000+10;dis_buf[7]=freq%1000/100;
}
if(freq>9999&&hz==0)
{
dis_buf[0]=22;dis_buf[1]=21;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>9999&&hz==1)
{
dis_buf[0]=22;dis_buf[1]=21;dis_buf[2]=21;
dis_buf[3]=21;dis_buf[4]=21;dis_buf[5]=freq/10000;dis_buf[6]=freq%10000/1000+10;dis_buf[7]=freq%1000/100;
}
}
else if(jiemian==1)
{
dis_buf[0]=23;dis_buf[1]=21;dis_buf[2]=21;dis_buf[3]=21;dis_buf[4]=21;dis_buf[5]=21;
dis_buf[6]=shidu/10;dis_buf[7]=shidu%10;
}
else if(jiemian==2)
{
sonic();
if(cm==0)//cm
{
dis_buf[0]=24;dis_buf[1]=21;dis_buf[2]=21;dis_buf[3]=count;dis_buf[4]=21;dis_buf[5]=21;
dis_buf[6]=distance/10;dis_buf[7]=distance%10;
}
if(cm==1)//m
{
dis_buf[0]=24;dis_buf[1]=21;dis_buf[2]=21;dis_buf[3]=21;dis_buf[4]=21;
dis_buf[5]=distance/100+10;dis_buf[6]=distance%100/10;dis_buf[7]=distance%10;
}
}
else if(jiemian==3)
{
if(para==0)
{
if(para_freq>99)
{
dis_buf[0]=25;dis_buf[1]=1;dis_buf[2]=21;dis_buf[3]=21;dis_buf[4]=21;
dis_buf[5]=para_freq/100;dis_buf[6]=para_freq%100/10+10;dis_buf[7]=para_freq%10;
}
if(para_freq>9)
{
dis_buf[0]=25;dis_buf[1]=1;dis_buf[2]=21;dis_buf[3]=21;dis_buf[4]=21;dis_buf[5]=21;
dis_buf[6]=para_freq/10+10;dis_buf[7]=para_freq%10;
}
}
else if(para==1)
{
dis_buf[0]=25;dis_buf[1]=2;dis_buf[2]=21;dis_buf[3]=21;dis_buf[4]=21;dis_buf[5]=21;
dis_buf[6]=para_shidu/10;dis_buf[7]=para_shidu%10;
}
else if(para==2)
{
dis_buf[0]=25;dis_buf[1]=3;dis_buf[2]=21;dis_buf[3]=21;dis_buf[4]=21;dis_buf[5]=21;
dis_buf[6]=para_distance/10+10;dis_buf[7]=para_distance%10;
}
}
}
void DA_output(void)
{
if(shidu<=para_shidu)
{
DA_Write(51);
}
else if(shidu>para_shidu&&shidu<80)
{
DA_Write((5+((4/(80-para_shidu))*(shidu-80))*51));
}
else if(shidu>=80)
{
DA_Write(255);
}
}
void jdq_kz(void)
{
P0=0xff;
if(distance>para_distance*10)
{
P2=(P2&0x1f)|0xa0;
P0=0x10;P2=0;
if(count_flag==0)
{
count_flag=1;
count++;
EEPROM_Write(0x00,count);
Delayms(5);
}
}
else
{
P2=(P2&0x1f)|0xa0;
P0=0x00;P2=0;
count_flag=0;
}
}
void pwm(void)
{
if(freq>para_freq*100)
{
pwm_flag=1;
}
else
{
pwm_flag=0;
}
}
void led_kz(void)
{
P0=0xff;
if(led_flag==0)
{
if(jiemian==0)
{
P2=(P2&0x1f)|0x80;
P0=P0&0xfe;P2=0;
}
else if(jiemian==1)
{
P2=(P2&0x1f)|0x80;
P0=P0&0xfd;P2=0;
}
else if(jiemian==2)
{
P2=(P2&0x1f)|0x80;
P0=P0&0xfb;P2=0;
}
}
else if(led_flag==1)
{
if(jiemian==0)
{
P2=(P2&0x1f)|0x80;
P0=(P0|~0xfe);P2=0;
}
else if(jiemian==1)
{
P2=(P2&0x1f)|0x80;
P0=(P0|~0xfd);P2=0;
}
else if(jiemian==2)
{
P2=(P2&0x1f)|0x80;
P0=(P0|~0xfb);P2=0;
}
}
if(jiemian==3)
{
P2=(P2&0x1f)|0x80;
P0=0xff;
}
if(freq>para_freq*100)
{
P2=(P2&0x1f)|0x80;
P0=P0&0xf7;P2=0;
}
else
{
P2=(P2&0x1f)|0x80;
P0=(P0|~0xf7);P2=0;
}
if(shidu>para_shidu)
{
P2=(P2&0x1f)|0x80;
P0=P0&0xef;P2=0;
}
else
{
P2=(P2&0x1f)|0x80;
P0=(P0|~0xef);P2=0;
}
if(distance>para_distance*10)
{
P2=(P2&0x1f)|0x80;
P0=P0&0xbf;P2=0;
}
else
{
P2=(P2&0x1f)|0x80;
P0=(P0|~0xbf);P2=0;
}
}
void keyscan(void)
{
if(P30==0)//s7
{
Delayms(10);
if(P30==0)
{
if(jiemian==3)
{
if(para==0)//khz
{
para_freq-=5;
if(para_freq==5)
{
para_freq=120;
}
}
else if(para==1)
{
para_shidu-=10;
if(para_shidu==0)
{
para_shidu=60;
}
}
else if(para==2)//m
{
para_distance-=1;
if(para_distance==0)
{
para_distance=12;
}
}
}
else if(jiemian==1)
{
if(k1_flag==0)
{
intr=0;
k1_flag=1;
}
}
else if(jiemian==0)
{
hz=~hz;
}
}
while(P30==0){led_kz();display();}
}
if(P30==1)
{
k1_flag=0;
}
if(P31==0)//s6
{
Delayms(10);
if(P31==0)
{
if(jiemian==3)
{
if(para==0)//khz
{
para_freq+=5;
if(para_freq==125)
{
para_freq=10;
}
}
else if(para==1)
{
para_shidu+=10;
if(para_shidu==70)
{
para_shidu=10;
}
}
else if(para==2)//m
{
para_distance+=1;
if(para_distance==13)
{
para_distance=1;
}
}
}
else if(jiemian==2)
{
cm=~cm;
}
}
while(P31==0);
}
if(P32==0)
{
Delayms(10);
if(P32==0)
{
if(para==0)
{
para=1;
}
else if(para==1)
{
para=2;
}
else if(para==2)
{
para=0;
}
}
while(P32==0);
}
if(P33==0)
{
Delayms(10);
if(P33==0)
{
if(jiemian==0)
{
jiemian=1;intr=0;
}
else if(jiemian==1)
{
jiemian=2;intr=0;
}
else if(jiemian==2)
{
jiemian=3;para=0;intr=0;
}
else if(jiemian==3)
{
jiemian=0;intr=0;
}
}
while(P33==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
{
if(jiemian==0)
{
intr++;
if(intr==100)
{
led_flag=~led_flag;
}
else if(intr==200)
{
led_flag=~led_flag;
}
else if(intr==300)
{
led_flag=~led_flag;
}
else if(intr==400)
{
led_flag=~led_flag;
}
else if(intr==500)
{
led_flag=~led_flag;
}
else if(intr==600)
{
led_flag=~led_flag;
}
else if(intr==700)
{
led_flag=~led_flag;
}
else if(intr==800)
{
led_flag=~led_flag;
}
else if(intr==900)
{
led_flag=~led_flag;
}
else if(intr==969)
{
AUXR |= 0x10;
}
else if(intr==999)
{
AUXR &= ~0x10;
intr=0;
led_flag=~led_flag;
time=(Newzheng+Newfan)*5;
freq=1000000/time;
}
}
else if(jiemian==2)//超声
{
intr++;
if(intr==100)
{
led_flag=~led_flag;
}
else if(intr==200)
{
led_flag=~led_flag;
}
else if(intr==300)
{
led_flag=~led_flag;
}
else if(intr==400)
{
led_flag=~led_flag;
}
else if(intr==500)
{
led_flag=~led_flag;
}
else if(intr==600)
{
intr=0;
d_flag=1;
led_flag=~led_flag;
}
}
else if(jiemian==1)
{
intr++;
if(intr==100)
{
led_flag=~led_flag;
}
else if(intr==200)
{
led_flag=~led_flag;
}
else if(intr==300)
{
led_flag=~led_flag;
}
else if(intr==400)
{
led_flag=~led_flag;
}
else if(intr==500)
{
led_flag=~led_flag;
}
else if(intr==600)
{
led_flag=~led_flag;
}
else if(intr==700)
{
led_flag=~led_flag;
}
else if(intr==800)
{
led_flag=~led_flag;
}
else if(intr==900)
{
led_flag=~led_flag;
}
else if(intr==1000)
{
led_flag=~led_flag;
intr=0;
if(k1_flag==1)count=0;
}
}
if(pwm_flag==1)
{
intr++;
if(intr<200)
{
P2=(P2&0x1f)|0xa0;
P0=P0&0x20;P2=0;
}
else if(intr>=200&&intr<1000)
{
intr=0;
P2=(P2&0x1f)|0xa0;
P0=(P0|~0x20);P2=0;
}
}
}
void Timer1Init(void) //5微秒@11.0592MHz
{
AUXR |= 0x40; //定时器时钟1T模式
TMOD &= 0x0F; //设置定时器模式
}
void tim2(void) interrupt 12
{
if(jiemian==0)
{
if(P34==0)
{
fan++;
if(f_flag==1)
{
f_flag=0;
Newfan=fan;
fan=0;
}
}
else if(P34==1)
{
zheng++;
if(f_flag==0)
{
f_flag=1;
Newzheng=zheng;
zheng=0;
}
}
}
}
void Timer2Init(void) //5u秒@11.0592MHz
{
AUXR &= 0xFB; //定时器时钟12T模式
T2L = 0xFB; //设置定时初值
T2H = 0xFF;
IE2 |= 0x04;
EA=1;
}
void sonic(void)
{
uint t;
if(d_flag==1)
{
dis_count++;
d_flag=0;
send_wave();
TR1=0;
while(TF1==0&&RX==0);
TR1=1;
while(TF1==0&&RX==1);
TR1=0;
if(TF1==1)
{
TF1=0;
}
else if(TF1==0)
{
t=TH1;
t<<=8;
t|=TL1;
distance=(uint)t*0.017;
distance/=12;
if(dis_count==1)
{
distance=0;
}
}
TH1=0;
TL1=0;
}
}
void send_wave(void)
{
uchar n=8;
do
{
TX=1;
somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;
TX=0;
somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;
}
while(n--);
}
void Allinit(void)
{
P2=(P2&0x1f)|0x80;
P0=0xff;P2=0;
P2=(P2&0x1f)|0xa0;
P0=0x00;P2=0;
P2=(P2&0x1f)|0xa0;
P0=0x00;P2=0;
P2=(P2&0x1f)|0xf0;
P0=0xff;P2=0;
}
void display(void)
{
uchar i;
for(i=0;i<8;i++)
{
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;
Delayms(1);
P2=(P2&0x1f)|0xe0;
P0=0xff;P2=0;
}
}
void Delayms(uint ms)
{
uint i,j;
for(i=ms;i>0;i--)
for(j=845;j>0;j--);
}
iic.c
#include <stc15f2k60s2.h>
#include <iic.h>
#include <intrins.h>
sbit sda=P2^1;
sbit scl=P2^0;
#define DELAY_TIME 10
//
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;
}
uchar AD_Read(uchar add)
{
uchar temp;
I2CStart();
I2CSendByte(0x90);
I2CWaitAck();
I2CSendByte(add);
I2CWaitAck();
I2CStop();
I2CStart();
I2CSendByte(0x91);
I2CWaitAck();
temp=I2CReceiveByte();
I2CWaitAck();
I2CStop();
return temp;
}
void DA_Write(uchar dat)
{
I2CStart();
I2CSendByte(0x90);
I2CWaitAck();
I2CSendByte(0x40);
I2CWaitAck();
I2CSendByte(dat);
I2CWaitAck();
I2CStop();
}
void EEPROM_Write(uchar add,uchar dat)
{
I2CStart();
I2CSendByte(0xa0);
I2CWaitAck();
I2CSendByte(add);
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 I2CWaitAck(void);
unsigned char I2CReceiveByte(void);
uchar AD_Read(uchar add);
void DA_Write(uchar dat);
void EEPROM_Write(uchar add,uchar dat);
#endif
以上就是全部内容,其中超声波有一点问题,就是第一次读取的时候值会跳很大,我这里是固定了92,所以我写了一个do{}while,更好的方法还没有找到。欢迎大佬指点。