标题:
单片机红外接收程序(Nokia5110液晶屏显示)
[打印本页]
作者:
51黑z
时间:
2016-9-11 22:23
标题:
单片机红外接收程序(Nokia5110液晶屏显示)
0.png
(71.46 KB, 下载次数: 84)
下载附件
2016-9-11 22:21 上传
本例程,实现单片机红外接收解码,并用nokia5110液晶屏来显示内容。完整keil工程文件下载:
http://www.51hei.com/bbs/dpj-55490-1.html
下面是部分程序代码的预览:
主程序:
#include "IR_Receive.h"
#include "Nokia5110.h"
#include "delay.h"
extern uint8_t IRcode_Type;//红外数据类型,RCA或NEC8或NEC16
extern uint16_t IRcode[2]; //红外数据中的系统码IRcode[0],红外数据中的用户码IRcode[1]
extern uint32_t RCAcode_Original;//RCA协议原码
extern uint32_t NECcode_Original;//NEC原始数据
void main(void)
{
IRreceiver_Init();
Nokia5110_Init();
Nokia5110_WriteString(0,0,"*IR_Receiver*");
Nokia5110_WriteString(2,0,"Rev:**********");
Nokia5110_WriteString(3,0,"CodeType:****");
Nokia5110_WriteString(4,0,"SysCode :****");
Nokia5110_WriteString(5,0,"UserCode:****");
while(1)
{
if(IRdata_Analysis())//解析成功串口打印正确红外码值
{
Nokia5110_Clear(1,5);
switch(IRcode_Type)
{
case IRcode_TypeRCA:
{
Nokia5110_Printf(2,0,"Rev:",RCAcode_Original,Hex);//打印出未进行解析的原始红外RCA数据
Nokia5110_WriteString(3,0,"CodeType: RCA");
Nokia5110_Printf(4,0,"SysCode : ",IRcode[0],Hex);
Nokia5110_Printf(5,0,"UserCode: ",IRcode[1],Hex);
break;
}
case IRcode_TypeNEC8:
{
Nokia5110_Printf(2,0,"Rev:",NECcode_Original,Hex);//打印出未进行解析的原始红外NEC数据
Nokia5110_WriteString(3,0,"CodeType: NEC8");
Nokia5110_Printf(4,0,"SysCode : ",IRcode[0],Hex);
Nokia5110_Printf(5,0,"UserCode: ",IRcode[1],Hex);
break;
}
case IRcode_TypeNEC16:
{
Nokia5110_Printf(2,0,"Rev:",NECcode_Original,Hex);//打印出未进行解析的原始红外NEC数据
Nokia5110_WriteString(3,0,"CodeType:NEC16");
Nokia5110_Printf(4,0,"SysCode:",IRcode[0],Hex);
Nokia5110_Printf(5,0,"UserCode:",IRcode[1],Hex);
break;
}
default:{break;}
}
IRcode_Type = IRcode_TypeNone;
Buzzer_Speak();//解码成功,蜂鸣器响
}
}
}
复制代码
#include "Nokia5110.h"
#include "ASII_Font.h"
#include "IR_Receive.h"
uint8_t Dex_Hex_Buffer[Length_Max];//数据缓冲区
extern uint8_t IRcode_Type;//定义收到的红外数据类型
/*************************************************************************************
函数:void Divide_Dex_Hex(uint32_t Num,uint8_t Format)
功能:数据分离,储存在缓冲中数组中,低位~高位=[0]~[Length_Max-1],返回数据位数
*************************************************************************************/
uint8_t Divide_Dex_Hex(uint32_t Num,uint8_t Format)
{
signed char i=0;
uint8_t Num_Cnt = 0;
for(i=0;i<Length_Max;i++) //缓冲清零
{
Dex_Hex_Buffer[i] = '0';
}
if(Num == 0)//Num = 0处理
{
if(Format == Dex)return 1;
if(Format == Hex)return 2;
}
else if(Format == Dex)//把数据分离成十进制数
{
i = 0;
while(Num)
{
Dex_Hex_Buffer[i] = Num%10+'0';//处理成ASIIC码
Num /= 10;
Num_Cnt++;
i++;
}
}
else if(Format == Hex)//把数据分离成十六进制数
{
i = 0;
while(Num)
{
Dex_Hex_Buffer[i] = Num%16;
Num /= 16;
Num_Cnt++;
i++;
}
for(i=Num_Cnt-1;i>=0;i--) //把分离出来的十六进制数据处理成ASIIC码
{
if(Dex_Hex_Buffer[i]<10)
{
Dex_Hex_Buffer[i] += 0x30;
}
else
{
Dex_Hex_Buffer[i] = Dex_Hex_Buffer[i]-0x0A+0x41;
}
}
if(Num_Cnt%2)Num_Cnt+=1; //十六进制返回的位数强制为偶数
}
return Num_Cnt;//返回数据十进制或十六进制位数
}
/*******************************************************
函数:void Nokia5110_Write(uint8_t dat,bit data_cmd);
功能:向Nokia5110中写入数据或命令;
*******************************************************/
void Nokia5110_Write(uint8_t dat,bit data_cmd)
{
uint8_t i;
LCD_CE = 0; /*使能5110*/
LCD_DC = data_cmd; /*DC=1,写入数据;DC=0,写入命令*/
for(i=0;i<8;i++)
{
if(dat&0x80)
{
LCD_DIN = 1;
}
else
{
LCD_DIN = 0;
}
LCD_CLK = 0;
dat<<=1;
LCD_CLK = 1;
}
LCD_CE = 1; /*关闭5110*/
}
/************************************************************************************************
函数:void Nokia5110_Clear(uint8_t Y_Start, uint8_t Y_End);
功能:对Nokia5110选择性区域进行清屏;
***********************************************************************************************/
void Nokia5110_Clear(uint8_t Y_Start, uint8_t Y_End)
{
uint16_t i;
uint16_t AreaSize = 0;
Nokia5110_Write(0x80|0x00,CMD);
Nokia5110_Write(0x40|Y_Start,CMD);
AreaSize = 84*(Y_End-Y_Start+1);
for(i=0;i<AreaSize;i++)
{
Nokia5110_Write(0x00,DATA);
}
}
/*******************************************************
函数:void Nokia5110_Init();
功能:对Nokia5110进行初始化;
*******************************************************/
void Nokia5110_Init(void)
{
delay_us(10);
LCD_RST = 0;
delay_us(10);
LCD_RST = 1; //RST=1 复位,开始写数据
Nokia5110_Write(0x21,CMD); //使用扩展指令集,水平寻址
Nokia5110_Write(0xC5,CMD); //写Vop到寄存器
Nokia5110_Write(0x07,CMD); //温度系数3
Nokia5110_Write(0x13,CMD); //偏置值1:48
Nokia5110_Write(0x20,CMD); //使用基本指令集,水平寻址
Nokia5110_Write(0x0C,CMD); //选择普通模式
Nokia5110_Clear(0,5); //清屏
}
/*******************************************************
函数:void Nokia5110_SetRC(uint8_t line,uint8_t lie);
功能:显示屏坐标设定,R:line=0~5,C:lie=0~13;
*******************************************************/
void Nokia5110_SetRC(uint8_t line,uint8_t lie)
{
lie*=6;
Nokia5110_Write(0x40|line,CMD);
Nokia5110_Write(0x80|lie, CMD);
}
/*******************************************************
函数:void Nokia5110_WriteChar(uint8_t Char);
功能:向5110液晶屏中写入一个字节;
*******************************************************/
void Nokia5110_WriteChar(uint8_t Char)
{
uint8_t i,j;
i = Char-0x20;
for(j=0;j<6;j++)
{
Nokia5110_Write(ASII_Font[i][j],DATA);
}
}
/*************************************************************************************
函数:void Nokia5110_WriteString(uint8_t line,uint8_t lie,uint8_t *pString);
功能:向5110液晶屏指定地址开始写入字符串;
************************************************************************************/
void Nokia5110_WriteString(uint8_t line,uint8_t lie,uint8_t *pString)
{
Nokia5110_SetRC(line,lie);
while(*pString != '\0')
{
Nokia5110_WriteChar(*pString);
pString++;
}
}
/*************************************************************************************
函数:void Nokia5110_ClearData(uint8_t line,uint8_t lie,uint8_t Length);
功能:清除指定坐标中的指定长度数据
************************************************************************************/
void Nokia5110_ClearData(uint8_t line,uint8_t lie,uint8_t Length)
{
uint8_t i=0;
Nokia5110_SetRC(line,lie);
for(i=0;i<Length;i++)
{
Nokia5110_WriteChar(' ');
}
}
/***************************************************************************************************
函数:void Nokia5110_Printf(uint8_t hang,uint8_t,lie,uint8_t *String,uint32_t Value,uint8_t Format);
功能:以十进制或者十六进制往5110液晶屏中写ASIIC数据;
**************************************************************************************************/
void Nokia5110_Printf(uint8_t hang,uint8_t lie,uint8_t *pString,uint32_t Value,uint8_t Format)
{
uint8_t i;
static uint8_t SysCode4Bit_Flag = 0;//系统码为4位标志位,用于显示NEC16系统码高八位为0
uint8_t Num_Cnt = 0;
Num_Cnt = Divide_Dex_Hex(Value,Format);
if((IRcode_Type==IRcode_TypeRCA)&&(Num_Cnt==4))//处理RCA系统码为0的情况,原码需要把00显示出来
{
Num_Cnt = 6;
}
if((IRcode_Type==IRcode_TypeNEC8)&&(Num_Cnt==6))//处理NEC8系统码为0的情况,原码需要把00显示出来
{
Num_Cnt = 8;
}
if((IRcode_Type==IRcode_TypeNEC16)&&(Num_Cnt==6))//处理NEC16系统码高八位为0的情况,原码需要把00显示出来
{
Num_Cnt = 8;
SysCode4Bit_Flag = 1;
}
if((SysCode4Bit_Flag==1)&&(Num_Cnt==2))//处理NEC16系统码高八位为0的情况,系统码需要把00显示出来
{
SysCode4Bit_Flag = 0;
Num_Cnt = 4;
}
Nokia5110_WriteString(hang,lie,pString);
if(Format==Hex)
{
Nokia5110_WriteChar('0');
Nokia5110_WriteChar('x');
}
for(i=0;i<Num_Cnt;i++)
{
Nokia5110_WriteChar(Dex_Hex_Buffer[(Num_Cnt-1)-i]);
}
}
复制代码
#include "STC89Cx_it.h"
#include "IR_Receive.h"
//红外解码原理:把红外中的载波解调成低电平,把红外中的低电平解调成高电平输出
//识别原理:识别一个完整周期的高低电平总时间来识别头码和"0"或"1"的值
#define Rev_Header 0x00 //数据接收状态:接收头码0xAA或oxAB
#define Rev_Length 0x01 //数据接收状态:接收头码数据包长度
#define Rev_DataPackage 0x02 //数据接收状态:接收数据包
extern uint8_t IRcode_Type; //声明收到的红外数据类型
extern uint8_t IRdataReceive_Flag;//声明接收红外数据状态,等待or接收中or接收完毕
extern uint32_t IRcode_Buffer; //红外数据缓存
uint8_t CycleTime = 0; //存储完整周期时间(高电平+低电平)
/**********************************************
函数:void INT0_Handler(void);
功能:外部中断0中断处理函数;
***********************************************/
void INT0_Handler(void) interrupt 0
{
}
/**********************************************
函数:void TIME0_Handler(void);
功能:定时器0中断处理函数;
***********************************************/
void TIME0_Handler(void) interrupt 1
{
CycleTime++;
if(CycleTime==255)CycleTime=0;
}
/**********************************************
函数:void INT1_Handler(void);
功能:外部中断1中断处理函数;
***********************************************/
void INT1_Handler(void) interrupt 2
{
static uint8_t EnterINT0_CNT = 0;//存储进入外部中断次数
static uint8_t Rev_State = Rev_Header;//定义接收状态
uint8_t CycleTime_Buffer=0; //周期时间缓冲变量
EnterINT0_CNT++; //每进入中断一次加1
//第一次进入中断周期清零,打开定时器0准备计时
if(EnterINT0_CNT==1)
{
CycleTime=0;
IRcode_Buffer=0;
TR0=1;
}
else//之后先读时间,再进行清零
{
CycleTime_Buffer=CycleTime;
CycleTime = 0;
}
//开始识别头码
if((Rev_State==Rev_Header)&&(EnterINT0_CNT==2))
{
Rev_State = Rev_DataPackage;
if((CycleTime_Buffer>60)&&(CycleTime_Buffer<100)) //头码时间位于6.0ms~10ms则为RCA码(标准8ms)
{
IRcode_Type = IRcode_TypeRCA;
}
else if((CycleTime_Buffer>110)&&(CycleTime_Buffer<160))//头码时间位于11ms~16ms(必须是大于11ms)则为NEC码(标准13.5ms)
{
IRcode_Type = IRcode_TypeNEC8;
}
else//如果都不是,则认为没有收到头码
{
TR0=0;
IRcode_Buffer = 0;
EnterINT0_CNT = 0;
Rev_State = Rev_Header;
}
}
if((Rev_State==Rev_DataPackage)&&(EnterINT0_CNT>2))//开始解码
{
IRcode_Buffer <<= 1;
switch(IRcode_Type)
{
case IRcode_TypeRCA:
{
if((CycleTime_Buffer>10)&&(CycleTime_Buffer<20))//码值时间位于1.0ms~2.0ms则为RCA'1'(标准1.5ms)
{
IRcode_Buffer |= (uint32_t)0x01;
}
else if((CycleTime_Buffer>20)&&(CycleTime_Buffer<30))//码值时间位于1.0ms~2.0ms则为RCA'0'(标准2.5ms)
{
IRcode_Buffer |= (uint32_t)0x00;
}
else
{
TR0=0;
IRcode_Buffer = 0;
EnterINT0_CNT = 0;
Rev_State = Rev_Header;
}
break;
}
case IRcode_TypeNEC8:
{
if((CycleTime_Buffer>6)&&(CycleTime_Buffer<16))//码值时间位于0.6ms~1.6ms则为NEC'0'(标准1.124ms)
{
IRcode_Buffer |= (uint32_t)0x00;
}
else if((CycleTime_Buffer>16)&&(CycleTime_Buffer<28))//码值时间位于1.6ms~2.8ms则为NEC'1'(标准2.25ms)
{
IRcode_Buffer |= (uint32_t)0x01;
}
else
{
TR0=0;
IRcode_Buffer = 0;
EnterINT0_CNT = 0;
Rev_State = Rev_Header;
}
break;
}
}
if(((EnterINT0_CNT==26)&&((IRcode_Type==IRcode_TypeRCA)))||((EnterINT0_CNT==34)&&((IRcode_Type==IRcode_TypeNEC8))))//RCA码加头码25,NEC码加头码33位,解码进入中断次数分别为26和34
{
TR0=0;//解码完毕关闭定时器
EnterINT0_CNT=0;
IRdataReceive_Flag=IRdataReceive_Success;
Rev_State = Rev_Header;//准备下一次接收
}
}
}
/**********************************************
函数:void TIME1_Handler(void);
功能:定时器1中断处理函数;
***********************************************/
void TIME1_Handler(void) interrupt 3
{
}
/**********************************************
函数:void USART_Handler(void);
功能:串口中断处理函数;
***********************************************/
void USART_Handler(void) interrupt 4
{
}
/**********************************************
函数:void TIME2_Handler(void);
功能:定时器2中断处理函数;
***********************************************/
void TIME2_Handler(void) interrupt 5
{
}
复制代码
作者:
腾飞的龙
时间:
2018-3-28 17:08
没有试验不知道好用不。还得感谢分享!!赞
作者:
单片机初级选手
时间:
2018-3-30 17:11
感谢分享
作者:
012138ww
时间:
2018-6-13 20:21
感谢分享
作者:
心素如简c
时间:
2020-6-28 16:53
这个有带仿真原理图吗
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1