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

📄 control.c

📁 震动模拟数据采集
💻 C
字号:
#include <c8051f060.h>                    // SFR declarations
#include <stdio.h>

unsigned int block;
unsigned int page;
unsigned char RECVDAT;
unsigned char abc;
unsigned char frame_cnt;
unsigned int bytecnt;
unsigned char time4;
unsigned char time3;
unsigned char time2;
unsigned char time1;
unsigned char k;
unsigned char inc;
unsigned char j;
unsigned char h;
unsigned int xdata * data write_ptr;
unsigned int xdata * data read_ptr;
bit time_flag;
bit frame_half1;
bit frame_half2;
bit s1;
bit s2;
bit wait;
bit f_write_status;
bit f_read_status;
unsigned int T0_count;
bit time1s_ok;
unsigned long flag;
bit UART0_RECV;

sbit we = P3^2;                       
sbit ale = P3^3;                  
sbit cle = P0^5;
sbit re = P3^0;
sbit rb = P3^4;
sbit wp = P3^1;

sbit rd = P3^7;  // 低电平表示读状态
sbit req = P3^6;
sbit JS=P3^5;

void SYSCLK_Init (void);
void UART0_Init(void);
void UART1_Init(void);
void PORT_Init(void);
void ADC2_Init(void);
void RAM_Init(void);
void Frame_Init(void);
void Timer4_Init(void);


sfr16 RCAP3=0xCA;
sfr16 TMR3=0xCC;
unsigned int T3reload;

sfr16 RCAP4=0xCA;
sfr16 TMR4=0xCC;
unsigned int T4reload;

void delays(unsigned int c)   //68ns
{  
   unsigned int i;
   for(i=0;i<c;i++);
}

void ADC2_ISR() interrupt 18
{
	AD2INT=0;
    
    if(s2==0 && s1==0)
	{   
	   AMX2SL=0x01; // 1通道送入AD转换
	   s2=0;s1=1;
     }
    else if(s2==0 && s1==1)
	{
	   AMX2SL=0x02; // 2通道送入AD转换
	   s2=1;
	 }
    else
	{
	   AMX2SL=0x00; // 0通道送入AD转换
       s2=0;s1=0;
	 }

	if(time_flag)  // 如果已打上时标
	 {  
	    if(k<14)          
		{ 
	 		*write_ptr=ADC2L;
            write_ptr++;
	     	*write_ptr=ADC2H;
			write_ptr++; // 地址推进
			k++;         // 振动数据计数加1
		 }
		else             // 振动数据的第29和30字节
		{
		    *write_ptr=ADC2L;
            write_ptr++;
	     	*write_ptr=ADC2H;
			write_ptr++; 
            write_ptr=write_ptr+14; // 连续推进14个地址	
			time_flag=0; // 表示时标未打上
			k=0;         // 将振动数据计数清零
		    time1=flag;
		    time2=flag>>8;
			time3=flag>>16;
			time4=flag>>24;
			
			if(frame_cnt==20)
		    {  
		  	   frame_half1=1;   // 前21帧已满
			   frame_cnt++;
		     }
	        else if(frame_cnt==41)
		    {
		  	    frame_half2=1;
			    frame_cnt=0;
			    write_ptr=4;     // RAM地址归0
 		     }
            else
		    {
		        frame_cnt++;
             } 

		 }	
	  }
     else //还没有打上时标
	 {
	   	*write_ptr=time4;
		write_ptr++;
		*write_ptr=time3;
		write_ptr++;
		*write_ptr=time2;
		write_ptr++;
		*write_ptr=time1;
		write_ptr++;
		*write_ptr=ADC2L;
        write_ptr++;
		*write_ptr=ADC2H;
        write_ptr++;
		k++;
        time_flag=1;   // 时标已打上
	  }	  

}

void Timer4_ISR() interrupt 16
{
	 TF4=0;
	 flag=flag+1;
}

void Timer0_ISR() interrupt 1
{
   if (T0_count==400)
   {
		 time1s_ok=1;  // 1s定时时间到
		 TH0= 0x70;    // 5ms 定时
	     TL0= 0x1f;  
		 T0_count=1; 
	}
    else
   {
        TH0= 0x70;    // 5ms 定时
	    TL0= 0x1f;  
        T0_count++;	
    }	
}

