C/C++

单片机红外线遥控器发射串口通信控制电脑

1427856939259.jpg

很简单的一个过程,单片机包含红外遥控模块,当接收到红外值,将值通过串口发送到电脑。通过程序接收串口缓存值,去做定义好的工作。

#include 
sbit LSA ?= P2^2;
sbit LSB ?= P2^3;
sbit LSC ?= P2^4;
sbit IRIN = P3^2;

unsigned char IrValue[6];	 ?//用来存放读取到的红外值、
void UsartConfiguration();
void Delay10ms(unsigned int c); ? //误差 0us
void send();
void main()
{?

	
	UsartConfiguration();
	while(1) //死循环 红外值
	{
		IrValue[4]=IrValue[2]>>4;	 	 	//高位
		IrValue[5]=IrValue[2]&0x0f;		//低位
		send(); //将值发送
		Delay10ms(50);
	}
}
void UsartConfiguration()
{

	//红外线初始化
	IT0=1;//下降沿触发
	EX0=1;//打开中断0允许
	EA=1;	//打开总中断

	IRIN=1;//初始化端口	


	SCON=0X50;			//设置为工作方式1
	TMOD=0X20;			//设置计数器工作方式2
	PCON=0X80;			//波特率加倍
	TH1=0XF3;		 ? ?//计数器初始值设置,注意波特率是4800的
	TL1=0XF3;
//	ES=1;						//打开接收中断
//	EA=1;						//打开总中断
	TR1=1;					 ? ?//打开计数器



}
void send(){
	//SBUF = i; ? //将要发送的数据放入到发送寄存器
	unsigned char i;
	for(i=0; i<5; i++)
	{

		if(IrValue[i]!=0){
			 SBUF = IrValue[i]; ? //将要发送的数据放入到发送寄存器
				while(!TI);		 ?//等待发送数据完成
				TI=0;			 ? ?//清除发送完成标志位
			IrValue[i]=0;
		}
					
	}
}
void Delay10ms(unsigned int c) ? //误差 0us
{
? ? unsigned char a, b;

	//--c已经在传递过来的时候已经赋值了,所以在for语句第一句就不用赋值了--//
? ? for (;c>0;c--)
	{
		for (b=38;b>0;b--)
		{
			for (a=130;a>0;a--);
		} ? ? ? ? ?
	} ? ? ??
}
void ReadIr() interrupt 0
{
	unsigned char j,k;
	unsigned int err;
	Time=0;					?
	DelayMs(70);

	if(IRIN==0)		//确认是否真的接收到正确的信号
	{	?
		
		err=1000;				//1000*10us=10ms,超过说明接收到错误的信号
		/*当两个条件都为真是循环,如果有一个条件为假的时候跳出循环,免得程序出错的时
		侯,程序死在这里*/	
		while((IRIN==0)&&(err>0))	//等待前面9ms的低电平过去 ?		
		{			
			DelayMs(1);
			err--;
		}?
		if(IRIN==1)			//如果正确等到9ms低电平
		{
			err=500;
			while((IRIN==1)&&(err>0))		 //等待4.5ms的起始高电平过去
			{
				DelayMs(1);
				err--;
			}
			for(k=0;k<4;k++)		//共有4组数据
			{				
				for(j=0;j<8;j++)	//接收一组数据
				{

					err=60;		
					while((IRIN==0)&&(err>0))//等待信号前面的560us低电平过去
					{
						DelayMs(1);
						err--;
					}
					err=500;
					while((IRIN==1)&&(err>0))	 //计算高电平的时间长度。
					{
						DelayMs(1);//0.14ms
						Time++;
						err--;
						if(Time>30)
						{
							EX0=1;
							return;
						}
					}
					IrValue[k]>>=1;	 //k表示第几组数据
					if(Time>=8)			//如果高电平出现大于565us,那么是1
					{
						IrValue[k]|=0x80;
					}
					Time=0;		//用完时间要重新赋值							
				}
			}
		}
		if(IrValue[2]!=~IrValue[3])
		{
			return;
		}
	}			
}


20150401110953.png

将值发送到Windows ,串口通信我们借助Windows中的ActiveX控件完成操作。MSComm 控件定义变量?m_CMscomm

BOOL C串口通信Dlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// 设置此对话框的图标。当应用程序主窗口不是对话框时,亚博可以人工存款吗将自动
	// ?执行此操作
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标

	// TODO: 在此添加额外的初始化代码
	m_CMscomm.put_CommPort(1);
	if(m_CMscomm.get_PortOpen())
		m_CMscomm.put_PortOpen(0);
	m_CMscomm.put_PortOpen(1);
	m_CMscomm.put_InputMode(1);
	static CString str("4800,n,8,1");?
	m_CMscomm.get_Input();
	m_CMscomm.put_RThreshold(1);
	m_CMscomm.put_Settings(str);
	//static char ch[10];
	CString str1("com");
	for(int i=1;i<10;i++) //循环查看可用串口
	{

		str1.Format("com%d",i);
		m_CComboBox.AddString(str1);

	}
	m_CComboBox.SetCurSel(0);

	return TRUE; ?// 除非将焦点设置到控件,否则返回 TRUE
}
void C串口通信Dlg::OnBnClickedButton1() //打开串口端口
{
	static char ch1[10];
	CString str("");
	if(m_CMscomm.get_PortOpen())
		m_CMscomm.put_PortOpen(false);
	m_CMscomm.put_CommPort(3);?
	m_CMscomm.put_PortOpen(3);
	str.Format("打开串口%d成功",3);
	if(m_CMscomm.get_PortOpen())
	{
		MessageBox(str);
	}
	else
	{

		MessageBox("不能打串口");
	}
}
//为控件注册事件 ?接收串口缓存
BEGIN_EVENTSINK_MAP(C串口通信Dlg, CDialogEx)
	ON_EVENT(C串口通信Dlg, IDC_MSCOMM1, 1, C串口通信Dlg::OnCommMscomm1, VTS_NONE)
END_EVENTSINK_MAP()


void C串口通信Dlg::OnCommMscomm1()
{
	VARIANT variant_inp;
	COleSafeArray safearray_inp;

	LONG len,k;
	BYTE rxdata[2048];
	CString strtemp;
	if(m_CMscomm.get_CommEvent()==2)
	{
		variant_inp=m_CMscomm.get_Input();
		safearray_inp=variant_inp;
		len=safearray_inp.GetOneDimSize();
		for(k=0;k

?

IMG_20150401_105254_193.gif

0 条评论

发表评论

你需要登录后才可进行发表