📄 tvp5150.c
字号:
/******************************************************************************
本程序大部分功能调试通过,没有调试或没有通过已在功能模块里说明
注: 本程序只供学习使用,未经作者允许,不能用于其它任何用途
//模 块 名:TVP5150 视频AD解码芯片驱动程序
//创 建 者:电子伙伴 日期:2008-6-10 15:30
//修 改 者: 日期:
//功能描述:
//其他说明:内部RC振荡
//芯片型号: STC12LE2051
//配 置:
//版 本:V1.0
//CopyRight:http://www.jxmcu.com gfs0521@126.com
******************************************************************************/
#include <STC12C5410AD.h>
#include <intrins.h>
#define HIGH 1
#define LOW 0
#define REG 250
#define DELAY 5
//#define TEST 1
//IO口定义
sbit ADC0 = P1^0; //亮度
sbit ADC1 = P1^1; //对比度
sbit ADC2 = P1^2; //色度
sbit SPDA = P1^5; //SPI DATA
sbit SPCLK = P1^6; //SPI CLOCK
sbit SPCE = P1^7; //SPI CE
sbit IIC_DA = P3^4; //TVP5150 IIC DTAA
sbit IIC_CLK = P3^5; //TVP5150 IIC CLOCK
#define TVP5150 0xba
//清看门狗溢出时间 12*64*32768/11059200=2.27S
#define CLRWDT() WDT_CONTR=0x3d
/******************************************************************************
函数功能说明:
unsigned char IIC_Read(unsigned char address)
void IIC_Write(unsigned char address,unsigned char dd)
/************************************************
//延时程序50个指令周期
//输入参数: 时间量
//延时时间范围:50-12760
//延时时间为:i*50(指令周期)+5
************************************************/
void delay50us(unsigned char i)
{
unsigned char j;
do
{
j=205;
while(--j);
}
while(--i);
}
/******************************************************************************
******************************************************************************/
void i2c_start(void) //起始位:SCL =1 时,在SDA 上有下降延
{
unsigned char t5us;
t5us=50;while(--t5us); IIC_CLK=0;
t5us=50;while(--t5us);
IIC_DA=1;
t5us=50;while(--t5us);
IIC_CLK=1;
t5us=50;while(--t5us);IIC_DA=0;
t5us=50;while(--t5us);IIC_CLK=0;
}
/******************************************************************************
******************************************************************************/
void i2c_stop(void) //停止位:SCL =1 时,在SDA 上有上升延
{
unsigned char t5us;
IIC_DA=0;t5us=50;while(--t5us);
IIC_CLK=1;t5us=50;while(--t5us);
IIC_DA=1;
}
/******************************************************************************
应答
******************************************************************************/
void i2c_ask(void)
{
unsigned int i=0; //预防死循环
unsigned char t5us;
IIC_DA=1;t5us=50;while(--t5us);
IIC_CLK=1;t5us=50;while(--t5us);
do
{
i--;
if(IIC_DA!=1) { IIC_CLK=0;i=0; }
}
while(i!=0);
}
/******************************************************************************
IIC读1个字节子程序,返回ACC1个字节的数据
******************************************************************************/
unsigned char rd24(void)
{
unsigned char i,iic,t5us;
IIC_DA=1;
i=8;iic=0;
do
{
IIC_CLK=1;t5us=50;while(--t5us);
i--; //增加延时
iic<<=1; //数据左移一位,先接收高位
if(IIC_DA) iic|=0x01; //数据是否为1
t5us=50;while(--t5us);
IIC_CLK=0; //时钟置低
t5us=50;while(--t5us);
}
while(i);
IIC_DA=1;t5us=50;while(--t5us);
IIC_CLK=1;t5us=50;while(--t5us);
IIC_CLK=0;
return(iic);
}
/******************************************************************************
IIC发送1个字节
******************************************************************************/
void wd24(unsigned char iic)
{
unsigned char i,t5us;
i=8;
do
{
if(iic&0x80) IIC_DA=1;
else { IIC_DA=0; }
t5us=50;while(--t5us);
IIC_CLK=1;
t5us=50;while(--t5us);
iic<<=1;
i--;
IIC_CLK=0;
t5us=50;while(--t5us);
}
while(i);
IIC_DA=1;IIC_CLK=1;
}
/******************************************************************************
IIC读子程序
******************************************************************************/
unsigned char IIC_Read(unsigned char DeviceID,address)
{
unsigned char dd;
i2c_start();wd24(DeviceID);i2c_ask();wd24(address);i2c_ask(); //送地址
i2c_start();wd24(DeviceID);i2c_ask();dd=rd24();i2c_stop(); //读数据
return(dd);
}
/******************************************************************************
IIC写子程序
输入地址2个字节,
******************************************************************************/
void IIC_Write(unsigned char DeviceID, unsigned char address,unsigned char datas)
{
//unsigned char i;
//WP=0;
i2c_start();
wd24(DeviceID);i2c_ask();
wd24(address); i2c_ask();
wd24(datas); i2c_ask();
//delay50us(3);
//while(!IIC_CLK); //TVP5150添加判断读高等待
i2c_stop();
//delay50us(200);
//WP=1;
}
////////////////////////////////////////////////////////////////////////////////
//Function : Init TVP5150
//input param: no
//return : no
////////////////////////////////////////////////////////////////////////////////
void TVP5150_Init(void)
{
IIC_Write(TVP5150,0x03,0x09);
IIC_Write(TVP5150,0xf7,0xc0);
IIC_Write(TVP5150,0x02,0x00); //标准TV信号
IIC_Write(TVP5150,0x07,0x6d);
IIC_Write(TVP5150,0x08,0x00);
IIC_Write(TVP5150,0x0e,0x00);
IIC_Write(TVP5150,0x1a,0x0c);
IIC_Write(TVP5150,0x1b,0x14);
IIC_Write(TVP5150,0x0d,0x07);
IIC_Write(TVP5150,0x0f,0x08);
IIC_Write(TVP5150,0x06,0x10);
IIC_Write(TVP5150,0xc2,0x04);
IIC_Write(TVP5150,0x09,0x61);
IIC_Write(TVP5150,0x28,0x00); //强制定义为PAL制
//IIC_Write(TVP5150,0x11,0xfc); //
//IIC_Write(TVP5150,0x12,0x04); //
//IIC_Write(TVP5150,0x13,0xfc); //
//IIC_Write(TVP5150,0x14,0x00); //
//IIC_Write(TVP5150,0x09,0x90); //
IIC_Write(TVP5150,0x0a,0xb0); //
IIC_Write(TVP5150,0x0c,0xa0); //
}
////////////////////////////////////////////////////////////////////////////////
//Function : AD采样 中断程序
//input param: no
//return : no
////////////////////////////////////////////////////////////////////////////////
#define AD_N 16
unsigned char Ad0[AD_N];
unsigned char Ad1[AD_N];
unsigned char Ad2[AD_N];
unsigned char Bright,Contrast,Color;
unsigned char AdChannel;
void Read_Ad(void)
{
unsigned int Sum;
unsigned char i;
ADC_CONTR&=0xe7; //停止AD转换
AdChannel++;
Sum=0;
switch(AdChannel&0x03)
{
case 0: Ad0[AD_N-1]=ADC_DATA;
for(i=0;i<15;i++)
{
Ad0[i]=Ad0[i+1];
Sum+=Ad0[i];
}
Contrast=Sum/AD_N;
ADC_CONTR=0xe1;
break;
case 1: Ad1[AD_N-1]=ADC_DATA;
for(i=0;i<15;i++)
{
Ad1[i]=Ad1[i+1];
Sum+=Ad1[i];
}
Bright=Sum/AD_N;
ADC_CONTR=0xe2;
break;
case 2: Ad2[AD_N-1]=ADC_DATA;
for(i=0;i<15;i++)
{
Ad2[i]=Ad2[i+1];
Sum+=Ad2[i];
}
Color=Sum/AD_N;
ADC_CONTR=0xe3;
break;
case 3:
default: ADC_CONTR=0xe0;
break;
}
ADC_CONTR|=0x08; //起动AD转换
}
#ifdef TEST
unsigned char ComCoun;
unsigned char ComValue[2];
void uart(void) interrupt 4
{
if(RI)
{
ComValue[ComCoun&0x01]=SBUF; //就取两个字节
ComCoun++;
RI=0;
}
}
#endif
////////////////////////////////////////////////////////////////////////////////
//Function : 初始化寄存器和IO口
//input param: no
//return : no
////////////////////////////////////////////////////////////////////////////////
void InitIO(void)
{
P1M0=0x0f; P1M1=0x00; //
P3M0=0; P3M1=0; //P3为普通准双向IO
P1=0xff;
P3=0xff;
ADC_CONTR=0xe0; //最长时间转换
delay50us(20); //AD起动延时1ms
//EADC_SPI=1;
#ifdef TEST
TMOD=0x20;
SCON=0x50;
PCON|=0x80;
TH1=0xd1;
TL1=0xd1; //5.37Mhz 600bps
TR1=1;
TR0=1;
ES=1;
EA=1;
#endif
}
void main(void)
{
unsigned char i,j;
unsigned char BrightBuf,ColorBuf,ContrastBuf;
unsigned int k;
InitIO();
delay50us(200);
delay50us(200);
delay50us(200);
delay50us(200);
delay50us(200);
TVP5150_Init();
#ifdef TEST
for(i=8;--i;)
{
TI=0;
SBUF=0x5a;
while(!TI);
TI=0;
SBUF=0xa5;
while(!TI);
TI=0;
}
#endif
for(i=0;i<4;i++)
{
Read_Ad();
delay50us(20);
}
for(i=0;i<16;i++)
{
Ad1[i]=Ad1[AD_N-1];
}
Bright=Ad1[0];
BrightBuf=Bright+1;
while(1)
{
CLRWDT();
for(i=3;i--;)
{
delay50us(20);
}
#ifdef TEST
if(ComCoun>1)
{
IIC_Write(TVP5150,ComValue[0],ComValue[1]);
ComCoun=0;
//TVP5150_Init();
}
#endif
Read_Ad();
if(BrightBuf!=Bright) //亮度最佳全程范围50-255
{
BrightBuf=Bright;
k=Bright&0x00ff;
k=k*200;
k=k/256;
i=(k+50)&0xff;
//k=(Bright*200)/255+50;
IIC_Write(TVP5150,0x09,i);
}
/*
if(ColorBuf!=Color) //色度最佳全程范围50-255
{
ColorBuf=Color;
k=(Color*200)/255+50;
IIC_Write(TVP5150,0x0a,k&0xff);
#ifdef TEST
SBUF=0x01;
while(!TI);
TI=0;
SBUF=Color;
while(!TI);
TI=0;
#endif
}
if(ContrastBuf!=Contrast) //对比度最佳全程范围80-255
{
ContrastBuf=Contrast;
k=(Contrast*170)/255+80;
IIC_Write(TVP5150,0x0c,k&0xff);
#ifdef TEST
SBUF=0x02;
while(!TI);
TI=0;
SBUF=Contrast;
while(!TI);
TI=0;
#endif
}
*/
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -