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