📄 hou_310_adc_vido.c
字号:
/////////////////////////////////////
// 外部中断0和1分别进入P0.6和P0.7 //
// 视频输入进入P2.7,进行采样过程 //
// 通过串口0向外以9600波特率发送数据 //
/////////////////////////////////////
#include "C8051F310.h"
///////采用10位 ADC1///////
///////说明:1:把P2.7配置为模拟输入引脚,作为视频输入端口。
////// 2:系统采用内部晶镇24.5MHZ,AD0采用系统时钟。
////// 3:程序中由一个指示灯接在310端口P1.1口(低电平驱动)。
////// 4:测量最大电压为3.29V.
///// 5:其他端口用法类似(通道选择寄存器一定要配的)。
//
#define ADC0STARD ADC0CN|=0x10;
sbit LED=P1^1;
sbit POP1=P3^4;
sbit POP2=P3^3;
sbit POP3=P3^2;
sbit POP4=P3^1;
int IsCaiYang=0; //当前是否采样
//int PointMax=0; //总的每行点数
int PointCur=0; //当前点数
//int RowMax=0; //总行数
int RowCur=0; //当前行
int RowNew=0; //当前行
int FramCur=0; // 当前帧
int FramNew=0; // 新帧
xdata unsigned int ImageData[10][10];
unsigned int tempsend=1;
int TempSendX=0,TempSendY=0;
int C51WorkMode=01;//C51机器与上位机之间通讯时候决定的工作模式变量;默认0
int tempSendData=0;
int pubi,pubj,pubm,pubn;
//sbit P07=P0^7;
// Peripheral specific initialization functions,
// Called from the Init_Device() function
void Timer_Init()
{
TMOD = 0x20;
CKCON = 0x08;
TH1 = 0x80; //chuankou 中是TH1 = 0x96;
TCON = 0x40; //容许时间中断
TMOD=0x20; //定时器采用模式2(8位自动从载定时器/计数器)
CKCON=0x00; //定时器采用系统时钟12分频(目标波特率9600)
TH1=0x96;
}
void PCA_Init()
{
PCA0MD &= ~0x40;// 关狗
PCA0MD = 0x00;
}
void UART_Init()
{
SCON0 = 0x10;
}
void Interrupts_Init()
{
EIE1 = 0x08; //扩展中断允许 ADC0中断容许
//IT01CF = 0x76;//P0.6->INT0 行同步型号 P0.7->INT1 场信号
//IT01CF = 0xFE;
IT01CF=0x76;
//原ADC的IE = 0x80;//开启总中断 串口中IE= 0x98;
IE =0x9D;
EX1=1; //开启外中断1
IT1=1; //1号中断以下降沿有效
EX0=1; //开启外中断0
IT0=1; //0号中断以下降沿有效
ES0=1; //允许UART0 中断
}
void Port_IO_Init()
{
P2MDIN = 0x7F;//端口P2.7配为模拟输入
//P0MDOUT = 0x80;// P0.7推挽输出
P1MDOUT = 0x02;//P1.1->LED
P3MDOUT = 0x1E; //P3口接了四个LED 分别是POP1234
XBR0 = 0x01;
XBR1 = 0x40;
}
// Initialization function for device,
// Call Init_Device() from your main program
void Init_Device(void)
{
OSCICN = 0x83;//晶振采用系统内部晶振,24MHz
Timer_Init();
PCA_Init();
Port_IO_Init();
UART_Init();
Interrupts_Init();//初视化中断输入 INT0 和 INT1
}
void adc0_ini();//ADC0配置
void delay(int time);
bit isnewdata;
float realDY=0;
unsigned int dianya=0;
void main()
{
int main_i,main_j;
adc0_ini(); //ADC0进行配置
Init_Device();
//EA=1; //开启全局中断
TR1=1; //TIMER1启动,给串口一提供稳定的波特率
ADC0H=0; //寄存器初始化
ADC0L=0;
ADC0STARD; //开启ADC0转换;
POP1=1;
POP2=1;
POP3=1;
POP4=1;
//LED=0;
//SBUF0=0x55;
for (main_i=0;main_i<10;main_i++)
for (main_j=0;main_j<10;main_j++)
ImageData[main_i][main_j]=0xFD;
while(1)
{
if(IsCaiYang==0)
{
//LED=~LED;
POP3= C51WorkMode;
}
}
}
///////////ADC1配置函数//////////
void adc0_ini()
{
AMX0P = 0x0F;//正通道选择寄存器配置在端口P2.7
AMX0N = 0x1F;//ADC0工作在单端方式
ADC0CF = 0x00;//ADC0为系统时;数据采用右对齐方式
ADC0CN = 0x80;//ADC0使能;连续跟踪方式;
//向AD0BUSY写1启动ADC1转换;
//AD0INT开始被放在0位,当转换完成时被置1;
//EIE1 = 0x08;//允许ADC0中断
//IE = 0x80;//总中断开关打开
REF0CN = 0x08;//ADC0参考电压为VDD提供
}
//////////////ADC0中断函数///////////////
void adc0(void) interrupt 10
{
POP1=~POP1;
POP2=~POP2;
ADC0CN&=0xdf;//1101,1111,AD0INT用软件清零0 AD0INT=0;
if (RowNew-26==RowCur)
{PointCur++;
}
else
{
PointCur=1;
RowCur=RowNew-26;
}
ImageData[RowCur][PointCur]=(ADC0H*256+ADC0L)>>4;//(ADC0H*256+ADC0L);//采样数据
ImageData[RowCur][9]=PointCur;//每行到底采样多少点
if ((IsCaiYang==1)&&(PointCur<7)) ADC0STARD;//直接启动下一次采样
}
////////////////////////////////////////////////////////////////////////////
//////////////INT0中断函数///////////////
void int1(void) interrupt 2//行同步信号
{
IE0=0; //清除中断0的中断标志位
IsCaiYang=0;
if (FramNew<2)
{ // 叔祖 hang++ if hang>max hang=0
if (FramNew==FramCur) //未开始新的帧
{
RowNew++;
//if (RowMax<RowNew) RowMax=RowNew;
if ((RowNew>=26)&&(RowNew<=35))
{
if (RowNew==26)
{IsCaiYang=1; //等待25个行信号过后开始采样,前面的是控制信息不采
PointCur=0; //新行,新帧
}
ADC0STARD;
ImageData[RowNew-26][0]=RowNew-25;//每行行号码
}
}
if (FramNew!=FramCur) //开始了新帧
{
RowCur=0; //开始新帧,则重新开始刷新叔祖,从[0][1] 开始
PointCur=0;
//RowNew=0; //开始新帧,则重新开始刷新叔祖,从[0][1] 开始
//PointNew=0;
}
}
}
////////////////////////////////////////////////////////////////////////////
void int0(void) interrupt 0 //奇偶场信号
{
IE1=0; //清除中断0的中断标志位
//标志,如果是○ biaozhi=~biaozhi
FramNew++;
if (FramNew>150) FramNew=0;//随便写的,在60帧里面测试
IsCaiYang=0; //换了新帧后,暂时不采样,等待25个行信号
if ((FramNew==2)&&(C51WorkMode==01)) //随便写的,在60帧里面测试
{
TempSendX=0;
TempSendY=0;
TI0=1;
}
}
//////////////////////////////////
//计数器1中断,实际上啥也不动,但给串口0一个波特率9600
void Timer1_ISR (void) interrupt 3
{
TF1=0;
}
//////////////////////////////////
//串口通讯中断
void UartInt(void) interrupt 4
{
unsigned int temp;
unsigned int aa;
if (RI0==1)
{RI0 = 0;
temp = SBUF0;
switch (temp)
{
case 01:
C51WorkMode=1;break;//接收到01表示开始自动发送IMGDATA
case 02:C51WorkMode=0;break;//接收到02表示关闭自动发送IMGDATA
case 03:TI0=1; //手动刷新一帧数据
TempSendX=0;
TempSendY=0;
C51WorkMode=3;
break;
case 04://) //接受到04表示上位机器请求通讯测试
//开始测试时候,C51向PC发送从1到200的数据
C51WorkMode=04;
tempSendData=0;TI0=1;break;//
case 05:
default: ;
}
//end case
POP4=~POP4;
}
if (TI0==1)
{TI0=0;
if (C51WorkMode==01) //如果工作在自动发送模式
if (TempSendX<10)
{
aa=ImageData[TempSendX][TempSendY];
if (aa==0xFF) aa=0xFE;
TempSendY++;
if (TempSendY==10) {TempSendX++;TempSendY=0;}
SBUF0=aa;
}
if (C51WorkMode==03) //如果工作在手动刷新
if (TempSendX<10)
{
aa=ImageData[TempSendX][TempSendY];
if (aa==0xFF) aa=0xFE;
TempSendY++;
if (TempSendY==10) {TempSendX++;TempSendY=0;}
SBUF0=aa;
}
if (C51WorkMode==04) //接受到04表示上位机器全球通讯测试
//开始测试时候,C51向PC发送从1到200的数据
{
if (tempSendData<200)
SBUF0=tempSendData++;
if (tempSendData>=200)
C51WorkMode=00;
//else
// C51WorkMode=0;//通讯测试完成,恢复工作状态
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -