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
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_ */
以上是头文件完成了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 }
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 }
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++)[!--empirenews.page--]
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 }
串行连接时候需要注意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 }
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_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 }