TLC5615 产生频率可变的正弦波

此时此刻 在心里默默的问自己一下  是不是个傻X  后天就考检测了  作为从来没听过一节课的我  现在还没看多少 却想着这个破玩意   哎     不过还是大概的翻了一下课本  其实有点后悔没听课 仔细看了一下  书里面的东西还是挺有用的  并且和自控  模电有大量的联系 更加坚信了一点  所有的学科都不是独立存在的  真的是一个相互联系的有机整体 如果正在上大学的你看到 请坚信  大学里面学到的那些理论真的很有用! 哈哈哈  纯属个人扯淡淡  不喜勿喷

进入正题:

TLC5615 产生频率可变的正弦波和三角波

三角波直接在最后附上代码

在大一的时候写过这个5615的基本程序  就是给个数字量 输出一个简单的模拟量  那之后没有深入下去管他  当时更不知道SPI这个冬冬    现在重新再学一下      昨天是做了一个产生正弦的波形可是  频率不可调 其实这样意义不大 所以决定做一下频率可调的用5615   直接这样说 :

利用中断  假设我们采样的点数是128个  每次进入中断  我在中断里面向5615写一个正弦表里面的值 这样进入128次中断即可写完一个周期的正弦波形  自然而然 这个波形的周期 就位128*中断时间    这样我们只要改变进入中断的时间即可改变输出正弦波形的周期  依据这个理论思想固然没有错 但是请注意:

1:如果我们把写函数  Write_TLC5615(sine[n++]);  放在中断里面  下面我把这个函数贴出来

void  Write_TLC5615(uint date)
{
    uint i;
TLC5615_SCLK=0;
TLC5615_CS=0;
date<<=6;
for(i=0;i<12;i++)
{
TLC5615_DIN=(bit)(date&0x8000);
TLC5615_SCLK=1;
date<<=1;
TLC5615_SCLK=0;
}
TLC5615_CS=1;
TLC5615_SCLK=0;

这是向5615写入数据的函数  我们以89c52单片机为例   如果你学过汇编  就应该大概知道  写一个数据也就是执行一遍这个写函数需要执行的指令周期是多少  这里我们设他为100US  (虽然我不太会汇编  应该差不太多吧 哈哈)

也就是说 即使我们不放在中断里面 放在主函数的while(1)里面全速的写 128个点的话 128*100 也要12.8ms  也就是说你最大产生的频率还不到100HZ  (这里我们假设的那段代码100US哈) 所以即使你产生可变频率的正弦波也只是100HZ以下的可变正弦波   但是请注意  这个函数是有执行时间的  也就是说我们把他放在中断里面 你进入中断的时间绝对不能大于中断里面代码的执行时间   !!!!!

我在百度这个资料的时候看到过这样一个问题  这里贴出来  供我们一起体会 

其实这个问题 我个人觉得就是上面我们所说的问题 无论你进入中断的速度有多快  你取得点数和你写函数写一个点执行的时间 两者的乘积决定了你正弦频率的最大值   OK?


2:这里顺便说一下那128个正弦表的点到底是如何得到的!

首先这里的128不是固定的 使我们自己认为设定的  你可以设定68个 或者1024或者别的 但是不要太大也不要太小   至于为什么 自己思考吧   哈哈  那么 这里我们还是以128个点来说明这里的128个正弦表的数值是如何计算出来的 首先无论你去多少点 正弦的一个周期走过的角度都是360度   那个128个点的话   每个点所占据的地盘是360/128   将这个值幻化成弧度制  就是  度数*π/180    用sin 求出来这点正弦值  用这个值成衣我们DA转换的最大输入数字量的一半+在加上这个最大输入量的一半  至于为什么这么做  简单说一下  因为我们的参考电压为正值  虽然是个正弦波但是我们也不能输出来负值 这点是由我们的硬件决定的 最大值的一半就相当于我们常见正弦波的那个X轴的0 就是给这个波形找了一个参考“零点”  仔细想一下  太懒了 不做太详细的说明 下面 我附上我计算正弦表的一段C语言代码  大家仔细体会思考一下   VC++6.0运行即可得到128个正弦点 直接付给DA转换即可

# include "stdio.h"
# include "math.h"
# define max 800
int A[128]={0};//用来存放正弦表
void main()
{
int i=0; 
double a,b;   //a:角度 b:弧度
a=360.000/128; 
for(i=0;i<128;i++)
{
b=a*i*0.01744; //角度转弧度  弧度=角度*(π/180)
A[i]=(int)((max/2)*sin(b)+(max/2));
printf("%d,",A[i]);
}
}

3:大家看上面的代码 最大值我并没有取1024    这是因为如果TLC5615的最大值1024 带入上段的代码中 你会发现 在输出电压上的峰值上会有那么一点失真  此时参(参参考电压是2.5V)按理来说最大可以输出5V  但是 根本到不了 4.8左右吧  这个我也不知道为什么  把 1024改小点 或者稍微增大一点参考电压应该就没问题了  

4:下面我附上代码和仿真电路图 代码中我只取了90个点  按键是用来改变进入中断的时间的 也就是用来调整正弦波频率的  按键按下的时候可以明显看到正弦波形的频率增大  声明一下 没有实物验证 没有实物验证 没有实物验证  !!

但是理论上大概是这样

#include<reg52.h>
# include"math.h"
#define   uint  unsigned int
#define   uchar unsigned char
uint    code sine_dot1[90]=
{
	400,427,455,483,510,536,562,587,611,634,656,677,697,715,731,746,759,770,780,
	788,793,797,799,799,797,794,788,780,771,759,746,731,715,697,678,657,635,612,
	588,563,537,511,484,456,428,400,373,345,317,290,264,238,213,188,165,143,122,
	103,85,69,54,41,29,19,12,6,2,0,0,2,5,11,19,28,39,52,67,83,101,120,141,163,
	186,210,235,261,287,315,342,370
};
sbit TLC5615_SCLK=P2^4;
sbit TLC5615_CS=P2^5;
sbit TLC5615_DIN=P2^6;
sbit K=P1^2;
int num=1000;
void delay(uint k)
{					   
	uint i,j;
	for(i=11;i>0;i--)
		for(j=k;j>0;j--);
}
void  Write_TLC5615(uint date)
{
    uint i;
	TLC5615_SCLK=0;
	TLC5615_CS=0;
	date<<=6;
	for(i=0;i<12;i++)
	{
		TLC5615_DIN=(bit)(date&0x8000);
		TLC5615_SCLK=1;
		date<<=1;
		TLC5615_SCLK=0;			
	}
	TLC5615_CS=1;
	TLC5615_SCLK=0;

} 
void init()  
{  
    TMOD=0x01;   
    TH0=(65536-num)/256;  
    TL0=(65536-num)%256;  
    EA=1;  
    ET0=1;  
    TR0=1;  
}  
void Key()
{
	if(K==0)
	{
		delay(10);
		while(!K);
		num+=1000;
		if(num==20000)
			num=1000;			
	}
}

void main()
{
	
	init() ;
	while(1)
	{
		Key();	
	}
} 
void T0_Time() interrupt 1  
{  
	int n;
    TH0=(65536-num)/256;  
    TL0=(65536-num)%256;  
	Write_TLC5615(sine_dot1[n++]);
	 	if(n>=90) n=0;
}          

三角波代码 

#include<reg52.h>
#define   uint  unsigned int
#define   uchar unsigned char
sbit TLC5615_SCLK=P2^4;
sbit TLC5615_CS=P2^5;
sbit TLC5615_DIN=P2^6;
sbit K1=P1^0; //K1  K2分别用来控制幅值的增减 
sbit K2=P1^1;
sbit K3=P1^2;//K3  K4用来 控制频率的增减
sbit K4=P1^3;
uint num1=0,num2=0;
void Delay_Mms(uint k)
{					   
	uint i,j;
	for(i=113;i>0;i--)
		for(j=k;j>0;j--);
}
void Dleay_Nus(uint u)
{
	for(u;u>0;u--);
}
void  Write_TLC5615(uint date)
{
    uint i;
	TLC5615_SCLK=0;
	TLC5615_CS=0;
	date<<=6;
	for(i=0;i<12;i++)
	{
		TLC5615_DIN=(bit)(date&0x8000);
		TLC5615_SCLK=1;
		date<<=1;
		TLC5615_SCLK=0;			
	}
	TLC5615_CS=1;
	TLC5615_SCLK=0;

}  

void Key()
{
	if(K1==0)
	{
		Delay_Mms(10);
		while(!K1);	
		num1+=10;	//num1增加或者减少 相应的幅值就增加或者减少  这里 选择增量为10  是为了更好的看到效果 
		if(num1==1000)		//num1的值越小幅值增加越小  下面的num2和这个一样
			num1=0;			
	}
	if(K2==0)
	{
		Delay_Mms(10);
		while(!K1);
		if(num1>=10)
		{
		   num1-=10;
		}
		if(num1<10)
			num1=0;			
	}

	if(K3==0)
	{
		Delay_Mms(10);
		while(!K3);
		num2+=10;
		if(num2==1000)
			num2=0;			
	}

	if(K4==0)
	{
		Delay_Mms(10);
		while(!K4);
		if(num2>=10)
		{
		   num2-=10;
		}
		if(num2<=10)
			num2=0;			
	}
	
}

void main()
{
	uint n;
	while(1)
	{
		for(n=0;n<100;n++)
		{
			Write_TLC5615(n+num1);
			Dleay_Nus(num2);	
		}
		for(n=100;n>0;n--)//这里的判定条件曾经写的n>=0;  有兴趣可以试试  出来的波形完全不一样  至于为什么  自己想吧
		{
			Write_TLC5615(n+num1);
			Dleay_Nus(num2);	
		} 
		Key();	
	}
}           


今天差不多就学习这么多  前面的文章中 有对TLC5615的其他一些基本介绍  有兴趣可以看看

http://blog.csdn.net/hopesunice/article/details/77726465

学艺不精  错误之处应该很多  欢迎一起学习 哈哈哈哈

  • 14
    点赞
  • 69
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值