1024手机基地看电影,午夜福利视频导航,国产精品福利在线一区,亚洲欧美日韩另类成人,在线观看午夜日本理论片,成年超爽免费网站,国产精品成人免费,精品动作一级毛片,成人免费观看网站,97精品伊人久久大香蕉

標題: 求教一個MCU程序,這個功能難度真的實現不了嗎? [打印本頁]

作者: bbxyliyang    時間: 2019-11-13 07:40
標題: 求教一個MCU程序,這個功能難度真的實現不了嗎?
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段數碼管或液晶顯示屏上開始延時時間倒計時,倒計時到0LED1滅。

循環延時模式指短按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;
         
   
  }
  
  
}
  

}


作者: bh2030693    時間: 2019-11-13 20:52
顯示函數如果正常,子函數不用貼出來,按鍵和主函數,中斷里面的一些關鍵語句應該做上注釋,雖然你的程序看起來不算復雜,但是別人也是不愿意花費太多時間研究你的程序,所以建議適當注釋,這樣你自己也容易發現問題,別人也能更快幫助你。




歡迎光臨 (http://m.raoushi.com/bbs/) Powered by Discuz! X3.1