这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 综合技术 » 基础知识 » MSP430,MODBUS 斑竹,救我吧?MSP430通信与MODBUS的难题!

共2条 1/1 1 跳转至

MSP430,MODBUS 斑竹,救我吧?MSP430通信与MODBUS的难题!

院士
2006-09-17 18:14:16     打赏
MSP430,MODBUS 斑竹,救我吧?MSP430通信与MODBUS的难题!



关键词: MSP430     MODBUS     斑竹     我吧     通信     难题    

院士
2006-12-22 22:43:00     打赏
2楼
问 斑竹,救救我吧!现在我才用MSP430F149的UART1通信,采用MODBUS的协议,以下使我的程序:
主程序:
#include "main.h"


//初始化时钟
void InitClock(void)
{
//DCOCTL = 0x60;
//BCSCTL1 = 0 ;
//// BCSCTL2 = SELM_2 | SELS | DIVM_0 | DIVS_0 ;
//BCSCTL2 = SELM_2 | DIVM_0 | DIVS_0 |SELS ;
//while(IFG1 & OFIFG)
//{
//IFG1 = 0 ;
//BCSCTL2 = SELM_2 | DIVM_0 | DIVS_0 |SELS ;
//}
unsigned int i;
_BIS_SR(OSCOFF);
BCSCTL1 &= ~XT2OFF;
BCSCTL1 |= XTS; // ACLK = LFXT1 = HF XTAL
BCSCTL2 |= SELS + SELM1;

do
{
IFG1 &= ~OFIFG; // Clear OSCFault flag
for (i = 0xFF; i > 0; i--); // Time for flag to set
}
while ((IFG1 & OFIFG) == OFIFG); // OSCFault flag still set?

}

//初始化系统
void InitSystem(void)
{
//初始化系统参数

WDTCTL = WDTPW + WDTHOLD; //stop watchdog
InitClock();
InitSci();
}


void main(void)
{

InitSystem() ; //初始化系统

_EINT();

for( ; ;)
{
if(flag)
{
UnpackRead(pBuffer);
if(UnpackFlag)
{
flag = 0;
UnpackFlag = 0;
P5OUT &= 0XEF;
//Uart1TX();
}
else
{
flag = 0;
UnpackFlag = 0;
PackRead(pBuffer,iAddress,iCount,pValue);
Uart1TX(pBuffer);
}
}

}
}
通信程序:
#include <MSP430x14x.h> //"comm.h"
#include "rtos.h"

#define ADDRESS 1

//frequency/2400 = 3333.3333
//frequency/4800 = 1666.6667
//frequency/9600 = 833.33333
//frequency/19200 = 416.666667
//frequency/38400 = 208.33333
//frequency/57600 = 138.88889
//frequency/115200 = 69.4444

//初始化串口0
const char Band0[6] = { 05, 0x82, 0xd41, 0xa0, 0xd0, 0x8a };
const char Band1[6] = {0x0d, 6, 0x3, 0x1, 0, 0 };
const char Band2[6] = {0x91, 0x6b, 0x00, 0x6b, 0x91, 0xef};
//const char Reverse[16] = {0,8,4,0xc, 2, 0xa, 6, 0xe, 1 ,9, 5, 0xd,3, 0xb,7,0xf };
#define BAND2400 0
#define BAND4800 1
#define BAND9600 2
#define BAND19200 3
#define BAND38400 4
#define BAND57600 5

//unsigned char count,temp;
unsigned char *pBuffer;
unsigned char i=0,j,flag,UnpackFlag;
unsigned int iAddress,iCount,Length,wCRC,Result;
unsigned char *pValue;
unsigned char Data[40],DataValue[40]=
{0x1010,0x1111,0x1212,0x1313,0x1414,0x1515,0x1616,0x1717,0x1818,0x1919};

void InitUart1(void);
void InitSci(void);
void Uart1TX(unsigned char *pBuffer);
void ReadDo(void);
unsigned int UnpackRead(unsigned char *pBuffer);
unsigned int PackRead(unsigned char *pBuffer,unsigned int iAddress,unsigned int iCount, unsigned char *pValue);
unsigned int Check_CRC(unsigned char *pBuffer,unsigned int Length);

//初始化串口1
void InitUart1(void)
{

UCTL1 = CHAR +SWRST;
UCTL1 = CHAR; // 8-bit character

UTCTL1 = SSEL1; // UCLK = ACLK

URCTL1 = 0;

//波特率设置
UBR01 = Band0[BAND9600];
UBR11 = Band1[BAND9600]; //
UMCTL1 = Band2[BAND9600]; // modulation

ME2 |= UTXE1 + URXE1; // Enable USART0 TXD/RXD

IE2 |= URXIE1; //MOD FOR DEBUG URXIE1+UTXIE1; // Enable USART0 RX interrupt
P3SEL |= 0xc0; // P3.6,7 = USART0 TXD/RXD

P3DIR |= 0x40; // P3.6 output direction
P5SEL &= 0x0EF ; //P5.4 RTX1 = P5.4
P5DIR |= 0x010 ; //p5.4 RTX1 OUTPUT
P5OUT &= 0x0EF ;


}
//初始化子程序
void InitSci(void)
{
InitUart1();

}


//通讯口1接受中断
interrupt [UART1RX_VECTOR] void Uart1Rx(void)
{
P5OUT |= 0x10 ;
//temp = RXBUF_1 ;
//TXBUF_1= temp;
//count = 10;
*(pBuffer+i) = RXBUF1;
i++;
while(*(pBuffer+i) == 0);
flag = 1;
}

void Uart1TX(unsigned char *pBuffer)
{
for(i=0;i<Result;i++)
{
TXBUF1=*(pBuffer+i);
while((UTCTL1&0x01) == 0);
}
flag = 0;
P5OUT &= 0xEF;
}

unsigned int UnpackRead(unsigned char *pBuffer) //从机接收到“读”指令包裹,解包程序
{
Check_CRC(pBuffer,6);
if((*(pBuffer+6) != HIBYTE(wCRC))|(*(pBuffer+7)!=LOBYTE(wCRC)))
//if(*(WORD *)(pBuffer + 6) = Check_CRC(pBuffer, 6)) //crc校验不正确,返回通讯错误
{
UnpackFlag = 1;
return UnpackFlag;
}
else
{
ReadDo();
return UnpackFlag;
} //
}
void ReadDo(void)
{
iAddress = *pBuffer;
if(iAddress == ADDRESS)
{
iCount = *(pBuffer+5);
j = MAKEWORD(*(pBuffer+3),*(pBuffer+2))-40011;
UnpackFlag = 0;
}
else
{
UnpackFlag = 1;
}
}

unsigned int PackRead(unsigned char *pBuffer,unsigned int iAddress,unsigned int iCount, unsigned char *pValue) //从站响应 “读”打包程序 (32位模式)
{
unsigned int i;
pBuffer[0] = iAddress; //“读”帧格式:地址
pBuffer[1] = 0x03; //功能
pBuffer[2] = iCount * 2; //字节数(2×寄存器数目)1Byte
for(i=0;i<iCount;i++) //回传寄存器数据
{
pBuffer[3+i*2] = HIBYTE(pValue[i+j]);
pBuffer[4+i*2] = LOBYTE(pValue[i+j]);
}
*(WORD*)pBuffer[3+iCount*2] = Check_CRC(pBuffer,(3+iCount*2)); //CRC校验码
Result = iCount*2+4;
return Result;
}
unsigned int Check_CRC(unsigned char *pBuffer,unsigned int Length)
{
unsigned int wCRC = 0xFFFF;
unsigned int i,j;
for(i=0;i<Length;i++)
{
wCRC ^= pBuffer[i];

for(j=0;j<8;j++)
{
if (wCRC & 0x0001)
wCRC = (wCRC >> 1) ^ 0xA001;
else
wCRC = wCRC >> 1;
}
}
return wCRC;
}
我发现我得这个程序不能接收、会传数据,斑竹,你帮我分析分析这个难题吧?谢谢你呢! 1: 1.时钟选择这句UTCTL1 = SSEL1; // UCLK = ACLK选的是SMCLK而不是ACLK.
2.unsigned int i;
_BIS_SR(OSCOFF);//这句话关掉了外部晶振XT1
BCSCTL1 &= ~XT2OFF;
BCSCTL1 |= XTS; // ACLK = LFXT1 = HF XTAL//没明白您怎么接的外部晶振
BCSCTL2 |= SELS + SELM1;//这句话应放在清标志后面,并且逻辑上也有问题。串口时钟选SMCLK,SMCLK选XT1而XT1关闭了,那就没时钟了也不会工作。

do
{
IFG1 &= ~OFIFG; // Clear OSCFault flag
for (i = 0xFF; i > 0; i--); // Time for flag to set
}
while ((IFG1 & OFIFG) == OFIFG); // OSCFault flag still set?
3、建议先用例程测试。

共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]