|
关于用MSP430F149测温湿度和风速的问题,温湿度传感器用的是DHT11(直接输出数字信号),风速采集的是模拟信号经过AD转换后输出。现在问题是用串口调试助手调试时显示的全是0(完全没有 按指定的数据帧格式输出,不过在测试时风速传感器没有接单片机(不知道有没有影响)),但如果把风速那块程序注释掉,又可以按指定的格式输出。代码如下:
#include
//#include "dht11.h"
//#include "uart0.h"
#include "Config.h"
#include
char s[40];
void delayus(unsigned int n);
typedef unsigned int U16;
typedef unsigned char U8;
unsigned char U8FLAG,k;
unsigned char U8count,U8temp;
unsigned char U8T_data_H,U8T_data_L,U8RH_data_H,U8RH_data_L,U8checkdata;
unsigned char U8T_data_H_temp,U8T_data_L_temp,U8RH_data_H_temp,U8RH_data_L_temp,U8checkdata_temp;
unsigned char U8comdata;
unsigned char outdata[5]; //定义发送的字节数
unsigned char indata[5];
unsigned char count, count_r=0;
unsigned int U16temp1,U16temp2;
uint TEMP0=0; //ADC值暂存变量
uchar Value[9];
uint Count=0; //时间计数变量
void Voltage_do(uchar temp0,uchar temp1,uchar temp2,uchar temp3,uint temp4)
{
Value[0]=0XAA;
Value[1]=0X05;
Value[2]=temp0;
Value[3]=temp1;
Value[4]=temp2;
Value[5]=temp3;
Value[6]=temp4>>8;
Value[7]=temp4;
Value[8]=0xBB;
}
//*************************************************************************
// ADC初始化程序,用于配置ADC相关寄存器
//*************************************************************************
void ADC_Init()
{
P6SEL|=0x01; //选择ADC通道
ADC12CTL0|= ADC12ON + SHT0_2 + MSC;
ADC12CTL1|= ADC12SSEL1 + ADC12SSEL0+CONSEQ_2+SHP; //SMCLK做时钟源
ADC12MCTL0= INCH_0; //参考控制位及通道选择,这里选择通道0
ADC12CTL0|= ENC; //使能转换器
}
//*************************************************************************
// 串口初始化及发送
//*************************************************************************
void UART_Init()
{
U0CTL|=SWRST; //复位SWRST
U0CTL|=CHAR; //8位数据模式
U0TCTL|=SSEL1; //SMCLK为串口时钟
U0BR1=baud_h; //BRCLK=8MHZ,Baud=BRCLK/N
U0BR0=baud_l; //N=UBR+(UxMCTL)/8
U0MCTL=0x00; //微调寄存器为0,波特率9600bps
ME1|=UTXE0; //UART1发送使能
ME1|=URXE0; //UART1接收使能
U0CTL&=~SWRST;
IE1|=URXIE0; //接收中断使能位
P3SEL|= BIT4; //设置IO口为普通I/O模式
P3DIR|= BIT4; //设置IO口方向为输出
P3SEL|= BIT5;
}
void Send_Byte(uchar data)
{
while((IFG1&UTXIFG0)==0); //发送寄存器空的时候发送数据
U0TXBUF=data;
}
//////////////////////DHT11///////////////////////////////////////////////////////
void DHT11_ReadChar(void)
{
U8 i;
DHT11_INPUT;
for(i=0;i<8;i++)
{
U8FLAG=2;
while( (!DHT11_IN) && U8FLAG++ );
delay_us(40); //40us
U8temp<<=1;
if(DHT11_IN) //26-28us高电平表示'0',30us后若还为高电平则表示为'1'
{
U8temp|=1;
}
U8FLAG=2;
while( (DHT11_IN) && U8FLAG++ ); //超时则U8FLAG到255后变为0,又自加一次变为1退出while
//超时则跳出for循环
if(U8FLAG==1)
break;//判断数据位是0还是1
// 如果高电平高过预定0高电平值则数据位为 1
//U8comdata<<=1;
U8comdata=U8temp; //0
}//rof
}
//--------------------------------
//-----湿度读取子程序 ------------
//--------------------------------
//----以下变量均为全局变量--------
//----温度高8位== U8T_data_H------
//----温度低8位== U8T_data_L------
//----湿度高8位== U8RH_data_H-----
//----湿度低8位== U8RH_data_L-----
//----校验 8位 == U8checkdata-----
//----调用相关子程序如下----------
//---- Delay();, Delay_10us();,COM();
//--------------------------------
void start_DHT11(void)
{
DHT11_OUTPUT;
DHT11_L;
delay_ms(18); //主机拉低18ms
DHT11_H; //总线由上拉电阻拉高 主机延时20-40us
delay_us(40); //40us;
DHT11_H; //主机设为输入 判断从机响应信号
DHT11_INPUT; //判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行
//if(!DHT11_INPUT)
//T !
if(!DHT11_IN) //检测P2.0输入电平
{
U8FLAG=2; //判断从机发出 80us 的低电平响应信号是否结束
while( (!DHT11_IN) && U8FLAG++ );
U8FLAG=2; //判断从机是否发出 80us 的高电平,如发出则进入数据接收状态
while( (DHT11_IN) && U8FLAG++ );//数据接收状态
DHT11_ReadChar(); //一个COM()调用接收一个字节的数据
U8RH_data_H_temp=U8comdata;
DHT11_ReadChar();
U8RH_data_L_temp=U8comdata;
DHT11_ReadChar();
U8T_data_H_temp=U8comdata;
DHT11_ReadChar();
U8T_data_L_temp=U8comdata;
DHT11_ReadChar();
U8checkdata_temp=U8comdata;
DHT11_OUTPUT;
DHT11_H; //数据校验
U8temp=(U8T_data_H_temp+U8T_data_L_temp+U8RH_data_H_temp+U8RH_data_L_temp);
if(U8temp==U8checkdata_temp)
{
U8RH_data_H=U8RH_data_H_temp;
U8RH_data_L=U8RH_data_L_temp;
U8T_data_H=U8T_data_H_temp;
U8T_data_L=U8T_data_L_temp;
U8checkdata=U8checkdata_temp;
}//fi
}//fi
}
//***********************************************************************
// TIMERA初始化,设置为UP模式计数
//***********************************************************************
void TIMERA_Init(void) //UP模式计数,计数周期为CCR0+1
{
TACTL |= TASSEL1 + TACLR + ID0 + ID1 + MC0 + TAIE; //SMCLK做时钟源,8分频,增加计数模式,开中断
TACCR0 = 9999; //CCR0=9999,10ms中断一次
}
//***********************************************************************
// TIMERA中断服务程序,需要判断中断类型
//***********************************************************************
#pragma vector = TIMERA1_VECTOR
__interrupt void Timer_A(void)
{
uchar j;
switch(TAIV) //需要判断中断的类型
{
case 2:break;
case 4:break;
case 10:Count++;break;
}
if(Count==6000) //100次为1秒
{
// Second++;
Count=0;
for(j=0;j<9;j++)
{
Send_Byte(Value[j]);
}
}
// while(Second>599)Second=0; //最大计数99秒
}
///////////////////////主函数///////////////////////////////////////////
void main( void )
{
WDTCTL=WDTPW+WDTHOLD;//关看门狗
Clock_Init();
UART_Init();
delay_ms(100); //延时100ms
delay_ms(100); //延时100ms
delay_ms(50000);
TIMERA_Init(); //设置TIMERA,P12输出PWM信号
_EINT();
ADC12CTL0 |= ADC12SC; //开启转换
while(1)
{
start_DHT11();
while((ADC12IFG & 0x0001) == 0); // 等待转换结束
TEMP0 = ADC12MEM0; //读取ADC转换值
Voltage_do(U8RH_data_H, U8RH_data_L,U8T_data_H,U8T_data_L,TEMP0);
}
}
|
|