此时此刻 在心里默默的问自己一下 是不是个傻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
学艺不精 错误之处应该很多 欢迎一起学习 哈哈哈哈