我用430的ADC12输入端接了4路的模拟量作为数据采集端,然后经过AD序列通道转换成数字量发给上位机监测,或者传给另外一个MCU,整体的思想是这些。现在的问题是:我现在先模拟了一路模拟量送给430单片机后,经过AD处理也都好着呢,然后我就通过UART0发送给上位机–串口助手,上面的接收也好着,可是我的设想是当上位机接收到数据后,我人为的在上面给下位机430单片机回执一个“确认信息”,比如在串口助手软件发送口输入个“recept”后显示在下位机的1602液晶上面,可是下位机就是接收不成功????我把接收函数写在了接收中断里面的,麻烦帮我解决下了~~~~~~当我单独调试上位机给下位机发数据然后显示在1602上面时都好着呢,但是接收和发送写在一块的时候,就出问题了。
/****************************************************/
//通信格式:N.8.1, 9600
// BCSCTL1 &= ~XT2OFF; //打开XT2高频晶体振荡器
// do
// {
// IFG1 &= ~OFIFG; //清除晶振失败标志
// for (i = 0xFF; i > 0; i–); //等待8MHz晶体起振
// }
// while ((IFG1 & OFIFG)); //晶振失效标志仍然存在
// BCSCTL2 |= SELM_2 + SELS; //MCLK和SMCLK选择高频晶振
/*****************************************************/
#include <msp430x14x.h>
#include "cry1602.h"
#include "BoardConfig.h"
#define CPU_F ((double)8000000) //本征函数
#define delay_us(x) __delay_cycles((long)(CPU_F*(double)x/1000000.0))#define delay_ms(x) __delay_cycles((long)(CPU_F*(double)x/1000.0))#define Num_of_Results 32
uchar shuzi[] = {"0123456789."};
uchar tishi[] = {"The thic is:"};//浓度指示语句
uchar pX=0,pY=1;
unsigned char Rindex=0; //数据指针
unsigned char RecBuf[3]; //数据缓冲区
static uint results[Num_of_Results]; //保存ADC转换结果的数组
void Trans_val(uint Hex_Val);
void PutString(uchar *ptr);
void PutChar(uchar zifu);
/*******************主函数*******************/
void main(void)
{ uchar *Tishi = " current smoking thickness:";
P6DIR|=BIT7;
P6OUT|=BIT7;
BoardConfig(0xb8);
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
DCOCTL = DCO0 + DCO1 + DCO2; // Max DCO
BCSCTL1 = RSEL0 + RSEL1 + RSEL2; // XT2on, max RSEL
BCSCTL2 |= SELS; // SMCLK = XT2
P3SEL |= 0x30; // P3.4,5 = USART0 TXD/RXD
ME1 |= URXE0 +UTXE0; // Enable USART0 TXD/RXD
UCTL0 |= CHAR; // 8-bit character
UTCTL0 |= SSEL0; // UCLK = ACLK
UBR00 = 0x03; // 32k/9600 – 3.41
UBR10 = 0x00; //
UMCTL0 = 0x4A; // Modulation
UCTL0 &= ~SWRST; // Initialize USART state machine
IE1 |= URXIE0; // 使能USART0的接收中断
PutString(Tishi);
P6SEL |= 0x01; // 使能ADC通道
ADC12CTL0 = ADC12ON +SHT0_8+MSC; // 打开ADC,设置采样时间
ADC12CTL1 = SHP+CONSEQ_2; // 使用采样定时器
//ADC12MCTL0 = INCH1;
ADC12IE = 0x01; // 使能ADC中断
ADC12CTL0 |= ENC; // 使能转换
ADC12CTL0 |= ADC12SC; // 开始转换 LcdReset(); //复位1602液晶
DispNChar(2,0,12,tishi); //显示提示信息
Disp1Char(11,1,'P'); //显示浓度单位 Disp1Char(12,1,'P'); //显示浓度单位
Disp1Char(13,1,'M'); //显示浓度单位
_EINT(); while(1)
{
LPM1;
}
}
/*******************************************
函数名称:PutSting
功 能:向PC机发送字符串
参 数:ptr–指向发送字符串的指针
返回值 :无
********************************************/
void PutString(uchar *ptr)
{
while(*ptr != '\0')
{
while (!(IFG1 & UTXIFG0)); TXBUF0 = *ptr++; }
while (!(IFG1 & UTXIFG0));
TXBUF0 = '\n';
}
/*******************************************
函数名称:PutChar
功 能:向PC机发送一个字符对应的ASCII码
参 数:
返回值 :无
********************************************/
void PutChar(uchar x )
{
while (!(IFG1 & UTXIFG0));
TXBUF0 =x;
delay_ms(200);
//IFG1&=0x00;//清除中断标志位
}
/*******************************************
函数名称:UART0_RXISR
功 能:UART0的接收中断服务函数
参 数:无
返回值 :无
********************************************/
#pragma vector = UART0RX_VECTOR //UART0的接受中断函数
__interrupt void UART0_RXISR(void)
{
while (!(IFG1 & URXIFG0)); //等待接收到字符
RecBuf[Rindex++] = RXBUF0; //将接收到的数据存放到缓存中 Disp1Char(pX++,pY,RecBuf[Rindex++]);
//IFG1=0;//清除中断标志位
if(pX == 16)
{
pX = 0; //x–位置的列坐标
//y–位置的行坐标
pY ^= 1;
}
delay_ms(10);
}
/*******************************************
函数名称:ADC12ISR
功 能:ADC中断服务函数,用多次平均的
计算P6.0口的模拟电压数值
参 数:无 返回值 :无
********************************************/
#pragma vector=ADC_VECTOR
__interrupt void ADC12ISR (void)
{ static uint index = 0;
results[index++] = ADC12MEM0; // Move results
if(index == Num_of_Results)
{
uchar i;
unsigned long sum = 0;
index = 0;
for(i = 0; i < Num_of_Results; i++)
{
sum += results[i];
}
sum >>= 5;
Trans_val(sum);
}
}
/*******************************************
函数名称:Trans_val
功 能:将16进制ADC转换数据变换成三位10进制
真实的模拟电压数据,并在液晶上显示 返回值 :无
********************************************/
void Trans_val(uint Hex_Val)
{
unsigned long caltmp;
uint Curr_Volt;
uchar t1,i,j;
uchar ptr[4];
caltmp = Hex_Val;
caltmp = (caltmp << 5) + Hex_Val; //caltmp = Hex_Val * 33
caltmp = (caltmp << 3) + (caltmp << 1); //caltmp = caltmp * 10
Curr_Volt = caltmp >> 12; //Curr_Volt = caltmp / 2^n
ptr[0] = Curr_Volt / 100; //Hex->Dec变换
t1 = Curr_Volt – (ptr[0] * 100);
ptr[2] = t1 / 10;
ptr[3] = t1 – (ptr[2] * 10);
ptr[1] = 10; //shuzi表中第10位对应符号"."
//在液晶上显示变换后的结果
for(j=0;j<8;j++)
{ for(i = 0;i < 4;i++)
{ Disp1Char((6 + i),1,shuzi[ptr[i]]);
PutChar(shuzi[ptr[i]]);
if(ptr[0]>=2&&ptr[2]==0)
{
P6OUT=~P6OUT;
}
}
while (!(IFG1 & UTXIFG0));
TXBUF0 = '\t'; //回车符隔开
}
while (!(IFG1 & UTXIFG0));
TXBUF0 = '\n'; //每8个数据发送完后,换行操作
}
我不知道接收中断函数那样写行不? 我当初以为是不是没有清楚接收中断的标志位IFG1,但是当清除后还是不行,后来一想接收中断又不是多源中断(不像P1口的多源中断),所以不存在清除标志位呀,所以郁闷了~~~~~~ 请高手指点。。。。。。
Charles Wu:
你的代码既然已经用中断函数来处理UART的接收,那就不需要手动在对URXIFG做操作了,430会自动判断URXIFG置位并清零。而你手动清除了IFG0,可能还会对UART的发送产生影响。
将while (!(IFG1 & URXIFG0)); //等待接收到字符去掉再试试