51_LanQiaoBei/题目/模拟题/4T15届模拟3_左岚85/4T15模拟3/User/main.c
2025-04-13 01:02:19 +08:00

203 lines
5.1 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "main.h"
/* LED显示 */
uchar ucLed[8] = {0, 0, 0, 0, 0, 0, 0, 0};
/* 数码管显示 */
uchar Seg_Slow_Down; // 数码管减速
uchar Seg_Buf[8] = {5, 10, 10, 10, 10, 10, 10, 10}; // 数码管显示的值
uchar Seg_Pos; // 数码管指示
uchar Seg_Point[8] = {0, 0, 0, 0, 0, 0, 0, 0}; // 某位是否显示小数点
/* 界面显示 */
uchar Seg_show_mode; // 0 测距 1 参数 2 记录
uchar Control_mode; // 0 按键 1 旋钮
/* 键盘方面 */
uchar Key_Slow_Down;
/* 数据 */
uchar Distance_value; // 距离测量数据
uchar Para_max = 60; // 参数上限
uchar Para_min = 10; // 参数下限
uchar Wring_count; // 报警次数
bit Wring_flag; // 报警标志
uchar Para_mode; // 0 不控制 1 上限 2 下限
uchar Vol_level; // 电压等级,用于控制上下限 1 2 3 4
bit Led_show_flag; // LED闪烁
/* 时间 */
uchar time_100ms;
/* 键盘处理函数 */
void Key_Proc()
{
static uchar Key_Val, Key_Down, Key_Up, Key_Old;
if (Key_Slow_Down)
return;
Key_Slow_Down = 1;
Key_Val = Key_Read();
Key_Down = Key_Val & (Key_Old ^ Key_Val);
Key_Up = ~Key_Val & (Key_Old ^ Key_Val);
Key_Old = Key_Val;
if (Key_Down == 4)
Seg_show_mode = (++Seg_show_mode) % 3;
if (Key_Down == 5)
{
if (Seg_show_mode == 1)
Control_mode = (++Control_mode) % 2;
if (Seg_show_mode == 2)
Wring_count = 0;
Para_mode = 0; // 这里切换的时候将旋钮调整的上下限模式重置防止出现bug
}
if (Seg_show_mode == 1)
{ // 按键控制模式
if (Control_mode == 0)
{
if (Key_Down == 9)
Para_max = (Para_max + 10 > 90) ? 50
: Para_max + 10;
if (Key_Down == 8)
Para_min = (Para_min + 10 > 40) ? 0
: Para_min + 10;
}
// 旋钮控制模式
else
{
if (Key_Down == 9)
Para_mode = 1;
if (Key_Down == 8)
Para_mode = 2;
}
}
}
/* 数码管处理函数 */
void Seg_Proc()
{
uchar i;
if (Seg_Slow_Down)
return;
Seg_Slow_Down = 1;
Distance_value = Ut_Wave_Data();
// 超出上下限
if ((Distance_value < Para_min || Distance_value > Para_max))
{
// 没有报警的时候
if (Wring_flag == 0)
{
Wring_count++;
Wring_flag = 1;
}
}
// 没有超出上下限拉低报警flag准备下一次报警
else
{
Wring_flag = 0;
}
// 当我们处于旋钮控制才进行采集电压
if (Control_mode == 1)
{
Vol_level = Ad_Read(0x03) / 51;
Vol_level = (Vol_level >= 4) ? 4 : Vol_level; // 限制一下防止出现判定5的极端情况
if (Para_mode == 1)
Para_max = Vol_level * 10 + 50;
else if (Para_mode == 2)
Para_min = Vol_level * 10;
}
switch (Seg_show_mode)
{
case 0:
/* 测距界面 */
Seg_Buf[0] = 11; // A
for (i = 1; i < 5; i++)
{
Seg_Buf[i] = 10;
}
Seg_Buf[5] = (Distance_value / 100 % 10 == 0) ? 10
: Distance_value / 100 % 10;
Seg_Buf[6] = ((Distance_value / 10 % 10 == 0) && (Seg_Buf[5] == 10)) ? 10
: Distance_value / 10 % 10;
Seg_Buf[7] = Distance_value % 10;
break;
case 1:
/* 参数界面 */
Seg_Buf[0] = 12; // P
Seg_Buf[1] = Control_mode + 1;
Seg_Buf[2] = 10;
Seg_Buf[3] = Para_min / 10 % 10;
Seg_Buf[4] = Para_min % 10;
Seg_Buf[5] = 13; //-
Seg_Buf[6] = Para_max / 10 % 10;
Seg_Buf[7] = Para_max % 10;
break;
case 2:
/* 记录界面 */
Seg_Buf[0] = 14; // E
for (i = 1; i < 7; i++)
{
Seg_Buf[i] = 10;
}
Seg_Buf[7] = (Wring_count > 9) ? 13
: Wring_count;
break;
}
}
/* LED处理函数 */
void Led_Proc()
{
ucLed[0] = (Seg_show_mode == 0);
ucLed[1] = (Seg_show_mode == 1);
ucLed[2] = (Seg_show_mode == 2);
ucLed[7] = (Wring_flag == 0) ? 1
: Led_show_flag;
}
/* 定时器0中断初始化 */
void Timer0_Init(void) // 1毫秒@12.000MHz
{
AUXR &= 0x7F; // 定时器时钟12T模式
TMOD &= 0xF0; // 设置定时器模式
TL0 = 0x18; // 设置定时初始值
TH0 = 0xFC; // 设置定时初始值
TF0 = 0; // 清除TF0标志
TR0 = 1; // 定时器0开始计时
ET0 = 1;
EA = 1;
}
/* 定时器0中断函数 */
void Timer0_ISR(void) interrupt 1
{
if (++Key_Slow_Down == 10)
Key_Slow_Down = 0;
if (++Seg_Slow_Down == 500)
Seg_Slow_Down = 0;
if (++Seg_Pos == 8)
Seg_Pos = 0;
if (Wring_flag)
{
if (++time_100ms == 100)
{
time_100ms = 0;
Led_show_flag ^= 1;
}
}
else
{
time_100ms = 0;
}
Seg_Disp(Seg_Pos, Seg_Buf[Seg_Pos], Seg_Point[Seg_Pos]);
Led_Disp(Seg_Pos, ucLed[Seg_Pos]);
}
void main()
{
System_Init();
Timer0_Init();
while (1)
{
Key_Proc();
Seg_Proc();
Led_Proc();
}
}