2、51单片机串口 和定时器冲突问题

注:本博客作为学习笔记,有错误的地方希望指正

问题:串口和定时器不能同时使用的问题
解决方法:
1、注意配置TMOD 的时候 要加上与运算给,不然就会改变该定时器的的在定时器的寄存器的值,后面定时器配置就会覆盖串口中使用到的定时器的TMOD 的状态值
2、其次还要在接收串口的数据的时候关闭EA,关闭全局中断,防止接收消息的时候被中断打断,不过51单片机有自己中断优先级管理的,不像STM32自己可以规定中断优先级的。
好的,介绍完毕,上菜(Code)
1、主函数 初始化定时器和串口配置,主循环中检测电机运行状态

#include "STC8051.h"
#include "Uart.h"
#include "Common.h"
#include "Motor_86.h"
#include 
/**********************************************************************************
函数名称:main()                                 					
功能描述:主函数.										                                            
参数说明:无                                                              
返回说明:无
其他说明:无                                                            
***********************************************************************************/
void main(void)
{
	Uart_Init();
	Motor_86_init();
	while(1)
	{  
	  Motor_86_Run();
	}
}

2、串口配置 Uart.c 配置串口的基本参数 和中断接收的判断处理

#include "STC8051.h"
#include "Common.h"
#include "Uart.h"
#include "Motor.h"
#include "Motor_86.h"
#include 

//#define STC12C5A60S2		  //条件编译决定使用12系列MCU
#define Fosc 11059200				//晶振
#define Band 9600 					//波特率

extern char Run_Flag;
U8 Tmp;
bit flag = 0; 

/**********************************************************************************
函数名称:Uart_Init()                              					
功能描述:完成对串口配置初始化  		  						                                            
参数说明:无                                                 
返回说明:无
其他说明:无                                                        
***********************************************************************************/
void Uart_Init(void)
{
#ifdef STC12C5A60S2

	AUXR = 0x15;					//1T
	BRT = 256 - Fosc/Band/32;		//波特率计算公式
	SM0 = 0;
	SM1 = 1; 						//工作方式
	REN = 1;						//允许接收
	PCON = 0x00;				//SMOD=0
	ES = 1;							//使能串口中断
	EA = 1;							//使能总中断

#else 								//STC89C52系列MCU
		
	TMOD |= 0x20;
	TH1  = 0xFD;
	TL1  = 0xFD;
	TR1  = 1;

	SM0 = 0;
	SM1 = 1;	   	//设置有定时器控制波特率的工作方式1
	REN = 1;			//串行口允许接受数据
	ES  = 1;  		//使能串口
	PCON = 0x00;	//波特率倍增不使能
	EA = 1;	
 
#endif			
}
/**********************************************************************************
函数名称:UartIntServe()                            					
功能描述:串口中断,用于监控上位机发送指令,收到什么数据就发送回什么数据		  						                                            
参数说明:无                                                  
返回说明:无
其他说明:无                                                        
***********************************************************************************/
void UartIntServ(void) interrupt 4 
{
	if (RI==1)     					//判断是否接受完一个字节数据   
	{  
		 EA = 0;							//关闭中断
	   Tmp = SBUF;					//接收数据
		 Massage_state = ~Massage_state;
	   if(Tmp == 0x01)			//系统启动       -> 安卓界面 "运行"
	   {
			 Run_Flag = 1;			//运行标志设置为1
			 ET0 = 1;						//打开定时器
	   }
	   else if(Tmp == 0x02)	//加速(延时减少) -> 安卓界面 "加速"
	   {	 
			 Speed -= 10;
			 if(Speed <= 10)		//向下溢出
				Speed = 10;
	   }
	   else if(Tmp == 0x03) //减速(延时增多) -> 安卓界面 "减速"
	   {
			 Speed += 10;
			 if(Speed >= 250)		//向下溢出
				Speed = 250;
	   }
	   else if(Tmp == 0x04) //暂停系统       -> 安卓界面 "停转"
	   {
			 Run_Flag = 0;			//运行标志设置为1
			 ET0 = 0;						//关闭定时器
			 Puse =0;						//脉冲端口拉低
	   }	
		 else if(Tmp == 0x05)	//暂停正转       -> 安卓界面 "正转"
	   {
			 Run_Dir = 1;				//方向标志设置为1
	   }	
		 else if(Tmp == 0x06)	//暂停反转       -> 安卓界面 "反转"
	   {
			 Run_Dir = 0;				//方向标志设置为0
	   }	
	   RI=0;	   						//接收标志位清零
		 EA = 1;							//开启中断
	}
}

