AD9910模块的使用

  前言,究极折磨怪AD9910!本次尝试使用AD9910产生FM载波,但调试过程十分难受,特此记录下来

  上AD9910模块,来自康威电子。听大佬说其并行数据通信实现困难,故明智地选择使用串行通信

 

 

   AD9910用来产生FM载波十分便利,来自AD官网的介绍。

 

  在实现数据发丝前,先了解以下AD9910模块提供的引脚分别有什么作用

STM32引脚配置 模块引脚 描述
 AD9910_PF0(GPIOA, GPIO_PIN_3)    PF0

Profile Select Pins.文件配置选择引脚,对应有8个配置文件寄存器,

根据引脚的状态进行选择。比如我使用的是第0个profile寄存器,引脚状态

为000.      

 AD9910_PF1(GPIOA, GPIO_PIN_4) PF1 
 AD9910_PF2(GPIOA, GPIO_PIN_5) PF2 
 AD9910_IOUP(GPIOA, GPIO_PIN_6) IOUP   维持一段高电平,会将IO缓存中的值传输至内部寄存器中。与AD9910串行通信有关
 AD9910_SDIO(GPIOA, GPIO_PIN_7) SDIO     数据
 AD9910_SCK(GPIOB, GPIO_PIN_0) SCK  时钟 
 AD9910_CS(GPIOB, GPIO_PIN_1) CSB  片选 
 AD9910_RET(GPIOB, GPIO_PIN_2) MASTER_RESET 复位 。清除内存中的值,并恢复为默认值
 AD9910_PWR(GPIOA, GPIO_PIN_8)  EXT_PWR_DWN  掉电。如果不使用,应该接逻辑0
 AD9910_OSK(GPIOA, GPIO_PIN_9)  OSK  Output Shift Keying.没用过,不清楚,本例程不需要使用
 AD9910_DRC(GPIOA, GPIO_PIN_10)  DRCTL  Digital Ramp Control。AD官方文档说明,如果不使用,应该接逻辑0
 AD9910_DRO(GPIOA, GPIO_PIN_11)  DROVER Digital Ramp Over。不需要使用
 AD9910_DRH(GPIOA, GPIO_PIN_12)  DRHOLD  Digital Ramp Hold。如果不使用,应该接逻辑0
 RAM_SWP_OVR(RSO)    RSO  RAM Sweep Over。使用的是正弦调制模式,不需要RAM
 PLL_LOCK(PLL) PLL   Clock Multiplier PLL Lock。输出口
 TxENABLE(TEN) TEN   Transmit Enable。用于并行通信,不用管
 PDCLK(PD) PD   Parallel Data Clock
 SDO SDO   Serial Data Output。输出口

  在硬件连接这里,有个大坑,就是表中标注的应该接逻辑0的地方,这里都需要单片机输出低电平(我尝试直接接地,但不管用,不懂)

  这样连接硬件后,在写好串行通信,应该就可以正常输出了。

  直接上网图

 

 

 

  串行通信时序图

 

 

 先是指令周期,后是数据。

 1 void CSM_AD9910_TransByte(uint8_t dat)
 2 {
 3     uint8_t i, sbt = 0x80;
 4     AD9910_SCK(0);
 5     for (i = 0; i < 8; i++)
 6     {
 7         if ((dat & sbt) == 0)
 8         {
 9             AD9910_SDIO(0);
10         }
11         else
12         {
13             AD9910_SDIO(1);
14         }
15         AD9910_SCK(1);
16         sbt = sbt >> 1;
17         AD9910_SCK(0);
18     }
19 }

写数据完成,接下来就是向寄存器写内容了

直接上代码,我使用正弦单频调制,采用商家给的例程,cfr1,cfr2和cfr3寄存器都已经配好了

void CSM_AD9910_Init()
{
    uint8_t i;
    uint8_t cfr1[5] = {0x00, 0x00, 0x40, 0x00, 0x00};
    uint8_t cfr2[5] = {0x01, 0x01, 0x00, 0x00, 0x00};
    uint8_t cfr3[5] = {0x02, 0x05, 0x0F, 0x41 ,0x32};     //寄存器控制字,40M输入  25倍频  VC0=101   ICP=001
    
    AD9910_PWR(0);
AD9910_PF0(
0); AD9910_PF1(0); AD9910_PF2(0);
AD9910_DRC(
0); AD9910_DRH(0); AD9910_RET(1); HAL_Delay(5); AD9910_RET(0);    //复位,寄存器恢复为默认值 AD9910_CS(0); for (i = 0; i < 5; i++) { CSM_AD9910_TransByte(cfr1[i]); } AD9910_CS(1); for (i = 0; i < 10; i++); AD9910_CS(0); for (i = 0; i < 5; i++) { CSM_AD9910_TransByte(cfr2[i]); } AD9910_CS(1); for (i = 0; i < 10; i++); AD9910_CS(0); for (i = 0; i < 5; i++) { CSM_AD9910_TransByte(cfr3[i]); } AD9910_CS(1); for (i = 0; i < 10; i++); AD9910_IOUP(1); for (i = 0; i < 10; i++); AD9910_IOUP(0); HAL_Delay(1); }

void CSM_AD9910_Config(uint32_t freq)
{
    uint8_t i;
    uint32_t temp_freq = (uint32_t)(4.294967296 * freq);    //(2^32/1G)

    profile0[8] = (uint8_t)temp_freq;
    profile0[7] = (uint8_t)(temp_freq >> 8);
    profile0[6] = (uint8_t)(temp_freq >> 16);
    profile0[5] = (uint8_t)(temp_freq >> 24);

    AD9910_CS(0);
    for (i = 0; i < 9; i++)
    {
        CSM_AD9910_TransByte(profile0[i]);
    }
    AD9910_CS(1);
    for (i = 0; i < 10; i++);

    AD9910_IOUP(1);
    for (i = 0; i < 10; i++);
    AD9910_IOUP(0);
    HAL_Delay(1);
}

 

posted @ 2023-03-18 12:25  哈啰世界  阅读(940)  评论(1编辑  收藏  举报