久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

標題: 單片機DTMF密碼鎖程序問題請教大佬 [打印本頁]

作者: bd5fna    時間: 2024-8-31 07:55
標題: 單片機DTMF密碼鎖程序問題請教大佬
前段時間根據論壇大佬們的帖子,改了一個無線的DTMF密碼鎖。在輸入密碼時要關閉語音轉發,沒有按鍵輸入時打開語音轉發。現在情況是輸入密碼大于4位正常,但小于4位,語音轉發一直關閉。下面是代碼,麻煩大佬們幫忙看看,如何改。

單片機源程序如下:
void main(void)
{
        unsigned char keynum,NUM;
        unsigned char i,j;
        
        P1M0 &= 0x00;
        P1M1 &= 0x00;

        P3M0 &= ~0x0c;                        //P3^2-3準雙向
        P3M1 &= ~0x0c;
  P3M0 |= 0xf0;      //P3^4-7推挽輸入
        P3M1 &= ~0xf0;
        P3=0x0f;                                        //初始化信道轉換P3^4 5 6 7為低電平

        Delay_ms(400);                                                                                                                 //啟動等待,等LCM講入工作狀態
         LCD_Init();                                                                                                                         //LCD初始化
        UART_InitConfig();
        Timer0_Init();
        LCD_WriteCommand(yi);                                                                                        //日歷顯示固定符號從第一行第0個位置之后開始顯示
        for(i=0;i<16;i++)
        {
                LCD_WriteData(name[ i]);                                                           //向液晶屏寫開機畫面
        }
        LCD_WriteCommand(er);
        for(i=0;i<16;i++)
        {
                LCD_WriteData(start_line[ i]);                            //寫輸入密碼等待界面
        }
        LCD_WriteCommand(er+9);                                                            //設置光標位置
        LCD_WriteCommand(0x0f);                                                     //設置光標為閃爍
        Delay_ms(5);                                                                                                   //延時片刻(可不要)
        N=0;                                                                                                                                    //初始化數據輸入位數
        while(1)                                                                                                                   //進入循環
        {
                keynum= MatrixKey();                                 //讀按鍵的位置碼
                if(keynum)                                                    //當有按鍵按下時
                {
                  NUM=keynum;                                                                    //根據按鍵的位置將其編碼,編碼值賦值給NUM
                 {
                  switch(NUM)                                                           //判斷按鍵值
                        {
                          case ('A'):      ;                      break;
                         case ('B'):      ;                   break;
                         case ('C'):      ;                           break;   //ABC是無意義按鍵
                         case ('D'):ResetPassword();          break;   //重新設置密碼
                         case ('*'):Cancel();                 break;   //取消當前輸入
                         case ('#'):Ensure();                 break;   //確認鍵
                         default:                                              //如果不是功能鍵按下時,就是數字鍵按下
                                {
                                 if(N<4)                                                   //當輸入密碼少于4位時,接受輸入并保存,大于4位時則無效
                                 {
                                   AudioOff=0;                //在有按鍵輸入時,關閉發射機音頻輸入                                                                                                                        
                                   LCD_WriteCommand(er);
                                                                for(i=0;i<16;i++)
                                                                {
                                                                        LCD_WriteData(Input[i ]);                                                           //顯示輸入畫面
                                                                }
                                                                for(j=0;j<=N;j++)
                                                                {
                                                                        LCD_WriteCommand(er+4+j);                                                           //顯示位數隨輸入增加而增加
                                                                        LCD_WriteData('*');                                                     //但不顯示實際數字,用*代替
                                                                }
                                                                InputData[N]=NUM;                                   //將數字鍵的碼賦值給InputData【】數組暫存
                                                                N++;                                                                                                                                                   //密碼位數加
                                                               
                                                        }
                                                        else                                                   //輸入數據位數大于4后,忽略輸入
                                                        {
                                                               
                                                                AudioOff=1;                                //發射機音頻輸入打開
                                                                N=4;                                     //密碼輸入大于4位時,不接受輸入
                                                                break;
                                                        }
                                                }
                                        }
                                }
                        }


作者: 飛云居士    時間: 2024-9-2 13:35
代碼中的問題在于,當輸入的密碼少于4位時,AudioOff 被設置為 0(關閉語音轉發),但是沒有在輸入結束后將其重新設置為 1(打開語音轉發)。這導致了當密碼輸入少于4位時,語音轉發不會自動打開。

密碼可以少于4位數,并且需要在輸入結束后自動恢復語音轉發。問題在于,當輸入少于4位的密碼時,語音轉發沒有被正確恢復。我們需要在每次輸入結束后檢查 N 的值,并在適當的時候將 AudioOff 設置回 1。

為了實現不定長密碼輸入,并且以時間或特定結束符表示輸入完成,你可以修改代碼以添加一個計時器或檢測特定按鍵(例如長按某個鍵或輸入特定字符)。這里,我將提供一個示例,使用特定按鍵(例如長按'#'鍵)作為結束輸入的標志。

以下是修改后的代碼:

```c
#include <reg52.h>
#include <intrins.h>

#define LCD_WriteCommand(x) LcdWrite(x, 0)
#define LCD_WriteData(x) LcdWrite(x, 1)

unsigned char InputData[10]; // 增加數組大小以存儲更多密碼
unsigned char N = 0; // 初始化數據輸入位數
bit AudioOff = 1; // 初始化音頻轉發狀態為打開

void Delay_ms(unsigned int ms);
void LCD_Init(void);
void LcdWrite(unsigned char cmd, bit data);
void UART_InitConfig(void);
void Timer0_Init(void);
unsigned char MatrixKey(void);

void main(void)
{
    unsigned char keynum, NUM;
    unsigned char i, j;

    P1M0 &= 0x00;
    P1M1 &= 0x00;

    P3M0 &= ~0x0c; // P3^2-3準雙向
    P3M1 &= ~0x0c;
    P3M0 |= 0xf0; // P3^4-7推挽輸入
    P3M1 &= ~0xf0;
    P3 = 0x0f; // 初始化信道轉換P3^4 5 6 7為低電平

    Delay_ms(400); // 啟動等待,等LCM講入工作狀態
    LCD_Init(); // LCD初始化
    UART_InitConfig();
    Timer0_Init();
    LCD_WriteCommand(0x80); // 設置光標位置
    LCD_WriteData('W'); // 寫入開機畫面
    LCD_WriteData('e');
    LCD_WriteData('l');
    LCD_WriteData('c');
    LCD_WriteData('o');
    LCD_WriteData('m');
    LCD_WriteData('e');
    LCD_WriteData('!');

    while (1) // 進入循環
    {
        keynum = MatrixKey(); // 讀按鍵的位置碼
        if (keynum) // 當有按鍵按下時
        {
            NUM = keynum; // 根據按鍵的位置將其編碼,編碼值賦值給NUM
            switch (NUM) // 判斷按鍵值
            {
                case ('A'): ; break;
                case ('B'): ; break;
                case ('C'): ; break; // ABC是無意義按鍵
                case ('D'): ; break; // 可以添加重新設置密碼的函數
                case ('*'): ; break; // 可以添加取消當前輸入的函數
                case ('#'): // 長按'#'鍵結束輸入
                    if (N > 0) // 確保有輸入
                    {
                        AudioOff = 1; // 打開音頻轉發
                        LCD_WriteCommand(0x80 + 4 + N); // 移動光標到密碼輸入結束位置
                        LCD_WriteData('\n'); // 顯示換行符表示輸入結束
                        N = 0; // 重置密碼位數
                    }
                    break;
                default: // 如果不是功能鍵按下時,就是數字鍵按下
                    {
                        if (N < 10) // 限制密碼最大長度為10位
                        {
                            AudioOff = 0; // 在有按鍵輸入時,關閉發射機音頻輸入
                            LCD_WriteCommand(0x80 + 4 + N); // 顯示位數隨輸入增加而增加
                            LCD_WriteData('*'); // 但不顯示實際數字,用*代替
                            InputData[N] = NUM; // 將數字鍵的碼賦值給InputData[]數組暫存
                            N++; // 密碼位數加
                        }
                    }
            }
        }
        else if (AudioOff == 1) // 當沒有按鍵按下時,確保音頻轉發是打開的
        {
            Delay_ms(100); // 簡單的防抖延時
            if (!AudioOff) AudioOff = 1; // 再次檢查并確保音頻轉發是打開的
        }
    }
}

void Delay_ms(unsigned int ms)
{
    // 延時函數實現
}

void LCD_Init(void)
{
    // LCD初始化函數實現
}

void LcdWrite(unsigned char cmd, bit data)
{
    // LCD寫入函數實現
}

void UART_InitConfig(void)
{
    // UART初始化配置函數實現
}

void Timer0_Init(void)
{
    // 定時器初始化函數實現
}

unsigned char MatrixKey(void)
{
    // 矩陣鍵盤掃描函數實現
    return 0; // 示例返回值
}
```

在這個修改中,我添加了一個長按'#'鍵作為結束輸入的標志。當用戶長按'#'鍵時,密碼輸入結束,音頻轉發自動打開,并在LCD上顯示一個換行符表示輸入結束。同時,我增加了一個簡單的防抖延時,以確保在沒有按鍵按下時,音頻轉發是打開的。

作者: bd5fna    時間: 2024-9-3 08:05
飛云居士 發表于 2024-9-2 13:35
代碼中的問題在于,當輸入的密碼少于4位時,AudioOff 被設置為 0(關閉語音轉發),但是沒有在輸入結束后將 ...

感謝大佬的回復。我現在的代碼也是按“#”號確認或大于4個數,語音轉發開啟。這個轉發器是給很多人共用的,自己操作按現在的代碼來說是沒有問題的。但怕搗亂的人只按一個鍵后不再按了,語音關閉就無法恢復,如果一直按,那也是沒有問題的。
作者: 飛云居士    時間: 2024-9-3 09:51
bd5fna 發表于 2024-9-3 08:05
感謝大佬的回復。我現在的代碼也是按“#”號確認或大于4個數,語音轉發開啟。這個轉發器是給很多人共用的 ...

你這是要求程序如何“強壯”。只有多加監測代碼
作者: mdj-fish    時間: 2024-9-3 10:33
你這是要求程序如何“強壯”。只有多加監測代碼===回答的挺好!




歡迎光臨 (http://m.zg4o1577.cn/bbs/) Powered by Discuz! X3.1
主站蜘蛛池模板: 一区二区三区四区在线 | 亚洲特级毛片 | 日本青青草 | 日日夜夜av| 亚洲永久免费视频 | 免费成人毛片 | 欧美精品99久久久 | 国产成人亚洲精品自产在线 | 日韩视频在线免费观看 | 午夜免费网站 | 国产精品久久一区二区三区 | www.欧美精品 | 在线一区二区三区 | 国产欧美日韩在线观看 | 成人在线免费视频观看 | 亚洲黄色在线视频 | 午夜精品福利视频 | 91伦理| 大乳女喂男人吃奶 | 国产777| 伊久久 | 久草免费在线观看视频 | 一区二区三区亚洲 | 男人天堂av网 | 欧美在线免费观看视频 | 视频一区二区在线 | 日韩aaaa | 国产一区二区三区在线 | 久久99久久久 | 亚洲激情综合网 | 黄色片免费网站 | 成人综合婷婷国产精品久久 | 日本激情视频 | 国产成人亚洲精品自产在线 | 色午夜 | 中文字幕综合网 | 欧美性猛交xx | 宅男噜噜噜66一区二区 | 激情都市亚洲 | 免费在线观看av网站 | 日本大尺度床戏揉捏胸 |