⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 osd.c

📁 s3c44b0红外解码。源码使用SOURCE INSIGHT打开 用ADS1.2编译。
💻 C
字号:
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <math.h>
#include ".\inc\44b.h"
#include ".\inc\DEF.H"
#include ".\inc\option.h"
#include ".\inc\tp.h"
void Port_Init(void);
void Uart_Init(int mclk,int baud);
void Uart_Select(int ch);
void Delay(int time);
void Isr_Init(void);
char Uart_Getch(void);
void Uart_SendByte(int data);
void Uart_SendString(char *pt);
void Uart_Printf(char *fmt,...);
void uart_IR_flash(int flash_time);
void read_write_flash(void);

/**************************************************/
char ir_code_conversion(U32 buf3);
void ir_pluse_test(void);
int bin_to_hex(char *p,int conversion_count);
int  key_ad(void);
char IR_handle(U32 *ir_add,U32 *ir_data);
void __irq pulse(void);
void ir_reset(void);
void IR_open(void);
void IR_read(void);
void IR_close(void);
void ir_test(void);
/***************************************************/

#define LOOP 1000
#define buf1_address (volatile U32 *)0xc7f0000
#define buf2_address (volatile U32 *)0xc710000

static int delayLoopCount=400;
static int whichUart=0;
int ir_count=0;//i=0,
int flag=0;
char x_flag=0;
volatile U32 *buf1=buf1_address,*buf2=buf2_address;
int pulse_time_value=0;


void Isr_Init(void)
{
    U32 i;
    
    for(i=_RAM_STARTADDRESS;i<(_RAM_STARTADDRESS+0x20);i+=4)
    {
	  *((volatile unsigned *)i)=0xEA000000+0x1FFE;
    }

    //rINTCON=0x1;	  // Vectored Int. IRQ enable,FIQ disable    
    rINTCON=0x5;	  // Non-vectored,IRQ enable,FIQ disable    

    rINTMOD=0x0;	  // All=IRQ mode
    rINTMSK|=BIT_GLOBAL|BIT_EINT4567;	  // All interrupt is masked.
}


void Port_Init(void)
{   
    //PORT C GROUP
	
	rPDATC = 0x0000;
	rPCONC = 0xfff5ff55;
	rPUPC=0x00;
    
   	//PORT E GROUP
	rPCONE=0x05969;//0x6552a;//0x2B;	
	  
 }
 
 void Uart_Init(int mclk,int baud)
{
    int i;
    if(mclk==0)
	mclk=MCLK;
    rUFCON0=0x0;     //FIFO disable
    rUFCON1=0x0;
    rUMCON0=0x0;
    rUMCON1=0x0;
//UART0
    rULCON0=0x3;     //Normal,No parity,1 stop,8 bit
    rUCON0=0x245;    //rx=edge,tx=level,disable timeout int.,enable rx error int.,normal,interrupt or polling
    rUBRDIV0=( (int)(mclk/16./baud + 0.5) -1 );
//UART1
    rULCON1=0x3;
    rUCON1=0x245;
    rUBRDIV1=( (int)(mclk/16./baud + 0.5) -1 );
    for(i=0;i<100;i++);
}

void Uart_Select(int ch)
{
    whichUart=ch;
}


void Delay(int time)//以100us为单位的延时程序
{
    int i,adjust=0;
    if(time==0)
    {
	time=200;
	adjust=1;
	delayLoopCount=400;
	rWTCON=((MCLK/1000000-1)<<8)|(2<<3);  // 1M/64,Watch-dog,nRESET,interrupt disable
	rWTDAT=0xffff;
	rWTCNT=0xffff;	 
	rWTCON=((MCLK/1000000-1)<<8)|(2<<3)|(1<<5); // 1M/64,Watch-dog enable,nRESET,interrupt disable 
    }
    for(;time>0;time--)
	for(i=0;i<delayLoopCount;i++);
    if(adjust==1)
    {
	rWTCON=((MCLK/1000000-1)<<8)|(2<<3);
	i=0xffff-rWTCNT;                 //  1count/16us?
	delayLoopCount=8000000/(i*64);	//400*100/(i*64/200)   
    }
}

void Uart_SendString(char *pt)
{
    while(*pt)
	Uart_SendByte(*pt++);
}


//if you don't use vsprintf(), the code size is reduced very much.

void Uart_Printf(char *fmt,...)
{
    va_list ap;
    char string[256];

    va_start(ap,fmt);
    vsprintf(string,fmt,ap);
    Uart_SendString(string);
    va_end(ap);
}

