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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1073|回復: 4
打印 上一主題 下一主題
收起左側

單片機DTMF密碼鎖程序問題請教大佬

[復制鏈接]
跳轉到指定樓層
樓主
ID:76027 發表于 2024-8-31 07:55 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
前段時間根據論壇大佬們的帖子,改了一個無線的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;
                                                        }
                                                }
                                        }
                                }
                        }

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:404160 發表于 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上顯示一個換行符表示輸入結束。同時,我增加了一個簡單的防抖延時,以確保在沒有按鍵按下時,音頻轉發是打開的。
回復

使用道具 舉報

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

感謝大佬的回復。我現在的代碼也是按“#”號確認或大于4個數,語音轉發開啟。這個轉發器是給很多人共用的,自己操作按現在的代碼來說是沒有問題的。但怕搗亂的人只按一個鍵后不再按了,語音關閉就無法恢復,如果一直按,那也是沒有問題的。
回復

使用道具 舉報

地板
ID:404160 發表于 2024-9-3 09:51 | 只看該作者
bd5fna 發表于 2024-9-3 08:05
感謝大佬的回復。我現在的代碼也是按“#”號確認或大于4個數,語音轉發開啟。這個轉發器是給很多人共用的 ...

你這是要求程序如何“強壯”。只有多加監測代碼
回復

使用道具 舉報

5#
ID:277531 發表于 2024-9-3 10:33 | 只看該作者
你這是要求程序如何“強壯”。只有多加監測代碼===回答的挺好!
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 男女免费视频网站 | 欧美视频在线播放 | 成人国产精品久久久 | 欧美精品福利视频 | 久久久成| 美女黄网 | 99久久久无码国产精品 | 久久伊人亚洲 | 一区二区三区 在线 | 亚洲日本一区二区三区四区 | 国产免费va | 久草网址| 青青草一区| 欧美成人一区二区三区 | 中文字幕一二三区 | 免费久 | 免费观看a级毛片在线播放 黄网站免费入口 | 精品久久久久久亚洲综合网 | 久久中文字幕视频 | 毛片视频观看 | 久久久视频在线 | 中文字幕免费在线 | 亚洲欧美一区二区三区在线 | 欧美人妖网站 | 在线免费观看视频黄 | 久久99精品久久久久久噜噜 | 日批日韩在线观看 | 欧美久久电影 | 欧美videosex性极品hd | 欧美在线一二三 | 成人在线视频一区二区三区 | 国产欧美精品在线观看 | 亚洲二区在线 | 91九色婷婷 | 久久精品一区 | 精品亚洲一区二区 | www.性色 | 伊人久久综合 | 久久i| 999视频 | 精品欧美一区二区精品久久久 |