void UART0_ISR() interrupt 4
{    
     if(RI0)
	 {
	    RI0=0;
		RECVDAT=SBUF0;
		UART0_RECV=1; // 接收到惯组数据
      }        
}
	


void main (void)
{
	wp=1;
	ale=0;
	cle=0;
	re=1;
	we=1;

	page=0;
	block=0;
	bytecnt=0;
	abc=0x00;
	read_ptr=0;
	frame_half1=1;
	frame_half2=1;
	frame_cnt=0;
	time1=0x00;
	time4=0x00;
	time3=0x00;
	time2=0x00;
	k=0;
	j=0;
	h=0;
    s1=0;
	s2=0;
	wait=1;
	f_read_status=0; 
	f_write_status=0; 
	
    EA=0;
    WDTCN=0x07;
    WDTCN=0xDE;
    WDTCN=0xAD;
    EA=1;

    SFRPAGE = 0;
    RSTSRC = 0x04;                      // enable missing clock detector reset

    SYSCLK_Init();
	PORT_Init(); 
    Timer4_Init();
	RAM_Init();
	write_ptr=4;          // 写地址指针应该初始化在第3个地址上 
	ADC2_Init();
    UART0_Init();
    UART1_Init();
	
	time_flag=0;
	k=0;
	rd=1;                // 输出置为高阻态   
    delays(2);

   //--------------------------------------------
   //     擦除FLASH
   //--------------------------------------------
   while(1)
   {    
         while(wait==1 && time1s_ok==0)  //在1s的定时时间里
		 {
		 	if(UART0_RECV==1)    //如果串口0接收到数据
			{
				f_write_status=1;    // 写状态标志
				wait=0;              // 退出1s的定时等待
				SFRPAGE = 0; 
                TR0=0;  // 关闭定时器0
			    ET0=0;  // 定时器0中断关闭
			    SFRPAGE = UART0_PAGE;
				SCON0   = 0x40; // 8位UART,可变波特率;接收禁止,清除TI0和RI0
				ES0=0;  // 串口0中断禁止
				SFRPAGE = ADC2_PAGE;
	            EIE2 |=0x10; // 允许ADC2中断
		        SFRPAGE = TMR3_PAGE;
	            TR3=1;       // 开启定时器3
			 }
    	 }
		 
		 if (time1s_ok==1 && f_write_status==0)  // 1s定时时间到,且未处于写状态
         {
		     time1s_ok=0;    // 清除1s定时时间到的标志
		     if (rd==0)      // 读信号有效
			 {
			    f_read_status=1;// 置读状态标志
				wait=0;         // 退出1s的定时等待 
			    SFRPAGE = 0; 
		        TR0=0;  // 关闭定时器0
			    ET0=0;  // 定时器0中断关闭
				SFRPAGE = UART0_PAGE;
				SCON0   = 0x40; // 8位UART,可变波特率;接收禁止,清除TI0和RI0
				ES0=0;  // 串口0中断禁止
				SFRPAGE = ADC2_PAGE;
	            EIE2 &=0xEF; // 禁止ADC2中断
		        SFRPAGE = TMR3_PAGE;
	            TR3=0;       //关闭定时器3
             }			 
		 }


     while(f_write_status==1)
     {
		 while(block<100)
		 { 
		    
			cle=1;
		    P2=0x60;  
			we=0;
			we=1;
			cle=0;
			ale=1;
	        P2=((block%4)<<6);
			we=0;
		    we=1;
			P2=((block>>2)%256);
			we=0;
			we=1;
			P2=(block>>10);
		    we=0;
		    we=1;
			ale=0;
	        cle=1;
			P2=0xd0;
			we=0;
			we=1;
	        cle=0;
			rb=1;
	        delays(5);   // wait for 340ns;
			while(!rb);  // wait for rb=1
	   //--------------------------------------------
	   //     写FLASH
	   //-------------------------------------------
			page=0;
			while(page<64)
		    {
				 cle=1;
				 P2=0x80;  // command 0x80
				 we=0;
				 we=1;
				 cle=0;
				 ale=1;
				 P2=0x00;   // column address #1
				 we=0;
				 we=1;
	             P2=0x00;   // column address #2
				 we=0;
				 we=1;   
				 P2=((block%4)<<6)|page;
				 we=0;
				 we=1;
				 P2=((block>>2)%256);
				 we=0;
				 we=1;
				 P2=(block>>10);
				 we=0;
				 we=1;
				 ale=0;
				 read_ptr=0;    // 读指针归0
				 bytecnt=0;     // 字节计数归0
				 
		 //----------------------
		          while(frame_half1==0); 
	              while(bytecnt<1008)
				  { 
					   we=0; 
					   P2=*read_ptr;
					   we=1;
					   bytecnt++; 	  						   
	                   read_ptr++;
	               }
				  frame_half1=0;
                  bytecnt=0;     // 字节计数归0
				  while(frame_half2==0); 
	              while(bytecnt<1008)
				  { 
					   we=0; 
					   P2=*read_ptr;
					   we=1;
					   bytecnt++; 	  						   
	                   read_ptr++;
	                }
				 frame_half2=0;
		       //------------------------
					  cle=1;
					  P2=0x10;
					  we=0;
					  we=1;
		              cle=0;
					  rb=1;
					  delays(5);  // wait for 340ns;
					  while(!rb); // wait for rb=1;	
					  page++;
				 }
			    block++;
			 }	
		
      }
	  while(f_read_status==1)    // 为1时进入读模式
	  {
	      SFRPAGE = UART0_PAGE;
	      SCON0   = 0x40;         // 8位UART,可变波特率;接收禁止,清除TI0和RI0              
	      ES0=0;  
          SFRPAGE = UART1_PAGE; 
		  block=1;
	  	  while(block<100) 
	     {
		    page=0;
		    while(page<64)
		    {  
			   	 cle=1;
				 P2=0x00; 
				 we=0;
				 we=1;
				 cle=0;
				 ale=1;
				 P2=0x00;  // column address #1
				 we=0;
				 we=1;
				 P2=0x00;  	
				 we=0;   
				 we=1;    // column address #2
				 P2=((block%4)<<6)|page;
				 we=0;
				 we=1;	 
				 P2=((block>>2)%256);
				 we=0;
				 we=1;
				 P2=(block>>10);
				 we=0;
				 we=1;
				 ale=0;
				 cle=1;
				 P2=0x30;
				 we=0;
				 we=1;
				 cle=0;	
	             delays(5); // wait for 340ns;
				 rb=1;
	             while(!rb); // wait for rb=1;
				 P2=0xFF;
				 bytecnt=0;
			     while(bytecnt<2016  && req==0)	
		         {
					re=0;	
					SBUF1=P2;  // 从P2口读FLASH数据  通过串口1发送
					re=1;	
					while(!TI1);
					TI1=0;	
		        	bytecnt++;	
				  }
				page++;							
			}
			block++; 
		 }  

		 }
   }

}
//-----------------------------------------------------------------------------

