AD9850驱动程序--MSP430版本

前段时间忙着画板子搞运放搞滤波了,程序更新的少,发现MSP430不是太好用,尤其Timer,不过也与我使用内部晶振有关,产生正玄波之前用MSP430发出PWM,再进行滤波变为正弦波太麻烦了,这次改用DDS芯片,今天板子回来一会就调了出来很方便。

AD9850为一款DDS芯片,这里不做什么详细介绍了,有两种接口:serial 和 parrel,两种接口驱动均完成

 

 1 /*
 2  * AD9850.h
 3  *
 4  *  Created on: 2013-7-12
 5  *      Author: Allen
 6  */
 7 
 8 #ifndef AD9850_H_
 9 #define AD9850_H_
10 
11 #include     <MSP430G2553.h>
12 #include    "MyType.h"
13 
14 
15 //----------------------------------------------------------------------------------
16 //AD9850:W_CLK P2.5
17 #define        AD9850_W_CLK_DIR            (P2DIR)
18 #define        AD9850_W_CLK_OUT            (P2OUT)
19 #define        AD9850_W_CLK_PIN_NUM        (BIT5)
20 
21 #define        AD9850_W_CLK_IO_INIT        (Set_Bit(P2DIR,AD9850_W_CLK_PIN_NUM))
22 #define        AD9850_W_CLK_H                (Set_Bit(P2OUT,AD9850_W_CLK_PIN_NUM))
23 #define        AD9850_W_CLK_L                (Clr_Bit(P2OUT,AD9850_W_CLK_PIN_NUM))
24 
25 //----------------------------------------------------------------------------------
26 //AD9850:FQ_UP P2.4
27 #define        AD9850_FQ_UP_DIR            (P2DIR)
28 #define        AD9850_FQ_UP_OUT            (P2OUT)
29 #define        AD9850_FQ_UP_PIN_NUM        (BIT4)
30 
31 #define        AD9850_FQ_UP_IO_INIT        (Set_Bit(P2DIR,AD9850_FQ_UP_PIN_NUM))
32 #define        AD9850_FQ_UP_H                (Set_Bit(P2OUT,AD9850_FQ_UP_PIN_NUM))
33 #define        AD9850_FQ_UP_L                (Clr_Bit(P2OUT,AD9850_FQ_UP_PIN_NUM))
34 
35 //----------------------------------------------------------------------------------
36 //AD9850:RESET P2.3
37 #define        AD9850_RESET_DIR            (P2DIR)
38 #define        AD9850_RESET_OUT            (P2OUT)
39 #define        AD9850_RESET_PIN_NUM        (BIT3)
40 
41 #define        AD9850_RESET_IO_INIT        (Set_Bit(P2DIR,AD9850_RESET_PIN_NUM))
42 #define        AD9850_RESET_H                (Set_Bit(P2OUT,AD9850_RESET_PIN_NUM))
43 #define        AD9850_RESET_L                (Clr_Bit(P2OUT,AD9850_RESET_PIN_NUM))
44 
45 //----------------------------------------------------------------------------------
46 //AD9850:BIT_DATA P1.7
47 #define        AD9850_BIT_DATA_DIR            (P1DIR)
48 #define        AD9850_BIT_DATA_OUT            (P1OUT)
49 #define        AD9850_BIT_DATA_PIN_NUM        (BIT7)
50 
51 #define        AD9850_BIT_DATA_IO_INIT        (Set_Bit(P1DIR,AD9850_BIT_DATA_PIN_NUM))
52 #define        AD9850_BIT_DATA_H            (Set_Bit(P1OUT,AD9850_BIT_DATA_PIN_NUM))
53 #define        AD9850_BIT_DATA_L            (Clr_Bit(P1OUT,AD9850_BIT_DATA_PIN_NUM))
54 
55 
56 extern void AD9850_INIT_SERIAL(void);
57 
58 extern void AD9850_RESET_SERIAL(void);
59 
60 extern void AD9850_WR_SERIAL(unsigned char w0,double frequence);
61 
62 extern void AD9850_INIT_PARREL(void);
63 
64 extern void AD9850_RESET_PARREL(void);
65 
66 extern void AD9850_WR_PARREL(unsigned char w0,double frequence);
67 
68 
69 #endif /* LED_H_ */
AD9850.h

以上是头文件完成了pin定义与位操作,并口的数据线操作并没定义,到时候直接用port操作很方便,AD9850的D0-D7与MSP430的P1.0-P1.7对应,一次写入8位很简单。

其中使用了#include "MyType.h"中一些操作:

// C
#define  Set_Bit(val, bitn)  (val |= (/*1 <<*/(bitn)))  
#define  Clr_Bit(val, bitn)  (val &= ~(/*1<<*/(bitn)))  
#define  Get_Bit(val, bitn)  (val & (1<<(bitn)) )

 

先写的串口的程序:

1 void AD9850_INIT_SERIAL(void)
2 {
3     AD9850_W_CLK_IO_INIT;
4     AD9850_FQ_UP_IO_INIT;
5     AD9850_RESET_IO_INIT;
6     AD9850_BIT_DATA_IO_INIT;
7 }
AD9850_INIT_SERIAL
 1 void AD9850_RESET_SERIAL(void)
 2 {
 3     AD9850_W_CLK_L;
 4     AD9850_FQ_UP_L;
 5     //rest信号
 6     AD9850_RESET_L;
 7     AD9850_RESET_H;
 8     AD9850_RESET_L;
 9     //w_clk信号
10     AD9850_W_CLK_L;
11     AD9850_W_CLK_H;
12     AD9850_W_CLK_L;
13     //fq_up信号
14     AD9850_FQ_UP_L;
15     AD9850_FQ_UP_H;
16     AD9850_FQ_UP_L;
17 
18 }
AD9850_RESET_SERIAL
 1 void AD9850_WR_SERIAL(unsigned char w0,double frequence)
 2 {
 3     unsigned char i,w;
 4     long int y;
 5     double x;
 6     //计算频率的HEX值
 7     x=4294967295/20;//适合125M晶振
 8     //如果时钟频率不为20MHZ,修改该处的频率值,单位MHz  !!!
 9     frequence=frequence/1000000;
10     frequence=frequence*x;
11     y=frequence;
12     //写w4数据
13     w=(y>>=0);
14     for(i=0;i<8;i++)
15     {
16 //       ad9850_bit_data=(w>>i)&0x01;
17        if((w>>i)&0x01)
18          AD9850_BIT_DATA_H;
19        else
20          AD9850_BIT_DATA_L;
21        AD9850_W_CLK_H;
22        AD9850_W_CLK_L;
23     }
24     //写w3数据
25     w=(y>>8);
26     for(i=0;i<8;i++)
27     {
28         if((w>>i)&0x01)
29           AD9850_BIT_DATA_H;
30         else
31           AD9850_BIT_DATA_L;
32         AD9850_W_CLK_H;
33         AD9850_W_CLK_L;
34     }
35     //写w2数据
36     w=(y>>16);
37     for(i=0;i<8;i++)
38     {
39         if((w>>i)&0x01)
40           AD9850_BIT_DATA_H;
41         else
42           AD9850_BIT_DATA_L;
43         AD9850_W_CLK_H;
44         AD9850_W_CLK_L;
45     }
46     //写w1数据
47     w=(y>>24);
48     for(i=0;i<8;i++)
49     {
50         if((w>>i)&0x01)
51           AD9850_BIT_DATA_H;
52         else
53           AD9850_BIT_DATA_L;
54         AD9850_W_CLK_H;
55         AD9850_W_CLK_L;
56     }
57     //写w0数据
58     w=w0;
59     for(i=0;i<8;i++)
60     {
61         if((w>>i)&0x01)
62           AD9850_BIT_DATA_H;
63         else
64           AD9850_BIT_DATA_L;
65         AD9850_W_CLK_H;
66         AD9850_W_CLK_L;
67     }
68     //移入始能
69     AD9850_FQ_UP_H;
70     AD9850_FQ_UP_L;
71 
72 }
AD9850_WR_SERIAL

串行连接时候需要注意pin2-4的连接:

 

以下是并行部分程序:

1 void AD9850_INIT_PARREL(void)
2 {
3     AD9850_W_CLK_IO_INIT;
4     AD9850_FQ_UP_IO_INIT;
5     AD9850_RESET_IO_INIT;
6     P1DIR=0xff;
7 
8 }
AD9850_INIT_PARREL
1 void AD9850_RESET_PARREL(void)
2 {
3     AD9850_W_CLK_L;
4     AD9850_FQ_UP_L;
5     //rest信号
6     AD9850_RESET_L;
7     AD9850_RESET_H;
8     AD9850_RESET_L;
9 }
AD9850_RESET_PARREL
 1 void AD9850_WR_PARREL(unsigned char w0,double frequence)
 2 {
 3     unsigned char w;
 4     long int y;
 5     double x;
 6     //计算频率的HEX值
 7     x=4294967295/20;//适合20M晶振
 8     //如果时钟频率不为20MHZ,修改该处的频率值,单位MHz !!!
 9     frequence=frequence/1000000;
10     frequence=frequence*x;
11     y=frequence;
12     //写w0数据
13     w=w0;
14     P1OUT=w;      //w0
15     AD9850_W_CLK_H;
16     AD9850_W_CLK_L;
17     //写w1数据
18     w=(y>>24);
19     P1OUT=w;      //w1
20     AD9850_W_CLK_H;
21     AD9850_W_CLK_L;
22     //写w2数据
23     w=(y>>16);
24     P1OUT=w;      //w2
25     AD9850_W_CLK_H;
26     AD9850_W_CLK_L;
27     //写w3数据
28     w=(y>>8);
29     P1OUT=w;      //w3
30     AD9850_W_CLK_H;
31     AD9850_W_CLK_L;
32     //写w4数据
33     w=(y>>0);
34     P1OUT=w;      //w4
35     AD9850_W_CLK_H;
36     AD9850_W_CLK_L;
37     //移入始能
38     AD9850_FQ_UP_H;
39     AD9850_FQ_UP_L;
40 
41 }
AD9850_WR_PARREL


主函数:

 1 char mode=0; //0:serial   1:parrel
 2 /*
 3  * main.c
 4  */
 5 int main(void) {
 6     WDTCTL = WDTPW | WDTHOLD;    // Stop watchdog timer
 7     
 8     mode=0;
 9 
10     if(mode==0)
11     {
12 
13         AD9850_INIT_SERIAL();
14         AD9850_RESET_SERIAL();
15         AD9850_WR_SERIAL(0,18000);
16     }
17     else if(mode==1)
18     {
19 
20         AD9850_INIT_PARREL();
21         AD9850_RESET_PARREL();
22         AD9850_WR_PARREL(0,25000);
23 
24     }
25 
26 
27 
28 
29 
30     while(1)
31     {
32 
33 
34     }
35     return 0;
36 }
main(void)


个人感受:方便,简单嘿嘿

 

posted @ 2013-10-21 15:51  wwjdwy  阅读(870)  评论(0编辑  收藏  举报