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

標題: 這個串口控制蜂鳴器 我選擇ASCII和16進制都試過了就是失敗幫忙看看 [打印本頁]

作者: 2500    時間: 2016-7-28 17:38
標題: 這個串口控制蜂鳴器 我選擇ASCII和16進制都試過了就是失敗幫忙看看
/*一. 程序功能
由上位機發送1給單片機,蜂鳴器以400ms頻率發聲,發送2時以200ms頻率發聲,發送3時以100ms頻率發聲,發送4時關閉蜂鳴器.

二. 程序源碼*/
#include <reg52.h>

//聲明程序需要的全局變量
unsigned char flag, a, num, benum;

//聲明單片機的蜂鳴器
sbit beep = P2 ^ 3;

//聲明初始化函數
void init();

//主函數
void main()
{
    //初始化
    init();

    while (1)
    {
       //檢測是否發生串口中斷
       if (flag == 1)
       {
           //手動將flag置0,方便下次檢測
           flag = 0;
           //關閉中斷???為什么需要關閉總中斷而不僅僅是串口中斷
           EA = 0;
           //開啟計數器0
           TR0 = 1;
           //根據串口接收的數據設置蜂鳴器的頻率基數
           switch(a)
           {
               case 1:
                   benum = 4;
                   break;
               case 2:
                   benum = 2;
                   break;
               case 3:
                   benum = 1;
                   break;
               case 4:
                   TR0 = 0;
                   beep = 1;
           }
           //開啟總中斷
           EA = 1;
        }
    }
}

void init()
{
    //設置定時器1為工作方式2, 定時器0為工作方式1
    TMOD = 0x21;
    //波特率 = (2的SMOD次方/32) * (T1溢出率)                                                                     //T1溢出率 = [256 - X]*12/晶振頻率
    //根據SMOD的0,1取值得到的X分別為TH1,TL1
    //波特率選取9600,晶振頻率為11.0592
    TH1 = 0xfd;
    TL1 = 0xfd;
    //以50s作為計數器0的基數
    TH0 = (65536 - 50000) / 256;
    TL0 = (65536 - 50000) % 256;
    //ET1 = 1;  這里不需要開啟定時器1中斷,因為定時器1工作在方式2,為8位自動重裝方式,進入中斷也無事可做
    //啟動T1定時器
    TR1 = 1;
    //開啟T0定時器
    ET0 = 1;
    //TR0 = 1; TR0的初始化放在主函數的while中,從而啟動T0定時器,使蜂鳴器按頻率發聲
    //設定串口工作方式
    //10位異步收發(8位數據), 波特率可變(由定時器溢出率控制)
    SM0 = 0;
    SM1 = 1;
    //容許串口中斷
    REN = 1;
    //開啟總中斷
    EA = 1;
    //開啟串口中斷
    ES = 1;
}

void ser() interrupt 4
{
    //RI為接收中斷標志位, 在方式0時, 當串行接收第8位數據結束時, 或在其他方式, 串行接收停止位的
    //中間時, 由內部硬件使RI置1, 向CPU發出中斷申請, 也必須在中斷服務程序中, 用軟件將其清0,取消
    //此中斷申請, 以方便下一次中斷申請檢測, 即這樣才能產生下一次中斷.
    //這里RI清0, 因為程序既然產生了串口中斷, 肯定是收到或發送了數據, 在開始時沒有發送任何數據
    //那必然是收到了數據, 此時RI會被硬件置1, 所以進入串口中斷服務程序后必須由軟件清0, 這樣才能
    //產生下一次中斷.
    RI = 0;
    //將SBUF中的數據讀走給a, 這是此中斷服務程序最重要的目的
    a = SBUF;
    //將串口中斷標志位置1,方便主程序檢測
    flag = 1;
}

void T0_timer() interrupt 1
{
    TH0 = (65536 - 50000) / 256;
    TL0 = (65536 - 50000) % 256;
    num++;
    if (num == benum)
    {
        num = 0;
        beep = ~beep;
    }
}


仿真也測試了  我在串口助手里面輸入1不來米 幫忙看看

作者: AMB    時間: 2016-7-29 09:01
把//ET1=1注釋,有要注釋的沒有注釋
作者: 2500    時間: 2016-7-29 13:53
AMB 發表于 2016-7-29 09:01
把//ET1=1注釋,有要注釋的沒有注釋

效果一樣的
作者: as9901    時間: 2016-7-30 07:08
沒看到讀串口部分,收到的數在哪里?a的值從哪來?




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