// Configure the Crossbar and GPIO ports


void PORT_Init (void)
{
	char old_SFRPAGE = SFRPAGE;
	SFRPAGE = CONFIG_PAGE;              // Switch to configuration page
	XBR0    = 0x04;      // 使能串口0               
	XBR1    = 0x00;				
	XBR2    = 0x44;      // 使能串口1 ,开启交叉开关
	P0MDOUT = 0xFF;    //  push-pull 输出
	P1MDIN  = 0xF8;	   //  P1口低3位为模拟输入,
	P1MDOUT = 0x00;    //  P1口输出保持默认为开漏输出	
    P1=0xFF;		   //  输出置为高阻态
	P2MDIN  = 0xFF;	  // P2口为数字输入模式		
	P2MDOUT = 0xFF;	 //  P2口输出push-pull	
	P3MDOUT = 0xFF; //   P3口输出保持默认为开漏输出
	SFRPAGE = old_SFRPAGE;           // restore SFRPAGE
}

void UART0_Init(void)
{
    char old_SFRPAGE = SFRPAGE;
	SFRPAGE = UART0_PAGE;              
	SCON0   = 0x50;         // 8位UART,可变波特率;接收允许,清除TI0和RI0
	SSTA0=0x15;
	ES0=1;                 // 串口0中断
	
                                       
	SFRPAGE = TMR2_PAGE;       // 定时器2作为串口0的波特率发生器        
    
	TMR2CF = 0x08;                     
	RCAP2L=0xff;       //921.6kbps           
    RCAP2H=0xFF;
	TMR2L=0xff;                      
	TMR2H=0xFF;
	TR2=1;  

	SFRPAGE = old_SFRPAGE;              
}

