OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3344|回复: 24

STM32F103RE控制AD9854ASQ程序 问题

[复制链接]

2

主题

33

帖子

0

精华

新手上路

积分
34
金钱
34
注册时间
2016-4-14
在线时间
10 小时
发表于 2016-4-16 12:33:02 | 显示全部楼层 |阅读模式
20金钱
输出是类似晶振的信号,不是正弦波啊,频率也不对。
#include "sys.h"
#include "delay.h"

#define AD9854_DATA  GPIOB->ODR//PB高八位
#define AD9854_ADDR  GPIOA->ODR//PA低八位
#define ad9854_reset  PCout(0)
#define ad9854_osk    PCout(1)//OSK触发信号
#define ad9854_fbh    PCout(2)//FSK触发信号
#define ad9854_updata PCout(3)
#define ad9854_wr     PCout(4)
#define ad9854_rd     PCout(5)

unsigned char ControlRegister[]={0x04,0x00,0x00,0x60};   //AD9854 特殊功能寄存器地址 无倍频,Mode 0
unsigned char FTW[]={0xf1,0xd2,0x4d,0x62,0x10,0x00};               //Frequency Tuning Word1 20M  5KHZ的FTW
unsigned char PAR[]={0x00,0x00};                         //Phase Adjust Register 1
unsigned char OSK[]={0x0a,0xff};                         //Output shaped keying multiplier,  650mv

void single_wave(unsigned long int fre);
void Init_AD9854(void);
void AD9854_Set_Mode0(void);
void AD9852_Send(unsigned char addr,unsigned char data);
void change_frequency(unsigned long int fre_temp);

void Init_Port(void);

