当前位置: 首页 > wzjs >正文

江阴网站优化公司寿光网站建设

江阴网站优化公司,寿光网站建设,怎么做页眉,移动端购物网站建设写这个文章是用来学习的,记录一下我的学习过程。希望我能一直坚持下去,我只是一个小白,只是想好好学习,我知道这会很难,但我还是想去做! 本文写于:2025.03.30 51单片机学习——第38节: [17-2] 红外遥控&红外遥控电机 前言开发板说明引用…

写这个文章是用来学习的,记录一下我的学习过程。希望我能一直坚持下去,我只是一个小白,只是想好好学习,我知道这会很难,但我还是想去做!

本文写于:2025.03.30

51单片机学习——第38节: [17-2] 红外遥控&红外遥控电机

  • 前言
  • 开发板说明
  • 引用
  • 解答和科普
  • 一、
  • 二、红外遥控接受
  • 三、红外遥控直流电机
  • 总结

前言

   本次笔记是用来记录我的学习过程,同时把我需要的困难和思考记下来,有助于我的学习,同时也作为一种习惯,可以督促我学习,是一个激励自己的过程,让我们开始51单片机的学习之路。
   欢迎大家给我提意见,能给我的嵌入式之旅提供方向和路线,现在作为小白,我就先学习51单片机了,就跟着B站上的江协科技开始学习了.
   在这里会记录下江协科技51单片机开发板的配套视频教程所作的实验和学习笔记内容,因为我之前有一个开发板,我大概率会用我的板子模仿着来做.让我们一起加油!
   另外为了增强我的学习效果:每次笔记把我不知道或者问题在后面提出来,再下一篇开头作为解答!

开发板说明

   本人采用的是慧净的开发板,因为这个板子是我N年前就买的板子,索性就拿来用了。不再另外购买视频中的普中开发板了。
   原理图如下
在这里插入图片描述
视频中的都用这个开发板来实现,如果有资源就利用起来。
仔细看了看:开发板的晶振为:11.0592Mhz;12Mhz晶振是用来给CH340G芯片外置晶振;

下图是实物图
在这里插入图片描述

引用

51单片机入门教程-2020版 程序全程纯手打 从零开始入门
还参考了下图中的书籍:
手把手教你学51单片机(C语言版)
在这里插入图片描述
STC89C52手册
在这里插入图片描述

解答和科普

一、

1.1测试中断的执行

#include <REGX52.H>
#include "Delay.h"
#include "LCD1602.h"
#include "I2C.h"
#include "PCF8591.h"
#include "Init.h"unsigned char Num;
void main()
{LCD_Init();LCD_ShowString(1,1,"A");Nixie_OFF();DianZhengGuan();IT0=1;		//下降沿触发IE0=0;		//中断标志位EX0=1;		//打开中断EA=1;		//打开所有中断PX0=1;		//优先级while(1){LCD_ShowNum(2,1,Num,3);}
}void Into_Routine(void)  interrupt 0
{
Num++;
}

实验现象:

外部中断0低电平触发

外部中断0下降沿触发

1.2红外解码
在这里插入图片描述
如何把东西解码出来,包括读取时间值进行计时,还有中断。
状态机:定义一个变量表示当前的状态,0表示空闲状态,然后当他收到下降沿之后,把定时器打开,开始计时,再把状态转为1状态,寻找Start或者Repeat头部的这一个信号,1状态再来个下降沿的话,继续判断状态,判断中间的时间,如果是起始信号,就把状态转化为2状态,2状态定义为开始解码1012总共32,如果是重发,就把重发标志位置1,还有变量缓存区用来存取,还会置为正确是否。
1.Timer0

