使用STC12C5A60S2,用推挽模式直接驅動LED顯示,輸入用4558緩沖放大,避免對信號的干擾。
制作出來的實物圖如下:
效果
e83e27e16d3b36aa5d2dc835ff3ad65.jpg (159.01 KB, 下載次數: 133)
下載附件
效果
2021-12-10 08:30 上傳
PCB-A
05.jpg (24.55 KB, 下載次數: 125)
下載附件
PCB-A
2021-12-10 08:30 上傳
PCB-B
06.jpg (18.45 KB, 下載次數: 132)
下載附件
PCB-B
2021-12-10 08:30 上傳
電路原理圖如下:
04.jpg (160.69 KB, 下載次數: 109)
下載附件
原理圖
2021-12-10 08:30 上傳
單片機源程序如下:
- #include "STC12C5A60S2.H"
- #include <intrins.h>
- #define uchar unsigned char//兩個宏定義
- #define uint unsigned int
- //定義左聲道15個LED所接的IO口
- sbit LEDL15=P2^2;
- sbit LEDL14=P2^1;
- sbit LEDL13=P2^0;
- sbit LEDL12=P3^7;
- sbit LEDL11=P3^6;
- sbit LEDL10=P3^5;
- sbit LEDL9=P3^4;
- sbit LEDL8=P3^3;
- sbit LEDL7=P3^2;
- sbit LEDL6=P1^7;
- sbit LEDL5=P1^6;
- sbit LEDL4=P1^5;
- sbit LEDL3=P1^4;
- sbit LEDL2=P1^3;
- sbit LEDL1=P1^2;
- //定義右聲道15個LED所接的IO口
- sbit LEDR15=P2^3;
- sbit LEDR14=P3^4;
- sbit LEDR13=P2^5;
- sbit LEDR12=P2^6;
- sbit LEDR11=P2^7;
- sbit LEDR10=P4^4;
- sbit LEDR9=P4^5;
- sbit LEDR8=P4^6;
- sbit LEDR7=P0^7;
- sbit LEDR6=P0^6;
- sbit LEDR5=P0^5;
- sbit LEDR4=P0^4;
- sbit LEDR3=P0^3;
- sbit LEDR2=P0^2;
- sbit LEDR1=P0^1;
- uint ADC_resultL,ADC_resultR,voL,voR; //定義幾個unsigned int型和unsigned char型變量
- uchar numL,numR,tt0,tt1,ttL,ttR,biaozhiL,biaozhiR,xuantingL,xuantingR,xialuoL,xialuoR,pfL,pfR;
- void delay(uchar z) //延時程序
- {
- uchar x,y;
- for(x=z;x>0;x--)
- for(y=100;y>0;y--);
- }
- void displayL() //左聲道顯示程序
- { P0M1 = 0x00; P0M0 = 0xFF; //P0(00000000B,11111111B)
- P1M1 = 0x00; P1M0 = 0xFC; //P1(00000000B,11111100B)
- P2M1 = 0x00; P2M0 = 0xFF; //P2(00000000B,11111111B)
- P3M1 = 0x00; P3M0 = 0xFF; //P3(00000000B,11111111B)
- P4M1 = 0x00; P4M0 = 0xFF; //P4(00000000B,11111111B)
- if(pfL==1)
- LEDL1=0;
- else
- {
- if(numL>=1)LEDL1=0;
- else LEDL1=1;
- }
- if(pfL==2)
- LEDL2=0;
- else
- {
- if(numL>=2)LEDL2=0;
- else LEDL2=1;
- }
- if(pfL==3)
- LEDL3=0;
- else
- {
- if(numL>=3)LEDL3=0;
- else LEDL3=1;
- }
- if(pfL==4)
- LEDL4=0;
- else
- {
- if(numL>=4)LEDL4=0;
- else LEDL4=1;
- }
- if(pfL==5)
- LEDL5=0;
- else
- {
- if(numL>=5)LEDL5=0;
- else LEDL5=1;
- }
- if(pfL==6)
- LEDL6=0;
- else
- {
- if(numL>=6)LEDL6=0;
- else LEDL6=1;
- }
- if(pfL==7)
- LEDL7=0;
- else
- {
- if(numL>=7)LEDL7=0;
- else LEDL7=1;
- }
- if(pfL==8)
- LEDL8=0;
- else
- {
- if(numL>=8)LEDL8=0;
- else LEDL8=1;
- }
- if(pfL==9)
- LEDL9=0;
- else
- {
- if(numL>=9)LEDL9=0;
- else LEDL9=1;
- }
- if(pfL==10)
- LEDL10=0;
- else
- {
- if(numL>=10)LEDL10=0;
- else LEDL10=1;
- }
- if(pfL==11)
- LEDL11=0;
- else
- {
- if(numL>=11)LEDL11=0;
- else LEDL11=1;
- }
- if(pfL==12)
- LEDL12=0;
- else
- {
- if(numL>=12)LEDL12=0;
- else LEDL12=1;
- }
- if(pfL==13)
- LEDL13=0;
- else
- {
- if(numL>=13)LEDL13=0;
- else LEDL13=1;
- }
- if(pfL==14)
- LEDL14=0;
- else
- {
- if(numL>=14)LEDL14=0;
- else LEDL14=1;
- }
- if(pfL==15)
- LEDL15=0;
- else
- {
- if(numL>=15)LEDL15=0;
- else LEDL15=1;
- }
- }
- void displayR() //右聲道顯示程序
- {
-
- if(pfR==1)
- LEDR1=0;
- else
- {
- if(numR>=1)LEDR1=0;
- else LEDR1=1;
- }
- if(pfR==2)
- LEDR2=0;
- else
- {
- if(numR>=2)LEDR2=0; else LEDR2=1;
- }
- if(pfR==3)
- LEDR3=0;
- else
- {
- if(numR>=3)LEDR3=0; else LEDR3=1;
- }
- if(pfR==4)
- LEDR4=0;
- else
- {
- if(numR>=4)LEDR4=0; else LEDR4=1;
- }
- if(pfR==5)
- LEDR5=0;
- else
- {
- if(numR>=5)LEDR5=0; else LEDR5=1;
- }
- if(pfR==6)
- LEDR6=0;
- else
- {
- if(numR>=6)LEDR6=0; else LEDR6=1;
- }
- if(pfR==7)
- LEDR7=0;
- else
- {
- if(numR>=7)LEDR7=0; else LEDR7=1;
- }
- if(pfR==8)
- LEDR8=0;
- else
- {
- if(numR>=8)LEDR8=0; else LEDR8=1;
- }
- if(pfR==9)
- LEDR9=0;
- else
- {
- if(numR>=9)LEDR9=0; else LEDR9=1;
- }
- if(pfR==10)
- LEDR10=0;
- else
- {
- if(numR>=10)LEDR10=0; else LEDR10=1;
- }
- if(pfR==11)
- LEDR11=0;
- else
- {
- if(numR>=11)LEDR11=0; else LEDR11=1;
- }
- if(pfR==12)
- LEDR12=0;
- else
- {
- if(numR>=12)LEDR12=0; else LEDR12=1;
- }
- if(pfR==13)
- LEDR13=0;
- else
- {
- if(numR>=13)LEDR13=0; else LEDR13=1;
- }
- if(pfR==14)
- LEDR14=0;
- else
- {
- if(numR>=14)LEDR14=0; else LEDR14=1;
- }
- if(pfR==15)
- LEDR15=0;
- else
- {
- if(numR>=15)LEDR15=0; else LEDR15=1;
- }
- }
- void init() //初始化程序
- {
- TMOD=0x11; //設定定時器0、1工作方式
- EA=1; //開總中斷
- TH0=0xb1; //高8位裝初值 TH0=(65536-20000)/256;
- TL0=0xe0; //低8位裝初值 TL0=(65536-20000)%256;
- ET0=1; //開定時器0
- TR0=1; //啟動定時器0
- TH1=0xd8; //高8位裝初值TH1=(65536-10000)/256
- TL1=0xf0; //低8位裝初值TL1=(65536-10000)%256
- ET1=1; //開定時器1
- TR1=1; //啟動定時器1
- }
- //---------------------------------------------------------------------
- //以下選擇 ADC 轉換速率,只能選擇其中一種
- // SPEED1 SPEED0 A/D轉換所需時間
- #define AD_SPEED 0x60 // 0110,0000 1 1 70 個時鐘周期轉換一次,
- // CPU工作頻率21MHz時 A/D轉換速度約 300KHz
- //#define AD_SPEED 0x40 //0100,0000 1 0 140 個時鐘周期轉換一次
- //#define AD_SPEED 0x20 //0010,0000 0 1 280 個時鐘周期轉換一次
- //#define AD_SPEED 0x00 //0000,0000 0 0 420 個時鐘周期轉換一次
- //---------------------------------------------------------------------
- uint ad_zhuanhuan(uchar channel)
- {
- uchar AD_finished=0; //存儲 A/D 轉換標志
- ADC_RES = 0; //高八位清零
- ADC_RESL = 0; //低兩位清零
- channel &= 0x07; //0000,0111 清0高5位
- ADC_CONTR = AD_SPEED;
- _nop_();
- ADC_CONTR |= channel; //選擇 A/D 當前通道
- _nop_();
- ADC_CONTR |= 0x80; //啟動 A/D 電源
- delay(1); //使輸入電壓達到穩定
- ADC_CONTR |= 0x08; //0000,1000 令 ADCS = 1, 啟動A/D轉換,
- AD_finished = 0;
- while (AD_finished ==0 ) //等待A/D轉換結束
- {
- AD_finished = (ADC_CONTR & 0x10); //0001,0000 測試A/D轉換結束否
- }
- ADC_CONTR &= 0xE7; //1111,0111 清 ADC_FLAG 位, 關閉A/D轉換,
- return (ADC_RES*256+ADC_RESL); //返回 A/D 高 8 位轉換結果
- }
- void main() //主程序
- {
- P4SW=0x70; //0x70=0111 0000 ,將P4.4 P4.5 P4.6設置成IO口
- init();
- // ADRJ = AUXR1^2:
- // 0: 10 位A/D 轉換結果的高8 位放在ADC_RES 寄存器, 低2 位放在ADC_RESL 寄存器
- // 1: 10 位A/D 轉換結果的最高2 位放在ADC_RES 寄存器的低2 位, 低8 位放在ADC_RESL 寄存器
- // AUXR1 &= ~0x04;
- //0000,0100, 令 ADRJ=0
- AUXR1 |= 0x04; //0000,0100, 令 ADRJ=1
- ADC_CONTR |= 0x80; //1000,0000 打開 A/D 轉換電源,啟動AD轉換
- P1ASF = 0x03; //0000,0011, 將 P1.0 P1.1 置成模擬口
- while(1)
- {
- voL= ADC_resultL*5.0; //左聲道電平轉換結果。語句中5.0=5*1.0其中*1.0是必不可少
- //的,不然C語言作整數處理,沒有想要的結果產生.
- if(voL>2000) numL=14;
- else if(voL>1635) numL=13;
- else if(voL>1432) numL=12;
- else if(voL>1270) numL=11;
- else if(voL>1130) numL=10;
- else if(voL>1006) numL=9;
- else if(voL>895) numL=8;
- else if(voL>797) numL=7;
- else if(voL>709) numL=6;
- else if(voL>650) numL=5;
- else if(voL>400) numL=4;
- else if(voL>262) numL=3;
- else if(voL>159) numL=2;
- else if(voL>70) numL=1;
- else numL=0;
- if(pfL<=numL) //檢測如果漂浮物不高于峰值就讓漂浮物置于峰值上面,同時 標志位 置0
- {
- pfL=numL+1;
- biaozhiL=0; //標志位 置0
- xuantingL=10; //變量xuantingL 改變此值可以設定左漂浮物懸停時間
- }
- else //if(pfL>numL) 如果漂浮物高于峰值就把標志位置1
- {
- biaozhiL=1; //標志位 置1
- }
- displayL(); //顯示左聲道具體電平值的段
- voR= ADC_resultR*5.0; //左聲道電平轉換結果。原理同上邊左聲道
- if(voR>2000) numR=14;
- else if(voR>1635) numR=13;
- else if(voR>1432) numR=12;
- else if(voR>1270) numR=11;
- else if(voR>1130) numR=10;
- else if(voR>1006) numR=9;
- else if(voR>895) numR=8;
- else if(voR>797) numR=7;
- else if(voR>709) numR=6;
- else if(voR>650) numR=5;
- else if(voR>400) numR=4;
- else if(voR>262) numR=3;
- else if(voR>159) numR=2;
- else if(voR>70) numR=1;
- else numR=0;
-
- if(pfR<=numR)
- {
- pfR=numR+1;
- biaozhiR=0;
- xuantingR=10;
- }
- else
- {
- biaozhiR=1;
- }
- displayR(); //顯示右聲道具體電平值的段
- }
- }
- void timer0() interrupt 1 //定時器0中斷程序
- {
- TH0=0xb1;
- TL0=0xe0;
- tt0++;
- if (tt0>=1) //20ms轉換一次.
- {
- tt0=0;
- ADC_resultL = ad_zhuanhuan(0); //P1.0 為 A/D 當前通道, 測量結果存ADC_result0
- ADC_resultR = ad_zhuanhuan(1); //P1.1 為 A/D 當前通道, 測量結果存ADC_result7
-
- }
- }
- void timer1() interrupt 3 //定時器1中斷程序
- {
- //再裝一次初值
- TH1=0xd8;
- TL1=0xf0;
-
- tt1++;
- if(tt1>=1)
- {
- if(biaozhiL)
- {
- ttL++;
- if(ttL>7) //改變此值可以設定左漂浮物下降速度
- {
- if(xuantingL==0)
- pfL--;
- else if(xuantingL>0)
- xuantingL--;
- ttL=0;
- }
- }
-
- if(biaozhiR)
- {
- ttR++;
- if(ttR>7) //改變此值可以設定右漂浮物下降速度
- {
- if(xuantingR==0)
- pfR--;
- else if(xuantingR>0)
- xuantingR--;
- ttR=0;
- }
- }
- tt1=0;
- }
- }
復制代碼
51hei.png (5.73 KB, 下載次數: 112)
下載附件
2021-12-10 16:22 上傳
附件只包含上面代碼的Keil工程(如上圖):
電平指示.rar
(94.75 KB, 下載次數: 65)
2021-12-10 08:32 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|