找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2505|回复: 0
收起左侧

STM32单片机控制AD9959 DDS和编码输出数字信号 正弦波点频输出源程序

[复制链接]
ID:540173 发表于 2022-5-25 16:21 | 显示全部楼层 |阅读模式
通过STM32控制DDS输出频率,通过按键控制输入十进制四位数字并进行BCD编码,输出结果由LCD12864点阵液晶屏显示
制作出来的实物图如下:
DDS.jpg
单片机源程序如下:
  1. 功能:stm32f103rct6控制,25MHz时钟, AD9959正弦波点频输出,范围0-200M,
  2.                         显示:12864cog
  3. 接口:控制接口请参照AD9959.h  按键接口请参照key.h
  4. #include "stm32_config.h"
  5. #include "stdio.h"
  6. #include "led.h"
  7. #include "lcd.h"
  8. #include "AD9959.h"
  9. #include "key.h"
  10. #include "timer.h"
  11. #include "task_manage.h"
  12. #define   Code_Freq 20   //编码输出频率
  13. u8 delay_time = 1000/Code_Freq;  //编码延时时间           

  14. extern u8 _return;
  15. int main(void)
  16. {
  17.         
  18.         MY_NVIC_PriorityGroup_Config(NVIC_PriorityGroup_2);        //设置中断分组
  19.         delay_init(72);        //初始化延时函数
  20.         LED_Init();        //初始化LED接口
  21.         key_init();
  22.         Init_AD9959();
  23.         Timerx_Init(99,71);
  24.         initial_lcd();
  25.   delay_ms(300);
  26.         Timer2_Init(delay_time*5,7199); //输出定时器初始化
  27.   Write_frequence(0,SinFre[0]);
  28.         while(1)
  29.         {

  30.                 KeyRead();
  31.                 Set_PointFre(Keycode, 0);
  32.                 if(_return)
  33.                 {
  34.                         _return=0;
  35.                         LCD_Refresh_Gram();
  36.                 }
  37.                 KEY_EXIT();
  38.         }        
  39. }
复制代码
  1. #include "AD9959.H"
  2. #include "task_manage.h"

  3. u8 CSR_DATA0[1] = {0x10};     // 开 CH0
  4. u8 CSR_DATA1[1] = {0x20};      // 开 CH1
  5. u8 CSR_DATA2[1] = {0x40};      // 开 CH2
  6. u8 CSR_DATA3[1] = {0x80};      // 开 CH3               
  7.                                                                                                                                        

  8. u8 FR2_DATA[2] = {0x20,0x00};//default Value = 0x0000
  9. u8 CFR_DATA[3] = {0x00,0x03,0x02};//default Value = 0x000302           
  10.                                                                                                                                        
  11. u8 CPOW0_DATA[2] = {0x00,0x00};//default Value = 0x0000   @ = POW/2^14*360
  12.                                                                                                                                        


  13. u8 LSRR_DATA[2] = {0x00,0x00};//default Value = 0x----
  14.                                                                                                                                        
  15. u8 RDW_DATA[4] = {0x00,0x00,0x00,0x00};//default Value = 0x--------
  16.                                                                                                                                        
  17. u8 FDW_DATA[4] = {0x00,0x00,0x00,0x00};//default Value = 0x--------

  18. //AD9959初始化
  19. void Init_AD9959(void)  
  20. {
  21.         GPIO_InitTypeDef  GPIO_InitStructure;      
  22.          u8 FR1_DATA[3] = {0xD0,0x00,0x00};//20倍频 Charge pump control = 75uA FR1<23> -- VCO gain control =0时 system clock below 160 MHz;
  23.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC, ENABLE);         //PA,PB,PC端口时钟使能
  24.         
  25.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_2|GPIO_Pin_7|GPIO_Pin_6|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10;//初始化管脚PA2.3.4.5.6.7.8.9.10
  26.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                  //推挽输出
  27.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;                 //IO口速度为2MHz
  28.         GPIO_Init(GPIOA, &GPIO_InitStructure);                                         //根据设定参数初始化GPIOA
  29.         
  30.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_10;//初始化管脚PB0.1.10                        
  31.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                  //推挽输出
  32.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;                 //IO口速度为2MHz
  33.         GPIO_Init(GPIOB, &GPIO_InitStructure);                                         //根据设定参数初始化GPIOB
  34.         
  35.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;        //初始化管脚PC0                        
  36.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                  //推挽输出
  37.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;                 //IO口速度为2MHz
  38.         GPIO_Init(GPIOC, &GPIO_InitStructure);                                         //根据设定参数初始化GPIOC
  39.                
  40.         Intserve();  //IO口初始化
  41.   IntReset();  //AD9959复位  
  42.         
  43.   WriteData_AD9959(FR1_ADD,3,FR1_DATA,1);//写功能寄存器1
  44.   WriteData_AD9959(FR2_ADD,2,FR2_DATA,1);
  45. //  WriteData_AD9959(CFR_ADD,3,CFR_DATA,1);
  46. //  WriteData_AD9959(CPOW0_ADD,2,CPOW0_DATA,0);
  47. //  WriteData_AD9959(ACR_ADD,3,ACR_DATA,0);
  48. //  WriteData_AD9959(LSRR_ADD,2,LSRR_DATA,0);
  49. //  WriteData_AD9959(RDW_ADD,2,RDW_DATA,0);
  50. //  WriteData_AD9959(FDW_ADD,4,FDW_DATA,1);
  51.    //写入初始频率
  52.         Write_frequence(3,SinFre[3]);
  53.         Write_frequence(0,SinFre[0]);
  54.         Write_frequence(1,SinFre[1]);
  55.         Write_frequence(2,SinFre[2]);

  56.         Write_Phase(3, SinPhr[3]);
  57.         Write_Phase(0, SinPhr[0]);
  58.         Write_Phase(1, SinPhr[1]);
  59.         Write_Phase(2, SinPhr[2]);
  60.         
  61.         Write_Amplitude(3, SinAmp[3]);
  62.         Write_Amplitude(0, SinAmp[0]);
  63.         Write_Amplitude(1, SinAmp[1]);
  64.         Write_Amplitude(2, SinAmp[2]);
  65. }
  66. //延时
  67. void delay1 (u32 length)
  68. {
  69.         length = length*12;
  70.    while(length--);
  71. }
  72. //IO口初始化
  73. void Intserve(void)                  
  74. {   
  75.                 AD9959_PWR=0;
  76.     CS = 1;
  77.     SCLK = 0;
  78.     UPDATE = 0;
  79.     PS0 = 0;
  80.     PS1 = 0;
  81.     PS2 = 0;
  82.     PS3 = 0;
  83.     SDIO0 = 0;
  84.     SDIO1 = 0;
  85.     SDIO2 = 0;
  86.     SDIO3 = 0;
  87. }
  88. //AD9959复位
  89. void IntReset(void)         
  90. {
  91.   Reset = 0;
  92.         delay1(1);
  93.         Reset = 1;
  94.         delay1(30);
  95.         Reset = 0;
  96. }
  97. //AD9959更新数据
  98. void IO_Update(void)  
  99. {
  100.         UPDATE = 0;
  101.         delay1(2);
  102.         UPDATE = 1;
  103.         delay1(4);
  104.         UPDATE = 0;
  105. }
  106. /*--------------------------------------------
  107. 函数功能:控制器通过SPI向AD9959写数据
  108. RegisterAddress: 寄存器地址
  109. NumberofRegisters: 所含字节数
  110. *RegisterData: 数据起始地址
  111. temp: 是否更新IO寄存器
  112. ----------------------------------------------*/
  113. void WriteData_AD9959(u8 RegisterAddress, u8 NumberofRegisters, u8 *RegisterData,u8 temp)
  114. {
  115.         u8        ControlValue = 0;
  116.         u8        ValueToWrite = 0;
  117.         u8        RegisterIndex = 0;
  118.         u8        i = 0;

  119.         ControlValue = RegisterAddress;
  120. //写入地址
  121.         SCLK = 0;
  122.         CS = 0;         
  123.         for(i=0; i<8; i++)
  124.         {
  125.                 SCLK = 0;
  126.                 if(0x80 == (ControlValue & 0x80))
  127.                 SDIO0= 1;         
  128.                 else
  129.                 SDIO0= 0;         
  130.                 SCLK = 1;
  131.                 ControlValue <<= 1;
  132.         }
  133.         SCLK = 0;
  134. //写入数据
  135.         for (RegisterIndex=0; RegisterIndex<NumberofRegisters; RegisterIndex++)
  136.         {
  137.                 ValueToWrite = RegisterData[RegisterIndex];
  138.                 for (i=0; i<8; i++)
  139.                 {
  140.                         SCLK = 0;
  141.                         if(0x80 == (ValueToWrite & 0x80))
  142.                         SDIO0= 1;         
  143.                         else
  144.                         SDIO0= 0;         
  145.                         SCLK = 1;
  146.                         ValueToWrite <<= 1;
  147.                 }
  148.                 SCLK = 0;               
  149.         }        
  150.         if(temp != 0)
  151.         IO_Update();        
  152.   CS = 1;
  153. }
  154. /*---------------------------------------
  155. 函数功能:设置通道输出频率
  156. Channel:  输出通道
  157. Freq:     输出频率
  158. ---------------------------------------*/
  159. void Write_frequence(u8 Channel,u32 Freq)
  160. {         
  161.                 u8 CFTW0_DATA[4] ={0x00,0x00,0x00,0x00};        //中间变量
  162.           u32 Temp;            
  163.           Temp=(u32)Freq*8.589934592;           //将输入频率因子分为四个字节  8.589934592=(2^32)/500000000 其中500M=25M*20(倍频数可编程)
  164.           CFTW0_DATA[3]=(u8)Temp;
  165.           CFTW0_DATA[2]=(u8)(Temp>>8);
  166.           CFTW0_DATA[1]=(u8)(Temp>>16);
  167.           CFTW0_DATA[0]=(u8)(Temp>>24);
  168.           if(Channel==0)         
  169.           {
  170.                         WriteData_AD9959(CSR_ADD,1,CSR_DATA0,1);//控制寄存器写入CH0通道
  171.       WriteData_AD9959(CFTW0_ADD,4,CFTW0_DATA,1);//CTW0 address 0x04.输出CH0设定频率
  172.                 }
  173.           else if(Channel==1)        
  174.           {
  175.                         WriteData_AD9959(CSR_ADD,1,CSR_DATA1,1);//控制寄存器写入CH1通道
  176.       WriteData_AD9959(CFTW0_ADD,4,CFTW0_DATA,1);//CTW0 address 0x04.输出CH1设定频率        
  177.           }
  178.           else if(Channel==2)        
  179.           {
  180.                         WriteData_AD9959(CSR_ADD,1,CSR_DATA2,1);//控制寄存器写入CH2通道
  181.       WriteData_AD9959(CFTW0_ADD,4,CFTW0_DATA,1);//CTW0 address 0x04.输出CH2设定频率        
  182.           }
  183.           else if(Channel==3)        
  184.           {
  185.                         WriteData_AD9959(CSR_ADD,1,CSR_DATA3,1);//控制寄存器写入CH3通道
  186.       WriteData_AD9959(CFTW0_ADD,4,CFTW0_DATA,1);//CTW0 address 0x04.输出CH3设定频率        
  187.           }                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 
  188.         
  189. }
  190. /*---------------------------------------
  191. 函数功能:设置通道输出幅度
  192. Channel:  输出通道
  193. Ampli:    输出幅度
  194. ---------------------------------------*/
  195. void Write_Amplitude(u8 Channel, u16 Ampli)
  196. {
  197.         u16 A_temp;//=0x23ff;
  198.         u8 ACR_DATA[3] = {0x00,0x00,0x00};//default Value = 0x--0000 Rest = 18.91/Iout
  199.         
  200.   A_temp=Ampli|0x1000;
  201.         ACR_DATA[2] = (u8)A_temp;  //低位数据
  202.   ACR_DATA[1] = (u8)(A_temp>>8); //高位数据
  203.   if(Channel==0)
  204.   {
  205.                 WriteData_AD9959(CSR_ADD,1,CSR_DATA0,1);
  206.     WriteData_AD9959(ACR_ADD,3,ACR_DATA,1);
  207.         }
  208.   else if(Channel==1)
  209.   {
  210.                 WriteData_AD9959(CSR_ADD,1,CSR_DATA1,1);
  211.     WriteData_AD9959(ACR_ADD,3,ACR_DATA,1);
  212.         }
  213.   else if(Channel==2)
  214.   {
  215.           WriteData_AD9959(CSR_ADD,1,CSR_DATA2,1);
  216.     WriteData_AD9959(ACR_ADD,3,ACR_DATA,1);
  217.         }
  218.   else if(Channel==3)
  219.   {
  220.                 WriteData_AD9959(CSR_ADD,1,CSR_DATA3,1);
  221.     WriteData_AD9959(ACR_ADD,3,ACR_DATA,1);
  222.         }
  223. }
  224. /*---------------------------------------
  225. 函数功能:设置通道输出相位
  226. Channel:  输出通道
  227. Phase:    输出相位,范围:0~16383(对应角度:0°~360°)
  228. ---------------------------------------*/
  229. void Write_Phase(u8 Channel,u16 Phase)
  230. {
  231.         u16 P_temp=0;
  232.   P_temp=(u16)Phase;
  233.         CPOW0_DATA[1]=(u8)P_temp;
  234.         CPOW0_DATA[0]=(u8)(P_temp>>8);
  235.         if(Channel==0)
  236.   {
  237.                 WriteData_AD9959(CSR_ADD,1,CSR_DATA0,1);
  238.     WriteData_AD9959(CPOW0_ADD,2,CPOW0_DATA,1);
  239.   }
  240.   else if(Channel==1)
  241.   {
  242.                 WriteData_AD9959(CSR_ADD,1,CSR_DATA1,1);
  243.     WriteData_AD9959(CPOW0_ADD,2,CPOW0_DATA,1);
  244.   }
  245.   else if(Channel==2)
  246.   {
  247.                 WriteData_AD9959(CSR_ADD,1,CSR_DATA2,1);
  248.     WriteData_AD9959(CPOW0_ADD,2,CPOW0_DATA,1);
  249.   }
  250.   else if(Channel==3)
  251.   {
  252.                 WriteData_AD9959(CSR_ADD,1,CSR_DATA3,1);
  253.     WriteData_AD9959(CPOW0_ADD,2,CPOW0_DATA,1);
  254.   }
  255. }
复制代码
Keil5代码下载(仅供参考):
代码.7z (230.54 KB, 下载次数: 35)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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