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

📄 main.c

📁 医疗设备中激光手术台程序源代码
💻 C
字号:
/*******************************************************************************
说明:
	1、UART接收数据格式:1:字节数,2,命令,具体字节,例如:5,0XA5,1,2,3



*******************************************************************************/





#include	<pic.h>
//#define DEBUG
#ifdef DEBUG
	__CONFIG (0x373A);//(0x3F3E);//
#else
	__CONFIG (0x3f3A);//(0x3F3E);//
#endif
__IDLOC(0x0702);

#include "public.h"
#include "uart.h"
#include "pwm.h"
#include "ad.h"

extern struct{
unsigned: 2;
unsigned ADGO:1;
unsigned  ADCS: 3;
unsigned :2;
}ADC @0x1f;


void init_ram(void)
{
	FSR=0x20;RP0=0;IRP=0;
	for (CCPR2H=0x60;--CCPR2H;)
	{ 	asm("clrf 0");
		++FSR;	
	}
	FSR=0xa0;
	for(CCPR2H=0x58;--CCPR2H;){
		asm("clrf 0");
		++FSR; 
	}
	send_cnt = 0;
	b_rec_ok = FALSE;
	rec_cnt=0;
	buzz_off();


	
	ccpr2_pulse_time = MIN_PULSE_TIME;	// 10us
	
	ccpr2_freq_cnt = MIN_FREQ_CNT;	// 50000
	ccpr2_freq = MIN_FREQ;
}

void init_cpu(void)
{
	TRISA=0xeb;	//RA0,1,2为AD检测输入脚,RA2为EEPROM CS
	TRISB=0xff;
	TRISD=0;   
	TRISC=0x90; //10010000   RC1,RC2为PWM输出
	TRISE=0;
	OPTION=5;  
	INTCON=0x40;
	
	ADCON0=0x99;	// FOSC/32, chanel 3
	ADCON1=0x84;	// 

	TXSTA=0x26;//0x46;	// slave mode,8 bit,异步通讯
	RCSTA=0x80;//0xc0;	// 不连续

	PIE1=0x20;//0x30;	// 系统只有三个中断,即UART 的RX TX 和 TIMER0
	SPBRG=51;	// 9600波特率
	TMR0=256-5000/(64/2);//5ms/	CCP2CON=0x0;	

	PR2=0xF9;	// TMR2值,用于设置PWM Timer2 Period
	CCP1CON=0x0f;	// ccp1 为pwm mode, CCP1CON<5:4>为00,分辨率为8位
	T2CON=4;	// 预分频为256:1,Postscale为1:1,TMR2使能,1k



	T1CON=0x10;	//0x30// 预分频为1:2,Internal clock
	PIR1=0;		//  所有中断标志为0
	
	TMR1ON=0;EN_TIMER1();T1CON=0x11;b_end = 0;	// 定时器TMR1设置	
	uart_rec_start();//CREN=1;		// Enables continuous receive, UART
	ei();
}



void init_all(void)
{

	init_cpu();
	init_ram();
	



}

void delay_ms(Word i)
{
	unsigned char j;
	do 
	{
		j=250;
		do 	
		{ 
			nop();nop();nop();nop();
		} while(--j);
		CLRWDT();
	} while(--i);
}

void self_check(void)
{
	if(PORTB&0x3f!=0x3b)
		err_code = ERR_SELF_CHECK;
			
}

void user_operate(void)
{
	
}	

void debug_mode(void)
{
	
}

void user_mode(void)
{
	/* 检测水温,水位,流量,光闸开关 */
	if(p_water_level)
		err_code = ERR_FLOWL;
	if(p_temp)
		err_code = ERR_TEMP;
	if(p_flow)
		err_code = ERR_WL;
	if(p_foot)
		err_code = ERR_FOOT;
	if(p_shut_k)
		err_code = ERR_SHUT_OFF;
	
	/* 电源上电 ,此时检测水流量(35)脚为低,延时10秒检测,(33)(34)(36)(37)维持高 */	
	power_on();
	delay_ms(10000);
	if( PORTB&0x1f != 0x1b)	
		err_code = ERR_SHUIBONG;
	self_check();	// 自检
	user_operate();
	
		
}	

