⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mcu020.c

📁 数字锁相环控制产生信号程序详解以及控制字计算方法
💻 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 + -