?? mcu020.c
字號:
#include <C8051F020.h>
#define uchar unsigned char
#define uint unsigned int
//----------------------------------------------------------------------
//全局常量
//----------------------------------------------------------------------
#define BAUDRATE 9600 //波特率bps
#define SYSCLK 22118400 //外部晶振
#define MAX_LEN 32 //每次接收/發送字符串的最大長度
#define Initialize 0X00 //PC機發送初始化命令代碼
#define Read 0X01 //PC機發送讀命令代碼
#define Write 0X02 //PC機發送寫命令代碼
#define Stop 0X03 //PC機發送停止命令代碼
sbit PLL_Data = P2^1; // PLL數據輸入端口
sbit PLL_Enable = P2^2; // PLL使能位控制端口
sbit PLL_CLK = P2^0; // PLL時鐘輸入端口
sbit GF_Enable = P1^6; // 功率放大器控制位
sbit RW_FPGA = P0^4; // 讀/寫FPGA選擇位
sbit WR_CLK = P0^5; // 寫FPGA時鐘
sbit EWR_FPGA = P0^7; // 寫FPGA結束中斷
sbit Rev_ACK = P3^4; // MCU接收一字節完成
sbit Rev_ready = P3^5; // 接收FPGA數據準備好
uchar idata Init[1]={0X0A}; // 初始化命令
uchar idata GROUP_SELECT[3]={0X17,0X00,0X00}; // 選擇卡命令
//---------------------------------------------------------------------
//全局變量
//---------------------------------------------------------------------
bit UART0_readflag = 0; //UART0讀取完成標志
bit UART0_sendflag = 0; //UART0發送完成標志
bit FPGA_readflag = 0; //接收FPGA的數據完成標志
uchar UART0_SC = 0; //UART0已經發送的字符個數
uchar RevFPGA_LEN = 0; //MCU接收FPGA的數據長度
uchar UART0_Rev; //UART0要接收的字符串
uchar idata UART0_Send[MAX_LEN]; //UART0要發送的字符串
uchar idata FPGA_DATA[MAX_LEN]; //用于存儲MCU接收FPGA的數據
//----------------------------------------------------------------------
//子函數聲明
//----------------------------------------------------------------------
void SYSCLK_Init(void); //系統時鐘初始化
void PORT_Init(void); //端口初始化
void Interrupts_Init(void); //中斷初始化
void UART0_Init(void); //串口UART0初始化
void Timer0_us (uint us); //定時器0產生1us
void Timer2_Init();
void Timer2_ISR(void);
void UART0_ISR(void); //串口中斷服務程序
void Send_FPGA(uchar *ptr,uchar len) reentrant;
void INT6_ISR(void);
void INT1_ISR(void);
void INT7_ISR(void);
void Config_PLL();
void send_bit(uchar temp);
//----------------------------------------------------------------------
//主函數
//----------------------------------------------------------------------
void main(void)
{
EA = 0;
WDTCN = 0XDE; //禁止看門狗
WDTCN = 0XAD;
SYSCLK_Init(); //時鐘初始化
PORT_Init(); //端口初始化
UART0_Init(); //串口初始化
Interrupts_Init(); //中斷初始化
Timer2_Init(); //定時器2初始化
Config_PLL(); //配置PLL
EA = 1; //開全局中斷
while(1)
{
while(!UART0_readflag); //等待接收PC的指令
UART0_readflag = 0; //清零接收完成標志
if(UART0_Rev==Initialize) //PC機發送初始化命令
{
GF_Enable = 1; //啟動功率放大器
Send_FPGA(Init,1); //發送初始化命令
}
else if(UART0_Rev==Read) //PC機發送讀卡命令
{
GF_Enable = 1; //啟動功率放大器
Send_FPGA(GROUP_SELECT,3);
TR2 = 1;
}
else if(UART0_Rev==Stop) //PC機發送停止命令
{
GF_Enable = 0; //停止功率放大器
}
}
}
//----------------------------------------------------------------------
//子函數具體實現
//----------------------------------------------------------------------
//系統時鐘初始化
void SYSCLK_Init(void)
{
uint i;
OSCXCN = 0x67; //采用外部晶振22.1184MHz,不分頻.
for(i=0;i<256;i++); //等待>1ms
while(!(OSCXCN&0x80)); //查詢直到XTLVLD=1,晶振穩定
OSCICN = 0x88; //切換到外部振蕩器,允許時鐘失效監測器.
}
//端口初始化
void PORT_Init(void)
{
XBR0 = 0x04; //允許UART0,RX、TX連到2個端口引腳.
XBR1 = 0x14; //INT0和INT1連接到兩個端口引腳
XBR2 = 0x40; //交叉開關使能,使能全局弱上拉
P0MDOUT |= 0xB1; //P0.0、P0.5、P0.4、P0.7為推挽輸出,即TX0所在的端口
P1MDOUT |= 0x40; //P1.6為推挽輸出
P2MDOUT |= 0X07; //P2.0、P2.1、P2.2為推挽輸出
P3MDOUT |= 0X30; //P3.4、P3.5為推挽輸出
P74OUT = 0X0C; //P5口為推挽輸出
P0 &= 0XEF; //P0.4初始值為0
P1 &= 0XBF; //P1.6初值為0(FPGA準備好)
P3 &= 0XCF; //P3.4、P3.5初值為0(MCU準備好和接收一字節完成)
}
//中斷初始化
void Interrupts_Init(void)
{
EIE2 |= 0X30; //INT6、INT7中斷開啟
IE |= 0X05; //INT0、INT1中斷開啟
TCON |= 0X05; //設置INT0、INT1中斷為下降沿觸發
IP |= 0X10; //設置UART0中斷為高優先級
}
//串口初始化
void UART0_Init(void)
{
SCON0 = 0x50; //選擇串口方式1,波特率可變
TMOD = 0x20; //選擇T1,方式2,自動再裝入8位計數器
CKCON |= 0X10; //Timer1 uses SYSCLK as time base
TL1 = -(SYSCLK/BAUDRATE/16); //T1初值,根據波特率,時鐘等計算.
TH1 = TL1;
ES0 = 1; //UART0中斷開啟
TR1 = 1; //啟動定時器T1
PCON |= 0X80; //PCON=0x80,SMOD0=1(禁止UART0的波特率/2功能)
}
//Timer0_us
void Timer0_us (uint us)
{
uint i; // us counter
TCON &= ~0x30; // STOP Timer0 and clear overflow flag
TMOD &= ~0x0f; // configure Timer0 to 16-bit mode
TMOD |= 0x01;
CKCON |= 0x08; // Timer0 counts SYSCLKs
for (i = 0; i < us; i++) { // count microseconds
TR0 = 0; // STOP Timer0
TH0 = (-SYSCLK/1000000) >> 8; // set Timer0 to overflow in 1us
TL0 = -SYSCLK/1000000;
TR0 = 1; // START Timer0
while (TF0 == 0); // wait for overflow
TF0 = 0; // clear overflow indicator
}
}
//定時器2初始化----30ms產生中斷
void Timer2_Init()
{
T2CON = 0x00; //禁止定時器T2,清TF2,采用SYSCLK/12為時基
RCAP2H = 0X00; //初始化重裝載值
RCAP2L = 0X0F;
TH2 = 0X00;
TL2 = 0X0F;
ET2 = 1; //T2中斷開啟
}
//定時器2中斷子程序---無卡響應
void Timer2_ISR(void) interrupt 5
{
TF2 = 0; //清除中斷標志
Send_FPGA(GROUP_SELECT,3); //發送SUCCESS命令
}
//UART0中斷服務程序
void UART0_ISR(void) interrupt 4 using 1
{
uchar temp;
if(RI0==1)
{
RI0 = 0;
UART0_Rev=SBUF0;
temp=UART0_Rev;
temp++;
SBUF0=temp;
UART0_readflag=1;
}
else if(TI0==1)
{
TI0 = 0;
}
}
//向FPGA發送數據子程序(狀態機)
void Send_FPGA(uchar *ptr,uchar len) reentrant
{
RW_FPGA=1; //寫FPGA(向FPGA發送數據)
WR_CLK = 0;
Timer0_us(10);
WR_CLK = 1; //WR_FPGA輸出上升沿啟動寫FPGA
Timer0_us (2); //延時2us,發送數據
while(len--!=0)
{
P5 = *ptr; //把要傳輸的數據放到P5口
Timer0_us(2); //延時使數據放在端口
WR_CLK = 0;
Timer0_us(10);
WR_CLK = 1; //發送上升沿通知FPGA取數據
ptr++;
}
EWR_FPGA = 0;
Timer0_us(10);
EWR_FPGA = 1; //EWR_FPGA輸出上升沿結束寫FPGA
RW_FPGA=0;
}
//FPGA發送數據開始中斷(外部中斷6)
void INT6_ISR(void) interrupt 19
{
P3IF &= 0XBF; //清除中斷標志
TR2 = 0; //停止Timer2
Rev_ready = 1; //MCU接收準備好
}
//接收FPGA數據中斷子程序
void INT1_ISR(void) interrupt 2
{
uchar temp;
temp = P5; //讀取端口數據
FPGA_DATA[RevFPGA_LEN] = temp; //把數據存入數組
RevFPGA_LEN++; //讀取數據字節數加1
Rev_ACK = 1; //返回讀取一個字節數據應答
}
//FPGA發送數據結束中斷(外部中斷7)
void INT7_ISR(void) interrupt 18
{
P3IF &= 0X7F; //清除中斷標志
FPGA_readflag = 1; //置位讀FPGA完成標志
}
//配置PLL子程序
void Config_PLL()
{
uchar i,j,k;
PLL_CLK = 0;
PLL_Data = 0;
PLL_Enable = 0;
for(i=0;i<13;i++) //發送Function Word
send_bit(0x00);
send_bit(0x01);
send_bit(0x00);
send_bit(0x00);
send_bit(0x01);
send_bit(0x00);
send_bit(0x00);
send_bit(0x01);
send_bit(0x01);
PLL_Enable = 1;
PLL_Enable = 0;
for(j=0;j<12;j++) //Reference Counter Word
send_bit(0x00);
send_bit(0x01);
for(j=0;j<8;j++)
send_bit(0x00);
PLL_Enable = 1;
PLL_Enable = 0;
for(k=0;k<6;k++) //發送AB-Counter Word
send_bit(0x00);
send_bit(0x01);
for(k=0;k<3;k++)
send_bit(0x00);
send_bit(0x01);
send_bit(0x01);
send_bit(0x00);
send_bit(0x00);
send_bit(0x01);
send_bit(0x00);
send_bit(0x01);
send_bit(0x00);
send_bit(0x00);
send_bit(0x00);
send_bit(0x01);
PLL_Enable = 1;
}
//向PLL發送一位數據
void send_bit(uchar temp)
{
PLL_CLK=0;
if(temp)
PLL_Data=1;
else
PLL_Data=0;
PLL_CLK=1;
PLL_CLK=0;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -