📄 osd.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 + -