• <li id="00i08"><input id="00i08"></input></li>
  • <sup id="00i08"><tbody id="00i08"></tbody></sup>
    <abbr id="00i08"></abbr>
  • 新聞中心

    EEPW首頁 > 嵌入式系統 > 設計應用 > 單片機STC5A60S2完成音頻采集與輸出

    單片機STC5A60S2完成音頻采集與輸出

    作者: 時間:2012-08-21 來源:網絡 收藏

    .c文件(主程序):

    本文引用地址:http://www.czjhyjcfj.com/article/171003.htm

    /*-------------------------------------------------------------------*/
    //一般說明
    //使用的,外接晶振32.768M
    //采用受用自帶的AD,自帶的PWM做DA使用
    //兩個按鍵一個控制錄音,一個控制,上電默認狀態為實時
    //外接RAM采用62256
    /*-------------------------------------------------------------------*/
    #include reg51.h>
    #include intrins.h>
    #include AD.H>
    #include PWM.H>
    //#include DEAL.H> //調用數字濾波頭文件,里面內容比較雜,調試證明作用不明顯
    #define uchar unsigned char
    #define uint unsigned int

    sfr AUXR=0x8E; //控制定時器0、1工作速度
    sfr BUS_SPEED=0xA1; //控制外擴RAM速度寄存器
    sfr P1M1=0x91; //設置I/O口工作狀態
    sfr P1M0=0x92;
    sbit P15=P1^5; //P1^5接按鍵1
    sbit P16=P1^6; //P1^6 接按鍵2

    uchar keycode; //定義鍵碼變量
    uchar xdata C5A60S2_ADC[32768]; //用片外RAM存儲采樣值
    /*-------------------------------------------------------------------*/
    void keyscan(void) //掃描鍵盤子程序
    {
    P15=1;
    _nop_();
    _nop_();
    P16=1;
    _nop_();
    _nop_();
    if(P15==0)
    {
    delay(1);
    if(P15==0);
    keycode=1; //按鍵1控制關輸出,開
    }
    if(P16==0)
    {
    delay(1);
    if(P16==0) //按鍵2控制開輸出,關
    keycode=2;
    }
    }
    /*-------------------------------------------------------------------*/
    void Init_T()
    {
    //BUS_SPEED=0; //控制外擴RAM速度讀寫在1T狀態, 注意62256最大承受速度約14M
    //PT0=1; //設置優先級
    //PT1=0;
    AUXR=0Xc0; //定時器0、1工作于不分頻狀態,即速度為常規12倍
    P1M1=1; //使P1.0工作于高阻狀態 做AD使用,
    P1M0=9; // PWM強推挽輸出電流達到20mA
    EA=1;
    ET0=1;
    TMOD=0X11; //定時器工作在模式1
    TR0=1; //開啟定時器0
    TL0=0xa0; //保證采樣速度與輸出速度一致
    TH0=0xf0;

    ET1=1;
    TR1=1; //開啟定時器0
    TL1=0xa0; //保證采樣速度與輸出速度一致 采樣速度為540個時鐘
    TH1=0xf0;

    }
    /*---------------------------------------------------------------- */
    time0() interrupt 1 using 2 //定時器0中斷用于定時
    {
    static uint ram_in=0; //存入第幾個ram單元
    ADC_CONTR=0xe8; //清空轉換標志位,同時開啟下一次轉換
    C5A60S2_ADC[ram_in++]=ADC_RES;;
    if(ram_in==32768) ram_in=0; //如果存滿RAM回到第一位
    TL0=0xa0; // 采樣速度為?個時鐘
    TH0=0xf0;
    }

    /*-----------------------------------------------------------------*/
    time1() interrupt 3 using 3 //定時器0中斷用于定時輸出
    {
    static uint ram_out=0; //輸出第幾個ram單元
    PWM(C5A60S2_ADC[ram_out++]); //輸出
    if(ram_out==32768) ram_out=0; //如果讀完RAM,回到第一位
    TL1=0xa0; //保證采樣速度等于輸出速度
    TH1=0xf0;
    }
    /*-----------------------------------------------------------------*/

    void main()
    {
    Init_ADC(); //AD初始化
    Init_PWM(); //PWM初始化
    Init_T(); //初始化定時器

    while(1)
    {
    keyscan() ;
    if(keycode==1){ TR0=1;TR1=0;CCAPM0=0;keycode=0;} //按鍵1控制開采集、關輸出
    if(keycode==2){ TR0=0;TR1=1;CCAPM0=0x42;keycode=0;} //按鍵2控制關采集、開輸出,
    }
    }

    .H文件1(AD.H):

    #define uchar unsigned char
    #define uint unsigned int
    /*---------------------------------------------------*/
    //注意AD轉換使用的是內部時鐘
    /*---------------------------------------------------*/
    //定義特殊功能寄存器
    sfr ADC_CONTR=0xBC; //AD控制寄存器
    sfr ADC_RES=0xBD; //AD輸出高八位寄存器
    sfr ADC_LOW2=0xBE; //AD輸出最后兩位寄存器
    sfr PLASF=0x9D; //控制P1口中的哪個作為模擬口
    sfr IPH=0XB7; //中斷優先級控制位
    sfr AUXR1=0XA2; //設置AD轉化結果寄存器的存儲方式
    //定義與AD有關寄存器的控制位
    #define ADC_POWER 0X80 //AD電源控制位
    #define ADC_FLAG 0X10 //AD轉換標志位,必須軟件清零
    #define ADC_START 0X08 //控制AD開始轉換位
    #define ADC_SPEEDLL 0X00 //540個時鐘
    #define ADC_SPEEDL 0X20 //360個時鐘
    #define ADC_SPEEDH 0X40 //180個時鐘
    #define ADC_SPEEDHH 0X60 //90個時鐘
    sbit EADC=IE^5; //定義單片機內部自帶AD中斷標志位

    /*--------------------------------------------------------*/
    //延時子程序
    void delay(uint n)
    {
    while(n--);
    }
    /*--------------------------------------------------------*/
    //初始化與單片機內部自帶AD相關的寄存器
    void Init_ADC()
    {

    //IPH=0X20; //AD中斷設置為最高優先級 0x20
    //IP=0X20;
    //開啟中斷總開關及AD中斷開關0x20
    //EA=1;
    //EADC=1; //開啟AD中斷開關,AD的開關標志位同89C52的T2標志位
    //AUXR1=0; //AD轉化結果寄存器的存儲方式8高+2低 這是默認值可以不設置
    PLASF=0x01; //設置P1.0作為模擬口
    ADC_RES=0 ; //清空AD輸出高八位寄存器
    //默認的AD輸出存儲方式為8+2
    ADC_CONTR=0xe8; //(ADC_POWER|ADC_SPEEDLL|ADC_START|0x00); //開啟AD電源,以90個時鐘速度采樣,并選擇P1.0作為輸入口
    delay(1000); //初次打開內部AD模擬電源需要適當延時,使電源穩定。
    }
    /*--------------------------------------------------------*/

    .H文件2(PWM.H):

    #define uchar unsigned char
    #define uint unsigned int
    sfr CCON=0XD8; //PCA控制寄存器
    sfr CMOD=0XD9; //工作模式寄存器
    sfr CL=0XE9 ; //PCA計數器低8位寄存器
    sfr CH=0XF9 ; //PCA計數器高8位寄存器
    sfr CCAPM0=0XDA ; //PCA模塊0的比較/捕獲寄存器
    sfr CCAP0L=0XEA ; //PCA模塊0低8位捕捉/比較寄存器
    sfr CCAP0H=0XFA ; //PCA模塊0高8位捕捉/比較寄存器
    sfr PCAPWM0=0XF2; //PCA模塊0的PWM寄存器
    sbit CCF0=CCON^0 ; //PCA模塊0中斷標志位,必須軟件清零
    sbit CCF1=CCON^1 ; //PCA模塊1中斷標志位,必須軟件清零
    sbit CR=CCON^6 ; //PCA計數控制位
    sbit CF=CCON^7 ; //PCA計數器溢出標志位

    void Init_PWM() //初始化PWM相關的寄存器
    {
    CCON=0; //PCA控制寄存器清零
    CL=0; //PCA計數器低8位寄存器
    CH=0; //PCA計數器高8位寄存器
    CMOD=0X08; //計數脈沖選擇:系統時鐘(越高越好),禁止CF位的中斷 ??????
    CCAPM0=0X42; //8位PWM,無中斷
    PCAPWM0=0X00; //與CCAP0H,CCAP0L組成9位數
    CR=1; //啟動PCA計數,必須軟件清零
    }
    void PWM(uchar dutyfactor) //調節占空比子程序
    {
    CCAP0H=CCAP0L=255-dutyfactor; //控制占空比
    }



    評論


    相關推薦

    技術專區

    關閉
    主站蜘蛛池模板: 胶州市| 正安县| 华阴市| 宁德市| 赣榆县| 海城市| 寿光市| 津南区| 双辽市| 平湖市| 肥乡县| 琼结县| 达州市| 射洪县| 虹口区| 蒙阴县| 互助| 东山县| 区。| 嘉峪关市| 雅安市| 洞头县| 田东县| 额济纳旗| 清丰县| 原阳县| 合江县| 九龙城区| 图木舒克市| 沁源县| 扎赉特旗| 文化| 临沧市| 阜宁县| 伊宁县| 山阴县| 浦县| 佛山市| 合水县| 偏关县| 东兴市|