int main( void )
{

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

2

主题

33

帖子

0

精华

新手上路

积分
34
金钱
34
注册时间
2016-4-14
在线时间
10 小时
 楼主| 发表于 2016-4-16 12:33:41 | 显示全部楼层
#include "sys.h"
#include "delay.h"

#define AD9854_DATA  GPIOB->ODR//PB高八位
#define AD9854_ADDR  GPIOA->ODR//PA低八位
#define ad9854_reset  PCout(0)
#define ad9854_osk    PCout(1)//OSK触发信号
#define ad9854_fbh    PCout(2)//FSK触发信号
#define ad9854_updata PCout(3)
#define ad9854_wr     PCout(4)
#define ad9854_rd     PCout(5)

unsigned char ControlRegister[]={0x04,0x00,0x00,0x60};   //AD9854 特殊功能寄存器地址 无倍频,Mode 0
unsigned char FTW[]={0xf1,0xd2,0x4d,0x62,0x10,0x00};               //Frequency Tuning Word1 20M  5KHZ的FTW
unsigned char PAR[]={0x00,0x00};                         //Phase Adjust Register 1
unsigned char OSK[]={0x0a,0xff};                         //Output shaped keying multiplier,  650mv

void single_wave(unsigned long int fre);
void Init_AD9854(void);
void AD9854_Set_Mode0(void);
void AD9852_Send(unsigned char addr,unsigned char data);
void change_frequency(unsigned long int fre_temp);

void Init_Port(void);

int main( void )
{
        Stm32_Clock_Init(9);        // 9??
        delay_init(72);                        // 72M?????
        delay_ms(200);

        Init_Port();
        Init_AD9854();
        delay_ms(10);


        AD9854_Set_Mode0();  
        while(1);
}

//IO初始化                                                                                                  
void Init_Port(void)
{
        RCC->APB2ENR |= 1<<2 ;       
        GPIOA->CRL &= 0xff000000;
        GPIOA->CRL |= 0x00333333 ;
        GPIOA->ODR |= 0x00ff ;
       
        RCC->APB2ENR |= 1<<3 ;       
        GPIOB->CRH &= 0xffffffff ;
        GPIOB->CRH |= 0x33333333 ;
        GPIOB->ODR |= 0xff00 ;

        RCC->APB2ENR |= 1<<4 ;       
        GPIOC->CRL &= 0xff000000 ;
        GPIOC->CRL |= 0x00333333 ;
        GPIOC->ODR |= 0x00ff ;
}

//写入一个控制字
void AD9852_Send(unsigned char addr,unsigned char data)   //????????
{
        ad9854_wr = 1;                                                // AD9854_WR_SET;
                                  
        AD9854_ADDR &= 0xff00|addr;
        AD9854_ADDR |= 0x00ff&addr;

        ad9854_wr = 1;                                                // AD9854_WR_SET;

        AD9854_DATA &= 0x00ff|data<<8;
        AD9854_DATA |= 0xff00&data<<8;

        ad9854_wr = 0;                                                // AD9854_WR_CLR;
        ad9854_wr = 1;                                                // AD9854_WR_SET;
        ad9854_updata = 1;                                        // AD9854_UPDATA_SET;
        ad9854_updata = 0;                                        // AD9854_UPDATA_CLR;
}
//AD9854初始化 特殊功能寄存器给地址
void Init_AD9854(void)
{
        unsigned char addr;
        unsigned char i;
         
        ad9854_reset = 0 ;                        // AD9854_RESET_CLR;
        ad9854_wr = 1 ;                                // AD9854_WR_SET;
        ad9854_rd = 0 ;                                // AD9854_RD_CLR;
        ad9854_updata = 0 ;                        // AD9854_UPDATA_CLR;
  
        addr = 0x1d;

        for(i=4;i>0;i--)
        {
                AD9852_Send(addr,ControlRegister[4-i]);
                addr++;
        }
        ad9854_updata = 1;                                        // AD9854_UPDATA_SET;
        ad9854_updata = 0;                                        // AD9854_UPDATA_CLR;
}
//MODE0 频率相位和幅度给特定控制字的地置
void AD9854_Set_Mode0(void)                                   //Mode 0 ??
{
        unsigned char addr;
        unsigned char counter;
         
        for(addr=0x00,counter=2;counter>0;counter--)        //??Phase Adjust Register 1
        {
                AD9852_Send(addr,PAR[2-counter]);
                addr++;
        }
  
        for(addr=0x04,counter=6;counter>0;counter--)        //??Frequency Tuning Word 1
        {
                AD9852_Send(addr,FTW[6-counter]);
                addr++;
        }
  
        for(addr=0x21,counter=2;counter>0;counter--)        //??Output shaped keying multiplier
        {
                AD9852_Send(addr,OSK[2-counter]);
                addr++;
        }
        ad9854_updata = 1;                                        // AD9854_UPDATA_SET;
        ad9854_updata = 0;                                        // AD9854_UPDATA_CLR;
}
//
//void single_wave(unsigned long int fre)
//{
//        unsigned char addr,i;
//        unsigned long int ff;
//        unsigned char *p;

//        ff=(unsigned long int)(4294967296*fre/20000000);//20M
//  
//        p=(unsigned char*)&ff;
//  
//        for(addr=0x04,i=0;i<6;i++)                  //??Frequency Tuning Word 1
//        {
//                AD9852_Send(addr,*(p+5-i));      
//                addr++;
//        }
//  
//        for(addr=0x00,i=0;i<2;i++)                  //??Phase Adjust Register 1
//        {
//                AD9852_Send(addr,PAR[i]);
//                addr++;
//        }
//  
//        for(addr=0x21,i=2;i>0;i--)                  //??Output shaped keying multiplier
//        {
//                AD9852_Send(addr,OSK[2-i]);
//                addr++;
//        }
//}

//void change_frequency(unsigned long int fre_temp)
//{
//        unsigned char addr,counter;
//        unsigned char *p;
//        p=(unsigned char*)&fre_temp;
  
//        for(addr=0x04,counter=0;counter<6;counter++)                //??Frequency Tuning Word 1
//        {
//                AD9852_Send(addr,*(p+5-counter));      
//                addr++;
//        }
//}
回复

使用道具 举报

2

主题

33

帖子

0

精华

新手上路

积分
34
金钱
34
注册时间
2016-4-14
在线时间
10 小时
 楼主| 发表于 2016-4-16 12:34:50 | 显示全部楼层
下面是全部程序,注释掉无关的!  
外部时钟20M,无倍频,单路输出,5KHz,怀疑是频率控制字没有写入!
回复

使用道具 举报

58

主题

6294

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
11552
金钱
11552
注册时间
2014-4-1
在线时间
1317 小时
发表于 2016-4-16 12:51:04 | 显示全部楼层
        ad9854_reset = 0 ;                        // AD9854_RESET_CLR;
        ad9854_wr = 1 ;                                // AD9854_WR_SET;
        ad9854_rd = 0 ;                                // AD9854_RD_CLR;
        ad9854_updata = 0 ;                        // AD9854_UPDATA_CLR;

看到这里我就笑了。

这些句子也许能够产生“外形相同”的波形,
但这还不算对。

a的下降沿之后必须等n久才能输出b的上升沿,这是有要求的,
名词叫“时序”。




回复

使用道具 举报

2

主题

33

帖子

0

精华

新手上路

积分
34
金钱
34
注册时间
2016-4-14
在线时间
10 小时
 楼主| 发表于 2016-4-16 13:04:13 | 显示全部楼层
本帖最后由 wel2016 于 2016-4-16 13:06 编辑
xuande 发表于 2016-4-16 12:51
ad9854_reset = 0 ;                        // AD9854_RESET_CLR;
        ad9854_wr = 1 ;      ...

     ad9854_reset = 0 ;                        // AD9854_RESET_CLR;
        ad9854_wr = 1 ;                                // AD9854_WR_SET;
        ad9854_rd = 0 ;                                // AD9854_RD_CLR;
        ad9854_updata = 0 ;                        // AD9854_UPDATA_CLR;
改为                 
        ad9854_wr = 1 ;                           //将读,写控制端设为无效                             ad9854_rd= 1 ;           
        AD9854_reset = 1;            
        delay_us(10);     
        AD9854_reset = 0;                         //复位AD9854
        ad9854_updata = 0 ;                        // AD9854_UPDATA_CLR;
        delay_ms(1000);//延时1S,等待初始化完成,10个系统时钟周期。







回复

使用道具 举报

2

主题

33

帖子

0

精华

新手上路

积分
34
金钱
34
注册时间
2016-4-14
在线时间
10 小时
 楼主| 发表于 2016-4-16 13:06:36 | 显示全部楼层
xuande 发表于 2016-4-16 12:51
ad9854_reset = 0 ;                        // AD9854_RESET_CLR;
        ad9854_wr = 1 ;      ...


     ad9854_reset = 0 ;                        // AD9854_RESET_CLR;
        ad9854_wr = 1 ;                                // AD9854_WR_SET;
        ad9854_rd = 0 ;                                // AD9854_RD_CLR;
        ad9854_updata = 0 ;                        // AD9854_UPDATA_CLR;
改为                 
        ad9854_wr = 1 ;                           //将读,写控制端设为无效                     
        ad9854_rd= 1 ;           
        AD9854_reset = 1;            
        delay_us(10);     
        AD9854_reset = 0;                         //复位AD9854
        ad9854_updata = 0 ;                        // AD9854_UPDATA_CLR;
        delay_ms(1000);//延时1S,等待初始化完成,10个系统时钟周期。
回复

使用道具 举报

58

主题

6294

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
11552
金钱
11552
注册时间
2014-4-1
在线时间
1317 小时
发表于 2016-4-16 13:06:39 | 显示全部楼层

AD9854_reset = 1;               
AD9854_reset = 0;

你知道reset这个高电平的宽度是多少?
手册要求是多少?





回复

使用道具 举报

58

主题

6294

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
11552
金钱
11552
注册时间
2014-4-1
在线时间
1317 小时
发表于 2016-4-16 13:07:39 | 显示全部楼层

时序,所有硬件信号都有时序,不单是reset。
看看手册上那些 ns 的数据有多少?!

你要全面查。

回复

使用道具 举报

2

主题

33

帖子

0

精华

新手上路

积分
34
金钱
34
注册时间
2016-4-14
在线时间
10 小时
 楼主| 发表于 2016-4-16 13:15:42 | 显示全部楼层
xuande 发表于 2016-4-16 13:07
时序,所有硬件信号都有时序,不单是reset。
看看手册上那些 ns 的数据有多少?!

你说得有道理,难就难在时序这!
回复

使用道具 举报

58

主题

6294

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
11552
金钱
11552
注册时间
2014-4-1
在线时间
1317 小时
发表于 2016-4-16 13:26:26 | 显示全部楼层
wel2016 发表于 2016-4-16 13:15
你说得有道理,难就难在时序这!


不难。

找个具体问题来问,立刻就一通百通了。




回复

使用道具 举报

58

主题

6294

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
11552
金钱
11552
注册时间
2014-4-1
在线时间
1317 小时
发表于 2016-4-16 13:27:10 | 显示全部楼层

时序必须保证,
这是一切操作的基础。


回复

使用道具 举报

2

主题

33

帖子

0

精华

新手上路

积分
34
金钱
34
注册时间
2016-4-14
在线时间
10 小时
 楼主| 发表于 2016-4-16 13:50:41 | 显示全部楼层
xuande 发表于 2016-4-16 13:26
不难。

找个具体问题来问,立刻就一通百通了。

看这个,我查资料说 复位要10个系统时钟周期,我用的外部20M晶振,周期0.05ms,也就是说reset由1到0的时间是0.5ms以上!

mode0 复位时序

mode0 复位时序
读时序.png
写时序.png
回复

使用道具 举报

2

主题

33

帖子

0

精华

新手上路

积分
34
金钱
34
注册时间
2016-4-14
在线时间
10 小时
 楼主| 发表于 2016-4-16 13:55:35 | 显示全部楼层
wel2016 发表于 2016-4-16 13:06
ad9854_reset = 0 ;                        // AD9854_RESET_CLR;
        ad9854_wr = 1 ;     ...

貌似我的复位有问题,正常写应该在这里实现吧
回复

使用道具 举报

58

主题

6294

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
11552
金钱
11552
注册时间
2014-4-1
在线时间
1317 小时
发表于 2016-4-16 13:57:58 | 显示全部楼层

20M,周期是0.05。。。。微秒

回复

使用道具 举报

2

主题

33

帖子

0

精华

新手上路

积分
34
金钱
34
注册时间
2016-4-14
在线时间
10 小时
 楼主| 发表于 2016-4-16 13:59:31 | 显示全部楼层
wel2016 发表于 2016-4-16 13:55
貌似我的复位有问题,正常写应该在这里实现吧

//写入一个控制字
void AD9852_Send(unsigned char addr,unsigned char data)   //????????
{
        ad9854_wr = 1;                                                // AD9854_WR_SET;
                                 
        AD9854_ADDR &= 0xff00|addr;
        AD9854_ADDR |= 0x00ff&addr;

        ad9854_wr = 1;                                                // AD9854_WR_SET;

        AD9854_DATA &= 0x00ff|data<<8;
        AD9854_DATA |= 0xff00&data<<8;

        ad9854_wr = 0;                                                // AD9854_WR_CLR;
        ad9854_wr = 1;                                                // AD9854_WR_SET;
        ad9854_updata = 1;                                        // AD9854_UPDATA_SET;
        ad9854_updata = 0;                                        // AD9854_UPDATA_CLR;
}
写是在这里实现的,数据位,和地址位,只有这两个地方需要写入,那读有什么用呢,我有不要输出数据?
回复

使用道具 举报

2

主题

33

帖子

0

精华

新手上路

积分
34
金钱
34
注册时间
2016-4-14
在线时间
10 小时
 楼主| 发表于 2016-4-16 14:02:39 | 显示全部楼层
xuande 发表于 2016-4-16 13:57
20M,周期是0.05。。。。微秒

(⊙o⊙)…原谅我小学学的烂!
回复

使用道具 举报

58

主题

6294

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
11552
金钱
11552
注册时间
2014-4-1
在线时间
1317 小时
发表于 2016-4-16 14:21:36 | 显示全部楼层
wel2016 发表于 2016-4-16 13:59
//写入一个控制字
void AD9852_Send(unsigned char addr,unsigned char data)   //????????
{


有读的程序吗?
我怎么没看到。。。


回复

使用道具 举报

2

主题

33

帖子

0

精华

新手上路

积分
34
金钱
34
注册时间
2016-4-14
在线时间
10 小时
 楼主| 发表于 2016-4-16 14:25:30 | 显示全部楼层
xuande 发表于 2016-4-16 14:21
有读的程序吗?
我怎么没看到。。。

对啊,我也很奇怪,确实没有。
回复

使用道具 举报

2

主题

33

帖子

0

精华

新手上路

积分
34
金钱
34
注册时间
2016-4-14
在线时间
10 小时
 楼主| 发表于 2016-4-16 14:26:29 | 显示全部楼层
xuande 发表于 2016-4-16 14:21
有读的程序吗?
我怎么没看到。。。

那个是要先读,再写????
我可以写一个。
回复

使用道具 举报

58

主题

6294

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
11552
金钱
11552
注册时间
2014-4-1
在线时间
1317 小时
发表于 2016-4-16 14:31:58 | 显示全部楼层

既然没有读的事,15L你为什么要提?有关吗?



回复

使用道具 举报

2

主题

33

帖子

0

精华

新手上路

积分
34
金钱
34
注册时间
2016-4-14
在线时间
10 小时
 楼主| 发表于 2016-4-16 14:38:59 | 显示全部楼层
xuande 发表于 2016-4-16 14:31
既然没有读的事,15L你为什么要提?有关吗?

应该是有读,不然怎么写,看:
void GPIO_Write_u8Data(GPIO_TypeDef* GPIOx,u8 PortVal,u8 Low_OR_Hight)
{
        u16 Data_Temp;
    Data_Temp = GPIO_ReadOutputData(GPIOx);
        if(Low_OR_Hight != 1)  
        {
                Data_Temp &= 0xff00;        //清零低八位数据
                Data_Temp |= PortVal;
        }else
        {
                Data_Temp &= 0x00ff;        //清零高八位数据
                Data_Temp |= PortVal<<8;
        }
        GPIO_Write(GPIOx, Data_Temp);
}

/***************************************************************************
* 函数名称: GPIO_ReadOutput_u8Data(GPIO_TypeDef* GPIOx,u8 Low_OR_Hight)
* 函数描述: 八位并行数据读取
* 参数列表: GPIOx:数据口选择
*                           PortVal:要写的八位数据
*         Low_OR_Hight:高低八位的选择?
*         0:低八位  1:高八位
* 返回结果:读到的八位IO口数据
*************************************************************************************/
u8 GPIO_ReadOutput_u8Data(GPIO_TypeDef* GPIOx,u8 Low_OR_Hight)
{
        u8 Data_Temp;
        if(Low_OR_Hight != 1)  
        {
                Data_Temp = GPIO_ReadOutputData(GPIOx);
                Data_Temp &= 0x00ff;        //读取低八位数据
        }else
        {
                Data_Temp = (GPIO_ReadOutputData(GPIOx) >> 8);
                Data_Temp &= 0xff00;        //读取高八位数据
        }
        return Data_Temp;
}
回复

使用道具 举报

2

主题

33

帖子

0

精华

新手上路

积分
34
金钱
34
注册时间
2016-4-14
在线时间
10 小时
 楼主| 发表于 2016-4-16 14:39:58 | 显示全部楼层
wel2016 发表于 2016-4-16 14:38
应该是有读,不然怎么写,看:
void GPIO_Write_u8Data(GPIO_TypeDef* GPIOx,u8 PortVal,u8 Low_OR_High ...

只不过 读 嵌套在写里面了
回复

使用道具 举报

2

主题

33

帖子

0

精华

新手上路

积分
34
金钱
34
注册时间
2016-4-14
在线时间
10 小时
 楼主| 发表于 2016-4-16 14:56:19 | 显示全部楼层
wel2016 发表于 2016-4-16 14:38
应该是有读,不然怎么写,看:
void GPIO_Write_u8Data(GPIO_TypeDef* GPIOx,u8 PortVal,u8 Low_OR_High ...

库函数版
回复

使用道具 举报

2

主题

33

帖子

0

精华

新手上路

积分
34
金钱
34
注册时间
2016-4-14
在线时间
10 小时
 楼主| 发表于 2016-4-20 16:17:47 | 显示全部楼层
小大尖 发表于 2016-4-20 09:46
https://ezchina.analog.com/search.jspa?q=AD9854  可以参考下这里的

表示已看穿
回复

使用道具 举报

2

主题

474

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
6532
金钱
6532
注册时间
2018-6-27
在线时间
550 小时
发表于 2019-5-27 11:28:04 | 显示全部楼层
学习学习,学习学习。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-17 22:59

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表