void UART1_Init(void)
{
    char old_SFRPAGE = SFRPAGE;
	SFRPAGE = UART1_PAGE;              
	SCON1   = 0x40;                      // TI和RI清0 
                                       
	SFRPAGE = 0;                        // 切换到Timer1 page  Switch to Timer 1 page,the same to Timer 2 page
    
    TMOD   = 0x21;                      // TMOD: timer 1, mode 2, 8-bit reload
	                                    //       timer 0, mode 1, 16-bit 
	CKCON  = 0x18;                      // sysclock as T1 time base 
	                                    // sysclock as T0 time base                   
	TH1    = 0xFE;                      // 0xfe,3.6864Mbps  
	TL1    = TH1;
	TR1    = 1;    // start Timer1
	                     
	TH0= 0x70;    // 5ms 定时
	TL0= 0x1f; 
	TR0= 1;// start Timer0 
	ET0= 1;// timer0 interrupt enable
	PT0= 0; //T0优先级为低优先级
	SFRPAGE = old_SFRPAGE;              // restore SFRPAGE
}


void Timer4_Init()
{
	char old_SFRPAGE = SFRPAGE;                             
	SFRPAGE = 2;
	TMR4CN=0x04;    // 开启T4,清除TF4标志
	TMR4CF=0x08;    // T4时钟选择系统时钟
	T4reload=1475;// 14745600/10000=1474.56,10k
	RCAP4=~T4reload+1;
	TMR4=0xffff;  // 立即装载
	EIE2 |= 0x04;  // 开启T4中断
    EIP2 |= 0x04;  // 优先级为高
    SFRPAGE = old_SFRPAGE;   // restore SFRPAGE	
}

void SYSCLK_Init (void)
{
	char old_SFRPAGE = SFRPAGE;
	int i;                                 
	SFRPAGE = CONFIG_PAGE;            
	OSCXCN = 0x67;                      // 外部晶振模式                                  
	for (i=0; i <5000; i++) ;           // XTLVLD blanking interval (>1ms)
//	while (!(OSCXCN & 0x80)) ;          // Wait for crystal osc. to settle
	CLKSEL = 0x01;                      // 采用外部时钟
	OSCICN = 0x00;                      // 内部晶振禁止
	SFRPAGE = old_SFRPAGE;              // restore SFRPAGE
}


void ADC2_Init()
{
   char old_SFRPAGE = SFRPAGE;
   SFRPAGE = ADC2_PAGE;
   ADC2CF=0x58; // 2M 的转换速度
   ADC2CN=0xc4; // 使能ADC2,低功耗跟踪模式,T3溢出启动ADC2转换
   AMX2CF=0x00; // 全部保持单端输入
   AMX2SL=0x00; // 0通道送入AD转换
   REF2CN=0x0B; // ADC2电压基准取自AV+,BIASE=1.偏压产生器工作,REFBE=1,内部参考电平工作并输出到VREF引脚
   //EIE2 |=0x10; // 允许ADC2中断

   SFRPAGE = TMR3_PAGE;
   TMR3CN=0x04; // 禁止T3,清除TF3
   TMR3CF=0x08; // T3时钟选择系统时钟 
   T3reload=983;// 14745600/15000=983.04,取为983,
   RCAP3=~T3reload+1;
   TMR3=0xffff;  // 立即装载  
   //TR3=1;       // 开启定时器3
   SFRPAGE = old_SFRPAGE; 
}

void Frame_Init()
{
	unsigned char m;

	*write_ptr=0x14;
	write_ptr++;
    *write_ptr=0x6F; 
    write_ptr++;
	for(m=0;m<46;m++)
	{
		*write_ptr=0x00;
	    write_ptr++;	  
	 }
}


void RAM_Init()
{

    unsigned char n;
	write_ptr=0;
	for(n=0;n<42;n++)
	{
	    Frame_Init();
     }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -