📄 hzmmisub18.c
字号:
}
}
//显示小ASCII串
void str_sasc(byte row,byte col,byte *str)
{
byte q,j;
word lram;
lram=row*20+col;
for(;*str;)
{
if(lram>=76*20)
return;
q=(*str++);
if(q==13)
{
lram+=20*8;
continue;
}
lib_addr.l=q*8l+0x100l;
lib_addr_out();
for(j=0;j<8;j++)
{
disp_order_data(0x0a,(byte)lram);
disp_order_data(0x0b,(byte)(lram/256));
disp_order(0x0c);
lib_data();
PORTC++;
lram+=20;
}
lram=lram-20*8+1;
if((lram%20)==0)
lram+=20*7;
}
}
//居中显示汉字串
void mediacy_hz(byte row,byte* str)
{
byte i;
i=strlen(str);
if(i>=20)
str_hz(row,0,str);
else
str_hz(row,10-i/2,str);
}
//让DS1302时钟芯片写使能
void time_wr_en(void)
{
byte i;
byte addr;
for(i=0;i<((T_RELOAD+50)/2000);i++)
PORTB|=RST_TM;//让DS1302操作使能,并作适当延时
addr=0x8f;//0x81为读
for(i=0;i<8;i++)
{
if(addr&1)
PORTB|=SPI_MI;
else
PORTB&=~SPI_MI;
PORTB|=SPI_SCK;
PORTB&=~SPI_SCK;
addr>>=1;
}
PORTB&=~SPI_MI;
DDRB&=~SPI_MI;//置spi_mosi为输入
for(addr=0,i=0;i<8;i++)
{
addr>>=1;
if(PINB&SPI_MI)
addr|=0x80;
PORTB|=SPI_SCK;
PORTB&=~SPI_SCK;
}
DDRB|=SPI_MI;
for(i=0;i<((T_RELOAD+50)/2000);i++)
PORTB&=~RST_TM;
if(addr==0)//如果已是写使能状态,则不用再设置了
return;
for(i=0;i<((T_RELOAD+50)/2000);i++)
PORTB|=RST_TM;//让DS1302操作使能,并作适当延时
addr=0x8e;//0x80为写
for(i=0;i<8;i++)
{
if(addr&1)
PORTB|=SPI_MI;
else
PORTB&=~SPI_MI;
PORTB|=SPI_SCK;
PORTB&=~SPI_SCK;
addr>>=1;
}
PORTB&=~SPI_MI;
for(i=0;i<8;i++)
{
PORTB|=SPI_SCK;
PORTB&=~SPI_SCK;
}
for(i=0;i<((T_RELOAD+50)/2000);i++)
PORTB&=~RST_TM;
}
//对DS1302秒读
byte time_sec_rd(void)
{
byte i;
byte addr;
for(i=0;i<((T_RELOAD+50)/2000);i++)
PORTB|=RST_TM;//让DS1302操作使能,并作适当延时
addr=0x81;//0x81为读
for(i=0;i<8;i++)
{
if(addr&1)
PORTB|=SPI_MI;
else
PORTB&=~SPI_MI;
PORTB|=SPI_SCK;
PORTB&=~SPI_SCK;
addr>>=1;
}
PORTB|=SPI_MI;
DDRB&=~SPI_MI;//置spi_mosi为输入
for(addr=0,i=0;i<8;i++)
{
addr>>=1;
if(PINB&SPI_MI)
addr|=0x80;
PORTB|=SPI_SCK;
PORTB&=~SPI_SCK;
}
DDRB|=SPI_MI;
for(i=0;i<((T_RELOAD+50)/2000);i++)
PORTB&=~RST_TM;
return addr;
}
//对DS1302串读
//读取当前时间,依序为:秒分时日月年
void time_str_rd(byte *tdata)
{
byte i,j;
byte addr;
for(i=0;i<((T_RELOAD+50)/2000);i++)
PORTB|=RST_TM;//让DS1302操作使能,并作适当延时
addr=(31<<1)|0x81;//0x81为读
for(i=0;i<8;i++)
{
if(addr&1)
PORTB|=SPI_MI;
else
PORTB&=~SPI_MI;
PORTB|=SPI_SCK;
PORTB&=~SPI_SCK;
addr>>=1;
}
PORTB|=SPI_MI;
DDRB&=~SPI_MI;//置spi_mosi为输入
for(j=0;j<9;tdata[j]=addr,j++)
for(addr=0,i=0;i<8;i++)
{
addr>>=1;
if(PINB&SPI_MI)
addr|=0x80;
PORTB|=SPI_SCK;
PORTB&=~SPI_SCK;
}
DDRB|=SPI_MI;
for(i=0;i<((T_RELOAD+50)/2000);i++)
PORTB&=~RST_TM;
tdata[5]=tdata[6];//调整年的顺序
}
//对DS1302串写
//修改当前时间,依序为:秒分时日月年
void time_str_wr(byte *tdata)
{
byte i,j;
byte addr;
if((tdata[5]-0)>(0x99-0))tdata[5]=0;
if((tdata[4]-1)>(0x12-1))tdata[4]=1;
if((tdata[3]-1)>(0x31-1))tdata[3]=1;
if((tdata[2]-0)>(0x23-0))tdata[2]=0;
if((tdata[1]-0)>(0x59-0))tdata[1]=0;
if((tdata[0]-0)>(0x59-0))tdata[0]=0;
for(i=0;i<((T_RELOAD+50)/2000);i++)
PORTB|=RST_TM;//让DS1302操作使能,并作适当延时
tdata[6]=tdata[5];//调整年的顺序
tdata[7]=0;//写使能
tdata[8]=0xab;//充电模式
addr=(31<<1)|0x80;//0x80为写
for(i=0;i<8;i++)
{
if(addr&1)
PORTB|=SPI_MI;
else
PORTB&=~SPI_MI;
PORTB|=SPI_SCK;
PORTB&=~SPI_SCK;
addr>>=1;
}
for(j=0;j<9;j++)
for(addr=tdata[j],i=0;i<8;i++)
{
if(addr&1)
PORTB|=SPI_MI;
else
PORTB&=~SPI_MI;
PORTB|=SPI_SCK;
PORTB&=~SPI_SCK;
addr>>=1;
}
for(i=0;i<((T_RELOAD+50)/2000);i++)
PORTB&=~RST_TM;
}
//在屏幕指定行显示时间
void disp_time(byte row)
{
byte i;
byte str[21];
str[0]='2';
str[1]='0';
for(;mstimer2<2;);
for(i=5;i<6;i--)
csprintf(&str[2+15-i*3],(time_str[i]>=16)?"%x-":"0%x-",time_str[i]);
str[10]=' ';
str[13]=':';
str[16]=':';
str[19]=' ';
str[20]=0;
init_disp_nocls();//每秒都对显示器初始化一次
str_hz(row,0,str);
}
//对网络cpu操作前的准备
void net_bgn(void)
{
DDRA=0;
PORTA=0x0;
PORTB|=NCPU_BUSY;
PORTE|=RD_WR;
PORTC=ctl_data;
PORTE|=ALE2;
}
//对网络cpu操作结束后恢复常态
void net_end(void)
{
PORTC=ctl_data;
PORTE&=~ALE2;
PORTE&=~RD_WR;
}
//等待握手信号为0
byte wait_0_hs(void)
{
word i;
byte a;
i=ms_count;
for(;;)
{
if((ms_count-i)>2)
break;
PORTC&=~NCPU1_CE;
PORTC|=NCPU1_CE;
a=PINA;
if((a&1)==0)//读忙状态
return 0;
}
return 1;
}
//从网络cpu读
byte net_read(void)
{
byte ndata;
if(wait_0_hs())
return 0xff;
PORTB&=~NCPU_BUSY;
PORTC&=~NCPU1_CE;
PORTC|=NCPU1_CE;
ndata=PINA;
PORTB|=NCPU_BUSY;
return ndata;
}
//对网络cpu写
void net_write(byte ndata)
{
if(wait_0_hs())
ndata=0;
DDRA=0xff;
PORTB&=~NCPU_BUSY;
PORTA=ndata;
PORTE&=~RD_WR;
PORTC&=~NCPU1_CE;
PORTC|=NCPU1_CE;
PORTE|=RD_WR;
PORTB|=NCPU_BUSY;
DDRA=0;
}
//等待握手信号为0
byte wait_0_hs_rst(void)
{
word i;
byte a;
i=ms_count;
for(;;)
{
if((ms_count-i)>200)
break;
PORTC&=~NCPU1_CE;
PORTC|=NCPU1_CE;
a=PINA;
if((a&1)==0)//读忙状态
return 0;
}
return 0;
}
//初始化网络cpu
void init_net(void)
{
net_bgn();
wait_0_hs_rst();
net_write(CMD_NULL); //传令牌
wait_0_hs_rst();
net_write(CMD_NULL); //传令牌
net_end();
}
//网络cpu复位
void net_rst(void)
{
net_bgn();
PORTC&=~NCPU_RST;
mstimer1=10;
while(mstimer1);
PORTC|=NCPU_RST;
mstimer1=690;
while(mstimer1);
wait_0_hs_rst();
net_write(CMD_NULL); //传令牌
wait_0_hs_rst();
net_write(CMD_NULL); //传令牌
net_end();
}
//在中断中接收串口数据
void rcv_int(void)
{
if(USR&0x80)
{
commu_buf[com_i]=UDR;
com_i++;
if(com_i>=commu_end)
poll_com=2;
else
mstimer3=50;//计数器置50ms
}
else
if(mstimer3==0)
{
if((comm_timer==0)||(com_i!=0))
{
comm_timer=0;
poll_com=2;
}
else
{
mstimer3=100;//重值计数器100ms
if(com_c_key!=0)
UDR=com_c_key;
}
}
}
//等待输出缓冲区空
void wait_com_empt(void)
{
mstimer3=10;
for(;mstimer3;comm_with_lon())
if(USR&0x20)
break;
}
//启动中断取数
void poll_rcv(byte c_key)
{
if(poll_com!=0)
return;
if(c_key==0xff)
com_c_key=0;
else
{
com_c_key=CPU_ID|c_key;
if(USR&0x80)//如果串口输入缓冲区中有数,则取出废掉
com_i=UDR;
}
com_i=0;
commu_end=(word)&commu_end-(word)commu_buf-2;//计算通讯缓冲区的长度
if(com_c_key!=0)
{
wait_com_empt();
for(;;)//等待输出缓冲区空
if(USR&0x20)
break;
UDR=com_c_key;
}
mstimer3=100;
poll_com=1;
}
//向串口发命令取数,如果命令是0xff,表示不发命令只取数,返回值是收数的长度
word com_rcv(byte c_key)
{
poll_com=0;
poll_rcv(c_key);
for(;poll_com==1;)
comm_with_lon();
poll_com=0;
return com_i;
}
//下发一个字节
void com_byte(byte c_key)
{
wait_com_empt();
UDR=c_key;
}
//下传多个字节
void com_snd(byte *str,word num)
{
word i;
for(i=0;i<num;i++)
{
wait_com_empt();
UDR=str[i];
}
}
//数据拷贝函数,对EEPROM指针特殊处理,大于等于0x4000的指针以EEPROM指针处理
void memcpy_e(byte *d,byte *s,byte num)
{
if((((word)s)>=0x4000)&&(((word)d)>=0x4000))
for(d=(byte *)((word)d&0x3fff),s=(byte *)((word)s&0x3fff);num;num--)
EEPROMwrite((word)d++,EEPROMread((word)s++));
else
if(((word)s)>=0x4000)
for(s=(byte *)((word)s&0x3fff);num;num--)
*d++=EEPROMread((word)s++);
else
if(((word)d)>=0x4000)
for(d=(byte *)((word)d&0x3fff);num;num--)
EEPROMwrite((word)d++,*s++);
else
for(;num;num--)
*d++=*s++;
}
//应用程序复位
void application_restart(void)
{
asm("cli"); //关中断
while(1)//过一会儿cpu内部看门狗动作
comm_with_lon();
}
//光标定位及形状选择
void set_cursor_position(byte row,byte col,const byte *p)
{
word lram;
byte i,j;
if(p==menucursor)
j=32;
else
j=1;
if(last_cursor)
{//擦除老光标
for(i=0;i<j;i++)
{
disp_order_data(0x0a,(byte)last_cursor);
disp_order_data(0x0b,(byte)(last_cursor/256));
disp_order(0x0c);
disp_data(0x00);
if(p==menucursor)
disp_data(0x00);
last_cursor+=20;
i++;
}
}
lram=row;
lram=lram*20+col;
last_cursor=lram;
for(i=0;i<j;i++)
{
disp_order_data(0x0a,(byte)lram);
disp_order_data(0x0b,(byte)(lram/256));
disp_order(0x0c);
if(p==menucursor)
disp_data(p[i]);
else
disp_data(0xff);
if(p==menucursor)
disp_data(p[i+1]);
lram+=20;
i++;
}
}
//显示函数
void LCD_display(byte j,byte k)
{
cls();
str_hz(j,k,disp_buffer);
}
//查表子程序,在二维表中查找要找的代码串,查到了则返回代码串在表中的位置
int FindString(const DaiMa *Table,char *ss)
{
int i;
for (i=0;;i++)
{
if(Table[i].AscCode==0)
break;//二维表结束
if(cstrcmp(Table[i].AscCode,ss)==0)
return i;
}
return -1;
}
//******************************************************************
//垃圾程序,用来调整程序中全部的字符串的长度和程序的长度
void rubbish_s(void)//
{
csprintf(disp_buffer,"fbjk");
//以上是调整字符串的长度
PORTB|=WDG;
PORTB|=WDG;
PORTB|=WDG;
PORTB|=WDG;
//以上是程序的长度
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -