?? ration.c
字號:
//#define keildebug
//#define debug
#include <reg922.h>
#include <stdio.h>
#include "ration.h"
#include <sysdef.h>
#include <intrins.h>
#include "iap_lite.h"
/*系統時鐘采用 Fosc=7.373
定時器方式1的定時時間 Time=(65536-THTL)*2/Fosc,默認5ms
定時器1工作在16位,用作系統時鐘
定時器0工作在16位,作為定時開始采樣用,定時范圍為0.1ms(0xfe8f)-15ms(0x27fe),默認為1ms=0xf19a,可以通過設置命令改變
串行口波特率由內部產生,11.059MHz->BRGR1:0=0x0050=115200Bps,0x00b0=57600Bps
7.373MHz->BRGR1:0=0x0030=115200Bps,0x0070=57600Bps
*/
void main (void)
{
interrupt_disable;
io_init();
resetwatchdog();
TRIM |= 0x40;
timer0_init();
timer1_init();
uart_init();
serial_init();
setupwatchdog();
comtxdbufempty=1;
read_eeprom_para();
/* for(i=0;i<4;i++) combuf[i] = 0;
combuf[0] = 1;
set_led(combuf);*/
interrupt_enable;
#ifdef debug
send_string("Ration OK\r\n");
#endif
while(1)
{
if(comrxdtimeout) //接收超時
{
process_command();//處理用戶從串口輸入的命令
}
}
}
static void int0_isr (void) interrupt 0
{
}
//定時時間基準=CPU時鐘/2
static void timer0_isr (void) interrupt 1
{
}
static void int1_isr (void) interrupt 2
{
}
static void timer1_isr (void) interrupt 3
{
interrupt_disable;
timer1_5ms;
com_timeout_count++;
msec++;
msec5++;
if(com_timeout_count > COM_TIMEOUT)
{
comrxdtimeout = 1;
com_timeout_count = 0;
send_disable;
}
if(msec>99) //時間500ms
{
msec = 0;
RUNLED = ~RUNLED;
if(led_light_state==1)//正常點亮,定時熄滅
{
if(RUNLED) led_lighttime_count--;
if(led_lighttime_count==0)
{
led_light_state = 0;
close_led();
}
}
WFEED1 = 0xa5; //喂狗程序
WFEED2 = 0x5a;
}
/* if(led_light_state)//發光管處在點亮狀態
if(msec5>led_freq_const) //
{
msec5 = 0;
led_freq_state = ~led_freq_state;
if(led_freq_state) close_led();
else set_led(curr_led);
}*/
interrupt_enable;
}
static void service_serial(void) interrupt 4 using 1
{
interrupt_disable;
com_timeout_count = 0; //用于控制串口接收超時
comrxdtimeout = 0;
if(TI )
{
TI = 0;
if(comtxdread!=comtxdwrite)
{
// send_enable;
SBUF=comtxdbuf[comtxdread];
comtxdread++;
if(comtxdread==com_txd_buffer_size) comtxdread=0;
comtxdbufempty=0;
}else
{
comtxdbufempty=1;
// send_disable;
}
}
if (RI)
{
RI = 0;
comrxdbuf[comrxdwrite]=SBUF;
comrxdwrite++;
if(comrxdwrite==com_rxd_buffer_size)comrxdwrite=0;
}
interrupt_enable;
}
static void adc_isr(void) interrupt 14
{
}
//配置定時器timer0
//定時器0工作在16位,作為定時器用
//定時時間基準=CPU時鐘/2
void timer0_init(void)
{
timer0_stop;
timer0_mode_16bit;
timer0_priority_low;
// timer0_interrupt_enable;
timer0_interrupt_disable;
}
//配置定時器timer1
//定時器1工作在16位,用作系統時鐘
void timer1_init(void)
{
timer1_stop;
timer1_mode_16bit;
timer1_priority_low;
timer1_interrupt_enable;
timer1_5ms;
timer1_run;
}
void uart_init()
{
P1M1&=0xfc; //把TXD和RXD設置為準雙向
P1M2&=0xfc;
SSTAT=0; //雙緩沖禁止,狀態中斷、雙緩沖中斷、組合中斷禁止,接收和發送共用中斷號
BRGCON=0; //準備寫波特率常數
serial_baud_9600;
BRGCON=3; //啟動UART的波特率發生器
}
void serial_init(void)
{
// serial_uart_9; //sm0=1; sm1=1;
serial_uart_8;
// serial_multi_enable;
serial_receive_enable; //允許接收REN=1
TB8 = 0; //9位UART時發送的第九位
TI = 0; //中斷標志,手工清零
serial_interrupt_enable; //ES=1
IP0 |= 0x10; //
IP0H |= 0x10; //
}
void io_init(void)
{
P0M1 = 0x00;
P0M2 = 0x00;
P1M1 = 0x00;
P1M2 = 0x90;
send_disable;
SOE = 1;
SCLR = 0;
SCLK = 0;
SDATA = 0;
SLH = 0;
delay_us(10);
SLH = 1;
delay_us(10);
SCLR = 1;
delay_us(10);
SLH = 0;
delay_us(10);
SOE = 0;
}
void int1_init(void)
{
int1_mode_hightolow;
// int1_interrupt_enable;
int1_interrupt_disable;
int1_priority_high;
}
void resetwatchdog(void) //喂狗程序
{
interrupt_disable;
WFEED1 = 0xa5;
WFEED2 = 0x5a;
interrupt_enable;
}
void setupwatchdog(void) //設置看門狗
{
interrupt_disable;
WDL = 255;
WDCON = 0xc5; //定時1.31秒
WFEED1 = 0xa5;
WFEED2 = 0x5a;
interrupt_enable;
}
void delay_ms(uchar thedelay)
//延時子程序,延時時間單位為1毫秒,晶振使用7.737兆赫,芯片使用mcs51兼容芯片
//thedelay為需要延時的毫秒數,最大為255毫秒
{
uint i;
uchar j;
for(j=0;j<thedelay;j++)
for(i=0;i<671;i++);
}
void delay_10us(uchar thedelay)
//軟件延時,說明同上
{
uchar j;
uchar i;
for(j=thedelay;j>0;j--)
for(i=0;i<9;i++);
}
void delay_us(uchar thedelay)
//軟件延時,說明同上
{
uchar i;
for(i=thedelay;i!=0;i--);
// for(i=0;i<thedelay;i++);
}
uchar get_char() //從串口緩沖區讀取字符
{
uchar temp;
temp=comrxdbuf[comrxdread++];
if(comrxdread==com_rxd_buffer_size){comrxdread=0;}
return(temp);
}
void send_char(uchar ascii) //往串口發送一個字符
{
serial_interrupt_disable;
send_enable;
comtxdbuf[comtxdwrite++]=ascii;
if(comtxdwrite==com_txd_buffer_size) comtxdwrite=0;
if(comtxdbufempty)
{
TI=1;
}
serial_interrupt_enable;
}
void send_hex(uchar senddata)
//往串口發送hex碼 表示的一個字符,例如senddata=0x3A
//那么將向串口發送兩個字符'3','A',hex[]為轉換表,在前面有定義
{
uchar ch;
ch=senddata>>4;
send_char(hex[ch]);
ch=senddata&0x0F;
send_char(hex[ch]);
}
void send_string(uchar *string) //往串口發送一個字符串,字符串為存儲在程序空間,碰到0x00結束
{
while(*string!=0)
{
send_char(*string);
string++;
}
}
void process_command(void) //命令處理子程序,返回命令處理結果serialmsg
{
uchar i,bytecrc;
serialmsg=0;
comrxdtimeout = 0;
if(comrxdread != comrxdwrite) //串口數據的緩沖區中有數據,進入命令處理
{
i = 0;
bytecrc = 0;
while(comrxdread != comrxdwrite)
{
combuf[i] = get_char();
bytecrc ^= combuf[i];
i++;
}
if((combuf_header != HEADER_FLAG))
{
return;//幀標志錯誤
}
if((combuf_addr != BROADCAST_ADDR)&&(combuf_addr != node_addr))
{
return;//非本機地址
}
if(i != combuf_length+6) return;//長度錯誤
if(bytecrc!=HEADER_FLAG) //校驗錯誤
{
serialmsg = SERIAL_CRC_ERROR;
}else
{
serialmsg = combuf_cmd;
switch(serialmsg)
{
case CMD_SET_NODEADDR:
if(combuf_length != 1) {serialmsg=SERIAL_PARA_ERROR;break;}
if(!set_nodeaddr(combuf_para)) {serialmsg=SERIAL_EXE_ERROR;break;}//設置站點地址
break;
case CMD_SET_EEPROM:
if(combuf_length != 17) {serialmsg=SERIAL_PARA_ERROR;break;}
if(!set_eeprom(combuf_para,&combuf_para+1)) {serialmsg=SERIAL_EXE_ERROR;break;}
break;
case CMD_SET_LED:
led_lighttime_count = led_lighttime;
if(led_lighttime) led_light_state = 1;//正常點亮
else led_light_state = 2; //常亮
if(combuf_length != 8) {serialmsg=SERIAL_PARA_ERROR;break;}
if(set_led(&combuf_para)) break;
else if(set_led(&combuf_para)) break;
else if(set_led(&combuf_para)) break;
else if(set_led(&combuf_para)) break;
else if(set_led(&combuf_para)) break;
else {serialmsg=SERIAL_EXE_ERROR;break;}
break;
case CMD_SET_LIGHTTIME:
if(combuf_length != 2) {serialmsg=SERIAL_PARA_ERROR;break;}
if(!set_lighttime(&combuf_para)) {serialmsg=SERIAL_EXE_ERROR;break;}
break;
case CMD_SET_FREQ:
if(combuf_length != 1) {serialmsg=SERIAL_PARA_ERROR;break;}
if(!set_freq(combuf_para)) {serialmsg=SERIAL_EXE_ERROR;break;}
break;
case CMD_SET_DELAY:
if(combuf_length != 1) {serialmsg=SERIAL_PARA_ERROR;break;}
if(!FLASH_WriteByte(pulse_delay_addr,combuf_para)) {serialmsg=SERIAL_EXE_ERROR;break;}
break;
case CMD_QUERY_NODEADDR:
combuf_para = node_addr;
combuf_length = 1;
break;
case CMD_QUERY_LED:
combuf_length = 8;
for(i=0;i<8;i++) *((uchar *)&combuf_para+i) = curr_led[i];
break;
case CMD_QUERY_LIGHTTIME:
combuf_para = *(uchar *)&led_lighttime;
*((uchar *)&combuf_para+1) = *((uchar *)&led_lighttime+1);
combuf_length = 2;
break;
case CMD_QUERY_FREQ:
combuf_para = led_freq;
combuf_length = 1;
break;
case CMD_QUERY_DELAY:
combuf_para = pulse_delay;
combuf_length = 1;
break;
case CMD_QUERY_EEPROM:
i = combuf_para * 16 / 256;
FLASH_ReadNByte(EEPROM_start_addr+combuf_para*16,&combuf_para,16);
//if(combuf_para>15) {serialmsg=SERIAL_PARA_ERROR;break;}
combuf_length = 16;
break;
default:
serialmsg = SERIAL_CMD_ERROR;
break;
}//end of switch 返回數據準備完成,已經存入combuf
}//end of bytecrc 校驗正確
if(serialmsg) //以下處理返回的數據從串行口發送出去
{
if((serialmsg>0x80)||(serialmsg<0x10))
{
reply_cmd_message(); //通過串行口返回命令處理正確或錯誤信息
}else
{
reply_query_para(); //通過串行口返回查詢命令信息
}
}//end of serialmsg
}
}
void reply_cmd_message(void) //返回命令處理正確或錯誤信息
{
uchar temp;
combuf_addr = node_addr;
send_char(HEADER_FLAG);
send_char(combuf_addr);
send_char(serialmsg);
send_char(0); //length
temp = HEADER_FLAG ^ combuf_addr ^ serialmsg;
send_char(temp);
send_char(HEADER_FLAG);
}
void reply_query_para(void) //返回查詢參數
{
uchar i;
uchar temp;
combuf_addr = node_addr;
combuf_cmd = serialmsg;
temp = 0;
for(i=0;i<combuf_length+4;i++)
{
temp ^= combuf[i];
send_char(combuf[i]);
}
send_char(temp);
send_char(HEADER_FLAG);
}
bit set_nodeaddr(uchar para)
{
if(FLASH_WriteByte(node_addr_addr,para) == 0) return(0);
node_addr = para;
return(1);
}
bit set_lighttime(uchar *ptr)
{
*(uchar *)&led_lighttime = *ptr;
*((uchar *)&led_lighttime+1) = *(ptr+1);
if(FLASH_WriteNByte(led_lighttime_addr,ptr,2)==0) return(0);
return(1);
}
bit set_freq(uchar para)
{
if(para>100) para = 100;
if(FLASH_WriteByte(led_freq_addr,para)==0) return 0;
led_freq = para;
// if(led_freq) led_freq_const = 100 / led_freq;
return(1);
}
bit set_eeprom(uchar pageaddr,uchar *ptr)
{
if(FLASH_WriteNByte(EEPROM_start_addr+pageaddr*16,ptr,16)==0) return(0);
return(1);
}
void read_eeprom_para()
{
uchar i;
node_addr = FLASH_ReadByte(node_addr_addr);
for(i=0;i<8;i++) curr_led[i] = 0;
FLASH_ReadNByte(led_lighttime_addr,&led_lighttime,2);
led_freq = FLASH_ReadByte(led_freq_addr);
// if(led_freq) led_freq_const = 100 / led_freq;
}
bit set_led(uchar *ptr)
{
//#define delay() delay_us(20)
uchar i,j;
SOE = 1;
delay_us(pulse_delay);
SCLR = 0;
SLH = 0;
delay_us(pulse_delay);
SLH = 1;
delay_us(pulse_delay);
SCLR = 1;
SLH = 0;
delay_us(pulse_delay);
SDATA = 0;
SCLK = 0;
delay_us(pulse_delay);
for(i=0;i<8;i++) curr_led[i] = *ptr++;
for(i=2;i<8;i++)
{
for(j=0;j<8;j++)
{
curr_led[7-i] = _crol_(curr_led[7-i],1);
if((curr_led[7-i] & 1)==1) SDATA = 1;
else SDATA = 0;
delay_us(pulse_delay);
SCLK = 1;
delay_us(pulse_delay);
SCLK = 0;
}
}
SDATA = 0;
delay_us(pulse_delay);
SLH = 1;
delay_us(pulse_delay);
SLH = 0;
delay_us(pulse_delay);
for(i=2;i<8;i++)
{
for(j=0;j<8;j++)
{
curr_read_led[7-i] = _crol_(curr_read_led[7-i],1);
curr_read_led[7-i] &= 0xfe;
curr_read_led[7-i] |= SDATAIN;
delay_us(pulse_delay);
SCLK = 1;
delay_us(pulse_delay);
SCLK = 0;
}
}
for(i=0;i<6;i++)
if(curr_led[i]!= curr_read_led[i]) return(0);
SOE = 0;
return(1);
}
void close_led(void)
{
uchar i;
led_light_state = 0;
for(i=0;i<8;i++) curr_led[i] = 0;
SDATA = 0;
SCLK = 0;
SCLR = 0;
SLH = 0;
delay_10us(2);
SLH = 1;
delay_10us(2);
SCLR = 1;
SLH = 0;
delay_10us(2);
SDATA = 0;
SCLK = 0;
delay_10us(2);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -