?? 三角波.c
字號:
#include <reg51.h> //幅值0~5 可調 頻率100~1000
#include <absacc.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define DAC1_h XBYTE[0x7FFF] //1230的高地址
#define DAC1_l XBYTE[0x3FFF] //1230的低地址 且啟動轉換
sbit CS7221 = P1^1; // 7221的片選
sbit DIN7221 = P1^0; // 7221的數據端
sbit CLK7221 = P1^2; // 7221的時鐘端
uchar DISPBUF[8]={0,1,2,3,4,5,6,7}; //顯示緩沖區
sbit so=P1^5; //165的數據輸出端
sbit sh=P1^4; //165的轉載移位端
sbit clk=P1^3; //165的時鐘端
#define fosc 12 // 晶振頻率
uint idata time0_0; // 臨時變量,用于計算定時
uint time0; //定時時間長度
uint pinlv=100; //頻率 默認為100
bit TIME1=0; //用于定時標志
bit kaishi=0; //用于定時標志
void delay(uint n); //延時子程序
void Initial7221(void); //MAX7221初始化
void WR7221(uchar addr,uchar Data); //MAX7221寫程序
void Max7221Display(uchar *buffer); //MAX7221顯示程序
void time2ms(void); //定時器0初始化程序
void time0_int(void); //定時器0中斷服務程序
void send(uchar high, uchar low); //DAC1230輸出轉換啟動
void DAC1230(void); //輸出三角波
uchar scankey(void); //鍵盤掃描
void key(void); //鍵盤處理
void disp(void); //顯示頻率
main()
{
Initial7221(); //初始化MAX7221
Max7221Display(&DISPBUF[0]); //顯示01234567
delay(10000); //延時
disp(); //顯示頻率
time2ms(); //定時器初始化
while(1)
{
key(); //鍵盤處理
if(kaishi==1) //允許輸出三角波
{
DAC1230(); //輸出三角波
}
}
}
void send(uchar high, uchar low) //DAC1230輸出轉換啟動
{
DAC1_h=((high<<4)|(low>>4)); //高8位輸出
DAC1_l=(low<<4); //低4位輸出 啟動轉換
}
void DAC1230(void) //輸出三角波
{
uchar i,k;
for(k=0;k<=15;k++) //上升 高字節調節
{
for(i=0;i<=5;i++) //低字節調節 一個周期 16*6=96個輸出
{
send(k,i*51); //DAC1230輸出
do{;}while(TIME1!=1); //沒到時間時 等待
TIME1=0; //清時間標志
}
}
for(k=0;k<=15;k++) //下降 高字節調節
{
for(i=0;i<=5;i++) //低字節調節
{
send(15-k,255-i*51);
do{;}while(TIME1!=1); //沒到時間時 等待
TIME1=0; //清時間標志
}
}
}
//-------------掃描鍵盤,返回鍵值i=(0-7) 無按鍵按下時j=0f--------------------
uchar scankey(void)
{
uchar i=0,j=0x0f;
sh=0; //采集 裝載
delay(1);
sh=1; // 可以移位了
delay(100);
for(i=0;i<8;i++) //8位按鍵 讀入
{
clk=0; //先 讀第一位
if(so==0) //對應鍵按下為0 否則為1
return(i); //返回鍵號
clk=1; //上升沿 移位
}
return(j); //無按鍵按下時 返回0f
}
void key(void)
{
uchar k;
uint pinlv0; //暫存頻率數
pinlv0=pinlv;
k=scankey(); //讀鍵號
if(k==0) //調節頻率按鍵 按下嗎
{
delay(1000); //延時去抖
k=scankey();
if(k==0) //調節頻率按鍵 按下
{
{do{k=scankey();}while(k==0);}//等待按鍵釋放時處理
for(;;)
{
k=scankey();
if(k==1) //加
{
delay(1000); //延時去抖
k=scankey();
if(k==1) //加
{ {do{k=scankey();}while(k==1);}//等待按鍵釋放時處理
pinlv0++;
if(pinlv0==1001) //頻率超過1000Hz時 調為100
{
pinlv0=100;
}
}
}
else if(k==2) //減
{
delay(1000); //延時去抖
k=scankey();
if(k==2) //減
{
{do{k=scankey();}while(k==2);}//等待按鍵釋放時處理
pinlv0--;
if(pinlv0==99) //頻率小于100Hz時 調為1000
{
pinlv0=1000;
}
}
}
else if(k==3) //確認鍵
{
delay(1000); //延時去抖
k=scankey();
if(k==3) //確認鍵
{
{do{k=scankey();}while(k==3);}//等待按鍵釋放時處理
pinlv=pinlv0;
time2ms(); //改變定時時間 變頻率
disp(); //顯示改變頻率
break; //返回
}
}
else if(k==4) //取消鍵
{
delay(1000); //延時去抖
k=scankey();
if(k==4) //取消鍵
{
{do{k=scankey();}while(k==4);}//等待按鍵釋放時處理
break; //返回
}
}
}
}
}
else if((k==5)&(kaishi==0)) //輸出三角波 按鍵按下嗎
{
delay(1000); //延時去抖
k=scankey();
if(k==5)
{
{do{k=scankey();}while(k==5);}//等待按鍵釋放
kaishi=1; //輸出三角波
}
}
else if((k==6)&(kaishi==1)) //停止輸出三角波 按鍵按下嗎
{
delay(1000); //延時去抖
k=scankey();
if(k==6)
{
{do{k=scankey();}while(k==5);}//等待按鍵釋放
kaishi=0; //停止輸出三角波
}
}
}
void time2ms(void) //T0定時器初始化
{
TMOD=0x01; // T0工作方式1
/* 定時設置 */
time0=1000000/pinlv/96; //每個D/A轉換的時間
time0_0 = 65536-time0*fosc/12; //計算初值
TH0=(time0_0/256); //裝定時器0初值
TL0=(time0_0%256);
TR0=1; //啟動定時器0
ET0=1; //打開定時器0中斷
EA=1; //打開總中斷
}
/* 定時器0中斷服務子程序,*/
void time0_int(void) interrupt 1
{
TH0=(time0_0/256); //重裝定時器0初值
TL0=(time0_0%256);
TIME1=1; //時間到標志位
}
void delay(uint n) //延時程序
{
uint i1,j1;
for (i1=0;i1<n;i1++)
for (j1=0;j1<1140;j1++);
}
void WR7221(uchar addr,uchar Data) //MAX7221的寫子程序
{
uchar i;
CS7221 = 0; //片選有效
for (i=0;i<8;i++) //寫8位地址
{
CLK7221 = 0; //時鐘低
DIN7221 = (addr&(0x80>>i)) ? 1:0;//先發高位 依次到低位
_nop_();
_nop_();
CLK7221 = 1; //時鐘高 上升沿鎖數據
_nop_();
_nop_();
}
for (i=0;i<8;i++) //寫8位數據
{
CLK7221 = 0; //時鐘低
DIN7221 = (Data&(0x80>>i)) ? 1:0;//先發高位 依次到低位
_nop_();
_nop_();
CLK7221 = 1; //時鐘高 上升沿鎖數據
_nop_();
_nop_();
}
CS7221 = 1; //片選無效
}
void Initial7221(void) //MAX7221初始化
{
WR7221(0x0A,0x0A); //亮度地址0AH,0x00~0x0F,0x0F最亮
WR7221(0x0B,0x07); //掃描LED個數地址0BH,0x00~0x07,最多掃描8個數碼管
WR7221(0x0C,0x01); //工作模式地址0x0C. 0x00:關斷;0x01:正常
WR7221(0x09,0xFF); //編碼模式地址0x09. 0x00~0xFF:哪一位為1,哪一位就支持編碼
}
void Max7221Display(uchar *buffer) //MAX7221顯示子程序
{
uchar i;
for (i=0;i<8;i++) //MAX7221的8個數碼管顯示
{
WR7221(i+1,*(buffer+i)); //調MAX7221的寫子程序
}
}
void disp(void)
{
DISPBUF[0]=pinlv/1000; //千位
DISPBUF[1]=pinlv%1000/100; //百位
DISPBUF[2]=pinlv%100/10; //十位
DISPBUF[3]=pinlv%10; //十位
Max7221Display(&DISPBUF[0]); //顯示
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -