用MCU产生一个正弦或余弦信号通常的办法便是制作一个正弦/余弦表,该种方法直接,简便,通常用于对精度要求不是很高的场合,而且所需的存储空间随表的大上而变,在有限的存储空间中制作这样一个表是较浪费的!利用信号与系统的概念我们可以将所产生的正弦信号看作对一个系统的冲激响应:H(n)=sin(WoTsn)U(n),对其作相应的Z变换即可得到该数字系统的系统参数.该种办法所需存储空间大大缩小,且精度高,通用性强!
源程序是以C和汇编混合编程的方式在CCS上仿真的,原本是想通过CCS的图形功能适时地实现正弦值的替换试验了多次没有成功所以最终通过数组的形式保存了200个值以供参考。C编程中同样需要编写中段向量,本例程中的中断向量表被重新映射到了0x0080开始的程序存储空间,这一点是需要注意的,但是有一点程序开始仍然是从从从0xff80处开始,因为复位向量的地址并没有随之改变。另外有一点需要注意的便是中断服务程序的申名方式,例程中为: interrupt void timer0{},timer0这一名称需要在向量表中定义: .ref _timer0,为什么需要在timer0前面加一下划线我至今没能搞懂!
#define PI 3.1415926
#define aa 2*cos(2*PI*2000/40000) /*2*0.95105652*/
#define bb -1
#define cc sin(2*PI*2000/40000) /*0.309016199*/
float y0,y1,y2;
float result[200];
char over;
void main()
{
y1=cc;
y2=aa*y1;
result[0]=0;
result[1]=y1;
result[2]=y2;
/*asm(" stm #00a0h, PMST ");*/ //MP/MC = 0, IPTR = 001,ovly=1
asm(" STM #0h,IMR ");
asm(" STM #0010h,TCR "); //关定时器
asm(" STM #2499,PRD ");//25us
asm(" STM #0C20h,TCR "); //TCR=最后四位
asm(" STM #0008h,IFR ");
asm(" ORM #0008h,*(IMR) ");/*开时间中断*/
asm(" RSBX INTM "); /*开中断*/
while(1);
}
interrupt void timer0()
{
static int i=3;
y0 = (aa*y2+bb*y1);
y1 = y2;
y2 = y0;
result[i++] = y0;
if(i==200)
{
asm(" SSBX INTM ");
over=1;
}
}
/*******************************************************************/
MEMORY {
PAGE 0:
RESEVE: org 00h len = 0x80
PAGE 0:
PROG1: org = 0x0100 len = 0x1200 /*数据存储区一部分被调用作为程序存储区*/
PAGE 0:
VECT: org = 0x0080, len = 0x80 /*这里正好验证了PMST=0x00a0h,因为*/
/*其中IPTR=001,所以向量集体搬移到0x0080了*/
PAGE 1:
RESEVE1: org 00h len = 0x1300
PAGE 1:
DARAM2: org = 0x1300 len = 0x400
PAGE 1:
DARAM1: org = 0x1700 len = 0x2900
}
SECTIONS{
.text : > PROG1 PAGE 0
.cinit : > PROG1 PAGE 0 /*存放C程序中的变量的初值和常量*/
.switch: > PROG1 PAGE 0
.vectors:> VECT PAGE 0
.const: > DARAM1 PAGE 1 /*存放C程序中的字符常量,浮点常量和用CONST申明的常量*/
.bss : > DARAM1 PAGE 1 /*为C语言中的全局或静态变量保留存储空间*/
.stack : > DARAM2 PAGE 1
.system: > DARAM2 PAGE 1 /*用于C程序中的动态分配存储空间*/
.data : > DARAM2 PAGE 1
}