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