|
/*************************************
01 (0x01) 讀線圈
02 (0x02) 讀離散量輸入
03 (0x03) 讀保持寄存器
04(0x04) 讀輸入寄存器
05 (0x05) 寫單個(gè)線圈
06 (0x06) 寫單個(gè)寄存器
15 (0x0F) 寫多個(gè)線圈
16 (0x10) 寫多個(gè)寄存器
*************************************/
#define _MAIN_C_
//============================
#include "includeFile.h"
//============================
#include "Delay.h"
sfr P4 = 0xC0; //8 bitPort4
bit irpro_ok,irok;
sbit IR=P3^3; //紅外接口標(biāo)志
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[]=" ";
/*------------------------------------------------
定時(shí)器1中斷處理
void tm1_isr() interrupt 1
------------------------------------------------*/
void tim1_isr()interrupt 3 //定時(shí)中斷
{
irtime++;
}
/*------------------------------------------------
外部中斷0中斷處理
------------------------------------------------*/
void EX0_ISR (void) interrupt 2 //外部中斷1服務(wù)函數(shù)
{
static unsigned char i; //接收紅外信號處理
static bit startflag; //是否開始處理標(biāo)志位
if(startflag)
{
if(irtime<63&&irtime>=33)//引導(dǎo)碼 TC9012的頭碼,9ms+4.5ms
i=0;
irdata=irtime;//存儲(chǔ)每個(gè)電平的持續(xù)時(shí)間,用于以后判斷是0還是1
irtime=0;
i++;
if(i==33)
{
irok=1;
i=0;
}
}
else
{
irtime=0;
startflag=1;
}
}
/*------------------------------------------------
定時(shí)器0初始化
------------------------------------------------*/
void timer_init(void)//定時(shí)器初始化
{
// IPH |= 0x01;
// PT1=1;
//IP = 0x08;
//IPH = 0x08;
TMOD =0x30;/////////設(shè)置工作方式2
TH1=0x00; //重載值
TL1=0x00; //初始化值
EA=1;
ET1=1;//開總中斷;開定時(shí)器中斷
TR1=1;////////啟動(dòng)計(jì)數(shù)器
}
/*------------------------------------------------
外部中斷1初始化
------------------------------------------------*/
void EX0init(void)
{
//IPH = 0x00;
//PX1 = 1;
IPH = 0x04;
IP = 0x00;
IT1 = 1; //指定外部中斷1下降沿觸發(fā),INT0 (P3.3)
EX1 = 1; //使能外部中斷
EA = 1; //開總中斷
}
/*------------------------------------------------
鍵值處理
注:分解顯示轉(zhuǎn)換值列表
------------------------------------------------*/
void Ir_work(void)//紅外鍵值散轉(zhuǎn)程序
{
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]; //處理數(shù)據(jù)碼并顯示
TimeNum[12] = TabA[IRcord[2]%16];
TimeNum[14] = TabA[IRcord[3]/16]; //處理數(shù)據(jù)反碼并顯示
TimeNum[15] = TabA[IRcord[3]%16];
TimeNum[17] = TabA[IRcord[4]/16]; //處理數(shù)據(jù)反碼并顯示
TimeNum[18] = TabA[IRcord[4]%16];
TimeNum[20] = TabA[IRcord[5]/16]; //處理數(shù)據(jù)反碼并顯示
TimeNum[21] = TabA[IRcord[5]%16];
irpro_ok=0;//處理完成標(biāo)志
}
/***************************************************************/
void Ir_towork(void)//紅外鍵值散轉(zhuǎn)程序
{
// PutStr(1,0,TimeNum);//顯示處理過后的碼值
switch(IRcord[2])//判斷第三個(gè)數(shù)碼值
{
case 0x0d:OLED_ShowNum(72,6,46,4,16);break;//o
case 0x0c:OLED_ShowNum(0,104,RegBuf_HOLD[0],4,16);break;//1 顯示相應(yīng)的按鍵值
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;//處理完成標(biāo)志
}
/********************************************
紅外碼值處理
*******************************************/
void Ircordpro(void)//紅外碼值處理函數(shù)
{
unsigned char i, j, k;
unsigned char cord,value;
k=1;
for(i=0;i<4;i++) //處理4個(gè)字節(jié)
{
for(j=1;j<=8;j++) //處理1個(gè)字節(jié)8位
{
cord=irdata[k];
if(cord>7)//大于某值為1,這個(gè)和晶振有絕對關(guān)系,這里使用12M計(jì)算,此值可以有一定誤差
value|=0x80;
if(j<8)
{
value>>=1;
}
k++;
}
IRcord=value;
value=0;
// tablex(IRcord[2]);
}
irpro_ok=1;//處理完畢標(biāo)志位置1
}
/******************************************************************
功能: 初始化
輸入: 站號設(shè)置
輸出: 無
版本: V15.09.0
作者: 大姆指測控 - 姚工, QQ:657874307
修改日期: 2015-09
說明:,根據(jù)P2口低四位編碼開關(guān)的設(shè)置,修改從站地址1-32位,默認(rèn)都為0則實(shí)際地址為1
******************************************************************/
uchar Get_ID_HD(void)
{
uchar temp,i=50;
P2|=0x0f;//0000 1111
while(i--);
temp=~P2; //P2.0-P2.3接撥碼開關(guān),用來設(shè)置4位站號 1111 0000
temp&=0x0f; //1111 0000&0000 1111 temp = 0000 0000
if(temp==0)
{
return 1; //站號不能為0,返回默認(rèn)的1
}
return temp; //返回站號
}
/******************************************************************
功能: 初始化
輸入: 無
輸出: 無
版本: V15.09.0
作者: 大姆指測控 - 姚工, QQ:657874307
修改日期: 2015-09
說明:系統(tǒng)上電之后,先取得系統(tǒng)設(shè)置的參數(shù),然后用這些參數(shù)來對相應(yīng)的模塊進(jìn)行初始化,如下:
1. 串口通信的波特率 和 校驗(yàn)值 [決定本從機(jī)的通信參數(shù)];
2. modbus 從機(jī)的站號 ,可以使用撥碼開關(guān)來設(shè)定站號,或者使用EEPROM存儲(chǔ)站號;
******************************************************************/
void SYSinit(void)
{
TimesMsinitInt(); //Ms定時(shí)器初始化,用作產(chǎn)生1ms的系統(tǒng)時(shí)間基準(zhǔn)
OLED_Init(); //初始化OLED
timer_init();//初始化定時(shí)器(打開后出現(xiàn)連接不上問題)
EX0init(); //初始化外部中斷
//先寫相應(yīng)的函數(shù),取得系統(tǒng)參數(shù)....
//以下例程使用固定值:19200 ,無校驗(yàn),
//站號 =撥碼開關(guān)設(shè)定1-32
UartInit(19200, NONE_PARITY); //串口初始化[須要確定好波特率和校驗(yàn)值]
ModbusInit(Get_ID_HD(),StartSend); //Modbus串口初始化[須要確定好站號]
//
// IP = 0x03;
// IPH = 0x09;
EA = 1;
}
//----------------------------START-------------------------------
//=================================================================
void main(void)
{
// u8 Data_p = P2;
SYSinit(); //系統(tǒng)初始化
// 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(); //串口數(shù)據(jù)幀檢查處理
TEST1();
//......
//繼續(xù)添加應(yīng)用程序代碼...
LED=1;
/******************************
功能:讀寄存器
調(diào)用:RegBuf_Input[0],0為寄存器地址對應(yīng)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);
/******************************
功能:讀寫寄存器
調(diào)用:RegBuf_HOLD[0],0為寄存器地址對應(yīng)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) //如果接收好了進(jìn)行紅外處理
{
Ircordpro();
irok=0;
}
if(irpro_ok) //如果處理好后進(jìn)行工作處理,如按對應(yīng)的按鍵后顯示對應(yīng)的數(shù)字等
{
Ir_work();
Ir_towork();
}
}
}
開始以為時(shí)紅外遙控程序問題,我都放在主程序里面調(diào)試了 |
|