?? pic2448.c
字號:
void ini_hardware(void) // 硬件初始化,相應設置值用英文說明,不明請參考數據手冊
{
TRISA =0b00111111; /* PORT_A as input */
TRISB =0b11001000; /* PORT_B as output(except PGD/C/M) */
TRISC =0b11000000; /* PORT_C as output(except TX,RX) */
TRISD =0b11111111; /* PORT_D as input */
TRISE =0b00000111; /* PORT_E as input */
OPTION = 0b11010111; /* TMR0 source CLKOUT, PSA=1:256 assigned to TMR0 */
TMR0 = 0; /* Clear TMR0 & Prescaler */
OPTION = 0b11011111; /* PSA=1:128 assigned to WDT */
CLRWDT(); /* Clears WDT */
OPTION = 0b10001111; /* PORT_B disable pull_ups, TMR0 source CLKOUT, PSA=1:128 assigned to WDT */
T1CON = 0b00110000; /* 1:8 Prescale,internal Fosc/4 clock, stop TMR1 */
TMR1L = (uint)(-17280)%256; /* 11.059M Fosc and 1:8 Prescale, T=50 ms / 2.8935708472737137173342978569491 us */
TMR1H = (uint)(-17280)/256;
TMR1ON = 1; /* restart TMR1 */
T2CON = 0b00000100; /* set 1:1 Prescaler,1:1 Postscale,Timer2 is on */
PR2 = 0xFF;
CCP1CON = 0b00001111; /* ENABLE PWM */
CCP2CON = 0b00001111;
SPBRG=0x08; /* set bps 19200 , 11.059M OSC and low BRG */
TXSTA=0b01000001;
RCSTA=0b11011000;
INTCON = 0b01000000; /* disable GIE,enable PE INT */
PIE1 =0b00100001; /* enable rx,T1 INT, disable tx INT,prevent TXREG empty cause TXIF interrupt */
PIE2 =0b00000000;
ADDEN=1;
TXEN=1;
}
uchar check_rx_frame() // 檢查接收幀是否完整
{
uchar i=0;
uint sum=0;
for(i=0;i<=3;i++) //檢驗加法和
sum+=sio_rx_buf[i];
id_addr=ADR_ID?0x41:0x47; //獲得模塊組地址
if(sum!=(sio_rx_buf[4]*256+sio_rx_buf[5]))
return 0;
return 1;
}
uchar process_rx_frame() // 接收幀處理,相關命令參照通信協議說明
{
rct_addr=sio_rx_buf[0];
cpu3=sio_rx_buf[2]*256+sio_rx_buf[3];
switch(sio_rx_buf[1])
{
case 0x11: // 查詢
{
sio_tx_buf[1]=0x11;
if((rct_addr-id_addr>=0)&&(rct_addr-id_addr<=5)) //若是本組模塊地址
{
sio_tx_buf[2]=(rct_cur[rct_addr-id_addr]*10)/256; //模塊電流和溫度
sio_tx_buf[3]=(rct_cur[rct_addr-id_addr]*10)%256;
sio_tx_buf[4]=0;
sio_tx_buf[5]=0;
return 1; //進入應答分支
}
else
return 0;
}
case 0x12: // 查詢
{
sio_tx_buf[1]=0x12;
if((rct_addr-id_addr>=0)&&(rct_addr-id_addr<=5)) //若是本組模塊地址
{
sio_tx_buf[2]=0; //交流輸入電壓和模塊電壓
sio_tx_buf[3]=0;
sio_tx_buf[4]=0;
sio_tx_buf[5]=0;
return 1; //進入應答分支
}
else
return 0;
}
case 0x80: // 設限流 模塊充電限流值(2字節)
{
if(rct_addr==0x40)
{
switch (cur_type)
{
case 15: // 15Bor10D
{
cur_pc = (cpu3*1023) / CUR_MAX_15B; // 轉換成PWM值
break;
}
case 20: // 20D
{
cur_pc = (cpu3*1023) / CUR_MAX_20D; // 轉換成PWM值
break;
}
case 25: // 25D
{
cur_pc = (cpu3*1023) / CUR_MAX_25D; // 轉換成PWM值
break;
}
case 30: // 30Dor40D
{
cur_pc = (cpu3*1023) / CUR_MAX_30D; // 轉換成PWM值
break;
}
default: // 若模塊配置未完成,則充電限流值采用默認值
break;
}// end of switch (rct_type)
cur_lmt=(cur_pc<=cur_nc)?cur_pc:cur_nc;
}
return 0;
}
case 0x81:// 整流器開機 // 設開關機
{
if(rct_addr==0x40)
{
if((sio_rx_buf[2]==0x0f)&&(sio_rx_buf[3]==0x0f))rct_pow=0xff;
}
else
{
if((sio_rx_buf[2]==0x0f)&&(sio_rx_buf[3]==0x0f))
{
if((rct_addr-id_addr>=0)&&(rct_addr-id_addr<=5)) //若是本組模塊地址
rct_pow|=(1<<(rct_addr-id_addr));
}
}
return 0;
}
case 0x82:// 整流器關機 // 設開關機
{
if(rct_addr==0x40)
{
if((sio_rx_buf[2]==0xf0)&&(sio_rx_buf[3]==0xf0))rct_pow=0x00;
}
else
{
if((sio_rx_buf[2]==0xf0)&&(sio_rx_buf[3]==0xf0))
{
if((rct_addr-id_addr>=0)&&(rct_addr-id_addr<=5)) //若是本組模塊地址
rct_pow&=~(1<<(rct_addr-id_addr));
}
}
return 0;
}
case 0x83: // 整流器浮充
{
if(rct_addr==0x40)
{
if((sio_rx_buf[2]==0x0f)&&(sio_rx_buf[3]==0x0f))
change=0;
}
return 0;
}
case 0x84: // 整流器均充
{
if(rct_addr==0x40)
{
if((sio_rx_buf[2]==0xf0)&&(sio_rx_buf[3]==0xf0))
change=1;
}
return 0;
}
case 0x90: //模塊浮充電壓設置值
{
if (cpu3 <= DCV_MID) // 若為24V系統
DC_F = (cpu3*1023) / DCV_MAX_24V; // 轉換成PWM值
else // 若為48V系統
DC_F = (cpu3*1023) / DCV_MAX_48V;
vol_set=change?DC_J:DC_F;
return 0;
}
case 0x91: //模塊均充電壓設置值
{
if (cpu3 <= DCV_MID) // 若為24V系統
DC_J = (cpu3*1023) / DCV_MAX_24V; // 轉換成PWM值
else // 若為48V系統
DC_J = (cpu3*1023) / DCV_MAX_48V;
vol_set=change?DC_J:DC_F;
return 0;
}
case 0x96: // 設限流 模塊充電限流值(2字節)最大
{
if(rct_addr==0x40)
{
flag_cfg = 1; // 模塊類型配置完成
if(cpu3 <= 1600)cur_type = 15; // 配置模塊電流值類型
else if(cpu3 <= 2100)cur_type = 20;
else if(cpu3 <= 2600)cur_type = 25;
else cur_type = 30;
switch (cur_type)
{
case 15: // 15Bor10B
{
cur_nc = (cpu3*1023) / CUR_MAX_15B;
break;
}
case 20: // 20D
{
cur_nc = (cpu3*1023) / CUR_MAX_20D;
break;
}
case 25: // 25D
{
cur_nc = (cpu3*1023) / CUR_MAX_25D;
break;
}
case 30: // 30Dor40D
{
cur_nc = (cpu3*1023) / CUR_MAX_30D;
break;
}
default:
{
flag_cfg = 0; // 需重新配置模塊類型
break;
}
}
cur_lmt=(cur_pc<=cur_nc)?cur_pc:cur_nc;
}
return 0;
}
default:
{
return 0;
}
}
}
void send_tx_frame() // 發送返回信息幀
{
uchar i=0;
uint sum=0;
if(bittest(rct_no,rct_addr-id_addr)==0x00)
return ;
//構造發送信息幀
sio_tx_buf[0]=rct_addr;
sio_tx_buf[6]=0;
sio_tx_buf[6]|= ((flag_cfg == 0) || (cur_lmt > 1023)) ? 0x40 : 0x00; // 若需要配置模塊類型, 或者模塊輸出電流超界, 則發送設置值bit=1
//if((rct_addr-id_addr>=0)&&(rct_addr-id_addr<=5)) //若是本組模塊地址
sio_tx_buf[6]|=((bittest(~rct_pow,rct_addr-id_addr))<<0);
sio_tx_buf[6]|=(cur_nc>=1023)?0x40:0x00;
sio_tx_buf[7]=0;
//if((rct_addr-id_addr>=0)&&(rct_addr-id_addr<=5)) //若是本組模塊地址
//sio_tx_buf[7]|=(rct_cur[rct_addr-id_addr]<5)?0x80:0x00;
sio_tx_buf[7]|=((bittest(rct_warn,rct_addr-id_addr))<<7);
if(bittest(~rct_pow,(rct_addr-id_addr)))sio_tx_buf[7]=0;
for(i=0;i<SIO_TX_LEN-2;i++) //校驗和
sum+=sio_tx_buf[i];
sio_tx_buf[8]=sum/256;
sio_tx_buf[9]=sum%256;
//構造完畢
EN485 = 0;
sio_tx_num = 0;
TX9D=1;
TXIE = 1;
TXREG = sio_tx_buf[0]; //start send frame 啟動發送
sio_rx_num = 0; //restart receive 重啟接收
}
void interrupt IntService(void) //中斷處理子程序
{
if(TMR1IF) //50 ms 中斷處理
{
TMR1IF=0;
TMR1ON=0;
TMR1L = (uint)(-17280)%256; //11.059M Fosc and 1:8 Prescale, T=50 ms / 2.8935708472737137173342978569491 us
TMR1H = (uint)(-17280)/256;
TMR1ON=1;
ticks++;
if(ticks > 19)
{
ticks = 0;
secs++;
norx_secs++;
if(norx_secs > 250)
norx_secs = 250;
if(secs>=59)
{
secs=0;
}
}
}
if((!EN485) && TXIF) //發送中斷處理
{
sio_tx_num++;
TX9D=0;
if(sio_tx_num <SIO_TX_LEN+1) //send 1 more invalid byte <<echo_info.sio_tx_buf[SIO_TX_LEN]>>
//insure last TSR send over
{
TXREG = sio_tx_buf[sio_tx_num];
}
else
{
sio_tx_num=SIO_TX_LEN+1;
TXIE = 0;
EN485 = 1;
}
}
while(RCIF) //接收中斷處理
{
img_RCSTA = RCSTA;
img_RCREG = RCREG;
if(img_RCSTA & 0x04) //frame error
{
continue;
}
if(img_RCSTA & 0x02) //receive over_run error
{
CREN = 0;
_NOP_;
CREN = 1; //reset CREN
continue;
}
if(sio_rx_num) // 已經開始接收
{
sio_rx_buf[sio_rx_num] = img_RCREG;
sio_rx_num++;
if(sio_rx_num >= SIO_RX_LEN)
{ADDEN=1;
sio_rx_num = 0;
if(check_rx_frame())
{
norx_secs = 0;
if(process_rx_frame())
{
send_tx_frame();
}
}
}
}
else // 未開始接收
{
if((img_RCREG&0xC0)==0x40) // 收到“頭“標志
{
sio_rx_buf[0] =img_RCREG;
sio_rx_num = 1;
ADDEN=0;
}
}
}
return;
}
void main()
{
//uchar t;
//uint i,j;
static uchar turn_ticks;
//get_warn_status();
di();
ini_hardware();
EN485 = 1; // set 485 receive
RLSW = 0; // RELAY OFF 繼電器脫開,(信號不穩定前,不輸出)
rct_pow = 0xff;
pow_process(); // all rect power on 全開機
vol_set = 750;
pwm_vol_set = 750; // out vol 46V 設輸出46V
cur_lmt = 1023;
pwm_cur_lmt = 1023; // no out cur limit 無限流
set_pwm_out();
delay(100); // 延時,使控制信號穩定
ticks = 0;
secs = 0;
norx_secs = 0;
sio_rx_num = 0;
sio_tx_num = SIO_TX_LEN + 1;
ei();
RLSW = 1; // RELAY ON 繼電器閉合,(信號穩定,輸出)
while(1) // 主循環
{
CLRWDT(); // 清看門狗
start_measure(); // 測量模擬量
pow_process(); // 處理關機
get_warn_status(); // 測量模塊狀態
if(norx_secs > 10) // 無通信超過10秒,繼電器脫開,模塊電壓,電流均不控
RLSW = 0; // RELAY OFF
else
RLSW = 1; // RELAY ON
if(norx_secs >= 240)
{
vol_set=900;
cur_lmt=1023;
rct_pow=0xff;
}
if(turn_ticks != ticks) // 每過50ms
{
turn_ticks = ticks;
calcu_vol_set_pwm(); // 計算調壓值
calcu_cur_lmt_pwm();
_NOP_;
set_pwm_out(); // 調整PWM輸出
}
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -