共2条
1/1 1 跳转至页
MSP430,MODBUS 斑竹,救我吧?MSP430通信与MODBUS的难题!
问
斑竹,救救我吧!现在我才用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、建议先用例程测试。
主程序:
#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 跳转至页
回复
有奖活动 | |
---|---|
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |
打赏帖 | |
---|---|
与电子爱好者谈读图二被打赏50分 | |
【FRDM-MCXN947评测】Core1适配运行FreeRtos被打赏50分 | |
【FRDM-MCXN947评测】双核调试被打赏50分 | |
【CPKCORRA8D1B评测】---移植CoreMark被打赏50分 | |
【CPKCORRA8D1B评测】---打开硬件定时器被打赏50分 | |
【FRDM-MCXA156评测】4、CAN loopback模式测试被打赏50分 | |
【CPKcorRA8D1评测】--搭建初始环境被打赏50分 | |
【FRDM-MCXA156评测】3、使用FlexIO模拟UART被打赏50分 | |
【FRDM-MCXA156评测】2、rt-thread MCXA156 BSP制作被打赏50分 | |
【FRDM-MCXN947评测】核间通信MUTEX被打赏50分 |