lzcyyds 2021-09-27 22:03 采纳率: 37.5%
浏览 179
已结题

DAC0832生成正弦波有瑕疵怎么解决

我是用DAC0832进行64次取点输出生成的正弦波,正弦波取码是
uchar code sin[64]={
135,145,158,167,176,188,199,209,218,226,234,240,245,249,252,254,254,253,251,247,243,237,230,222,213,204,193,182,170,158,146,133,121,108,96,84,72,61,50,41,32,24,17,11,7,3,1,0,0,2,5,9,14,20,28,36,45,55,66,78,90,102,114,128};
但是生成的正弦波有部分异常凸起,不知道该怎么解决
还有lcd显示f=和wave form:的时候只在启动仿真的时候显示1秒,随后就没有了,不知道是哪里出了问题

img


img


//TH0=m/256

img


```c
#include<reg51.h>
#include<absacc.h>
#define dac0832 XBYTE[0x7fff]       //定义DAC0832端口地址
#define uchar unsigned char               //宏定义
#define uint unsigned int

sbit s0=P3^0;                            //定义按键的接口
sbit s1=P3^1;
sbit s2=P3^2;
sbit s3=P3^3;
sbit s4=P3^4;
sbit s5=P3^5;

                                       
sbit lcdrs=P2^5;                       //液晶控制位
sbit lcden=P2^6;

char flag1,flag2,flag3,u;                       //定义全局变量
int pinlv=100,bujin=1,bujin1=1;
uchar code table[]="0123456789";        //定义显示的数组
uchar code table1[]="f=        Wave form:";
unsigned long int m;
int a,b,h,num1,i;

//自定义字符
uchar code zifu[]={
                        0x0e,0x11,0x11,0x00,0x00,0x00,0x00,0x00,       //左半部分
                        0x00,0x00,0x00,0x00,0x11,0x11,0x0e,0x00,      //右半部分   正弦波       0  1

                        0x00,0x07,0x04,0x04,0x04,0x04,0x1c,0x00,
                        0x00,0x1c,0x04,0x04,0x04,0x04,0x07,0x00,      //矩形波       2  3

                        0x00,0x01,0x02,0x04,0x08,0x10,0x00,0x00,
                        0x00,0x10,0x08,0x04,0x02,0x01,0x00,0x00,      //三角波       4  5

};
uchar code sin[64]={                                                                                                        //一个周期采样64次,所以组内64个数据
135,145,158,167,176,188,199,209,218,226,234,240,245,249,252,254,254,253,251,247,243,237,230,222,213,204,193,182,170,158,
146,133,121,108,96,84,72,61,50,41,32,24,17,11,7,3,1,0,0,2,5,9,14,20,28,36,45,55,66,78,90,102,114,128
};                      //正弦波取码
uchar code juxing[64]={
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
};                      //矩形波取码

uchar code sanjiao[64]={
0,8,16,24,32,40,48,56,64,72,80,88,96,104,112,120,128,136,144,152,160,168,176,184,192,200,208,216,224,232,240,248,
248,240,232,224,216,208,200,192,184,176,168,160,152,144,136,128,120,112,104,96,88,80,72,64,56,48,40,32,24,16,8,0
};                        //三角波取码

void delay(uint xms)     //延时函数
{
    int a,b;
    for(a=xms;a>0;a--)
        for(b=110;b>0;b--);
}
void write_com(uchar com)        //写命令函数
{
    lcdrs=0;
    P1=com;    
    delay(1);
    lcden=1;
    delay(1);                                       
    lcden=0;
}

void write_date(uchar date)        //写数据函数
{
    lcdrs=1;
    P1=date;
    delay(1);
    lcden=1;
    delay(1);
    lcden=0;
}

//自定义字符集
void Lcd_ram()      
{ 
    uint i,j,k=0,temp=0x40;           //temp=0x40;指针指向第一个字符的首地址
    for(i=0;i<7;i++)                 //依次输入8个字符
    {
       for(j=0;j<8;j++)                  //一层一层输入字符(8层)
       {
        write_com(temp+j);
        write_date(zifu[k]);
        k++;
       }
       temp=temp+8;                    //指针转到下一个字符存储地址
    }
}

void init_lcd()                    //初始化函数
{
    uchar i;                                  
    lcden=0;                    //默认开始状态为关使能端,见时序图  
    Lcd_ram();
    write_com(0x0f);
    write_com(0x38);            //显示模式设置,默认为0x38,不用变。
    write_com(0x01);            //显示清屏,将上次的内容清除,默认为0x01. 
    write_com(0x0c);            //显示功能设置0x0f为开显示,显示光标,光标闪烁;0x0c为开显示,不显光标,光标不闪
    write_com(0x06);            //设置光标状态默认0x06,为读一个字符光标加1. 
    write_com(0x80);            //设置初始化数据指针,是在读指令的操作里进行的,把指针移到第一行第一个字符处
    for(i=10;i<20;i++)               //显示初始化
    {
        write_date(table1[i]);        //在第一行输出“Wave form:”            
    }
    write_com(0x80+0x40);        //把指针移到第二行第一个字符处
    for(i=0;i<10;i++)
    {
        write_date(table1[i]);      //在第二行输出“f=     ”
    }
}

void initclock()               //时钟初始化
{
    TMOD=0x01;                      //16位定时器0
    TH0=a;
    TL0=b;
    EA=1;                           //中断允许位
    ET0=1;                           //T0溢出中断允许位
    TR0=1;                           //T0启动位
}

void display()                   //显示函数
{
    uchar qian,bai,shi,ge;
    qian=pinlv/1000;
    bai=pinlv%1000/100;
    shi=pinlv%1000%100/10;
    ge=pinlv%1000%100%10;
    write_com(0x80+0x40+0x09);        //指针指向第二行第9个字符位置

       if(qian==0)
    write_date(' ');                 //输出空格
    else
    write_date(table[qian]);
    if(qian==0&&bai==0)                    //若千位和百位都是0输出空格
    write_date(' ');
    else
    write_date(table[bai]);
    write_date(table[shi]);
    write_date('.');
    write_date(table[ge]);
    write_date('H');
    write_date('z');
    if(flag1)                //正弦波
    {
        write_com(0x80+10);             //指针移到第一行第10个字符位置
        write_date(0);
        write_date(1);
        write_date(0);
        write_date(1);
        write_date(0);
        write_date(1);
    }
    else if(!flag1)
    {
        write_com(0x80+10);
        write_date(' ');
    }
    if(flag2)
    {
        write_com(0x80+10);
        write_date(2);
        write_date(3);
        write_date(2);
        write_date(3);
        write_date(2);
        write_date(3);
    }
    else if(!flag2)
    {
        write_com(0x80+10);
        write_date(' ');
    }
    if(flag3)
    {
        write_com(0x80+10);
        write_date(4);
        write_date(5);
        write_date(4);
        write_date(5);
        write_date(4);
        write_date(5);
    }
    else if(!flag3)
    {
        write_com(0x80+10);
        write_date(' ');
    }
}

void keyscan()                    //键盘检测函数
{                                       
    if(s3==0)                           //判断key3频率加按键是否按下
    {     
        EA=0;                          //关闭中断
        delay(2);                    //消抖
        if(s3==0)                               //再次判断
        {
            while(!s3);                          
            pinlv+=bujin;
            if(pinlv>1000)                           //频率最高是100hz(100.0)
            {
                pinlv=100;
            }
            display();                            //显示函数
            m=65536-(150000/pinlv);                
            a=m/256;                                
            b=m%256;                         //TL0=m%256
            EA=1;                             //打开中断
        }
    }
    if(s4==0)                              //key4频率减按键
    {     
        
        delay(5);
        if(s4==0)
        {
            EA=0;    
            while(!s4);
            pinlv-=bujin;
            if(pinlv<100)
            {
                pinlv=1000;
            }
            display();
            m=65536-(150000/pinlv);
            a=m/256;
            b=m%256;    
            EA=1;
        }
    }
    if(s0 == 0)                                    //key0波形选择按键
    {     
        delay(5);
        if(s0 == 0)
        {
            EA = 0;
            while(!s0);
            flag1 =! flag1;
            display();
            EA = 1;
        }
    }
        if(s1 == 0)                                 //key1波形选择按键
    {     
        delay(5);
        if(s1 == 0)
        {
            EA = 0;
            while(!s1);
            flag2 =! flag2;
            display();
            EA = 1;
        }
    }        if(s2 == 0)                                
    {     
        delay(5);
        if(s2 == 0)
        {
            EA = 0;
            while(!s2);
            flag3 =! flag3;
            display();
            EA = 1;
        }
    }        
}

void bujindisplay()                         //步进显示界面设置
{
    uint bai,shi,ge;
    bai=bujin1/100;
    shi=bujin1%100/10;
    ge=bujin1%100%10;
    write_com(0x80+11);                       //选中第一行第11个字符位置
    if(bai==0)                                    //同pinlv设置阶段
    write_date(' ');
    else
    write_date(table[bai]);
    write_date(table[shi]);
    write_date('.');
    write_date(table[ge]);
}
void bujinjiance()                                 //步进键盘设置
{
    if(s5 == 0)
    {
        delay(5);
        if(s5 == 0)
        {
             while(!s5);
             h++;
             if(h == 1)
             {
                  write_com(0x01);               //清屏
                 write_com(0x80);               //初始化显示步进设置界面,指针指向第一行第一个字符位置
                 write_date('S');delay(1);      //step value
                 write_date('t');delay(1);
                 write_date('e');delay(1);
                 write_date('p');delay(1);
                 write_date(' ');delay(1);
                 write_date('v');delay(1);
                 write_date('a');delay(1);
                 write_date('l');delay(1);
                 write_date('u');delay(1);
                 write_date('e');delay(1);
                 write_date(':');delay(1);
                 bujin1=bujin;                      //把步进值赋给临时变量
                 
                 bujindisplay();                  //显示步进值(一开始设置步进=1,所以计算结果显示0.1)
             }
             if(h == 2)                               //退出设置
             {
                 h = 0;
                bujin=bujin1;                       //把设置好的临时步进值赋给步进
                
                init_lcd();                           //显示屏初始化
                initclock();                       //定时器初始化
                display();                           //调用显示函数
             }
        }
    }
    if(h == 1)                                        //设置步进时
    {
        if(s3 == 0)
        {
            delay(5);
            if(s3 == 0)
            {
                while(!s3);                             
                bujin1++;                              //临时步进值+1
                if(bujin1>=101)                      //最多加到100(10Hz)
                {
                    bujin1=1;                          //超过则返回1
                }
                bujindisplay();
            }
        }
        if(s4 == 0)
        {
            delay(5);
            if(s4 == 0)
            {
                while(!s4);
                bujin1--;
                if(bujin1<=0)
                {
                    bujin1=100;
                }
                bujindisplay();
            }
        }
    }
}

void dac_out()
{
    if (s0 == 0)    
        {
            delay(2);
            if (s0 == 0)
            {
                while(!s0);                 
                flag1=!flag1;
            }            
        }
        if (flag1)
        {    
            for (i=0;i<64;i++)           
            dac0832=sin[i];
        }
        else if(!flag1)
        {
            dac0832=juxing[47];
        }
        if (s1 == 0)    
        {
            delay(2);
            if (s1 == 0)
            {
                while(!s1);                   
                flag2=!flag2;
            }            
        }
        if (flag2)
        {    
            for (i=0;i<64;i++)           
            dac0832=juxing[i];
        }
        else if(!flag2)
        {
            dac0832=juxing[47];
        }
        if (s2 == 0)    
        {
            delay(2);
            if (s2 == 0)
            {
                while(!s2);                   
                flag3=!flag3;
            }            
        }
        if (flag3)
        {    
            for (i=0;i<64;i++)           
            dac0832=sanjiao[i];
        }
        else if(!flag3)
        {
            dac0832=juxing[47];
        }          
}

void main()                     //主函数
{    
    init_lcd();                               //调用初始化程序
    m=65536-(150000/pinlv);                   //定时器初值
    a=m/256;
    b=m%256;
    initclock();                           //定时器初始化
    while(1)
    {
        if(h == 0)                           //正常模式不是步进调节
        {
            keyscan();                       //扫描键盘
                                           //display();
        }         
        bujinjiance();                        //扫描步进调节程序
        dac_out();                            //波形输出                                    
    }
}
void T0_time()interrupt 1           //定时器
{
    TH0=a;                           //根据不同的初值,定时器定时时间不同,达到不同频率的目的
    TL0=b;
    u++;
    if(u>=64)                       
    u=0;
}

```

  • 写回答

