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

📄 ration.c

📁 /*系统时钟采用 Fosc=7.373 定时器方式1的定时时间 Time=(65536-THTL)*2/Fosc,默认5ms 定时器1工作在16位
💻 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 + -