[资料分享] MSP430单片机自身的硬件SPI通信

Aguilera   2019-11-9 16:54 楼主

由于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 }

回复评论

暂无评论,赶紧抢沙发吧
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复