4条回答 默认 最新

  • 老皮芽子 2021-09-28 13:56
    关注

    代码逻辑比较乱
    dac0832=juxing[47];
    毛刺应该是这条干的坏事。去掉这条应该会好。(有3行这个代码,都去掉)
    flag1,flag2,flag3, if判断混乱。会影响 DAC输出

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

问题事件

  • 系统已结题 10月6日
  • 已采纳回答 9月28日
  • 修改了问题 9月28日
  • 创建了问题 9月27日

悬赏问题

  • ¥15 一个服务器已经有一个系统了如果用usb再装一个系统,原来的系统会被覆盖掉吗
  • ¥15 使用esm_msa1_t12_100M_UR50S蛋白质语言模型进行零样本预测时,终端显示出了sequence handled的进度条,但是并不出结果就自动终止回到命令提示行了是怎么回事:
  • ¥15 前置放大电路与功率放大电路相连放大倍数出现问题
  • ¥30 关于<main>标签页面跳转的问题
  • ¥80 部署运行web自动化项目
  • ¥15 腾讯云如何建立同一个项目中物模型之间的联系
  • ¥30 VMware 云桌面水印如何添加
  • ¥15 用ns3仿真出5G核心网网元
  • ¥15 matlab答疑 关于海上风电的爬坡事件检测
  • ¥88 python部署量化回测异常问题