void cmd_deal(void)
{
	unsigned int buf1;
	unsigned long long_buf;
	if(b_rec_ok)
	{
		b_rec_ok = FALSE;
		switch(cmd_type)	// rec_data[1]
		{
			case CHANGE_CHANEL:			// 00
				ADC.ADCS=rec_data[2];	// 改变AD通道命令是第二个字节,具体通道是第三个字节
				break;
			case PWM_AUTO_ADD_ONE:		// 02
				b_pwm_auto_add=TRUE;
				break;		
			case CLR_PWM_AUTO_ADD_ONE:			// 03
				b_pwm_auto_add = FALSE;
				break;
			case PWM_SET_NUM:			// 04
				pwm_data = rec_data[2]*256+rec_data[3];
				break;	
			case PWM_SET:			// 05,脉冲模式设置
				switch(rec_data[2])	// switch(rec_data[2])
				{
					case MODE0:		// 00
						CCP2CON=0;
						p_runi=HIGH;
					
						break;
					case MODE1:		// 01
						CCP2CON=0;
						p_runi=LOW;
						break;
					case MODE2:		// 02
						break;
					case MODE3:		// 03
						switch(rec_data[3])
						{
							case FREQ_SET:	// 00
								buf1=rec_data[4]*128;
								long_buf=1000000;
								buf1=long_buf/buf1-1;
								PR2=buf1&0x00ff;
								break;
							case PULSE_TIME_SET:	// 01
							
								break;
							case T2CON_SET:	// 02
								T2CON = rec_data[4];
								break;	
							case PR2_SET:	//03 PR2频率设置
								PR2 = rec_data[4];
								break;
							case PR2_AUTO_ADD_ONE:	// 04
								PR2++;
								break;
							case PULSE_AUTO_ADD_ONE:	// 05
								pwm_data++;
								break;
							default:
								break;	
						}
					
						break;
					case MODE4:		// 04
						break;
					case MODE5:		// 05
						break;


					default:
						break;
				}// end switch(rec_data[2])
			case RUNI_SET:		// 06,    cmd type is 05 06 00/01 + cnt 
				switch(rec_data[2])
				{
					case RUNI_PUSLE_SET:	// 00
						ccpr2_pulse_time = rec_data[3]*256+rec_data[4];
						if(ccpr2_pulse_time>=ccpr2_freq_cnt)	// 高电平时间大于周期则出错
						{
							err_code = ERR_PULSE_OVER_CIRCLE;
							b_end = 1;
						}
						else
						{
							TMR1ON=1;EN_TIMER1();b_end = 0;
						}
						break;
					case RUNI_FREQ_SET:		// 01
						ccpr2_freq = rec_data[3]*256 + rec_data[4];	// 接收ccpr2的频率设定
						if(ccpr2_freq>MAX_FREQ)		// RUNI频率不得超过500Hz
						{
							err_code = ERR_MAX_FREQ;
							b_end = 1;				// 在定时器1中断里回关掉输出的 
							break;
						}
						else
						{
							TMR1ON=1;EN_TIMER1();b_end = 0;
						}
						if(ccpr2_freq<MIN_FREQ)	// RUN3频率不得低于20Hz
						{
							err_code = ERR_MIN_FREQ;
							b_end = 1;
							break;
						}
						else
						{
							TMR1ON=1;EN_TIMER1();b_end = 0;
						}

						ccpr2_freq_cnt = 1000000/ccpr2_freq;
						break;
					default:
						break;
					}
			default:
				break;
		}//end switch(cmd_type)
	}	
}

void main(void)
{
	init_all();
	
	uart_send_start();
	pwm_data = 0;
	while(1) 
	{
		
		cmd_deal();
		if(b_pwm_auto_add)
			pwm_data++;
		pwm_out(pwm_data);
#if 1		
		ad_test();
		uart_send_byte((Byte)((pwm_data>>8)&0x00ff));
#endif 

#if 0		
		uart_send_byte(0xaa);
		uart_send_byte(0xaa);
		uart_send_byte((Byte)((ccpr2_freq>>8)&0x00ff));
		uart_send_byte((Byte)((ccpr2_freq)&0x00ff));
		
		uart_send_byte((Byte)((ccpr2_freq_cnt>>8)&0x00ff));
		uart_send_byte((Byte)((ccpr2_freq_cnt)&0x00ff));
		
		uart_send_byte((Byte)((ccpr2_pulse_time>>8)&0x00ff));
		uart_send_byte((Byte)((ccpr2_pulse_time)&0x00ff));
		uart_send_byte(b_end);
#endif
		nop();
		nop();
		nop();
		CLRWDT();
		delay_ms(200);	
	}


//	if(p_mode)	// 高电位进入用户模式,低电位进入调试模式,
//		debug_mode();	// 调试模式
//	else
//		user_mode();	// 用户模式
}




//////// 中断程序 //////////
void interrupt InterC(void)
{  
	bOptic = 1;
	if(TMR1IF)  
	{  //定时器1的中断程式
		TMR1IF=0;

		TMR1T=(0xffff-ccpr2_freq_cnt);
		CCP2IF=0;
		if(b_end)
		{ 
			TMR1IE=0;CCP2CON=0;NOP();
			TMR1ON=0;p_runi=0;
		}
		else
		{
			if(bOptic) 
			{//3
		  			CCPR2T=TMR1T+8;
					CCP2CON=8;
					while(!CCP2IF) continue;
					CCP2IF=0; CCPR2T+=ccpr2_pulse_time;
					CCP2CON=9;
			} //3
		}
	} //定时器1的中断程式
	
	if(RCIF)
	{ 
		if(FERR||OERR)	// 如果接收出错,则出错处理
		{
			CREN=0;	
			RCREG;RCREG;
			b_rec_ok = FALSE;
			CREN=1;
		}
		else 	// 数据格式:1:字节数,2,命令,具体字节,例如:5,0XA5,1,2,3
		{			
			rec_data[rec_cnt++] = RCREG;
	
			if(rec_data[0]!=0 && rec_data[0]==rec_cnt)	// 接收完毕
			//if(rec_cnt==SEND_CNT)
			{
				b_rec_ok = TRUE;
				rec_cnt = 0;
			}
			else
				b_rec_ok = FALSE;
		}
	}
	
}




⌨️ 快捷键说明

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