void Uart_SendByte(int data)
{
    if(whichUart==0)
    {
	if(data=='\n')
	{
	    while(!(rUTRSTAT0 & 0x2));
	   Delay(10);	//because the slow response of hyper_terminal 
	    WrUTXH0('\r');
	}
	while(!(rUTRSTAT0 & 0x2)); //Wait until THR is empty.
	Delay(10);
	WrUTXH0(data);
    }
    else
    {
	if(data=='\n')
	{
    	while(!(rUTRSTAT1 & 0x2));
	    Delay(10);	//because the slow response of hyper_terminal 
	    rUTXH1='\r';
	}
	while(!(rUTRSTAT1 & 0x2));  //Wait until THR is empty.
	Delay(10);
	rUTXH1=data;
    }	
}


void uart_IR_flash(int flash_time)
{  int i=0,ir_time=3000;//改变ir_time可以改变led闪烁的频率
   int T=500;//T 改变发光亮度
   Uart_Select(1);
  while(flash_time)
    {while(T!=0)
	{Uart_Printf("%d",i);
	  T--;
    }
	  Delay(ir_time); 
	  flash_time--;
   	}
}


char Uart_Getch(void)
{
    if(whichUart==0)
    {	    
	while(!(rUTRSTAT0 & 0x1)); //Receive data read
	return RdURXH0();
    }
    else
    {
	while(!(rUTRSTAT1 & 0x1)); //Receive data ready
	return	rURXH1;
    }
}


void ir_test(void)
{
IR_open();
//Uart_Printf("ir_count=%d\n",ir_count);

if(ir_count==34) 
	{
      Uart_Printf("ir_count=%d\n",ir_count);
	  ir_reset();
      Uart_Getch();
    }
 
}

/**********************************************************************
经示波器统计下降为34个
采用EXINT2中断,不停的读定时器观察寄存器的值,
并计算前一下降沿与后一个下降沿的计数的差值。保存到buf2中。

************************************************************************/

void __irq pulse(void)
{U32 first_value=0,next_value=0;
   
    rI_ISPC=BIT_EINT2;	//clear pending_bit IRQ中断服务程序清除器。结束中断服务程序
	rINTPND=~BIT_EINT2;//直接可以挂EXINT2
    // ir_count++;
	switch(x_flag)
		{
		 case 0: {
		          rTCON |=0x2<<24 ; //manual update
                  rTCON =0x0<<24; //clear manal update bit
      	          rTCON |= 0x1<<24; // start Timer 5
	              first_value=rTCNTO5; //读取定时器观测寄存器1的计数值
	              if(first_value==0)
				  	*buf1=65535;
				  else
                  *buf1=first_value;
		          buf1++;
		          x_flag=1;
		          ir_count++;
				  break;
      	         }
		 
	    case 1:
	  	       {
	  	       next_value=rTCNTO5;
		      *buf1=next_value;
	          *buf2=*(buf1-1)-*buf1;
	           buf2++;
		       buf1++;
		       ir_count++;
			   break;
	    	  }
		
	  	}
	
}



/****************************************************
name:ir_code_conversion()
把得到的红外脉宽数值转换为编码信息0 1;
*****************************************************/
char ir_code_conversion(U32 buf3)
{
 if(buf3>70&&buf3<80)return '0'; 
 if(buf3>142&&buf3<150)return '1';
 return 'E';
}



/*********************************************
name bin_to_hex()
二进制到十六进制转换

**********************************************/
int bin_to_hex(char *p,int conversion_count)
{int  temp1=0x0,temp2=0;
for(temp2=0;temp2<conversion_count;temp2++)
{
temp1=(temp1<<1)|(*p-'0');
p++;
}
 return temp1;

}


/******************************************************************
******************************************************************/

char IR_handle(U32 *ir_add,U32 *ir_data)
{ int count=0,i=0,ir_flag=0;
  char ir_bin[32],*ir_add_code,*ir_data_code,ch_flag;
  U32 p_v;
  static int j=0;
Uart_Printf(" ir_count: %d \n",ir_count);
count=ir_count;
/**********提高稳定性和自动纠错复位*****************/
if(count<34)
{
  j++;
  if(j>34)
  	{ir_reset();
     j=0;
  	}
}
/************************************************/
    if(count==34)
     { 
      buf2=buf2_address;
      buf1=buf1_address;
      count--;
	  if(*buf2>880)
	  	{count--;
		 buf2++;
		 i=0;
		while(count)
			{ p_v=*buf2;
		      /********测试脉宽*********/
		     //Uart_Printf(" %d ",*buf2);
			  
			  /*************************/
		     ch_flag=ir_code_conversion(p_v);
			 /************脉宽数值读取错误复位处理******************/
			if(ch_flag=='E')
			 	{Uart_Printf("error\n");
			     goto reset;
				}
		/*********************************************************/
			ir_bin[i++]=ch_flag;
		//Uart_Printf(" %c ",ch_flag);
			buf2++;
			count--;
			}
		ir_add_code=ir_bin;
		ir_data_code=ir_bin+16;
	    *ir_add=bin_to_hex(ir_add_code,16);
	    *ir_data=bin_to_hex(ir_data_code,16);
		ir_flag=1;
			
	  	}
	  
	  else
	  	{
	    Uart_Printf("NO IR SIGNAL\n");
	  	}
	    ir_reset();
   reset:
         ir_reset();
	    
	}
//提高代码的稳定性 超过的范围给相关数值复位	
 if(count>34) ir_reset();
 
 return ir_flag;
}