2.1 Uart.h 基本配置

#ifndef __UART_H__
#define __UART_H__

#define U8 unsigned char   //字符型
#define U16 unsigned int   //整型
#define U32 unsigned long  //长整型

extern U8 Tmp; 
extern bit flag;
//UART 相关函数------------------------
extern void Uart_Init(void);			 
//UART----END-------------------------------
#endif

3、电机函数配置(定时器0配置)

#include "Motor_86.h"
#include "STC8051.h"
unsigned int timer1; 	  //运行计数
int Speed = 5;			  //运行速度
char Run_Flag = 0;			//是否运行标志
char Run_Dir = 0;				//运行方向标志
unsigned char i=0;
void delay_ms(unsigned int i)
{
    unsigned char j;
    for(i; i > 0; i--)   //循环 600*255 次 
        for(j = 255; j > 0; j--);
}
/*********************************************
*			函数名称:Motor_86_init
*			函数功能:步进电机初始化
*			参    数:无
*			说    明:无
**********************************************/
void Motor_86_init(void)
{
	EA  = 1;	   	//打开总中断
	TR0 = 1;	 		//打开定时器0中断
	ET0 = 0;	 		//关闭定时器0
	TH0=(65536-5000)/256; 		 //给time0装初值
	TL0=(65536-5000)%256;
	TMOD|=0x02;		//设置定时器t0的工作方式
}
/*********************************************
*			函数名称:Motor_86_Dir_Contol
*			函数功能:步进电机的方向控制
*			参    数:dir dir=0 反方向 dir=1 正方向
*			说    明:无
**********************************************/
void Motor_86_Dir_Contol(char dir)
{
	if(dir == 0)
	{
		DIR = 0;
	}
	else if(dir == 1)
	{
		DIR = 1;
	}
}
/********************************************
*			函数名称:Motor_86_Run
*			函数功能:步进电机运行控制
*			参    数:无
*			说    明:无
*********************************************/
void Motor_86_Run(void)
{
	if(Run_Flag == 1)						//只有在系统启动后才具有加速,减速和正转,反转的..
	{
		if(Run_Dir == 1)					//正方向运行
		{
			Motor_86_Dir_Contol(1);
		}
		else if(Run_Dir == 0)			//反方向运行
		{
			Motor_86_Dir_Contol(0);
		}
	}
	else
	{
		delay_ms(500); 							//没有运行空延时等待事件的发生
		Run_state = 0;
		delay_ms(500); 							//没有运行空延时等待事件的发生
		Run_state = 1;
	}
}
/********************************************
*			函数名称:Motor_86_Time
*			函数功能:定时器中断
*			参    数:无
*			说    明:无
*********************************************/
void time0(void) interrupt 1 using 0
{
		TH0=(65536-5000)/256; 
		TL0=(65536-5000)%256;
    timer1++; 	//计数+1
		if(timer1>=Speed)
		{
			Puse =0;
		}
		else
		{
			Puse =1;
		}
		if(timer1 >= 250)
		{
			timer1 = 0;
		}
}

3.1电机函数头文件配置

#ifndef _Motor_86_H_
#define _Motor_86_H_
#include "STC8051.h"

sbit  DIR  = P1^0;			//步进电机方向引脚 0.0
sbit  Puse = P1^3;			//步进电机脉冲引脚 0.1
sbit  Run_state     = P1^1;	//状态显示
sbit  Massage_state = P1^2;	//消息接收显示

extern int Speed;
extern unsigned int timer1; 
extern char Run_Flag;
extern char Run_Dir;
void delay_ms(unsigned int i);
void Motor_86_init(void);
void Motor_86_Dir_Contol(char dir);
void Motor_86_Run(void);
#endif

4、历程解说视频:源码分析

你可能感兴趣的:(单片机,物联网,嵌入式)