单片机串口通讯

never_QL 2009-12-30 11:15:57
发送代码


#include "msp430x14x.h"
#define uchar unsigned char
#define uint unsigned int
#define URXD1 BIT7
#define UTXD1 BIT6

uchar dataSedBuffer[100]={"123"}; //发送数据缓存区
uchar redySedLen = 4; //准备发送的数据的总长度,包括'\0'
uchar curtSedLen = 0; //当前已经发送的数据的长度

void Delay_us(uint count)
{
while(count-- ){_NOP();_NOP();_NOP();}
}

void Init_clk()
{
uchar i;

WDTCTL = WDTPW +WDTHOLD;
BCSCTL1 &= ~XT2OFF; //8MHz
BCSCTL2 &= SELM1 +SELS;
do
{
IFG1 &= ~OFIFG;
for(i=0;i<100;i++);
}while((IFG1 & OFIFG)!=0);
IFG1 &= ~OFIFG;
}

void Init_usart()
{
U1CTL = SWRST;
U1CTL |= CHAR; //8位数据
U1TCTL |= SSEL1; //时钟SMCLK
U1BR0 = 0x45;
U1BR1 = 0x00; //波特率115200
U1MCTL = 0x00; //小数不设置
ME2 |= UTXE1; //使能UART1的发送
U1CTL &= ~SWRST;
P3SEL |= UTXD1; //端口功能设置为第二功能
}
void main()
{
Init_clk();
Init_usart();
while(1)
{
U1TXBUF = dataSedBuffer[curtSedLen];
if(curtSedLen >= redySedLen)
{
curtSedLen = 0;
Delay_us(60000);
}
while((IFG2 & UTXIFG1)==0);
}
}


MSP430单片机。
程序一直卡死在 while((IFG2 & UTXIFG1)==0);这一句。数据不能发送出去。

下面是接收代码

#include "msp430x14x.h"
#define uchar unsigned char
#define uint unsigned int
#define URXD1 BIT7

uchar dataRecBuffer[100]; //接收数据缓存区
uchar saveRecLen = 0; //最后存储收到数据的总长度
uchar curtRecLen = 0; //当前收到的数据长度

void Delay_us(uint count)
{
while(count-- ){_NOP();};
}

void Init_clk()
{
uchar i;

WDTCTL = WDTPW +WDTHOLD;
BCSCTL1 &= ~XT2OFF; //8MHz
BCSCTL2 &= SELM1 +SELS;
do
{
IFG1 &= ~OFIFG;
for(i=0;i<100;i++);
}while((IFG1 & OFIFG)!=0);
IFG1 &= ~OFIFG;
}

void Init_usart()
{
U1CTL = SWRST;
U1CTL |= CHAR; //8位数据
U1TCTL |= SSEL1; //时钟SMCLK
U1BR0 = 0x45;
U1BR1 = 0x00; //波特率115200
U1MCTL = 0x00; //小数设置
ME2 |= URXE1; //使能UART1的发送和接收
U1CTL &= ~SWRST;
IE2 |= URXIE1; //UART1接收中断使能
P3SEL |= URXD1; //端口功能设置为第二功能
}

#pragma vector = UART1RX_VECTOR
__interrupt void UART1_RX_ISR(void)
{
dataRecBuffer[curtRecLen] = RXBUF1; //接收数据
curtRecLen += 1;
if(dataRecBuffer[curtRecLen-1] == 13 ||dataRecBuffer[curtRecLen-1] == 0) //接收到ENTER(换行)符
{
saveRecLen = curtRecLen-1; //保存收到的总长度
curtRecLen = 0;
}
}

void main()
{
Init_clk();
Init_usart();
_EINT();
while(1){};
}

程序一直卡死在while(1){};进不了中断,接收不到数据。

我做的是两个单片机串口通信,一个发送,一个接收。
帮忙看下哪儿错了,谢谢了!
...全文
247 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
never_QL 2009-12-31
  • 打赏
  • 举报
回复
我RI,居然是因为软件环境设置错了。
tcdzyq 2009-12-30
  • 打赏
  • 举报
回复
不好意思,看错.以下为参考例程,在32K晶振下波特率为2400,肯定可用,供楼主参考

#include <MSP430X14X.H>

void Init_UART1(void); //声明UART初始化函数
void Init_Timer_A(void); //初始化定时器模块
#define INBUF_LEN 4 //数据长度
unsigned char UART1_RXBUF1[INBUF_LEN];
char checksum,count3;
char TX_Flag;
void send_string_com( unsigned char *str, unsigned int strlen);
void main(void)
{
WDTCTL = WDTPW + WDTHOLD ; //关闭看门狗

Init_UART1(); //UART初始化函数
_EINT(); //通用中断允许
while(1) //主循环
{
if( TX_Flag ==1) //如果取数标志已置位,就将读到的数从串口发出
{
TX_Flag = 0 ; //取数标志清0
send_string_com(UART1_RXBUF1,INBUF_LEN);
}
}
}
void Init_UART1(void)
{
UCTL1 &=~ SWRST; // SWRST复位,USART允许
UCTL1 = 0x10; // 8位数据位,1位停止位,无校验
UBR01 = 0x0D;
UBR11 = 0x00; // 使用32KHz晶振时波特率为2400bps
UMCTL1 = 0x6B; // 位调整
UTCTL1 = 0x10; // 选定ACLK(32KHz晶振)为时钟源
ME2 |= 0x30; //UART发送及接收模块允许
P3SEL = 0xC0; // P3.6 P3.7被USART1发送模块占用
P3DIR = 0X40; // P3.6 输出,P3.7 输入
IE2 |= URXIE1; //接收中断允许


}

