蓝桥杯单边机国赛的一些经验总结

文章详细介绍了如何使用STC15单片机的定时器模块进行超声波测距和频率测量。通过初始化不同的定时器,实现了1毫秒的定时器服务,并利用定时器1和定时器0分别处理超声波信号和频率测量。此外,还涉及了串口通信和定时器控制继电器的方法。
摘要由CSDN通过智能技术生成

自己的一些平时积累,如有发现什么不足,还望指正。

1.定时器模块

 对我而言,超声波我推荐用PCA测量,因为stc15单片机只有3个定时器,定时器0用于测量频率,而串口通信只能用定时器1和2,当然串口通信我觉得定时2好点,因为串口通信不需要高的优先级,所以还需要用一个定时器去规划所有时间。

2.超声波测距

unsigned int distance=0,distance_time=1;
bit distance_flag=0;
void Timer1Init(void)		//1毫秒@12.000MHz
{
	AUXR |= 0x40;		//定时器时钟1T模式
	TMOD &= 0x0F;		//设置定时器模式
	TL1 = 0x20;		//设置定时初始值
	TH1 = 0xD1;		//设置定时初始值
	TF1 = 0;		//清除TF1标志
	TR1 = 1;		//定时器1开始计时
	EA=1;//
	ET1=1;
}

void Timer1_Service() interrupt 3{
    if(++distance_time>=500){distance_time=1;distance_flag=1;}//也可以选200
}

void Delay12us()		//@12.000MHz
{
	unsigned char i;

	_nop_();
	_nop_();
	i = 33;
	while (--i);
}

void Sonic_init(){
	CMOD=0x00;//这个需要选系统时钟的12分之一,写CMOD=0x04为系统时钟,不对
	CCON=0x00;
}

void Get_distance(){
	uchar num123=8;
	CH=0;
	CL=0;
	CF=0;
	CR=1;
	while(num123--){
		P10=1;Delay12us();
		P10=0;Delay12us();
	}
	while(!CF&&P11);
	CR=0;
	if(CF==1){
		CF=0;
		distance=255;//这个跟题意来
	}
	else{
		distance=(uint)((CH*256+CL+156)*0.017);//距离上有接近3cm误差
	}
}

void main(){
    while(1){
        if(distance_flag){distance_flag=0;Get_distance();}
    }
}

3.频率测量

 频率测量记得1s测一次,同时需要连接P34与SIGNAG,同时其由RB3控制。

unsigned int frequency=0,frequency_time=1;
bit frequency_flag=0;
void Timer1Init(void)		//1毫秒@12.000MHz
{
	AUXR |= 0x40;		//定时器时钟1T模式
	TMOD &= 0x0F;		//设置定时器模式
	TL1 = 0x20;		//设置定时初始值
	TH1 = 0xD1;		//设置定时初始值
	TF1 = 0;		//清除TF1标志
	TR1 = 1;		//定时器1开始计时
	EA=1;//
	ET1=1;
}

void Timer1_Service() interrupt 3{
    if(++frequency_time>=1000){frequency_time=1;frequency_flag=1;}//1秒
}

void Timer0Init(void)		//微秒@12.000MHz
{
	AUXR |= 0x80;		//定时器时钟1T模式
//	TMOD &= 0xF0;		//设置定时器模式(改成计数)
	TMOD |= 0x04;		//设置定时器模式//改成计数模式
	TL0 = 0x00;		//设置定时初始值
	TH0 = 0x00;		//设置定时重载值
	TF0 = 0;		//清除TF0标志
}

void Timer0(){
	TR0=0;
	frequency=TH0*256+TL0;
	TH0=0;
	TL0=0;
	TF0=0;
	TR0=1;
}

void main(){
    while(1){
        if(frequency_flag){frequency_flag=0;Timer0();}
    }

}

 4.串口通信

#include <stdio.h>
#include <string.h>

unsigned char buffer[30]//范围根据输出或读入字符串大小设定
unsigned char rec_num=0,rec_time=1;
bit rec_flag=0,send_flag=0;

void Timer1Init(void)		//1毫秒@12.000MHz
{
	AUXR |= 0x40;		//定时器时钟1T模式
	TMOD &= 0x0F;		//设置定时器模式
	TL1 = 0x20;		//设置定时初始值
	TH1 = 0xD1;		//设置定时初始值
	TF1 = 0;		//清除TF1标志
	TR1 = 1;		//定时器1开始计时
	EA=1;//
	ET1=1;
}

void Timer1_Service() interrupt 3{
	if(rec_flag&&++rec_time>=50){//50ms限定时
		rec_flag=0;
		rec_time=1;
		send_flag=1;
	}
}

void UartInit(void)		//9600bps@12.000MHz 注意波特率
{
	SCON = 0x50;		//8位数据,可变波特率
	AUXR |= 0x01;		//串口1选择定时器2为波特率发生器
	AUXR |= 0x04;		//定时器时钟1T模式
	T2L = 0xC7;		//设置定时初始值
	T2H = 0xFE;		//设置定时初始值
	AUXR |= 0x10;		//定时器2开始计时
    ES=1;//打开串口中断
}

void Service_usart() interrupt 4{
	if(RI){
		RI=0;
		buffer[rec_num++]=SBUF;
		rec_flag=1;
	}
}

void Send_date(uchar date){
	SBUF=date;
	while(!TI);
	TI=0;
}

void Send_String(uchar *str){
	while(*str)
		Send_date(*str++);
}

void main(){
    while(1){
//如果字符比较,之间比较相等就行,也不许要最后叫'\0',可直接if('A'==buffer[0]);
		if(send_flag){//接受到字符串
			send_flag=0;
			buffer[rx_cnt]='\0';//等于\r\n
			rx_cnt=0;
			if(!strcmp("ST\r\n",buffer)){//比较是否相等
				sprintf(buffer,"$%d,%d\r\n",20,0);//数值也可以是变量,将字符赋该buffer中
				Send_String(buffer);
			}
    }
}

 5.定时器2控制转机

 定时器2的中断允许通过IE2控制,同时其中断函数编号为12。

unsigned char relay_num=0;
void Timer2Init(void)		//200微秒@12.000MHz
{
	AUXR |= 0x04;		//定时器时钟1T模式
	T2L = 0xA0;		//设置定时初始值
	T2H = 0xF6;		//设置定时初始值
	AUXR |= 0x10;		//定时器2开始计时
	IE2|=0x04;
}

void Timer2_service () interrupt 12{
	uchar relay_true=0x00;
	if(relay_num<=relay_now)
		relay_true|=0x20;
	else
		relay_true&=0xdf;
	relay_num=(relay_num+1)%5;
	P0=relay_true;P2|=0xa0;P2&=0x1f;
}

这个在第13届国赛时考了

 就是因为1kHz是1ms,所以不太好用你的定时器1进行调解,当你其实可以设置定时器1位200us的,然后其他时间同时改变就行,但多学一种方法也是好的。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值