📄 51
字号:
#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 + -