欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1378|回復: 1
收起左側

求教一個MCU程序,這個功能難度真的實現不了嗎?

[復制鏈接]
ID:190577 發表于 2019-11-13 07:40 | 顯示全部樓層 |閱讀模式
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;
         
   
  }
  
  
}
  

}

回復

使用道具 舉報

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

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表