|
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;
}
}
}
|