正在做一个无线通讯,外接的是APC240CF的无线通讯模块,设置P2.4输出和P2.5输入,准备在USART0的通讯基础上实现,485通讯我已经实现了,经过删减后,但是我发现我的这个程序无法进入通讯中断。其次我把whil(1)和中断标志位进入判定语句receive_flag==1:删除后,427芯片TXD脚可以保持一直发送固定的信号,但是RXD脚也受到了影响,也一致产生固定的信号,起波长与TXD的波几乎一致,只是开头和结尾为1,中间为0。当不删除的时候(即如下程序)示波器可以观察,不过这样用示波器观察在进入mian.c之后要执行WMSendRDData(ComBuf);的时候与我预计的没什么问题,毕竟度只是初始化,但是一执行WMSendRDData(ComBuf);语句请教下我这边是出现了什么问题了?附程序和头文件
主程序 main.c
#include <msp430x42x.h>
#include "main.h"
uchar8 ComBuf[COMBUFLEN];
uchar8 BufNum=0;
uint32 FV=5432; // 流速 Flow Velocity
uint32 FL=1111; // 流量
int receive_flag=0;
uchar8 WMAddress[7]={1,2,3,4,5,6,7};
void InitUART0(void) //波特率初始化
{
// case 1200:
UTCTL0 = SSEL0; // UCLK = ACLK
UBR00 = 0x1b; // 32768/1200 = 27.307
UBR10 = 0x00;
UMCTL0 = 0x11; //调整字节UMCTL0中1的个数为0.307*8=2.45≈2,均匀分布1得到0x11
}
void BasicTimer_Init (void) // BasicTimer On
{
BTCTL |= BTDIV + BT_fCLK2_DIV16; // ACLK/(256*16)
IE2 |= BTIE; // Enable BT interrupt
}
void DisableWDT(void)//About WDT 关闭看门狗
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
}
void DCO_Init(void)//DCO初始化
{
uint16 i;
FLL_CTL0 = XCAP18PF + DCOPLUS; // Configure MCLK
SCFQCTL = 60;
SCFI0 = FLLD_2; // SMCLK = MCLK = 32.768*(60+1)*2 = 399.77K
SCFI1 = 0;
do {
IFG1 &= ~OFIFG; // Clear oscillator fault flag
for (i = 5000; i; i--); // Delay
} while(IFG1 & OFIFG); // Test osc fault flag
}
//串口初始化
void Uart0_Init(void)
{
P2SEL|=BIT4+BIT5;
P2DIR|=BIT4;
P2DIR&=~BIT5;
U0CTL |= SWRST; //控制寄存器位
U0CTL &= ~(SYNC + MM);
UCTL0 |= CHAR + PEV + PENA; // 8-bit character
InitUART0();
ME1 |= UTXE0 + URXE0; // Enable USART0 TXD/RXD
UCTL0 &=~SWRST; // Initialize USART state machine
IE1 |= URXIE0; // Enable USART0 RX interrupt
IE1 &=~ UTXIE0; //发送中断关闭;
IFG1 = 0X00; //中断标志位清零
}
//发送一个字节
void TxdOneByte(uchar8 ch)
{
while(!(UTCTL0 & TXEPT));
TXBUF0 = ch;
}
//发送一个缓冲帧
void TxdBuf (uchar8 buf[],uchar8 len)
{
int i;
for(i = 0; i < len; i++) {
TxdOneByte(buf[i]);
}
}
void LToOctal(unsigned char *ptr, unsigned long mun)
{
int i=4;
for(;i>=0;i--)
{
ptr[i]=mun%10;
mun=mun/10;
}
}
void delay(int ms)
{
int sub=200;
for(;ms>=0;ms--)
sub--;
}
///////////////////////////////////////////////////////////////////////
#pragma vector =UART0RX_VECTOR
__interrupt void USART0_RX (void)
{
delay(100);
_DINT();
receive_flag=1;
ComBuf[BufNum++] = RXBUF0;
if(BufNum == COMBUFLEN) //防止溢出
BufNum = 0;
_EINT();
}
//水表接收到读操作后返回的响应数据处理
void WMSendRDData(uchar8 pdata[]) //pdata为串口接收到的数据,RtnRslt为返回的帧起始地址
{
uchar8 rtnrslt[60];
uchar8 i=0,check=0;
for(i=0;i<4;i++)
rtnrslt[i] = 0XFE;//COMLEADER;
rtnrslt[i++] = 0X68;//COMHEAD;
rtnrslt[i++] = 0X16;//COMTYPE;
rtnrslt[i++] = WMAddress[0];
rtnrslt[i++] = WMAddress[1];
rtnrslt[i++] = WMAddress[2];
rtnrslt[i++] = WMAddress[3];
rtnrslt[i++] = WMAddress[4];
rtnrslt[i++] = WMAddress[5];
rtnrslt[i++] = WMAddress[6];
rtnrslt[i++] = pdata[9]+0x80; //返回的应答命令为原命令再加0x80
rtnrslt[i++] = 0x16;//LENREADDATA;
rtnrslt[i++] = pdata[11]; //DI0
rtnrslt[i++] = pdata[12]; //DI1
rtnrslt[i++] = 0; //SER
LToOctal(&rtnrslt[50],FL); //当前累积流量,定点数,两位小数
rtnrslt[i++] = rtnrslt[53];
rtnrslt[i++] = rtnrslt[52];
rtnrslt[i++] = rtnrslt[51];
rtnrslt[i++] = rtnrslt[50];
rtnrslt[i++] = 0x2C; //单位 m3
LToOctal(&rtnrslt[50],FV); //瞬时流量,定点数,4位小数
rtnrslt[i++] = rtnrslt[53];
rtnrslt[i++] = rtnrslt[52];
rtnrslt[i++] = rtnrslt[51];
rtnrslt[i++] = rtnrslt[50];
rtnrslt[i++] = 0x35; //单位 m3/h
// rtnrslt[i++] = Data8ToBCD(30); //实时时间,sec
// rtnrslt[i++] = Data8ToBCD(WorkTime.min/480); //实时时间,min
// rtnrslt[i++] = Data8ToBCD(WorkTime.hour); //实时时间,hour
// rtnrslt[i++] = Data8ToBCD(WorkTime.day); //实时时间,day,
// rtnrslt[i++] = Data8ToBCD(WorkTime.month); //实时时间,月
// rtnrslt[i++] = Data8ToBCD(WorkTime.year); //实时时间,年低八位
// rtnrslt[i++] = 0x20; //实时时间,年高八位
rtnrslt[i++] = 0; //水表状态ST1 用户自定义
rtnrslt[59] = i;
for(i=4;i<(rtnrslt[59]);i++)//校验计算
{
check += rtnrslt[i];
}
i = rtnrslt[59];
rtnrslt[i++] = check;
rtnrslt[i++] = 0X16;//COMREAR; //帧结束
TxdBuf(rtnrslt,i);
}
void main(void) //主程序
{
DisableWDT(); //禁止看门狗,方便系统初始化
DCO_Init();
BasicTimer_Init();
Uart0_Init();
while(1)
{
if (receive_flag==1)
{
WMSendRDData(ComBuf);
receive_flag=0;
}
Delay_ZZG(200);
}
}
void Delay_ZZG(unsigned int ms)
{
unsigned int i,j;
for( i=0;i<ms;i++)
for(j=0;j<2000;j++); //8MHz晶振时
}
//将无符号8位数据转换成压缩BCD码
uchar8 Data8ToBCD(uchar8 dat)
{
uchar8 bcd=0;
if(dat > 99)
return 0;
while(dat > 9)
{
dat -= 10;
bcd++;
}
bcd <<= 4;
bcd += dat;
return bcd;
}
const uchar8 BCD_DA_Table[10]={0,6,12,18,24,30,36,42,48,54};//BCD码的十进制调整DA的参数表
//将压缩BCD码转换成无符号8位数
uchar8 BCDToData8(uchar8 bcd)
{
return(bcd - BCD_DA_Table[bcd>>4]);
}
头文件main.h
#ifndef _MAIN_H_
#define _MAIN_H_
//#include <string.h>
//////////////////////////////////////////////////////
typedef unsigned char uchar8;
typedef unsigned int uint16;
typedef unsigned long uint32;
typedef unsigned long long uint64;
#define COMBUFLEN 120
#define ComSendBuf (ComBuf+80) //接收缓冲大小,后40字节并共用于半双工通信时的发送
//#define COMREAR 16
//#define COMLEADER 16
//函数外部声明
extern unsigned char ComBuf[COMBUFLEN];
extern void Uart0_Init (void);
extern void TxdOneByte(uchar8 ch);
extern void TxdBuf (unsigned char buf[],unsigned char len);
//extern unsigned char WMRcvDataProcess(unsigned char pdata[], unsigned char rtnrslt[]);//水表接收到的串口帧数据预处理,进行帧判断和错误处理
extern void WMSendRDData(unsigned char pdata[]); //水表接收到读操作后返回的响应数据处理//pdata为串口接收到的数据,RtnRslt为返回的帧起始地址
extern void InitUART0(void);
extern void LToOctal(unsigned char *ptr, unsigned long mun);// rljasm.s43
extern unsigned char Data8ToBCD(unsigned char dat);// rljasm.s43 //将数据转换成压缩BCD码
extern unsigned char BCDToData8(unsigned char bcd);//将压缩BCD码转换成无符号8位数
extern void BasicTimer_Init (void);
extern void Delay_ZZG(unsigned int ms);
#endif |