#include <REGX52.H>void Timer0_Init(void)		//1毫秒@11.0592MHz
{//	TMOD不能复制,如果同时使用定时器1和0,它会覆盖淹没,TMOD &= 0xF0;		//设置定时器模式TMOD |= 0x01;		//设置定时器模式TL0 = 0;		//设置定时初值TH0 = 0;		//设置定时初值TF0 = 0;		//清除TF0标志TR0 = 0;		//定时器0不计时
}void Timer0_SetCounter(unsigned char Value)
{TH0=Value/256;TL0=Value%256;}unsigned int Timer0_Getcounter(void)
{return (TH0<<8)|TL0;}void Timer0_Run(unsigned char Flag)
{TR0=Flag;}```c
#ifndef		__TIMER0_H
#define 	 __TIMER0_Hvoid Timer0_Init(void)	;
void Timer0_SetCounter(unsigned char Value);
unsigned int Timer0_Getcounter(void);
void Timer0_Run(unsigned char Flag);
#endif
#include <REGX52.H>
#include "Delay.h"
#include "LCD1602.h"
#include "I2C.h"
#include "PCF8591.h"
#include "Init.h"
#include "INT0.h"
#include "Timer0.h"
#include "IR.h"unsigned int Time;
void main()
{LCD_Init();LCD_ShowString(1,1,"A");Nixie_OFF();DianZhengGuan();Timer0_Init();Timer0_SetCounter(0);Timer0_Run(1);Delay(1);Time=Timer0_Getcounter();while(1){LCD_ShowNum(2,1,Time,3);}
}

实验现象:
在这里插入图片描述
测试遥控的进入

#include <REGX52.H>
#include "Timer0.h"
#include "INT0.h"unsigned int IR_Time;
unsigned char IR_State;unsigned char IR_Data[4];			//缓存
unsigned char IR_pData;unsigned char IR_DataFlag;
unsigned char IR_RepearFlag;
unsigned char IR_Address;			//Data又要接受数据又要输出数据 变搜变输出,可能会出错
unsigned char IR_Command;void IR_Init(void)
{Timer0_Init();Int0_Init();
}void Into_Routine(void)  interrupt 0
{if(IR_State==0){P1=0x00;Timer0_SetCounter(0);Timer0_Run(1);IR_State=1;}else if(IR_State==1){IR_Time=Timer0_Getcounter();Timer0_SetCounter(0);	if(IR_Time>12442-500&& IR_Time<12442+500)		//13500{IR_State=2;}else if(IR_Time>10368-500&& IR_Time<10368+500){IR_RepearFlag=1;Timer0_Run(0);	IR_State=0;	}else{IR_State=1;}}}

遥控能进入的话,会产生中断,进入状态0,然后会让LED灯全亮。
实验现象:

测试遥控灯

二、红外遥控接受

#include <REGX52.H>
#include "Delay.h"
#include "LCD1602.h"
#include "I2C.h"
#include "PCF8591.h"
#include "Init.h"
#include "INT0.h"
#include "Timer0.h"
#include "IR.h"unsigned int Time;
unsigned char Address;
unsigned char Command;
void main()
{LCD_Init();LCD_ShowString(1,1,"LED");Nixie_OFF();DianZhengGuan();IR_Init();while(1){if(IR_GetDataFlag()){Address=IR_GetAddress();Command=IR_GetCommand();LCD_ShowHexNum(2,1,Address,2);LCD_ShowHexNum(2,6,Command,2);}if(Command==0x16){P1=0x00;}}
}
#include <REGX52.H>void Timer0_Init(void)		//1毫秒@11.0592MHz
{//	TMOD不能复制,如果同时使用定时器1和0,它会覆盖淹没,TMOD &= 0xF0;		//设置定时器模式TMOD |= 0x01;		//设置定时器模式TL0 = 0;		//设置定时初值TH0 = 0;		//设置定时初值TF0 = 0;		//清除TF0标志TR0 = 0;		//定时器0不计时
}void Timer0_SetCounter(unsigned char Value)
{TH0=Value/256;TL0=Value%256;}unsigned int Timer0_GetCounter(void)
{return (TH0<<8)|TL0;}void Timer0_Run(unsigned char Flag)
{TR0=Flag;}
#include <REGX52.H>
#include "Timer0.h"
#include "INT0.h"unsigned int IR_Time;
unsigned char IR_State;unsigned char IR_Data[4];
unsigned char IR_pData;unsigned char IR_DataFlag;
unsigned char IR_RepeatFlag;
unsigned char IR_Address;
unsigned char IR_Command;/*** @brief  红外遥控初始化* @param  无* @retval 无*/
void IR_Init(void)
{Timer0_Init();Int0_Init();
}/*** @brief  红外遥控获取收到数据帧标志位* @param  无* @retval 是否收到数据帧,1为收到,0为未收到*/
unsigned char IR_GetDataFlag(void)
{if(IR_DataFlag){IR_DataFlag=0;return 1;}return 0;
}/*** @brief  红外遥控获取收到连发帧标志位* @param  无* @retval 是否收到连发帧,1为收到,0为未收到*/
unsigned char IR_GetRepeatFlag(void)
{if(IR_RepeatFlag){IR_RepeatFlag=0;return 1;}return 0;
}/*** @brief  红外遥控获取收到的地址数据* @param  无* @retval 收到的地址数据*/
unsigned char IR_GetAddress(void)
{return IR_Address;
}/*** @brief  红外遥控获取收到的命令数据* @param  无* @retval 收到的命令数据*/
unsigned char IR_GetCommand(void)
{return IR_Command;
}//外部中断0中断函数,下降沿触发执行
void Int0_Routine(void) interrupt 0
{if(IR_State==0)				//状态0,空闲状态{Timer0_SetCounter(0);	//定时计数器清0Timer0_Run(1);			//定时器启动IR_State=1;				//置状态为1}else if(IR_State==1)		//状态1,等待Start信号或Repeat信号{IR_Time=Timer0_GetCounter();	//获取上一次中断到此次中断的时间Timer0_SetCounter(0);	//定时计数器清0//如果计时为13.5ms,则接收到了Start信号(判定值在12MHz晶振下为13500,在11.0592MHz晶振下为12442)if(IR_Time>12442-500 && IR_Time<12442+500){IR_State=2;			//置状态为2}//如果计时为11.25ms,则接收到了Repeat信号(判定值在12MHz晶振下为11250,在11.0592MHz晶振下为10368)else if(IR_Time>10368-500 && IR_Time<10368+500){IR_RepeatFlag=1;	//置收到连发帧标志位为1Timer0_Run(0);		//定时器停止IR_State=0;			//置状态为0}else					//接收出错{IR_State=1;			//置状态为1}}else if(IR_State==2)		//状态2,接收数据{IR_Time=Timer0_GetCounter();	//获取上一次中断到此次中断的时间Timer0_SetCounter(0);	//定时计数器清0//如果计时为1120us,则接收到了数据0(判定值在12MHz晶振下为1120,在11.0592MHz晶振下为1032)if(IR_Time>1032-500 && IR_Time<1032+500){IR_Data[IR_pData/8]&=~(0x01<<(IR_pData%8));	//数据对应位清0IR_pData++;			//数据位置指针自增}//如果计时为2250us,则接收到了数据1(判定值在12MHz晶振下为2250,在11.0592MHz晶振下为2074)else if(IR_Time>2074-500 && IR_Time<2074+500){IR_Data[IR_pData/8]|=(0x01<<(IR_pData%8));	//数据对应位置1IR_pData++;			//数据位置指针自增}else					//接收出错{IR_pData=0;			//数据位置指针清0IR_State=1;			//置状态为1}if(IR_pData>=32)		//如果接收到了32位数据{IR_pData=0;			//数据位置指针清0if((IR_Data[0]==~IR_Data[1]) && (IR_Data[2]==~IR_Data[3]))	//数据验证{IR_Address=IR_Data[0];	//转存数据IR_Command=IR_Data[2];IR_DataFlag=1;	//置收到连发帧标志位为1}Timer0_Run(0);		//定时器停止IR_State=0;			//置状态为0}}
}

实验现象:

红外遥控显示键码值并控制LED

2.3遥控键码值

#include <REGX52.H>
#include "Delay.h"
#include "LCD1602.h"
#include "I2C.h"
#include "PCF8591.h"
#include "Init.h"
#include "INT0.h"
#include "Timer0.h"
#include "IR.h"unsigned char Num;
unsigned char Address;
unsigned char Command;
void main()
{LCD_Init();LCD_ShowString(1,1,"ADDR  CMD  NUM");LCD_ShowString(2,1,"00    00   000");Nixie_OFF();DianZhengGuan();IR_Init();while(1){if(IR_GetDataFlag()||IR_GetRepeatFlag()){Address=IR_GetAddress();Command=IR_GetCommand();LCD_ShowHexNum(2,1,Address,2);LCD_ShowHexNum(2,7,Command,2);if(Command==IR_VOL_X){Num--;}if(Command==IR_VOL_Z){Num++;}LCD_ShowNum(2,12,Num,3);}}
}

实验现象:

红外遥控键码值控制值增加和减少

三、红外遥控直流电机

1.Motor.c

#include <REGX52.H>
#include "Timer1.h"sbit Moter= P1^7;
unsigned char Counter,Compare;void Motor_Init(void)
{Timer1_Init();}void Motor_SetSpeed(unsigned char Speed)
{Compare=Speed;	
}void Timer1_Routine()   interrupt  3	//跳转到这里,触发中断
{TL1 = 0xA4;		//设置定时初值TH1 = 0xFF;		//设置定时初值Counter++;			//定时器定时递增Counter%=100;			//周期清零if(Counter<Compare)	//比较{Moter=1;		//给1转}else{Moter=0;}
}
#ifndef		__MOTOR_H
#define 	 __MOTOR_Hvoid Motor_Init(void);
void Motor_SetSpeed(unsigned char Speed);#endif

2.Timer1.c

#include <REGX52.H>void Timer1_Init(void)		//100us @11.0592MHz
{//	TMOD不能复制,如果同时使用定时器1和0,它会覆盖淹没,TMOD &= 0x0F;		//设置定时器模式TMOD |= 0x10;		//设置定时器模式TL0 = 0xA4;		//设置定时初值TH1 = 0xFF;		//设置定时初值TF1 = 0;		//清除TF0标志TR1 = 1;		//定时器0开始计时ET1=1;EA=1;PT1=0;
}/*
void Timer1_Routine()   interrupt  3	//跳转到这里,触发中断
{static unsigned int T0Count;		//Tcount为计数值  static只有本函数使用TL1 = 0x66;					//重新设置定时初值TH1 = 0xFC;					//重新设置定时初值T0Count++;if(T0Count>=1000){T0Count=0;P1_0=~P1_0;}}*/
#ifndef		__TIMER1_H
#define 	 __TIMER1_Hvoid Timer1_Init(void)	;
#endif

3.IR.c

#include <REGX52.H>
#include "Timer0.h"
#include "INT0.h"unsigned int IR_Time;
unsigned char IR_State;unsigned char IR_Data[4];
unsigned char IR_pData;unsigned char IR_DataFlag;
unsigned char IR_RepeatFlag;
unsigned char IR_Address;
unsigned char IR_Command;/*** @brief  红外遥控初始化* @param  无* @retval 无*/
void IR_Init(void)
{Timer0_Init();Int0_Init();
}/*** @brief  红外遥控获取收到数据帧标志位* @param  无* @retval 是否收到数据帧,1为收到,0为未收到*/
unsigned char IR_GetDataFlag(void)
{if(IR_DataFlag){IR_DataFlag=0;return 1;}return 0;
}/*** @brief  红外遥控获取收到连发帧标志位* @param  无* @retval 是否收到连发帧,1为收到,0为未收到*/
unsigned char IR_GetRepeatFlag(void)
{if(IR_RepeatFlag){IR_RepeatFlag=0;return 1;}return 0;
}/*** @brief  红外遥控获取收到的地址数据* @param  无* @retval 收到的地址数据*/
unsigned char IR_GetAddress(void)
{return IR_Address;
}/*** @brief  红外遥控获取收到的命令数据* @param  无* @retval 收到的命令数据*/
unsigned char IR_GetCommand(void)
{return IR_Command;
}//外部中断0中断函数,下降沿触发执行
void Int0_Routine(void) interrupt 0
{if(IR_State==0)				//状态0,空闲状态{Timer0_SetCounter(0);	//定时计数器清0Timer0_Run(1);			//定时器启动IR_State=1;				//置状态为1}else if(IR_State==1)		//状态1,等待Start信号或Repeat信号{IR_Time=Timer0_GetCounter();	//获取上一次中断到此次中断的时间Timer0_SetCounter(0);	//定时计数器清0//如果计时为13.5ms,则接收到了Start信号(判定值在12MHz晶振下为13500,在11.0592MHz晶振下为12442)if(IR_Time>12442-500 && IR_Time<12442+500){IR_State=2;			//置状态为2}//如果计时为11.25ms,则接收到了Repeat信号(判定值在12MHz晶振下为11250,在11.0592MHz晶振下为10368)else if(IR_Time>10368-500 && IR_Time<10368+500){IR_RepeatFlag=1;	//置收到连发帧标志位为1Timer0_Run(0);		//定时器停止IR_State=0;			//置状态为0}else					//接收出错{IR_State=1;			//置状态为1}}else if(IR_State==2)		//状态2,接收数据{IR_Time=Timer0_GetCounter();	//获取上一次中断到此次中断的时间Timer0_SetCounter(0);	//定时计数器清0//如果计时为1120us,则接收到了数据0(判定值在12MHz晶振下为1120,在11.0592MHz晶振下为1032)if(IR_Time>1032-500 && IR_Time<1032+500){IR_Data[IR_pData/8]&=~(0x01<<(IR_pData%8));	//数据对应位清0IR_pData++;			//数据位置指针自增}//如果计时为2250us,则接收到了数据1(判定值在12MHz晶振下为2250,在11.0592MHz晶振下为2074)else if(IR_Time>2074-500 && IR_Time<2074+500){IR_Data[IR_pData/8]|=(0x01<<(IR_pData%8));	//数据对应位置1IR_pData++;			//数据位置指针自增}else					//接收出错{IR_pData=0;			//数据位置指针清0IR_State=1;			//置状态为1}if(IR_pData>=32)		//如果接收到了32位数据{IR_pData=0;			//数据位置指针清0if((IR_Data[0]==~IR_Data[1]) && (IR_Data[2]==~IR_Data[3]))	//数据验证{IR_Address=IR_Data[0];	//转存数据IR_Command=IR_Data[2];IR_DataFlag=1;	//置收到连发帧标志位为1}Timer0_Run(0);		//定时器停止IR_State=0;			//置状态为0}}
}
#ifndef __IR_H__
#define __IR_H__#define IR_CH_X			0x45
#define IR_CH			0x46
#define IR_CH_Z			0x47
#define IR_PREV			0x44
#define IR_NEXT			0x40
#define IR_PAUSE		0x43
#define IR_VOL_X		0x07
#define IR_VOL_Z		0x15
#define IR_EQ			0xD9
#define IR_0			0x16
#define IR_100+			0x19
#define IR_200+			0x0d
#define IR_1			0x0C
#define IR_2			0x18
#define IR_3			0x5E
#define IR_4			0x08
#define IR_5			0x1C
#define IR_6			0x5A
#define IR_7			0x42
#define IR_8			0x52
#define IR_9			0x4Avoid IR_Init(void);
unsigned char IR_GetDataFlag(void);
unsigned char IR_GetRepeatFlag(void);
unsigned char IR_GetAddress(void);
unsigned char IR_GetCommand(void);
#endif

4.main.c

#include <REGX52.H>
#include "Delay.h"
#include "Key.h"
#include "Timer1.h"
#include "Nixie.h"
#include "Init.h"
#include "IR.h"
#include "Motor.h"unsigned char KeyNum,Speed,Command;void main()
{DianZhengGuan();Motor_Init();IR_Init();while(1){
//		KeyNum=Key();
//		if(KeyNum==1)
//		{
//			Speed++;
//			Speed%=4;
//		
//				if(Speed==0){Motor_SetSpeed(0);}
//				if(Speed==1){Motor_SetSpeed(50);}
//				if(Speed==2){Motor_SetSpeed(75);}
//				if(Speed==3){Motor_SetSpeed(100);}
//			
//				Nixie(1,Speed);		//数码管静态显示会锁存
//		}if(IR_GetDataFlag()){Command=IR_GetCommand();if(Command==IR_0) {Speed=0;}if(Command==IR_1) {Speed=1;}if(Command==IR_2) {Speed=2;}if(Command==IR_3) {Speed=3;}if(Speed==0){Motor_SetSpeed(0);}if(Speed==1){Motor_SetSpeed(50);}if(Speed==2){Motor_SetSpeed(75);}if(Speed==3){Motor_SetSpeed(100);}Nixie(1,Speed);		//数码管静态显示会锁存}	}	
}

5.INT0

#include <REGX52.H>void Int0_Init(void)
{IT0=1;		//下降沿触发IE0=0;		//中断标志位EX0=1;		//打开中断EA=1;		//打开所有中断PX0=1;		//优先级}
#ifndef __INT0_H__
#define __INT0_H__
void Int0_Init(void);
#endif

实验现象:

红外控制直流电机

总结

本节课主要学了红外遥控了,对定时器写入和写出的,还有解码的功能,最重要的是这个解码过程,设置了3个状态,每个状态执行分别执行不同的功能,识别出开始的信号和设置很多个标志位,通过操作进行定时器的开始,进而解码出开始和连发,进而分辨出是发送的是信号0还是信号1,最后读取值进入数组中,拆分为4个unsigned char类型,分别存入最后变量地址和数据中,并根据数据Command进行有关的操作。
2、最后进行了实验:红外遥控直流电机,根据读到的Command,相当于读取按键值,然后执行相关的功能,完成本次实验。


文章转载自:

http://klscJivU.wschL.cn
http://6FNubvhy.wschL.cn
http://Zla7lIW5.wschL.cn
http://ZvidreBy.wschL.cn
http://BbKotTtx.wschL.cn
http://Es8w9Nf5.wschL.cn
http://ht6iAzOF.wschL.cn
http://GxhJYAay.wschL.cn
http://Nki2nPPO.wschL.cn
http://aZlSN4eh.wschL.cn
http://DvMaWUz1.wschL.cn
http://TbrAbZvT.wschL.cn
http://NuLq2eRF.wschL.cn
http://vwcSZoin.wschL.cn
http://xQSfAo8y.wschL.cn
http://ucuzBL8j.wschL.cn
http://epH9pvFG.wschL.cn
http://zLkSiZDl.wschL.cn
http://QKM9tDc8.wschL.cn
http://ifK9WCsF.wschL.cn
http://A6iDp9bv.wschL.cn
http://Y84dyo0N.wschL.cn
http://fMWGkRpj.wschL.cn
http://6hhesoBW.wschL.cn
http://EMYLTciG.wschL.cn
http://ZaRy9BB1.wschL.cn
http://9Eq4Zfmd.wschL.cn
http://N7IL6kMD.wschL.cn
http://YkaTXMP3.wschL.cn
http://A8Dr9u2Z.wschL.cn
http://www.dtcms.com/wzjs/612229.html

相关文章:

  • 建设网站最好的免费服务器有哪些
  • 网站建设服务收费标准学做网站多久
  • 十大卖衣服网站上海比较好的网站建设公司
  • 网站上的qq咨询怎么做wordpress不能登录
  • 重庆奉节网站建设宁波网站建设外包
  • 怎么在网站标头做图标广州建论坛网站
  • 此网站正在建设中页面网站建设培训教程 新手入门到精通
  • 网站建设玖金手指排名11网站字体加载不出来怎么办
  • p2p网站建设报价wordpress重置密碼
  • wordpress多站点 文章做网站开发学什么内容
  • 装修效果图网站推荐seo关键词优化服务
  • 广州公司网站提供ios开发软件
  • 系统 网站开发工程师做网站准备什么软件
  • 上海网站建设网页制作你却装饰装潢设计
  • 重庆网站建设建站收费微信公众平台开发者工具
  • 统计网站流量的网站网页游戏网站大全免费软件
  • 做网站找雷鸣企业推广方式推荐隐迅推
  • 建立网站一般多少钱比较好的网站开发公司
  • 公众号官方深圳网站搜索优化工具
  • 网站定位广告惠州市惠城区规划建设局网站
  • 重庆最好的网站建设wordpress 软件主题
  • 知名营销类网站识图
  • 用cdr做网站设计尺寸要多少昆明关键词优化
  • 网站中有一个非常著名的原则wordpress域名邮箱
  • 免费创建虚拟网站网站技术建设维护技术论文
  • 阿里云的网站程序如何做网站建设岗位周计划
  • 美的公司网站建设的目的wordpress广告图片代码
  • 网站的软件维护包括什么小型教育网站的开发与建设系统
  • flash网站开发工具小制作小发明手工五年级
  • 找家里做的工作到什么网站wordpress 防cc