1、 时间继电器有四种模式即延时开模式、延时关模式、循环延时模式和复位模式。使用板载按键A的短按方式控制延时开模式,使用按键A的长按方式控制延时关模式;使用板载按键B的短按方式控制循环延时模式,使用按键B的长按方式控制复位模式。短按操作:按键按下,按下时间<1s,属于一次短按操作 ;长按操作:按键按下,按下时间>1s,属于一次长按操作。
2、使用板载按键C 和D键设定延时间隔,延时间隔初始化为0。延时间隔范围为0-99秒,C键设定个位秒,D键设定十位秒。每按一次C键增加1秒,每按一次D键增加10秒。延时间隔的精度为0.1秒(即使用处理器ATmega128的定时器/计数器的单位定时时间为0.1秒)。
3、延时开模式指短按A键后,板载发光二极管LED1灭,在7段数码管或液晶显示屏上开始延时时间倒计时,倒计时到0,板载发光二极管LED1长亮;
延时关模式指长按A键后,发光二极管LED1长亮,在7段数码管或液晶显示屏上开始延时时间倒计时,倒计时到0,LED1灭。
循环延时模式指短按B键后在第一个延时间隔内LED1闪烁显示,在下一个延时间隔内LED1长亮,如此交替进行,直至进入复位模式后停止。7段数码管或液晶显示屏上同时不断进行延时时间倒计时。
复位模式指长按B键后进入复位模式,LED1灭,在7段数码管或液晶显示屏上显示设定的延时间隔。
4、一种模式尚未完成要求变换另一种模式时,则当前模式完成后再更换,但任何一种模式下只要复位键按下,立即进入复位模式。 现在问题:模式切换功能还是没有实现,两种延时模式结束后不会跳到新的模式里;循环模式应该是一次闪烁一次长亮循环的,现在是两次长亮一次闪烁循环,两种延时模式结束后按A或短按B也不会进入新的模式
#include <macros.h>
#include <string.h>
#include <stdio.h>
#include <iom128v.h>
#define uchar unsigned char
#define uint unsigned int
unsigned int t0_ovfnum;//t0软件定时计数器
#define RS_CLR PORTC &= ~(1 << PC0) //RS置低
#define RS_SET PORTC |= (1 << PC0) //RS置高
#define RW_CLR PORTC &= ~(1 << PC1) //RW置低
#define RW_SET PORTC |= (1 << PC1) //RW置高
#define EN_CLR PORTC &= ~(1 << PC2) //E置低
#define EN_SET PORTC |= (1 << PC2) //E置高
#define Data_IO PORTA //液晶数据口
#define Data_DDR DDRA //数据口方向寄存器
uchar shi=0,ge=0;
uchar time;
uchar flag;
uchar num=1;
uchar flag_z=1;
uchar flag_s=1;
uint key_press_num=0;
/*******************************************
函数名称: Delayms
功 能: 延时指定毫秒(8M晶振)
参 数: MS--延时的毫秒数
返回值 : 无
/********************************************/
void delay_nms(uint MS)
{
uint i,j;
for( i=0;i<MS;i++)
for(j=0;j<1141;j++); //1141是在8MHz晶振下,通过软件仿真反复实验得到的数值
}
//*************************************************************************
// 初始化子程序
//*************************************************************************
void system_init(void)
{
Data_IO = 0xFF; //电平设置
Data_DDR = 0xFF; //方向输出
PORTF = 0xFF; //电平设置
DDRF = 0xFF; //方向输出
PORTD=0xFF;
DDRD=0x00;
}
//***********************************************************************
// 显示屏命令写入函数
//***********************************************************************
void LCD_write_com(unsigned char com)
{
RS_CLR;
RW_CLR;
EN_SET;
Data_IO = com;
delay_nms(5);
EN_CLR;
}
//***********************************************************************
// 显示屏数据写入函数
//***********************************************************************
void LCD_write_data(unsigned char data)
{
RS_SET;
RW_CLR;
EN_SET;
Data_IO = data;
delay_nms(5);
EN_CLR;
}
//***********************************************************************
// 显示屏清空显示
//***********************************************************************
void LCD_clear(void)
{
LCD_write_com(0x01);
delay_nms(5);
}
//***********************************************************************
// 显示屏字符串写入函数
//***********************************************************************
void LCD_write_str(unsigned char x,unsigned char y,unsigned char *s)
{
if (y == 0)
{
LCD_write_com(0x80 + x);
}
if(y==1)
{
LCD_write_com(0x80+0x40+x);
}
while (*s)
{
LCD_write_data( *s);
s ++;
}
}
//***********************************************************************
// 显示屏单字符写入函数
//***********************************************************************
void LCD_write_char(unsigned char x,unsigned char y,unsigned char data)
{
if (y == 0)
{
LCD_write_com(0x80 + x);
}
else
{
LCD_write_com(0xC0 + x);
}
LCD_write_data( data);
}
void xs_d(unsigned char x,unsigned char y,unsigned int aa)
{
if (y == 0)
{
LCD_write_com(0x80 + x);
}
else
{
LCD_write_com(0xC0 + x);
}
LCD_write_data('T');
LCD_write_data('i');
LCD_write_data('m');
LCD_write_data('e');
LCD_write_data(':');
LCD_write_data(aa/10+0x30);
LCD_write_data(aa%10+0x30);
LCD_write_data(' ');
LCD_write_data(' ');
LCD_write_data(' ');
LCD_write_data(' ');
LCD_write_data(' ');
LCD_write_data(' ');
LCD_write_data(' ');
LCD_write_data(' ');
LCD_write_data(' ');
LCD_write_data(' ');
}
//***********************************************************************
// 显示屏初始化函数
//***********************************************************************
void LCD_init(void)
{
DDRA = 0xFF; //I/O口方向设置
DDRA |= (1 << PA5) | (1 << PA6) | (1 << PA7);
LCD_write_com(0x38); //显示模式设置
delay_nms(5);
LCD_write_com(0x08); //显示关闭
delay_nms(5);
LCD_write_com(0x01); //显示清屏
delay_nms(5);
LCD_write_com(0x06); //显示光标移动设置
delay_nms(5);
LCD_write_com(0x0C); //显示开及光标设置
delay_nms(5);
}
void timer0_init(void)//1ms
{
TCCR0 = 0x00; //stop
TCNT0 = 0xB2; //set count
TIMSK |= 0x01; //timer interrupt sources
}
void key(void)//按键扫描
{
static unsigned char i=0;
if(PIND==0xef)
{
delay_nms(2);
if(PIND==0xef)
{
while(PIND!=0xff)
{
key_press_num++;
delay_nms(10);
if(key_press_num==100)
{
key_press_num=0;
while(PIND!=0xff)
{
PORTE=0x00;
if(flag_z==1)
{
flag=2;
flag_z=0;
}
}
}
}
TCCR0 = 0x05;
if(flag==2)
{}
else
{
PORTE=0xff;
if(flag_z==1)
{
flag=1;flag_z=0;
}
}
}
}
if(PIND==0xdf)
{
delay_nms(2);
if(PIND==0xdf)
{
while(PIND!=0xff)
{
key_press_num++;
delay_nms(10);
if(key_press_num==100)
{
key_press_num=0;
while(PIND!=0xff)
{
flag_z=1;
if(flag==3)
{flag_s=0;}
flag=4;
TCCR0=0x00;
time=10*shi+ge;
}
}
if((flag==4)&&(flag_s==1))break;
if(flag_z==1)
{
flag=3;
flag_s=1;
flag_z=0;
}
TCCR0=0x05;
}
}
}
if(PIND==0xbf)
{
delay_nms(2);
if(PIND==0xbf)
{
shi++;
if(shi>9)
shi=0;
time=10*shi+ge;
while(PIND!=0xff);
}
}
if(PIND==0x7f)
{
delay_nms(2);
if(PIND==0x7f)
{
ge++;
if(ge>9)
ge=0;
time=10*shi+ge;
while(PIND!=0xff);
}
}
}
//*************************************************************************
// 主程序
//*************************************************************************
void main(void)
{
system_init(); //系统初始化,设置IO口属性
delay_nms(10); //延时100ms
LCD_init(); //液晶参数初始化设置
DDRC=0xFF; //PC口上拉电阻使能
PORTC=0xff; //PC高四位输入低四位输出
DDRE=0xFF; //PC口上拉电阻使能
PORTE=0xff; //PC高四位输入低四位输出
timer0_init();
_SEI(); //开全局中断
while (1)
{
key();
if(flag==3)
{
if(num==1)
{
PORTE=0xff;
delay_nms(10);
PORTE=0x00;
delay_nms(10);
}
if(num==2)
PORTE=0x00;
if(time==0)
{
time=10*shi+ge;
num++;
if(num>2)
num=1;
}
}
if(flag==4)
{
PORTE=0xff;
time=10*shi+ge;
}
xs_d(0,0,time);
}
}
#pragma interrupt_handler timer0_ovf_isr:iv_TIM0_OVF
void timer0_ovf_isr(void)
{
TCNT0 = 0xB2; //reload counter value
t0_ovfnum ++;
if(t0_ovfnum == 100)//100ms
{
t0_ovfnum = 0;
if(time>0)
{
time--;
}
else
{
TCCR0 =0; //stop
flag_z=1;
if(flag==1)
PORTE=0x00;
if(flag==2)
PORTE=0xff;
}
}
}
|