由于MSP430F169单片机含有两个USART串口通信模块,都可以作为SPI同步通信,所以可以实现单片机自身的同步通信。
1 #include <msp430f169.h>
2 //延时函数
3 #define CPU_F ((double)8000000) //外部高频晶振8MHZ
4 #define delay_us(x) __delay_cycles((long)(CPU_F*(double)x/1000000.0))
5 #define delay_ms(x) __delay_cycles((long)(CPU_F*(double)x/1000.0))
6
7 //自定义数据结构,方便使用
8 #define uchar unsigned char
9 #define uint unsigned int
10 #define ulong unsigned long
11 //串口波特率计算,当BRCLK=CPU_F时用下面的公式可以计算,否则要根据设置加入分频系数
12 #define baud 9600 //设置波特率的大小
13 #define baud_setting (uint)((ulong)CPU_F/((ulong)baud)) //波特率计算公式
14 #define baud_h (uchar)(baud_setting>>8) //提取高位
15 #define baud_l (uchar)(baud_setting) //低位
16 //LMB162液晶控制管脚配置
17 #define DataDIR P4DIR //数据口方向
18 #define DataPort P4OUT //P4口为数据口
19
20 #define RS_0 P5OUT &= ~BIT5 //RS置低
21 #define RS_1 P5OUT |= BIT5 //RS置高
22
23 #define RW_0 P5OUT &= ~BIT6 //RW置低
24 #define RW_1 P5OUT |= BIT6 //RW置高
25
26 #define EN_0 P5OUT &= ~BIT7 //E置低
27 #define EN_1 P5OUT |= BIT7 //E置高
28 /**
29 * 系统时钟初始化,外部8M晶振
30 */
31 void CLOCK_Init()
32 {
33 uchar i;
34 BCSCTL1&=~XT2OFF; //打开XT2振荡器
35 BCSCTL2|=SELM1+SELS; //MCLK为8MHZ,SMCLK为8MHZ
36 do{
37 IFG1&=~OFIFG; //清除振荡器错误标志
38 for(i=0;i<100;i++)
39 _NOP();
40 }
41 while((IFG1&OFIFG)!=0); //如果标志位1,则继续循环等待
42 IFG1&=~OFIFG;
43 }
44 /**
45 *显示屏命令写入函数
46 */
47 void LCD_write_com(unsigned char com)
48 {
49 RS_0;
50 RW_0;
51 DataPort = com; //命令写入端口
52 EN_1;
53 delay_ms(5);
54 EN_0;
55 delay_ms(5);
56 }
57 /**
58 * 显示屏数据写入函数
59 */
60 void LCD_write_data(unsigned char data)
61 {
62 RS_1;
63 RW_0;
64 DataPort = data; //数据写入端口
65 EN_1;
66 delay_ms(5);
67 EN_0;
68 delay_ms(5);
69 }
70 /**
71 * 显示屏字符串写入函数
72 */
73 void LCD_write_str(unsigned char H,unsigned char L,unsigned char *s)
74 {
75
76 if (H == 0)
77 {
78 LCD_write_com(0x80 + L); //第一行显示
79 }
80 else
81 {
82 LCD_write_com(0xC0 + L); //第二行显示
83 }
84
85 while (*s)
86 {
87 LCD_write_data( *s);
88 s ++;
89 }
90 }
91 /**
92 * 显示屏单字符写入函数
93 */
94 void LCD_write_char(unsigned char H,unsigned char L,unsigned char data)
95 {
96
97 if (H == 0)
98 {
99 LCD_write_com(0x80 + L); //第一行显示
100 }
101 else
102 {
103 LCD_write_com(0xC0 + L); //第二行显示
104 }
105
106 LCD_write_data( data);
107 }
108 /**
109 * 显示屏初始化函数
110 */
111 void LCD_init(void)
112 {
113 EN_0;
114 LCD_write_com(0x38); //显示模式设置
115 delay_ms(5);
116 LCD_write_com(0x08); //显示关闭
117 delay_ms(5);
118 LCD_write_com(0x01); //显示清屏
119 delay_ms(5);
120 LCD_write_com(0x06); //显示光标移动设置
121 delay_ms(5);
122 LCD_write_com(0x0C); //显示开及光标设置
123 delay_ms(5);
124 }
125 /*
126 * 主机SPI初始化
127 */
128 void Init_M_SPI()
129 {
130 U0CTL |=SWRST;
131 P3SEL |=BIT1+BIT2+BIT3;
132 U0CTL |= CHAR+SYNC+MM; //U0SART_SPI 8位字符 SPI 主机模式
133 U0TCTL |= CKPH+SSEL1+STC; //主机:SMCLK作为SPI时钟,3线模式
134 U0BR0 = baud_l;
135 U0BR1 = baud_h;
136 U0MCTL = 0x00;
137 ME1 = USPIE0; //USART0 SPI使能
138 U0CTL &=~SWRST;
139 IE1 &=~UTXIE0;
140 IE1 &=~URXIE0;
141 P3DIR |=BIT1;
142
143 }
144 /*
145 * 从机SPI初始化
146 */
147 void Init_S_SPI()
148 {
149 U1CTL |=SWRST;
150 P5SEL |=BIT1+BIT2+BIT3;
151 U1CTL = CHAR+SYNC; //U1SART_SPI 8位字符 SPI 从机模式
152 U1TCTL = CKPL+STC; //从机:外部时钟,3线模式
153 ME2 = USPIE1; //USART1 SPI使能
154 U1CTL &=~SWRST;
155 IE2 = URXIE1;
156 P5DIR |=BIT2;
157 }
158 /*
159 *主机单字符发送函数
160 */
161 void Send_Byte(uchar data)
162 {
163 U0TXBUF = data;
164 while((IFG1&UTXIFG0)==0);
165 IFG1 &=~UTXIFG0;
166 }
167 #pragma vector=USART1RX_VECTOR
168 __interrupt void USART1RX(void)
169 {
170 uchar data;
171 data = U1RXBUF;
172 LCD_write_char(1,15,data);
173 delay_ms(5);
174 }
175 /*
176 * 键盘扫描
177 */
178 uchar key_scan(){
179 uchar a=1,s,count=1;
180 uchar value=0;
181 for(a=1;a<0x10;a<<=1){
182 P2DIR = 0xFF;
183 P2OUT = 0x00;
184 P2DIR=0x0f;
185 P2OUT=a;
186 if(P2IN!=a){
187 if(0x10&P2IN)
188 s=0;
189 if(0x20&P2IN)
190 s=1;
191 if(0x40&P2IN)
192 s=2;
193 if(0x80&P2IN)
194 s=3;
195 value=s*4+count+'0';
196 }
197 count++;
198 }
199 return value;
200 }
201 /**
202 * 主函数
203 */
204 void main(void)
205 {
206 WDTCTL = WDTPW | WDTHOLD; // 关闭看门狗
207 P4SEL = 0x00;
208 P4DIR = 0xFF; //数据口输出模式
209 P5SEL =(P5SEL&0x8F);
210 P5DIR|= BIT5 + BIT6 + BIT7; //控制口设置为输出模式
211 CLOCK_Init();
212 Init_M_SPI();
213 Init_S_SPI();
214 LCD_init();
215 uchar temp=0;
216 _EINT();
217 while(1){
218 LCD_write_str(0,0,"*COM-MSP430-SPI*");
219 LCD_write_str(1,0,"KEY=");
220 LCD_write_str(1,11,"COM=");
221 delay_ms(5);
222 if(key_scan()==0)
223 continue;
224 else
225 {
226 temp = key_scan();
227 delay_ms(5);
228 LCD_write_char(1,4,temp);
229 delay_ms(5);
230 Send_Byte(temp);
231 }
232 }
233 }
|