/*************************************
01 (0x01) 读线圈
02 (0x02) 读离散量输入
03 (0x03) 读保持寄存器
04(0x04) 读输入寄存器
05 (0x05) 写单个线圈
06 (0x06) 写单个寄存器
15 (0x0F) 写多个线圈
16 (0x10) 写多个寄存器
*************************************/
#define _MAIN_C_
//============================
#include "includeFile.h"
//============================
#include "Delay.h"
sfr P4 = 0xC0; //8 bitPort4
bit irpro_ok,irok;
sbit IR=P3^3; //红外接口标志
uint count;
uchar irtime;
//u8 numa = 234;
sbit LED = P4^4;
uchar IRcord[6];
uchar irdata[33];
uchar code TabA[22]="0123456789ABCDEFGHIJKL";
uchar data TimeNum[]=" ";
/*------------------------------------------------
定时器1中断处理
void tm1_isr() interrupt 1
------------------------------------------------*/
void tim1_isr()interrupt 3 //定时中断
{
irtime++;
}
/*------------------------------------------------
外部中断0中断处理
------------------------------------------------*/
void EX0_ISR (void) interrupt 2 //外部中断1服务函数
{
static unsigned char i; //接收红外信号处理
static bit startflag; //是否开始处理标志位
if(startflag)
{
if(irtime<63&&irtime>=33)//引导码 TC9012的头码,9ms+4.5ms
i=0;
irdata=irtime;//存储每个电平的持续时间,用于以后判断是0还是1
irtime=0;
i++;
if(i==33)
{
irok=1;
i=0;
}
}
else
{
irtime=0;
startflag=1;
}
}
/*------------------------------------------------
定时器0初始化
------------------------------------------------*/
void timer_init(void)//定时器初始化
{
// IPH |= 0x01;
// PT1=1;
//IP = 0x08;
//IPH = 0x08;
TMOD =0x30;/////////设置工作方式2
TH1=0x00; //重载值
TL1=0x00; //初始化值
EA=1;
ET1=1;//开总中断;开定时器中断
TR1=1;////////启动计数器
}
/*------------------------------------------------
外部中断1初始化
------------------------------------------------*/
void EX0init(void)
{
//IPH = 0x00;
//PX1 = 1;
IPH = 0x04;
IP = 0x00;
IT1 = 1; //指定外部中断1下降沿触发,INT0 (P3.3)
EX1 = 1; //使能外部中断
EA = 1; //开总中断
}
/*------------------------------------------------
键值处理
注:分解显示转换值列表
------------------------------------------------*/
void Ir_work(void)//红外键值散转程序
{
TimeNum[5] = TabA[IRcord[0]/16]; //处理客户码并显示
TimeNum[6] = TabA[IRcord[0]%16];
TimeNum[8] = TabA[IRcord[1]/16]; //处理客户码并显示
TimeNum[9] = TabA[IRcord[1]%16];
TimeNum[11] = TabA[IRcord[2]/16]; //处理数据码并显示
TimeNum[12] = TabA[IRcord[2]%16];
TimeNum[14] = TabA[IRcord[3]/16]; //处理数据反码并显示
TimeNum[15] = TabA[IRcord[3]%16];
TimeNum[17] = TabA[IRcord[4]/16]; //处理数据反码并显示
TimeNum[18] = TabA[IRcord[4]%16];
TimeNum[20] = TabA[IRcord[5]/16]; //处理数据反码并显示
TimeNum[21] = TabA[IRcord[5]%16];
irpro_ok=0;//处理完成标志
}
/***************************************************************/
void Ir_towork(void)//红外键值散转程序
{
// PutStr(1,0,TimeNum);//显示处理过后的码值
switch(IRcord[2])//判断第三个数码值
{
case 0x0d:OLED_ShowNum(72,6,46,4,16);break;//o
case 0x0c:OLED_ShowNum(0,104,RegBuf_HOLD[0],4,16);break;//1 显示相应的按键值
case 0x18:OLED_ShowNum(72,6,456,4,16);break;//2
/***********
case 0x5e:LCD1602_Dis_OneChar(4,0,Tab[3]);break;//3
case 0x08:LCD1602_Dis_OneChar(4,0,Tab[4]);break;//4
case 0x1c:LCD1602_Dis_OneChar(4,0,Tab[5]);break;//5
case 0x5a:LCD1602_Dis_OneChar(4,0,Tab[6]);break;//6
case 0x42:LCD1602_Dis_OneChar(4,0,Tab[7]);break;//7
case 0x52:LCD1602_Dis_OneChar(4,0,Tab[8]);break;//8
case 0x4a:LCD1602_Dis_OneChar(4,0,Tab[9]);break;//9
case 0x45:LCD1602_Dis_OneChar(4,0,Tab[10]);break;//1
case 0x46:LCD1602_Dis_OneChar(4,0,Tab[11]);break;//1
case 0x47:LCD1602_Dis_OneChar(4,0,Tab[12]);break;//1
case 0x44:LCD1602_Dis_OneChar(4,0,Tab[13]);break;//1
case 0x40:LCD1602_Dis_OneChar(4,0,Tab[14]);break;//1
case 0x43:LCD1602_Dis_OneChar(4,0,Tab[15]);break;//1
case 0x07:LCD1602_Dis_OneChar(4,0,Tab[16]);break;//1
case 0x15:LCD1602_Dis_OneChar(4,0,Tab[17]);break;//1
case 0x09:LCD1602_Dis_OneChar(4,0,Tab[18]);break;//1
case 0x16:LCD1602_Dis_OneChar(4,0,Tab[19]);break;//1
case 0x19:LCD1602_Dis_OneChar(4,0,Tab[20]);break;//1
default:break;
**********/
}
irpro_ok=0;//处理完成标志
}
/********************************************
红外码值处理
*******************************************/
void Ircordpro(void)//红外码值处理函数
{
unsigned char i, j, k;
unsigned char cord,value;
k=1;
for(i=0;i<4;i++) //处理4个字节
{
for(j=1;j<=8;j++) //处理1个字节8位
{
cord=irdata[k];
if(cord>7)//大于某值为1,这个和晶振有绝对关系,这里使用12M计算,此值可以有一定误差
value|=0x80;
if(j<8)
{
value>>=1;
}
k++;
}
IRcord=value;
value=0;
// tablex(IRcord[2]);
}
irpro_ok=1;//处理完毕标志位置1
}
/******************************************************************
功能: 初始化
输入: 站号设置
输出: 无
版本: V15.09.0
作者: 大姆指测控 - 姚工, QQ:657874307
修改日期: 2015-09
说明:,根据P2口低四位编码开关的设置,修改从站地址1-32位,默认都为0则实际地址为1
******************************************************************/
uchar Get_ID_HD(void)
{
uchar temp,i=50;
P2|=0x0f;//0000 1111
while(i--);
temp=~P2; //P2.0-P2.3接拨码开关,用来设置4位站号 1111 0000
temp&=0x0f; //1111 0000&0000 1111 temp = 0000 0000
if(temp==0)
{
return 1; //站号不能为0,返回默认的1
}
return temp; //返回站号
}
/******************************************************************
功能: 初始化
输入: 无
输出: 无
版本: V15.09.0
作者: 大姆指测控 - 姚工, QQ:657874307
修改日期: 2015-09
说明:系统上电之后,先取得系统设置的参数,然后用这些参数来对相应的模块进行初始化,如下:
1. 串口通信的波特率 和 校验值 [决定本从机的通信参数];
2. modbus 从机的站号 ,可以使用拨码开关来设定站号,或者使用EEPROM存储站号;
******************************************************************/
void SYSinit(void)
{
TimesMsinitInt(); //Ms定时器初始化,用作产生1ms的系统时间基准
OLED_Init(); //初始化OLED
timer_init();//初始化定时器(打开后出现连接不上问题)
EX0init(); //初始化外部中断
//先写相应的函数,取得系统参数....
//以下例程使用固定值:19200 ,无校验,
//站号 =拨码开关设定1-32
UartInit(19200, NONE_PARITY); //串口初始化[须要确定好波特率和校验值]
ModbusInit(Get_ID_HD(),StartSend); //Modbus串口初始化[须要确定好站号]
//
// IP = 0x03;
// IPH = 0x09;
EA = 1;
}
//----------------------------START-------------------------------
//=================================================================
void main(void)
{
// u8 Data_p = P2;
SYSinit(); //系统初始化
// numa = 0x01;
OLED_Clear();
OLED_ShowCHinese(0,0,0);//
OLED_ShowCHinese(18,0,1);//
OLED_ShowCHinese(36,0,2);//
OLED_ShowCHinese(54,0,3);//
OLED_ShowCHinese(72,0,4);//
OLED_ShowCHinese(90,0,5);//
// OLED_ShowCHinese(108,0,6);//
while (1)
{
UartRxPoll(); //串口数据帧检查处理
TEST1();
//......
//继续添加应用程序代码...
LED=1;
/******************************
功能:读寄存器
调用:RegBuf_Input[0],0为寄存器地址对应30001
*****************************/
OLED_ShowNum(0,6,RegBuf_Input[0],4,16);
OLED_ShowNum(32,6,RegBuf_Input[1],4,16);
OLED_ShowNum(64,6,RegBuf_Input[2],4,16);
OLED_ShowNum(96,6,RegBuf_Input[3],4,16);
/******************************
功能:读写寄存器
调用:RegBuf_HOLD[0],0为寄存器地址对应40001
*****************************/
OLED_ShowNum(0,4,RegBuf_HOLD[0],4,16);//最大16950
OLED_ShowNum(32,4,RegBuf_HOLD[1],4,16);//最大16950
OLED_ShowNum(64,4,RegBuf_HOLD[2],4,16);//最大16950
OLED_ShowNum(96,4,RegBuf_HOLD[3],4,16);//最大16950
// OLED_ShowNum(0,6,SwBuf_IN[0],4,16);//最大16950
// OLED_ShowChar(40,6,SwBuf_IN[0]);
/***************测试控制*************/
OLED_ShowChar(0,2,TimeNum[5]);
OLED_ShowChar(8,2,TimeNum[6]);
OLED_ShowChar(16,2,TimeNum[8]);
OLED_ShowChar(24,2,TimeNum[9]);
OLED_ShowChar(32,2,TimeNum[11]);
OLED_ShowChar(40,2,TimeNum[12]);
OLED_ShowChar(48,2,TimeNum[14]);
OLED_ShowChar(56,2,TimeNum[15]);
OLED_ShowChar(64,2,TimeNum[17]);
OLED_ShowChar(72,2,TimeNum[18]);
OLED_ShowChar(80,2,TimeNum[20]);
OLED_ShowChar(88,2,TimeNum[21]);
if(irok) //如果接收好了进行红外处理
{
Ircordpro();
irok=0;
}
if(irpro_ok) //如果处理好后进行工作处理,如按对应的按键后显示对应的数字等
{
Ir_work();
Ir_towork();
}
}
}
开始以为时红外遥控程序问题,我都放在主程序里面调试了 |