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