C/C++

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

1427856939259.jpg

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

#include <reg51.h>
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<len;k++)
			safearray_inp.GetElement(&k,rxdata+k);
		for(k=0;k<len;k++)
		{
			BYTE bt=*(char*)(rxdata+k);
			strtemp.Format("%d|",bt);
			m_send+=strtemp;
			if(k==1){
				switch(bt){ //接收到的 值
					case 69:
					AfxMessageBox("开关");
					break;
					case 70:
					keybd_event(181,0,2,0);
					keybd_event(181,0,0,0);
					break;
					case 71: //173
					keybd_event(173,0,0,0);
					keybd_event(173,0,0,0);
					break;
					case 68:
					keybd_event(179,0,0,0);
					keybd_event(179,0,0,0);
					break;
					case 64:
					keybd_event(177,0,0,0);
					keybd_event(177,0,0,0);
					break;
					case 67:
					keybd_event(176,0,0,0);
					keybd_event(176,0,0,0);
					break;
					case 21:
					keybd_event(174,0,0,0);
					keybd_event(174,0,0,0);
					break;
					case 9:
					keybd_event(175,0,0,0);
					keybd_event(175,0,0,0);
					break;

					case 74: //9
					POINT p;
					if(GetCursorPos(&p)){
						HWND hWnd = ::WindowFromPoint(p);
						if(::IsWindow(hWnd)){
							DWORD id=0;
							GetWindowThreadProcessId(hWnd,&id);
							if(id!=0){

								TerminateProcess(OpenProcess(1,0,id),0);
							}
						}

					}


					break;
					default:
					break;
				}

			}
		}
		m_send+="\r\n";
	}
	UpdateData(FALSE);
}
/*
69开关
70Mode
71静音
68播放
64上移
67下一
7 EQ
21VOL-
9 VOL+
22 0
25 RPT
13 U/SD
12 1
24 2
94 3
8  4
28 5
90 6
66 7
82 8
74 9
本人遥控器所得值
*/

 

IMG_20150401_105254_193.gif

0 条评论

发表评论

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