?? 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 + -