这段代码是一个基于msp430微控制器的嵌入式系统程序,主要实现了以下功能:
初始化和配置:
初始化了OLED显示屏、DS18B20温度传感器、火焰传感器、风扇(通过PWM控制)和蜂鸣器。
设置了CPU时钟源和分频,以满足各组件的工作需求。
配置了中断服务例程用于定时更新温度显示。
DS18B20温度传感器:
定义了一系列函数来初始化DS18B20传感器,并读取温度值。通过单总线协议与DS18B20通信,进行温度转换并读取温度数据。
get_one_temperature
函数用于读取温度传感器的值,并将其转换为摄氏度的整数值。
火焰传感器:
风扇控制:
OLED显示:
低功耗管理:
综上所述,这个程序设计了一个相对完整的环境监控系统,能够自动检测环境温度、响应火焰存在报警,并根据温度调节风扇转速,同时所有这些信息都会实时显示在OLED屏幕上。
cpp/*
* OLED
* SCL ----------P3.0
* SDA ----------P3.1
* VCC ----------3.3V
* GND ----------GND
*
*
* DS18B20
* DATA ----------P1.5
* VCC ----------3.3V
* GND ----------GND
*
* 火焰传感器
* DATA ----------P1.2
* VCC ----------3.3V
* GND ----------GND
*
*
* 风扇
* 这里是PWM引脚 注意接驱动
* DATA ----------P2.4
* VCC ----------3.3V
* GND ----------GND
*
*
* 蜂鸣器
* DATA ----------P2.5
* VCC ----------3.3V
* GND ----------GND
*
*
*
*
*
* 火焰传感器(输出低)检测到火焰蜂鸣器响(没有火焰时蜂鸣器关闭)
* 没有火焰时蜂鸣器关闭
*
* 温度小于40 风扇不转
* 40到60 占空比50%转
* 60以上 全速转
*
* 显示屏实时显示温度
*
*
cppvoid main(void)
{
WDTCTL = WDTPW | WDTHOLD; /* Stop watchdog timer */
P5SEL |= BIT4 + BIT5; /* XT1引脚复用,用作晶振 */
UCSCTL6 &= ~(XT1OFF + XT2OFF); /* 打开XT1、XT2 */
P5SEL |= BIT2 + BIT3; /* XT2引脚复用,用作晶振 */
while (SFRIFG1 & OFIFG) /* 等待晶振正常起振 */
{
SFRIFG1 &= ~OFIFG;
UCSCTL7 &= ~(DCOFFG + XT1LFOFFG + XT2OFFG);
}
UCSCTL4 |= SELA__XT1CLK + SELS__XT2CLK + SELM__XT2CLK; /* 时钟源选择 ACLK---XT1CLK SMCLK---XT2CLK MCLK---XT2CLK */
UCSCTL5 |= DIVA__1 + DIVS__4 + DIVM__1; /* 时钟源分频 ACLK/1=32768HZ SMCLK/4=1MHZ MCLK/1=4MHZ */
OLED_Init(); /* OLED初始化 */
P1DIR |= BIT0; /* LED0 */
P1OUT |= BIT0;
P4DIR |= BIT7; /* LED1 */
P4OUT |= BIT7;
P1REN |= BIT2; //火焰传感器
P1OUT |= BIT2;
DS18b20_Port_Init();
TA1CTL |= MC_1 + TASSEL_1 + TACLR; /* 10MS 定时 */
TA1CCR0 = 32768 / 100;
TA1CCTL0 = CCIE;
P2DIR |= (BIT4 + BIT5); /* 方向 */
P2SEL |= (BIT4 + BIT5); /* 第二功能不开 */
TA2CCR0 = 1000; /* PWM模式 计数到1000 PWM周期就是1MS */
TA2CCTL1 = OUTMOD_7; /* 模式 */
TA2CCR1 = 0; /* p2.4 占空比 */
TA2CCTL2 = OUTMOD_7; /* 模式 */
TA2CCR2 = 0; /* p2.5 占空比 蜂鸣器 */
TA2CTL = TASSEL_2 + MC_1 + TACLR; /* smclk, up-down mode, clear TAR 1MHZ */
OLED_ShowString(0, 1, " SYSTEM");
OLED_ShowString(0, 4, "Temp :");
_EINT(); //打开总中断
while (1)
{
//火焰传感器
if ((P1IN & BIT2) == 0)
{
delay_ms(1);
if ((P1IN & BIT2) == 0)
{
//低电平就是有火焰的情况
TA2CCR2 = 500; /* p2.5 占空比 蜂鸣器 */
}
}
if ((P1IN & BIT2) == 1)
{
delay_ms(1);
if ((P1IN & BIT2) == 1)
{
//高电平就是没有火焰的情况
TA2CCR2 = 0; /* p2.5 占空比 蜂鸣器 */
}
}
//打开定时器
TA1CTL |= MC_1 + TASSEL_1 + TACLR; /* 10MS 定时 */
LPM0; //进入低功耗
}
}
char counts = 0;
#pragma vector=TIMER1_A0_VECTOR
__interrupt void TIMER1_A0()
{
TA1CTL = 0; //关闭定时器
counts = (counts + 1) % 50;
if (counts == 49)
{
//0.5s刷新一次温度
temp_value = get_one_temperature();
//根据温度改变占空比
if (temp_value < 400)
{
//温度小于40度 不转
TA2CCR1 = 0;
}
else if (temp_value < 60)
{
//温度小于60 50%占空比
TA2CCR1 = 500; //最大值998
}
else
{
//温度大于60 99%占空比
TA2CCR1 = 998; //最大值998
}
/* 距离存入数组里 */
count = 0;
xianshishuzu[count++] = temp_value % 1000 / 100 + '0';
xianshishuzu[count++] = temp_value % 100 / 10 + '0';
xianshishuzu[count++] = '.';
xianshishuzu[count++] = temp_value % 10 / 1 + '0';
xianshishuzu[count++] = ' ';
xianshishuzu[count++] = 'C';
xianshishuzu[count++] = 0;
/* 显示出来 温度*/
OLED_ShowString(50, 4, xianshishuzu);
}
LPM0_EXIT; //退出低功耗
}
cpphttps://docs.qq.com/sheet/DUEdqZ2lmbmR6UVdU?tab=BB08J2
本文作者:Dong
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC。本作品采用《知识共享署名-非商业性使用 4.0 国际许可协议》进行许可。您可以在非商业用途下自由转载和修改,但必须注明出处并提供原作者链接。 许可协议。转载请注明出处!