//向串口发送一个字符
void send_char_com( unsigned char ch)
{
TXBUF1=ch;
while ((UTCTL1&0x01)==0 );

}

//向串口发送一个字符串,strlen为该字符串长度

void send_string_com( unsigned char *str, unsigned int strlen)
{
unsigned int k= 0 ;
do
{
send_char_com(*(str + k));
k++;
} while (k < strlen);
}
/*****************************************************************************
USART1接收中断函数
******************************************************************************/
#pragma vector=UART1RX_VECTOR
__interrupt void UART1(void)
{
if (URXIFG1)
{
unsigned char ch;
IFG2 &=~ URXIFG1 ;
ch=RXBUF1;
if (ch> 127 )
{
count3= 0 ;
UART1_RXBUF1[count3]=ch;
checksum= ch- 128 ;
}
else
{
count3++;
UART1_RXBUF1[count3]=ch;
checksum ^= ch;
if ( (count3==(INBUF_LEN- 1 )) && (!checksum) )
{
TX_Flag = 1 ;
//如果串口接收的数据达到INBUF_LEN个,且校验没错,
//就置位取数标志
}
}
}
}
gooogleman 2009-12-30
  • 打赏
  • 举报
回复
呵呵。俺以后把毕业设计上传上来。虽然有点烂,但是对初学者有点帮助,呵呵。
kyzf 2009-12-30
  • 打赏
  • 举报
回复
你可以尝试下,不用中断 发送与接收数据。

首先你可以尝试:
1、一个单片机 直接按照固定的波特率,发送一段数据(比如0-9,或者0-99)
看另外一个单片机是否接收到?

2、把第一步调通后,你再进行:第一个单片机 直接按照固定的波特率,发送一段数据;之后另外一个单片机把接收的数据都发送回来?看第一个单片机是否能接收到?

3、把上面2步调通后,你的2个单片机就能相互通信; 此时你就主要调测下你中断初始化,以及中断处理函数中的数据发送与接收。
tcdzyq 2009-12-30
  • 打赏
  • 举报
回复
开全局中断
宇帆 2009-12-30
  • 打赏
  • 举报
回复
程序一直卡死在 while((IFG2 & UTXIFG1)==0);这一句。数据不能发送出去。

可能是初始化不对 也可能是硬件有问题

建议楼主 先和PC通信
never_QL 2009-12-30
  • 打赏
  • 举报
回复
单片机没有串口和PC相连,我怎么弄PC和单片机的通讯?
贝隆 2009-12-30
  • 打赏
  • 举报
回复
学习
tcdzyq 2009-12-30
  • 打赏
  • 举报
回复
地电平(GND)与大地是两个概念,楼主要弄清楚.要分别接地也可以,需要用光耦隔离.
建议楼主先用PC机与其中一台通,不要一台都没搞清楚就搞联机,都不知道哪出的问题.
[Quote=引用 8 楼 never_ql 的回复:]
共地的意思是两个连接在一起,然后同时连接到地?
[/Quote]
宇帆 2009-12-30
  • 打赏
  • 举报
回复
两个要通信 共地是必须的
ghosty_hand 2009-12-30
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 never_ql 的回复:]
我是楼主,还有个问题。
两个单片机相连,必须要将GND连接在一起共地吗?
分别接地 不行吗?

另外两个单片机通信该怎么调试?单步调试没有用。
还有上面的问题,还是没有解决掉,不知道是不能发送,还是不能接收,
help.....
[/Quote]


最好的办法就是拿示波器来看数据
cyymycc 2009-12-30
  • 打赏
  • 举报
回复
两块MCU是焊接在一块板子上不会出问题,1#的txd接2#的rxd,1#的rxd接2#的txd即可。
不用中断,用查询方式 发送与接收数据。
never_QL 2009-12-30
  • 打赏
  • 举报
回复
还有个问题,我这两块MCU是焊接在一块板子上。我用JTAG接口分别烧进发送和接收的程序。这样会不会出问题?
我先烧进发送代码,在IAR软件里执行它。它是一个死循环,不停的在一定时间间隔里发送数据串。然后我将仿真器数据线拔掉,插在另外一块单片机上,将接受代码烧进去。这个接收代码就是接收那个发送代码发送出的数据。
然后我调试接收代码,发现接收代码并没有接收到数据,因为没有触发接收中断。
我不知道这样的操作过程有没有错误的地方?
如果哪位朋友有空闲,帮我看看我的代码有没有问题吧。谢谢了,我快被这东西弄的没办法了
never_QL 2009-12-30
  • 打赏
  • 举报
回复
共地的意思是两个连接在一起,然后同时连接到地?
kyzf 2009-12-30
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 never_ql 的回复:]
我是楼主,还有个问题。
两个单片机相连,必须要将GND连接在一起共地吗?
分别接地 不行吗?

另外两个单片机通信该怎么调试?单步调试没有用。
还有上面的问题,还是没有解决掉,不知道是不能发送,还是不能接收,
help.....
[/Quote]

首先2个MCU 通讯,严格讲,都得共地;否则2边的电平参考不一样;很容易导致信号出错。
never_QL 2009-12-30
  • 打赏
  • 举报
回复
我是楼主,还有个问题。
两个单片机相连,必须要将GND连接在一起共地吗?
分别接地 不行吗?

另外两个单片机通信该怎么调试?单步调试没有用。
还有上面的问题,还是没有解决掉,不知道是不能发送,还是不能接收,
help.....

27,382

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