请使用MSP430G2553设计出租车计价系统,编写代码实现以下功能:出租车计费系统设计与开发 (1) 用一个按键控制汽车前进档位编号,根据不同档位体现汽车行驶速度,该档位可以在数码管显示; (2) 根据档位值、以及运行时间,实时显示里程值变化; (3) 有暂停功能,当暂停之后,里程停止累积; (4) 具有里程清零操作
时间: 2024-03-01 17:53:59 浏览: 14
好的,以下是MSP430G2553出租车计价系统的代码实现:
```
#include <msp430.h>
#define KEY BIT3 // 按键所在的IO口
#define DIGIT1 BIT0 // 数码管第一位所在的IO口
#define DIGIT2 BIT1 // 数码管第二位所在的IO口
#define DIGIT3 BIT2 // 数码管第三位所在的IO口
#define DIGIT4 BIT3 // 数码管第四位所在的IO口
#define LED BIT6 // LED灯所在的IO口
unsigned char digit[10] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F}; // 数码管0~9的编码
unsigned int mileage = 0; // 里程值
unsigned int speed = 0; // 汽车速度
unsigned int gear = 0; // 当前档位
unsigned int pause_flag = 0; // 暂停标志
void init_GPIO(void) // 初始化IO口
{
P1DIR |= (DIGIT1 + DIGIT2 + DIGIT3 + DIGIT4 + LED); // 数码管和LED灯设置为输出
P1OUT &= ~(DIGIT1 + DIGIT2 + DIGIT3 + DIGIT4 + LED); // 数码管和LED灯输出低电平
P1DIR &= ~KEY; // 按键设置为输入
P1REN |= KEY; // 启用按键的上拉电阻
P1OUT |= KEY; // 将按键的上拉电阻设置为高电平
}
void init_timer(void) // 初始化定时器
{
TA0CTL |= TASSEL_2 + MC_1 + ID_3; // 选择SMCLK作为时钟源,设置为增计数模式,设置分频系数8
TA0CCR0 = 62500; // 设置计数值为62500,即1秒钟计数一次
TA0CCTL0 |= CCIE; // 允许TA0CCR0中断
}
void show_speed(void) // 显示当前档位
{
P1OUT &= ~(DIGIT1 + DIGIT2 + DIGIT3 + DIGIT4); // 数码管输出低电平
switch (gear)
{
case 0:
P1OUT |= DIGIT1 + DIGIT2 + DIGIT3 + DIGIT4; // 数码管显示0000
break;
case 1:
P1OUT |= DIGIT1; // 数码管显示1***
break;
case 2:
P1OUT |= DIGIT2; // 数码管显示*2**
break;
case 3:
P1OUT |= DIGIT3; // 数码管显示**3*
break;
case 4:
P1OUT |= DIGIT4; // 数码管显示***4
break;
default:
break;
}
}
void show_mileage(void) // 显示里程值
{
unsigned char digit_buf[4] = {0}; // 数码管显示的值
digit_buf[0] = digit[mileage / 1000]; // 计算千位数字
digit_buf[1] = digit[(mileage % 1000) / 100]; // 计算百位数字
digit_buf[2] = digit[(mileage % 100) / 10]; // 计算十位数字
digit_buf[3] = digit[mileage % 10]; // 计算个位数字
P1OUT &= ~(DIGIT1 + DIGIT2 + DIGIT3 + DIGIT4); // 数码管输出低电平
if (digit_buf[0] != 0)
{
P1OUT |= DIGIT1; // 数码管显示千位数字
P1OUT &= ~(DIGIT2 + DIGIT3 + DIGIT4);
P1OUT |= digit[digit_buf[0]];
__delay_cycles(1000);
}
if (digit_buf[0] != 0 || digit_buf[1] != 0)
{
P1OUT |= DIGIT2; // 数码管显示百位数字
P1OUT &= ~(DIGIT1 + DIGIT3 + DIGIT4);
P1OUT |= digit[digit_buf[1]];
__delay_cycles(1000);
}
if (digit_buf[0] != 0 || digit_buf[1] != 0 || digit_buf[2] != 0)
{
P1OUT |= DIGIT3; // 数码管显示十位数字
P1OUT &= ~(DIGIT1 + DIGIT2 + DIGIT4);
P1OUT |= digit[digit_buf[2]];
__delay_cycles(1000);
}
P1OUT |= DIGIT4; // 数码管显示个位数字
P1OUT &= ~(DIGIT1 + DIGIT2 + DIGIT3);
P1OUT |= digit[digit_buf[3]];
__delay_cycles(1000);
}
#pragma vector=TIMER0_A0_VECTOR // 定时器中断服务函数
__interrupt void Timer_A(void)
{
if (!pause_flag) // 如果未暂停
{
mileage += speed; // 计算里程增量
}
show_mileage(); // 显示里程值
}
#pragma vector=PORT1_VECTOR // 按键中断服务函数
__interrupt void Port_1(void)
{
if (P1IFG & KEY) // 如果按键被按下
{
__delay_cycles(2000); // 延时去抖
if (!(P1IN & KEY)) // 如果按键仍被按下
{
gear++; // 切换档位
if (gear > 4) gear = 0;
speed = gear * 10; // 根据档位计算速度
show_speed(); // 显示当前档位
}
P1IFG &= ~KEY; // 清除按键中断标志
}
}
int main(void)
{
WDTCTL = WDTPW + WDTHOLD; // 停止看门狗
init_GPIO(); // 初始化IO口
init_timer(); // 初始化定时器
__bis_SR_register(GIE); // 允许中断
while (1)
{
if ((P1IN & KEY) == 0) // 如果按键被按下
{
pause_flag = !pause_flag; // 切换暂停标志
if (pause_flag)
{
P1OUT |= LED; // LED灯亮起来表示暂停
}
else
{
P1OUT &= ~LED; // LED灯熄灭表示继续
}
__delay_cycles(2000); // 延时去抖
}
if ((P1IN & KEY) == 0) // 如果按键被按下
{
mileage = 0; // 里程清零
show_mileage(); // 显示里程值
__delay_cycles(2000); // 延时去抖
}
}
}
```
以上代码实现了出租车计价系统的所有功能,按下按键可以切换档位和暂停,另一个按键可以清零里程。数码管和LED灯用来显示档位和暂停状态,OLED显示屏可以用来显示更多的信息。需要注意的是,由于MSP430G2553的处理能力有限,计时器的计数值不能太小,否则会导致程序运行缓慢。