先写了第一个程序如下,很简单,输出频率能达到500HZ左右,如图。
#include<iom16v.h>
#include<macros.h>
#define uchar unsigned char
#define uint unsigned int
unsigned char k=0,c=1;
unsigned char i;
#pragma data:code
flash unsigned char juchi[147]={
9,38,76,116,154,188,223,247,254,234,164,50,1,9,38,76,116,154,187,217,239,252,254,240,205,145,68,19,1,1,10,22,35,49,61,73,83,90,97,101,104,104,103,99,94,87,78,68,56,43,29,16,5,0,6,36,102,175,224,248,254,247,230,204,172,136,97,58,23,1,13,101,204,247,253,237,208,170,126,83,41,8,2,60,175,237,254,248,227,197,162,125,89,54,25,4,1,26,91,166,215,240,252,254,252,246,240,232,224,216,209,204,200,198,197,198,200,204,209,216,223,231,239,246,252,254,252,241,217,170,97,29,1,4,23,52,87,123,160,195,224,246,254,239,181,66,3
};
#pragma data:data
int f=0;//示波器上请改变此频率
//sbit cs = Pc^3;
//sbit clk = Pc^4;
//sbit din = Pc^5;
void DA_Conver(unsigned char DAValue)
{
PORTC&=0B11110111;//cs=0
PORTC&=0B11101111;//clk=0;
for(i = 0; i < 8; i++)
{
if(DAValue&0B10000000) {PORTC |= 0B00100000;}
else {PORTC&=0B11011111;}
PORTC|=0B00010000;//clk = 1;
DAValue <<= 1;
PORTC&=0B11101111; //clk = 0;
}
//9位数据为0
PORTC|=0B00010000;//clk = 1;
PORTC&=0B11101111; //clk = 0;
//10位数据为0
PORTC|=0B00010000;//clk = 1;
PORTC&=0B11101111; //clk = 0;
//第一个填充字节
PORTC|=0B00010000;//clk = 1;
PORTC&=0B11101111; //clk = 0;
//第二个填充字节
PORTC|=0B00010000;//clk = 1;
PORTC&=0B11101111; //clk = 0;
PORTC|=0B00001000;//cs = 1;
}
void delaynus(unsigned int n)
{
if (n == 0)
return ;
while (--n);
}
void main(void) //主函数
{
unsigned char i,j;
DDRC=0xff;
PORTC=0xff;
f=0;
while(1)
{
DA_Conver(juchi[k]);
delaynus(f);
k++;
if(k==147) k=0;
}
}
后来加上了一些1602液晶显示和按键选择波形频率,然后最高频率就降到260了,这是为什么呀?DDS的程序几乎完全不变
#include<iom16v.h> //包含单片机寄存器的头文件
#include<macros.h> //包含_nop_()函数定义的头文件
#define uchar unsigned char
#define uint unsigned int
/*******************************************************************************
以下是对液晶模块的操作程序
*******************************************************************************/
#define RS_0 PORTC&=~(1<<PC0)
#define RS_1 PORTC|=(1<<PC0)
#define RW_0 PORTC&=~(1<<PC1)
#define RW_1 PORTC|=(1<<PC1)
#define E_0 PORTC&=~(1<<PC2)
#define E_1 PORTC|=(1<<PC2)
#pragma data:code //数据较多,存入flash
flash unsigned char juchi[147]={
9,38,76,116,154,188,223,247,254,234,164,50,1,9,38,76,116,154,187,217,239,252,254,240,205,145,68,19,1,1,10,22,35,49,61,73,83,90,97,101,104,104,103,99,94,87,78,68,56,43,29,16,5,0,6,36,102,175,224,248,254,247,230,204,172,136,97,58,23,1,13,101,204,247,253,237,208,170,126,83,41,8,2,60,175,237,254,248,227,197,162,125,89,54,25,4,1,26,91,166,215,240,252,254,252,246,240,232,224,216,209,204,200,198,197,198,200,204,209,216,223,231,239,246,252,254,252,241,217,170,97,29,1,4,23,52,87,123,160,195,224,246,254,239,181,66,3
};
flash unsigned char juchi2[147]={
219,254,158,0,54,144,221,254,167,1,41,123,201,249,235,72,2,52,124,190,239,254,207,60,0,25,72,121,166,204,233,250,254,244,218,173,117,67,34,17,9,5,4,6,10,20,39,75,128,182,224,247,254,248,228,197,158,112,62,17,1,91,224,254,231,178,110,40,0,115,246,243,187,106,27,10,202,254,208,126,38,5,197,253,206,120,32,11,210,252,200,115,30,9,200,254,213,139,58,1,82,237,250,209,145,77,19,4,120,232,254,237,203,161,115,74,38,11,0,10,51,112,165,199,219,230,236,238,238,235,228,215,192,154,96,37,5,1,17,47,84,127,172,213,244,254,215};
flash unsigned char juchi8[147]={
9,38,76,116,154,188,223,247,254,234,164,50,1,9,38,76,116,154,187,217,239,252,254,240,205,145,68,19,1,1,10,22,35,49,61,73,83,90,97,101,104,104,103,99,94,87,78,68,56,43,29,16,5,0,6,36,102,175,224,248,254,247,230,204,172,136,97,58,23,1,13,101,204,247,253,237,208,170,126,83,41,8,2,60,175,237,254,248,227,197,162,125,89,54,25,4,1,26,91,166,215,240,252,254,252,246,240,232,224,216,209,204,200,198,197,198,200,204,209,216,223,231,239,246,252,254,252,241,217,170,97,29,1,4,23,52,87,123,160,195,224,246,254,239,181,66,3
};
flash unsigned char juchi3[147]={
9,38,76,116,154,188,223,247,254,234,164,50,1,9,38,76,116,154,187,217,239,252,254,240,205,145,68,19,1,1,10,22,35,49,61,73,83,90,97,101,104,104,103,99,94,87,78,68,56,43,29,16,5,0,6,36,102,175,224,248,254,247,230,204,172,136,97,58,23,1,13,101,204,247,253,237,208,170,126,83,41,8,2,60,175,237,254,248,227,197,162,125,89,54,25,4,1,26,91,166,215,240,252,254,252,246,240,232,224,216,209,204,200,198,197,198,200,204,209,216,223,231,239,246,252,254,252,241,217,170,97,29,1,4,23,52,87,123,160,195,224,246,254,239,181,66,3
};
flash unsigned char juchi4[147]={
9,38,76,116,154,188,223,247,254,234,164,50,1,9,38,76,116,154,187,217,239,252,254,240,205,145,68,19,1,1,10,22,35,49,61,73,83,90,97,101,104,104,103,99,94,87,78,68,56,43,29,16,5,0,6,36,102,175,224,248,254,247,230,204,172,136,97,58,23,1,13,101,204,247,253,237,208,170,126,83,41,8,2,60,175,237,254,248,227,197,162,125,89,54,25,4,1,26,91,166,215,240,252,254,252,246,240,232,224,216,209,204,200,198,197,198,200,204,209,216,223,231,239,246,252,254,252,241,217,170,97,29,1,4,23,52,87,123,160,195,224,246,254,239,181,66,3
};
flash unsigned char juchi5[147]={
9,38,76,116,154,188,223,247,254,234,164,50,1,9,38,76,116,154,187,217,239,252,254,240,205,145,68,19,1,1,10,22,35,49,61,73,83,90,97,101,104,104,103,99,94,87,78,68,56,43,29,16,5,0,6,36,102,175,224,248,254,247,230,204,172,136,97,58,23,1,13,101,204,247,253,237,208,170,126,83,41,8,2,60,175,237,254,248,227,197,162,125,89,54,25,4,1,26,91,166,215,240,252,254,252,246,240,232,224,216,209,204,200,198,197,198,200,204,209,216,223,231,239,246,252,254,252,241,217,170,97,29,1,4,23,52,87,123,160,195,224,246,254,239,181,66,3
};
flash unsigned char juchi6[147]={
9,38,76,116,154,188,223,247,254,234,164,50,1,9,38,76,116,154,187,217,239,252,254,240,205,145,68,19,1,1,10,22,35,49,61,73,83,90,97,101,104,104,103,99,94,87,78,68,56,43,29,16,5,0,6,36,102,175,224,248,254,247,230,204,172,136,97,58,23,1,13,101,204,247,253,237,208,170,126,83,41,8,2,60,175,237,254,248,227,197,162,125,89,54,25,4,1,26,91,166,215,240,252,254,252,246,240,232,224,216,209,204,200,198,197,198,200,204,209,216,223,231,239,246,252,254,252,241,217,170,97,29,1,4,23,52,87,123,160,195,224,246,254,239,181,66,3
};
flash unsigned char juchi7[147]={
9,38,76,116,154,188,223,247,254,234,164,50,1,9,38,76,116,154,187,217,239,252,254,240,205,145,68,19,1,1,10,22,35,49,61,73,83,90,97,101,104,104,103,99,94,87,78,68,56,43,29,16,5,0,6,36,102,175,224,248,254,247,230,204,172,136,97,58,23,1,13,101,204,247,253,237,208,170,126,83,41,8,2,60,175,237,254,248,227,197,162,125,89,54,25,4,1,26,91,166,215,240,252,254,252,246,240,232,224,216,209,204,200,198,197,198,200,204,209,216,223,231,239,246,252,254,252,241,217,170,97,29,1,4,23,52,87,123,160,195,224,246,254,239,181,66,3
};
#pragma data:data //跳出flash
unsigned char const string[ ]= {"Signal? \0"};
unsigned char const string1[ ]={"Press K1 or K2\0"};
unsigned char const string2[ ]= {"Freq? press \0"};
unsigned char const string3[ ]={"K3-K8: 1hz-1khz \0"};
unsigned char const string4[ ]={"Enjoy it ! "};
uchar a=0,b=0;
long int f=0,zhouqi=0,k=0,i=0;
//sbit cs = Pc^3;
//sbit clk = Pc^4;
//sbit din = Pc^5;
void DA_Conver(unsigned char DAValue)
{
PORTC&=0B11110111;//cs=0
PORTC&=0B11101111;//clk=0;
for(i = 0; i < 8; i++)
{
if(DAValue&0B10000000) {PORTC |= 0B00100000;}
else {PORTC&=0B11011111;}
PORTC|=0B00010000;//clk = 1;
DAValue <<= 1;
PORTC&=0B11101111; //clk = 0;
}
//9位数据为0
PORTC|=0B00010000;//clk = 1;
PORTC&=0B11101111; //clk = 0;
//10位数据为0
PORTC|=0B00010000;//clk = 1;
PORTC&=0B11101111; //clk = 0;
//第一个填充字节
PORTC|=0B00010000;//clk = 1;
PORTC&=0B11101111; //clk = 0;
//第二个填充字节
PORTC|=0B00010000;//clk = 1;
PORTC&=0B11101111; //clk = 0;
PORTC|=0B00001000;//cs = 1;
}
/*****************************************************
函数功能:延时若干微秒
入口参数:n
***************************************************/
void delaynus(unsigned int n)
{
if (n == 0)
return ;
while (--n);
}
/*****************************************************
函数功能:延时若干毫秒
入口参数:n
***************************************************/
void delay(uint xms)
{
int i,j;
for(i=0;i<xms;i++)
{ for(j=0;j<1140;j++) ; }
}
/*****************************************************
函数功能:将模式设置指令或显示地址写入液晶模块
入口参数:dictate
***************************************************/
void Write_com (unsigned char dictate)
{
DDRA=0xff;
RS_0; //根据规定,RS和R/W同时为低电平时,可以写入指令
RW_0;
E_0; //E置低电平(根据表8-6,写指令时,E为高脉冲,
// 就是让E从0到1发生正跳变,所以应先置"0"
delaynus(50); //空操作两个机器周期,给硬件反应时间
PORTA=dictate; //将数据送入P0口,即写入指令或地址
delaynus(40); //空操作四个机器周期,给硬件反应时间
E_1; //E置高电平
delaynus(40);
E_0; //当E由高电平跳变成低电平时,液晶模块开始执行命令
}
/*****************************************************
函数功能:指定字符显示的实际地址
入口参数:x
***************************************************/
void WriteAddress(unsigned char x)
{
Write_com(x|0x80); //显示位置的确定方法规定为"80H+地址码x"
}
/*****************************************************
函数功能:将数据(字符的标准ASCII码)写入液晶模块
入口参数:y(为字符常量)
***************************************************/
void WriteData(unsigned char y)
{
DDRA=0xff;
RS_1; //RS为高电平,RW为低电平时,可以写入数据
RW_0;
E_0; //E置低电平(根据表8-6,写指令时,E为高脉冲,
// 就是让E从0到1发生正跳变,所以应先置"0"
PORTA=y; //将数据送入P0口,即将数据写入液晶模块
delaynus(40); //空操作四个机器周期,给硬件反应时间
E_1; //E置高电平
delaynus(40); //空操作四个机器周期,给硬件反应时间
E_0; //当E由高电平跳变成低电平时,液晶模块开始执行命令
}
/*****************************************************
函数功能:对LCD的显示模式进行初始化设置
***************************************************/
void LcdInt(void)
{
delay(15); //延时15ms,首次写指令时应给LCD一段较长的反应时间
Write_com(0x38); //显示模式设置:16×2显示,5×7点阵,8位数据接口
delay(5); //延时5ms
Write_com(0x38);
delay(5);
Write_com(0x38); //3次写 设置模式
delay(5);
Write_com(0x0C); //显示模式设置:显示开,有光标,光标闪烁
delay(5);
Write_com(0x06); //显示模式设置:光标右移,字符不移
delay(5);
Write_com(0x01); //清屏幕指令,将以前的显示内容清除
delay(5);
}
void main(void) //主函数
{
unsigned char i,j;
PORTA=0xff;//A口全部置为输出,用来控制LED1602
DDRA=0xff;
PORTC=0xff;//C口全部置为输出,1-3脚用来控制LED1602,4-6控制5615
DDRC=0xff;
PINB=0xff;//B口全部设为输入,用来按键选择波形和频率
DDRB=0x00;
PIND=0xff;//D口全部设为输入,用来按键选择波形和频率
DDRD=0x00;
LcdInt(); //调用LCD初始化函数
delay(10);
Write_com(0x01);//清显示:清屏幕指令
delay(5);
WriteAddress(0x00); // 设置显示位置为第一行的第1个字
delay(5);
i = 0;
while(string != '\0') //'\0'是数组结束标志
{
WriteData(string);
i++;
delay(100);
}
WriteAddress(0x40); // 设置显示位置为第二行的第1个字
i = 0;
while(string1 != '\0') //'\0'是数组结束标志
{
WriteData(string1);
i++;
delay(100);
}
while(1){
if (~PIND&0B00000100){a=1;break;}
if (~PIND&0B00001000){b=1;break;}
}
Write_com(0x01);//清显示:清屏幕指令
delay(5);
WriteAddress(0x00); // 设置显示位置为第一行的第1个字
delay(5);
i = 0;
while(string2 != '\0') //'\0'是数组结束标志
{
WriteData(string2);
i++;
delay(100);
}
WriteAddress(0x40); // 设置显示位置为第二行的第1个字
i = 0;
while(string3 != '\0') //'\0'是数组结束标志
{
WriteData(string3);
i++;
delay(100);
}
while(1){
if (~PIND&0B00010000){f=1000;break;}
if (~PIND&0B00100000){f=500;break;}
if (~PINB&0B00010000){f=200;break;}
if (~PINB&0B00100000){f=50;break;}
if (~PINB&0B01000000){f=20;break;}
if (~PINB&0B10000000){f=0;break;}
}
Write_com(0x01);//清显示:清屏幕指令
delay(5);
WriteAddress(0x00); // 设置显示位置为第一行的第1个字
delay(5);
i = 0;
while(string4 != '\0') //'\0'是数组结束标志
{
WriteData(string4);
i++;
delay(100);
}
if (a){
while(1)//如果选择波形1
{
DA_Conver(juchi[k]);
k++;
if(k==147) k=0;
delaynus(f);
}
}
else {
while(1)//如果选择波形2
{
DA_Conver(juchi2[k]);
k++;
if(k==147) k=0;
delaynus(f);
}
}
}
请问这是为什么啊??该怎么解决呢。。。谢谢大家!
|