×
嵌入式 > 技术百科 > 详情

msp430串口数据收发的讨论

发布时间:2020-06-20 发布时间:
|
在做串口通信看 沈建华编著 一书中感到书中有些控制字没有列出,编写程序时容易忘记写.出现不必要的错误. ME2 IE2 IFG2 (或ME1   IE1 IFG1)下面的本程序用的是USART1.要从.H的头文件里找上面三个特殊功能寄存器的用法.

#define IE2_                (0x0001) /* Interrupt Enable 2 */

DEFC(   IE2               , IE2_)

#define U1IE                IE2       /* UART1 Interrupt Enable Register */

#define URXIE1              (0x10)

#define UTXIE1              (0x20)

#define IFG2_               (0x0003) /* Interrupt Flag 2 */

DEFC(   IFG2              , IFG2_)

#define U1IFG               IFG2      /* UART1 Interrupt Flag Register */

#define URXIFG1             (0x10)

#define UTXIFG1             (0x20)

#define ME2_                (0x0005) /* Module Enable 2 */

DEFC(   ME2               , ME2_)

#define U1ME                ME2       /* UART1 Module Enable Register */

#define URXE1               (0x10)

#define UTXE1               (0x20)

#define USPIE1              (0x10)

430的波特率的使用很有特点.: 时钟源可通过UTCTL<0 1>中的SSEL1 SSEL0 选择外部时钟 UCLK1 ACLK SMCLK   SMCLK   对于波特率的计算: 比如时钟750KHz,波特率115200,750000/115200=6.51 小数0.51*8=4.08 那么UxMCTL就可以为0xAA或者0x55(4个1均匀分布)关波特率=BRCLK/(UBR+(M7+M6+M5+M4+M3+M2+M1+M0)/8) 是反过来的运算. 本程序中用ACLK :32768HZ      32768/9600=3.4133...   那么UBR就是3 再用 0.4133*8=3.3064 取整数 3 在波特率调整控制器中UMCTL中的M7~M0 任意修改3个位并且不能紧靠在一起.同时UMCTL的值要求不能少于0x03

#include "msp430x16x.h"

void Delay(unsigned char m);

void ComInit(void);

unsigned char Usart_Tx_Data[30]={"You are the best ! cheer on! "};

void InitSystemClock(void) // 初始化系统时钟

{

unsigned char i;

WDTCTL=WDTPW+WDTHOLD; //关闭看门狗

BCSCTL1=0x00;          //Set 430 clk 开启XT2,DOC的标称频率为最低 且不分频;XT1为低速晶体(32.768K)

BCSCTL2=SELM_2+SELS;   //选择MCLK SCLK的时钟源为高速时钟 不分频,均为8M

do

{

    IFG1&=~OFIFG;

    for(i=0xff;i>0;i--);

}

while ((IFG1&OFIFG)!=0);

//P5DIR=0XFF;

//P5OUT|=BIT7;

//P5IN=0X80;

//P5SEL|=BIT4+BIT5+BIT6;//将MCLK SCLK ACLK分别输出至P5.4 5 6口

}

void main(void)

{

int i;

InitSystemClock(); // 初始化系统时钟

ComInit();

//InitLCD();

//P1DIR=0x00;   

//P1IE=0xff;

   _EINT();

while(1)

{

    Delay(100);

}

/*

while(1)

{

         for(i=0;i<30;i++)

        {

         TXBUF1=Usart_Tx_Data[i];

         while((UTCTL1&0X01)==0);

         Delay(100);

        }

} */

     

}

void Delay(unsigned char m)

{

unsigned char i;

while(m--)

{

for(i=0;i<0xff;i++);

}

}

void ComInit(void) //串口初始化

{

UCTL1|=SWRST;

UCTL1 = CHAR;                         // 8-bit 字符 无校验 1位停止位 UART模式 无反馈 线路空闲多机模式

/*******************波特率为1200*******************/

/* UTCTL1=SSEL0;                        //选择ACLK为波特率发生器时钟源(32.768K), UCLKI与UCLK极性相同

UBR01 = 0x1B;                         // 波特率设置寄存器    波特率为1200

UBR11 = 0x00;                         // // 波特率设置寄存器

UMCTL1 = 0x11;                           //波特率 调整寄存器

*/

/**************************************/

/*******************波特率为2400*******************/

/* UTCTL1=SSEL0;                        //选择ACLK为波特率发生器时钟源(32.768K), UCLKI与UCLK极性相同

UBR01 = 0x0D;                         // 波特率设置寄存器    波特率为2400

UBR11 = 0x00;                         // // 波特率设置寄存器

UMCTL1 = 0x6D;                           //波特率 调整寄存器

*/

/**************************************/

/*******************波特率为9600*******************/

UTCTL1=SSEL0;                        //选择ACLK为波特率发生器时钟源(32.768K), UCLKI与UCLK极性相同

UBR01 = 0x03;                         // 波特率设置寄存器

UBR11 = 0x00;                         // // 波特率设置寄存器

UMCTL1 = 0x4A;                           //波特率 调整寄存器

/**************************************/

/*******************波特率为19200*******************

UTCTL1=SSEL0+SSEL1;                        //选择SMCLK为波特率发生器时钟源(8M), UCLKI与UCLK极性相同

UBR01 = 0xA0;                         // 波特率设置寄存器    8M 下波特率为19200

UBR11 = 0x01;                         // // 波特率设置寄存器

UMCTL1 = 0x6d;                           //波特率 调整寄存器

**************************************/

/*******************波特率为115200*******************

UTCTL1=SSEL0+SSEL1;                        //选择SMCLK为波特率发生器时钟源(8M), UCLKI与UCLK极性相同

UBR01 = 0x45;                         // 波特率设置寄存器   SMCLK为8M下波特率为115200

UBR11 = 0x00;                         // // 波特率设置寄存器

UMCTL1 = 0x55;                           //波特率 调整寄存器

/**************************************/

                   

ME2|= UTXE1 + URXE1;                  // 使能 USART1 TXD/RXD

IE2|= URXIE1+UTXIE1;                         // 使能 USART1 接收和发送 中断

UCTL1&=~SWRST;

P3SEL |= BIT6+BIT7;                        // P3.6,7 = USART1 TXD/RXD 选择第二功能

}

#pragma vector=UART1RX_VECTOR

__interrupt void OnRecieve(void)   //将接收到的字符显示到串口输出

{

while((IFG2&URXIFG1)==0);        //选择的是USART1

TXBUF1=RXBUF1;

while((UTCTL1&0X01)==0);

Delay(1);

}

      //本程序包括自动发送数组里的数据或将接收到的数据再从新发回.多添加一条语句实现功能.

      while((UTCTL1&0X01)==0); 将接收到的数据发送完才能退出中断. 少这一句 在串口调试助手中能看到TX加1 RX也加1 接收数据区却没有显示. 原因就是数据没有发送完就退出了中断.

     //此程序只要修改头文件就可运行. 其实还有很多的更为复杂的应用.欢迎交流! ^_^

其实在任何一种单片机先看懂官方或者网上的一些程序,再在这些程序基础上添加自己想要实现的功能,这是实现编程的最好也是最快方式,但是,不要认为这就可以了,不但要看懂理写程序人的意思,将程序变成适应自己修改的程序,并完全正确.要一个学习的过程和时间.



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
Keil5(MDK5)在调试(debug)过程中遇到的问题