/*************************************************************/
/*************************************************************/

void IR_read(void)
{ U32 iradd,irdata;
  char irflag=0;
	do
		{
	irflag=IR_handle(&iradd,&irdata);
		}
	while(!irflag);
		Uart_Printf("0x%x  0x%x\n",iradd,irdata);
		Uart_Getch();
}

void IR_open(void)
{
/**************************************************************
   定时器5初始化
******************定时器每次时间间隔为15us,最大计时为1.02sec;************/
  rTCFG0=0xFA<<16;//prescaler = 250  每一次计数间隔时间为15us
  rTCFG1=0x100000;  //1/4 ( MCLK = 66 MHz ) 0.060 us (16.5 MHz ) 15.5 us (58.6 KHz ) 1.02 sec
  rTCNTB5=65535;
  rTCON |=2<<24 ; //manual update
  rTCON = 0<<24; //clear manal update bit
/****************************************************************************/
rEXTINT=0x200; //INT2 下降沿触发;
rINTCON=0x5;//设置是用IRQ还是FIQ,IRQ使用模式
pISR_EINT2=(int)pulse;
rINTMSK=~(BIT_GLOBAL|BIT_EINT2);//设置INT2服务可以使用。开中断。
 
}



void IR_close(void)
{
rINTMSK=(BIT_GLOBAL|BIT_EINT2);//设置INT2服务可以使用。关中断。
rTCON |= 0x0<<24;
}



/************************红外复位处理*************************/
void ir_reset(void)
{   
    buf1=buf1_address;
	buf2=buf2_address;
 	x_flag=0;
	ir_count=0;
}
/*****************************************************************/

/*********************************A/D模数转换****************/
int  key_ad(void)
{
     int i,difference,average;
     U32 Pt[10],pa[10];
	 Uart_Select(0);
    rADCCON=0x01<<2;			// AIN1
	for(i=0;i<9;i++)
	{
    	 rADCCON|=0x1;		    // Start X-position conversion
	     while(rADCCON & 0x1);	// Check if Enable_start is low
    	 while(!(rADCCON & 0x40));	// Check ECFLG
	    Pt[i]=(0x3ff&rADCDAT);
	}
	Pt[9]=(Pt[0]+Pt[1]+Pt[2]+Pt[3]+Pt[4]+Pt[5]+Pt[6]+Pt[7]+Pt[8])/9;
	
	Delay(800);

	for(i=0;i<9;i++)
	{
    	  rADCCON|=0x1;		// Start X-position conversion
	      while(rADCCON & 0x1);	// Check if Enable_start is low
    	  while(!(rADCCON & 0x40));	// Check ECFLG
	    pa[i]=(0x3ff&rADCDAT);
	}
	pa[9]=(pa[0]+pa[1]+pa[2]+pa[3]+pa[4]+pa[5]+pa[6]+pa[7]+pa[8])/9;
	difference=abs(Pt[9]-pa[9]);
	average=(Pt[9]+pa[9])/2;
	if(difference<5)
	{
	 	 if(average>36&&average<41)  {Uart_Printf("    VOL+\n");return 0;}
		 if(average>60&&average<66)  { Uart_Printf("   VOL-\n");return 0;}
		 if(average>122&&average<130) {Uart_Printf("   CH+\n");return 0;}
		 if(average>177&&average<188) {Uart_Printf("   POWER\n");return 0;}
		 else 
		 	{Uart_Printf("ERROR\n");return 0;}

	//Uart_Printf("[AIN1] conversion result %04d  %04d\n", difference,average);
	}
	else
		{
		  
		  Uart_Printf("NO DATA\n");return 0;
		}
}	
/**********************************************************************/



void Main(void)
{  
    Isr_Init();
    Port_Init();
    Uart_Init(0,115200); 
	//IR_open();
   // Uart_Select(1);
//    Delay(0);  //calibrate Delay()
   // Delay(5000);
	
   while(1)
  {// 
    // uart_IR_flash(1);
	 // uart_ir();
	//key_ad();
	    IR_open();
		IR_read();
		IR_close();
		//ir_test();

   }
 
  	
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -