- 打卡等级:初来乍到
- 打卡总天数:3
- 最近打卡:2025-11-07 10:02:37
已绑定手机
注册会员
- 积分
- 61
|
发表于 2025-11-7 10:07:36
|
显示全部楼层
源代码:
main.c:
#include <AI8051U.H>
#include "main.h"
#include "math.h"
#include "stc32_stc8_usb.h"
#include "stdio.h"
#include "string.h"
#include "wave1.h"
#include "uart.h"
#include "pwm.h"
#include "speak.h"
void led_proc();
unsigned char key_slow=0; //开关减速
unsigned int dis_slow=0; //距离减速
unsigned char uart_slow=0; //串口减速
unsigned int adc_slow=0; //adc减速函数
unsigned int init_slow=0; //开关初始化减速
unsigned char com_slow=0; //组合操作模式减速
unsigned char run_slow=0; //组合运行减速
float dis; //测量的距离
float adc_dat=0; //读取adc值
bit forward_start_flag=0; //正转启动标志
bit forward_stop_flag=0; //正转停止标志
bit reverse_start_flag=0; //反转启动标志
bit reverse_stop_flag=0; //反转停止标志
bit set_t_start_flag=0; //设定时间开始标志
bit t_count_flag=0; //设定时间倒计时开始标志
unsigned int t_count=0; //倒计时累减周期
float dis_set_t=0; //设定时间时测量的距离
float set_t; //测定的距离转化的设定时间
float set_tt; //设定运行时间
bit set_volt_flag=0; //设定电压开始标志
float dis_set_volt=0; //设定电压时测量的距离
float set_volt=0; //测定的距离转化的设定电压
bit pwm_measure_flag=0; //pwm测量标志
float sudu; //风速
float pwm_duty=30; //pwm占空比
bit volt_on_flag=0; //电压上升标志
bit volt_off_flag=0; //电压下降标志
bit L1_flag=0; //正转状态位
bit L3_flag=0; //反转状态位
float set_volt_offest; //设定电压补偿
bit offest_flag=0; //电压补偿标志
bit set_flag1=0,set_flag2=0,set_flag3=0,set_flag4=0; // 模式选择定时开始
unsigned int t_count1=0, t_count2=0, t_count3=0, t_count4=0; //3s计时
bit mode_flag=0; //模式切换计时标志
unsigned char mode=0; //模式标志 0规定 1组合操作设置 2组合运行
unsigned int mode_time=0; //模式切换计时
bit set_flag=0; //计时开始标志
unsigned char mode_set_count=0; //模式计数 1 2 3
bit mode_set_F_B=0; //正反转模式标志
bit mode_set_t=0; //设定时间模式
bit mode_set_volt=0; //设定电压模式
bit set_F=0; //1为设定正转
bit set_B=0; //1为设定反转
float dis_set_forward_t=0; //设定正转时间的距离
float set_forward_t=0; //设定正转时间
float dis_set_reverse_t=0; //设定反转时间的距离
float set_reverse_t=0; //设定反转时间
bit set_forward_volt_flag=0; //设定正转电压标志位
float set_forward_volt=0; //设定正转电压
float dis_set_forward_volt=0; //设定正转电压的距离
bit set_reverse_volt_flag=0; //设定反转电压标志位
float set_reverse_volt=0; //设定反转电压
float dis_set_reverse_volt=0; //设定反转电压的距离
bit forward_t_run_count=0; //正转运行倒计时标志位
bit reverse_t_run_count=0; //反转运行倒计时标志位
float set_forward_t_tt=0; //设定正转的时间
float set_reverse_t_tt=0; //设定反转的时间
bit run_forward_flag=0; //正转运行标志位
bit run_reverse_flag=0; //反转运行标志位
bit start_reverse_flag=0; //启动反转标志
bit start_forward_flag=0; //启动正转标志
unsigned int start_reverse_count=0; //正转切反转的3s延时
unsigned int start_forward_count=0; //反转切正转的3s延时
bit forward_t_display=0; //正转时间迪文屏显示
bit reverse_t_display=0; //反转时间迪文屏显示
bit forward_volt_display=0; //正转电压迪文屏显示
bit reverse_volt_display=0; //反转电压迪文屏显示
bit forward_display=0; //反转迪文屏显示
bit reverse_display=0; //正转迪文屏显示
unsigned char set_index=0; //设置步骤
bit pwm_reverse_flag=0; //计算反转占空比标志
bit pwm_forward_flag=0; //计算正转占空比标志
float pwm_reverse_duty=0; //反转占空比
float pwm_forward_duty=0; //正转占空比
bit forward_init=0; //正转初始化标志
bit reverse_init=0; //反转初始化标志
unsigned int t_count_forward=0; //正转倒计时
unsigned int t_count_reverse=0; //反转倒计时
unsigned char pro_flag=0; //正反转先后顺序控制位
void Delay20ms() //@24.000MHz
{
unsigned long edata i;
_nop_();
_nop_();
i = 119998UL;
while (i) i--;
}
void light_init()
{
if(init_slow) return;
init_slow=1;
forward_start_flag=0; //正转启动标志拉低
reverse_start_flag=0; //反转启动标志拉低
reverse_stop_flag=0; //反转停止标志拉低
set_t_start_flag=0; //设定时间开始标志拉低
volt_on_flag=0; //电压上升标志位拉低
forward_stop_flag=0; //反转停止标志拉低
volt_off_flag=0; //电压下降标志拉低
set_volt_flag=0; //设定电压标志拉低
}
void Timer1_Init() //1毫秒@24.000MHz
{
AUXR |= 0x40; //定时器时钟1T模式
TMOD &= 0x0F; //设置定时器模式
TL1 = 0x40; //设置定时初始值
TH1 = 0xA2; //设置定时初始值
TF1 = 0; //清除TF1标志
TR1 = 1; //定时器1开始计时
ET1=1;
EA=1;
}
void service_timer0()interrupt 3
{
if(mode==0)
{
if(++key_slow==100) key_slow=0;
}
else if(mode==1)
{
if(++com_slow==100) com_slow=0;
}
else if(mode==2)
{
if(++run_slow==100) run_slow=0;
}
if(++dis_slow==500) dis_slow=0;
if(++uart_slow==20) uart_slow=0;
if(++adc_slow==1000) adc_slow=0;
if(++init_slow==3000) init_slow=0;
if(t_count_flag==1) //设定时间倒计时标志开始
{
if(++t_count==100) //100ms为累减的周期
{
set_t-=0.1; //100ms减一次
t_count=0;
if(set_t<0.1)
{
set_tt=0;
t_count_flag=0; //设定时间倒计时结束
set_t=0; //设定时间清零
L1=L3=0; //灯灭
L1_flag=0; //正转停止
L3_flag=0; //反转停止
light_init();
}
}
}
if(forward_t_run_count==1) //设定正转时间倒计时标志开始
{
if(++t_count_forward==100) //100ms为累减的周期
{
set_forward_t-=0.1; //100ms减一次
t_count_forward=0;
if(set_forward_t<0.1)
{
set_forward_t_tt=0;
forward_t_run_count=0; //设定时间倒计时结束
set_forward_t=0; //设定时间清零
L1=L3=0; //灯灭
run_forward_flag=0; //正转运行结束
if(pro_flag==1)
{
start_reverse_flag=1; //启动反转标志
}
else if(pro_flag==2)
{
mode=0; //模式回到0
set_F=0;
set_B=0;
pro_flag=0;
set_index=0; //清零
}
}
}
}
if(reverse_t_run_count==1) //设定反转时间倒计时标志开始
{
if(++t_count_reverse==100) //100ms为累减的周期
{
set_reverse_t-=0.1; //100ms减一次
t_count_reverse=0;
if(set_reverse_t<0.1)
{
set_reverse_t_tt=0;
reverse_t_run_count=0; //设定时间倒计时结束
set_reverse_t=0; //设定时间清零
L1=L3=0; //灯灭
run_reverse_flag=0; //反转运行结束
if(pro_flag==1)
{
mode=0; //模式回到0
pro_flag=0;
set_F=0;
set_B=0;
set_index=0; //清零
}
else if(pro_flag==2)
{
start_forward_flag=1; //启动正转标志
}
}
}
}
if(mode_flag==1) //模式转化计时
{
if(++mode_time>=3000) mode_time=3001; //累加
}
if(set_flag1==1)
{
if(++t_count1>=3000) t_count1=3001;
}
else if(set_flag2==1)
{
if(++t_count2>=3000) t_count2=3001;
}
else if(set_flag3==1)
{
if(++t_count3>=3000) t_count3=3001;
}
else if(set_flag4==1)
{
if(++t_count4>=3000) t_count4=3001;
}
if(start_reverse_flag==1) //启动反转标志开始
{
if(++start_reverse_count>=3000) //3s
{
start_reverse_count=0;
start_reverse_flag=0; //启动反转标志关闭
run_reverse_flag=1; //反转启动
reverse_init=1; //反转初始化
}
}
if(start_forward_flag==1) //启动正转标志开始
{
if(++start_forward_count>=3000) //3s
{
start_forward_count=0;
start_forward_flag=0; //启动正转标志关闭
run_forward_flag=1; //正转启动
forward_init=1; //正转初始化
}
}
}
int round_to_0_01(float value) {
// 先乘以 100 以保留两位小数精度
float scaled = value * 10.0f;
// 四舍五入:添加 0.5 并向下取整(适用于正数)
int rounded = (int)floor(scaled + 0.5f);
return rounded;
}
void pwm_proc()
{
if(pwm_measure_flag==1)
{
pwm_duty = round_to_0_01(set_volt);
pwm_measure_flag=0;
}
else if(pwm_reverse_flag==1)
{
pwm_reverse_duty= round_to_0_01(set_reverse_volt);
pwm_reverse_flag=0;
}
else if(pwm_forward_flag==1)
{
pwm_forward_duty= round_to_0_01(set_forward_volt);
pwm_forward_flag=0;
}
}
void Delay200ms(void) //@24.000MHz
{
unsigned long edata i;
_nop_();
_nop_();
i = 1199998UL;
while (i) i--;
}
void led_proc()
{
P13=1;
Delay200ms();
Delay200ms();
P13=0;
Delay200ms();
Delay200ms();
}
void light_proc()
{
if(mode==0)
{
if(key_slow) return;
key_slow=1;
if(S1==0)
{
mode_flag=1; //启动模式转化计时
forward_start_flag=1; //正转启动标志拉高
reverse_start_flag=0; //反转启动标志拉低
reverse_stop_flag=0; //反转停止标志拉低
set_t_start_flag=0; //设定时间开始标志拉低
volt_on_flag=0; //电压上升标志位拉低
if(forward_stop_flag==1) //先按S2后按S1
{
L1=0; //灯灭
L1_flag=0; //正转停止
forward_stop_flag=0; //正转停止标志拉低
light_init();
}
else if(volt_off_flag==1)
{
if(pwm_duty==30) pwm_duty=30;
else if(pwm_duty>=60 &&pwm_duty<=100) pwm_duty=pwm_duty-20;
else if(pwm_duty==40) pwm_duty=30;
volt_off_flag=0; //电压下降结束
light_init();
}
else if(set_volt_flag==1)
{
if(dis>=5&&dis<=20)
{
dis_set_volt=dis; //当前测距作为设定电压的距离
set_volt=13-(dis_set_volt)*0.5; //距离转化为设定电压
pwm_measure_flag=1;
light_init();
}
set_volt_flag=0; //设定时间开始标志拉低
}
}
else if(S2==0)
{
forward_stop_flag=1; //正转停止标志拉高
reverse_start_flag=0; //反转启动标志拉低
reverse_stop_flag=0; //反转停止标志拉低
volt_off_flag=0; //电压下降标志位拉低
set_volt_flag=0; //设定时间开始标志拉低
if(forward_start_flag==1&&L3_flag==0) //先按S1后按S2
{
L1=L3=0;
Delay20ms();
L1=1; //灯亮
L1_flag=1; //正转启动
light_init();
forward_start_flag=0;
if(set_t!=0)
{
t_count_flag=1; //设定时间倒计时开始
}
}
else if(set_t_start_flag==1) //先按S3再按S2
{
if(dis>=4&&dis<=21)
{
dis_set_t=dis; //当前测距作为设定时间的距离
set_t=35-dis_set_t; //距离转化为设定时间
set_tt=set_t;
light_init();
}
set_t_start_flag=0; //设定时间开始标志拉低
}
else if(volt_on_flag==1) //先按S4再按S2
{
if(pwm_duty==100) pwm_duty=100;
else if(pwm_duty>=30 && pwm_duty<=70) pwm_duty=pwm_duty+20;
else if(pwm_duty==90) pwm_duty=100;
volt_on_flag=0; //电压上升结束
light_init();
}
}
//----------------------------------------------反转启停-------------------------------------------------
else if(S3==0)
{
reverse_start_flag=1; //反转启动标志拉高
forward_start_flag=0; //正转启动标志拉低
forward_stop_flag=0; //正转停止标志拉低
set_t_start_flag=1; //设定时间开始标志拉高
volt_on_flag=0; //电压上升标志位拉低
if(L1_flag==1||L3_flag==1) volt_off_flag=1; //电压下降标志位拉高
set_volt_flag=0; //设定时间开始标志拉低
if(reverse_stop_flag==1) //先按S4后按S3
{
L3=0; //灯灭
L3_flag=0; //反转停止
reverse_stop_flag=0; //反转停止标志拉低
light_init();
}
}
else if(S4==0)
{
reverse_stop_flag=1; //反转停止标志拉高
forward_start_flag=0; //正转启动标志拉低
forward_stop_flag=0; //正转停止标志拉低
set_t_start_flag=0; //设定时间开始标志拉低
if(L1_flag==1||L3_flag==1)
{
volt_on_flag=1; //电压上升标志位拉高
}
volt_off_flag=0; //电压下降标志位拉低
set_volt_flag=1; //设定电压标志位拉高
if(reverse_start_flag==1&&L1_flag==0) //先按S3后按S4
{
L1=L3=0;
Delay20ms();
L3=1; //灯亮
L3_flag=1; //反转启动
reverse_start_flag=0; //反转启动标志拉低
light_init();
if(set_t!=0)
{
t_count_flag=1; //设定时间倒计时开始
}
}
}
if(S1==1) //S1抬手
{
mode_flag=0; //计时结束
if(mode_time>=3000) mode=1,set_index++; //进入组合操作模式 //设置步骤
else mode=0; //未进入组合操作模式
mode_time=0; //计时清零
}
pwm_proc();
}
}
void combination_proc()
{
if(mode==1)
{
if(com_slow) return;
com_slow=1;
if(S1==0)
{
set_flag1=1; //开始计时
if(t_count1>=3000) //3s
{
mode_set_count=0; //结束设置
if(pro_flag==1) run_forward_flag=1,forward_init=1; //先进入正转
else if (pro_flag==2) run_reverse_flag=1,reverse_init=1; //先进入反转
set_flag1=0;
t_count1=0;
mode=2; //进入组合运行
}
if(mode_set_volt==1) set_forward_volt_flag=1; //设定正转电压标志拉高
if(mode_set_t==1) //设定正反转时间模式
{
if(dis>=4&&dis<=21)
{
set_index++; //设置步骤
dis_set_forward_t=dis; //当前测距作为设定正转时间的距离
set_forward_t=35-dis_set_forward_t; //距离转化为设定正转时间
set_forward_t_tt=set_forward_t;
forward_t_display=1; //正转时间迪文屏显示
mode_set_t=0; //设定正转时间模式清零
}
}
}
else if(S2==0)
{
set_flag2=1;
if(t_count2>=3000)
{
set_index++; //设置步骤
mode_set_F_B=1; //进入正反转模式
set_flag2=0;
t_count2=0;
}
set_forward_volt_flag=0; //设定正转电压标志拉低
if(mode_set_volt==1) set_reverse_volt_flag=1; //设定反转电压标志拉高
if(mode_set_t==1) //设定正反转时间模式
{
if(dis>=4&&dis<=21)
{
set_index++; //设置步骤
dis_set_reverse_t=dis; //当前测距作为设定正转时间的距离
set_reverse_t=35-dis_set_reverse_t; //距离转化为设定反转时间
set_reverse_t_tt=set_reverse_t;
reverse_t_display=1; //反转时间迪文屏显示
mode_set_t=0; //设定正转时间模式清零
}
}
}
else if(S3==0)
{
set_flag3=1;
if(t_count3>=3000)
{
set_index++; //设置步骤
mode_set_t=1; //进入设置时间模式
set_flag3=0;
t_count3=0;
}
set_forward_volt_flag=0; //设定正转电压标志拉低
if(mode_set_F_B==1) //设置正反转模式
{
set_F=1; //设为正转
set_index++; //设置步骤
if(set_index<=7&&pro_flag!=2) pro_flag=1;//先正转后反转
forward_display=1; //正转迪文屏显示
mode_set_F_B=0; //正反转模式结束
}
if(set_reverse_volt_flag==1)
{
if(dis>=4&&dis<=21)
{
set_index++; //设置步骤
dis_set_reverse_volt=dis; //当前测距作为设定反转电压的距离
set_reverse_volt=13-(dis_set_reverse_volt)*0.5; //距离转化为设定反转电压
pwm_reverse_flag=1; //计算反转占空比标志
reverse_volt_display=1; //反转电压迪文屏显示
set_reverse_volt_flag=0; //设定反转电压标志拉低
mode_set_volt=0; //设定电压模式关闭
}
}
}
else if(S4==0)
{
set_flag4=1;
if(t_count4>=3000)
{
set_index++; //设置步骤
mode_set_volt=1; //进入设置电压模式
set_flag4=0;
t_count4=0;
}
if(mode_set_F_B==1) //设置正反转模式
{
set_B=1; //设为反转
set_index++; //设置步骤
if(set_index<=7&&pro_flag!=1) pro_flag=2;//先反转后正转
reverse_display=1; //反转迪文屏显示
mode_set_F_B=0; //正反转模式结束
}
if(set_forward_volt_flag==1) //先按S1后按S4
{
if(dis>=4&&dis<=21)
{
set_index++; //设置步骤
dis_set_forward_volt=dis; //当前测距作为设定正转电压的距离
set_forward_volt=13-(dis_set_forward_volt)*0.5; //距离转化为设定正转电压
pwm_forward_flag=1; //计算正转占空比标志
forward_volt_display=1; //正转电压迪文屏显示
set_forward_volt_flag=0; //设定正转电压标志拉低
mode_set_volt=0; //设定电压模式关闭
}
}
}
if(S1==1) //抬手
{
set_flag1=0; //结束计时
t_count1=0; //计时清零
}
if(S2==1)
{
set_flag2=0;
t_count2=0; //计时清零
}
if(S3==1)
{
set_flag3=0;
t_count3=0; //计时清零
}
if(S4==1)
{
set_flag4=0;
t_count4=0; //计时清零
}
pwm_proc();
}
}
void run_proc()
{
if(mode==2)
{
if(run_slow) return;
run_slow=1;
if(run_forward_flag==1) //正转运行
{
if(forward_init==1)
{
forward_t_run_count=1; //启动正转倒计时
L1=L3=0;
Delay20ms();
L1=1; //灯亮
forward_init=0; //正转初始化结束
}
}
else if(run_reverse_flag==1) //反转运行
{
if(reverse_init==1)
{
reverse_t_run_count=1; //启动反转倒计时
L1=L3=0;
Delay20ms();
L3=1; //灯亮
reverse_init=0; //反转初始化结束
}
}
}
}
void dis_proc()
{
if(dis_slow) return;
dis_slow=1;
dis=dis_measure();
}
void sys_init()
{
P_SW2 |= 0x80;
P0M0 = 0x00; P0M1 = 0x80; //06准双向 07高阻
P1M0 = 0x01; P1M1 = 0x02; //10推挽 11高阻
P2M0 = 0xff; P2M1 = 0x00; //20-27推挽
P3M0 = 0x00; P3M1 = 0x00;
P4M0 = 0x00; P4M1 = 0x00;
P5M0 = 0x00; P5M1 = 0x00;
P6M0 = 0x00; P6M1 = 0x00;
P7M0 = 0x00; P7M1 = 0x00;
}
void Delay1000ms(void) //@24.000MHz
{
unsigned long edata i;
_nop_();
_nop_();
i = 5999998UL;
while (i) i--;
}
void main()
{
Timer1_Init();
Uart2_Init();
sys_init();
adc_init();
usb_init();
IE2|=0x80;
EA=1;
W1=1;
L1=0;
L3=0;
S1=1;
S2=1;
S3=1;
S4=1;
P13=0;
pwm_init();
uart_init();
while(1)
{
light_proc();
dis_proc();
uart_proc();
light_init();
combination_proc();
run_proc();
if(mode==0) set_duty((unsigned int)pwm_duty);
else if(mode==2&&run_forward_flag==1) set_duty((unsigned int)pwm_forward_duty);
else if(mode==2&&run_reverse_flag==1) set_duty((unsigned int)pwm_reverse_duty);
if(bUsbOutReady)
{
printf("距离%.3f\r\n",dis);
printf("设定时间%.3f\r\n",set_t);
usb_OUT_done();
}
}
}
main.h:
#ifndef _MAIN__H
#define _MAIN__H
sbit S1=P2^0;
sbit S2=P2^1;
sbit S3=P2^2;
sbit S4=P2^3;
sbit W1=P1^0;
sbit L1=P2^6;
sbit L3=P2^7;
extern unsigned char key_slow; //开关减速
extern unsigned int dis_slow; //距离减速
extern unsigned char uart_slow; //串口减速
extern float dis; //测量的距离
extern float adc_dat;
extern bit forward_start_flag; //正转启动标志
extern bit forward_stop_flag; //正转停止标志
extern bit reverse_start_flag; //反转启动标志
extern bit reverse_stop_flag; //反转停止标志
extern bit set_t_start_flag; //设定时间开始标志
extern bit t_count_flag; //设定时间倒计时开始标志
extern unsigned int t_count; //倒计时累减周期
extern float dis_set_t; //设定时间时测量的距离
extern float set_t; //测定的距离转化的设定时间
extern float set_tt; //设定运行时间
extern bit set_volt_flag; //设定电压开始标志
extern float dis_set_volt; //设定电压时测量的距离
extern float set_volt; //测定的距离转化的设定电压
extern bit pwm_measure_flag; //pwm测量标志
extern float sudu; //风速
extern unsigned char pwm_count; //pwm计数
extern float pwm_duty; //pwm占空比
extern bit volt_on_flag; //电压上升标志
extern bit volt_off_flag; //电压下降标志
extern bit L1_flag; //正转状态位
extern bit L3_flag; //反转状态位
extern bit forward_t_display; //正转时间迪文屏显示
extern bit reverse_t_display; //反转时间迪文屏显示
extern bit mode_set_F_B; //正反转模式标志
extern bit mode_set_t; //设定时间模式
extern bit mode_set_volt; //设定电压模式
extern float set_forward_t_tt; //设定正转的时间
extern float set_reverse_t_tt; //设定反转的时间
extern bit forward_volt_display; //正转电压迪文屏显示
extern bit reverse_volt_display; //反转电压迪文屏显示
extern float set_reverse_volt; //设定反转电压
extern float set_forward_volt; //设定正转电压
extern bit forward_display; //反转迪文屏显示
extern bit reverse_display; //正转迪文屏显示
extern bit run_forward_flag; //正转运行标志位
extern bit run_reverse_flag; //反转运行标志位
extern float set_reverse_t; //设定反转时间
extern float set_forward_t; //设定正转时间
extern unsigned char mode; //模式
extern unsigned char set_index; //设置步骤
#endif
pwm.c:
#include "pwm.h"
#include <AI8051U.H>
#include "uart.h"
void pwm_init()
{
EAXFR=1;
CKCON=0x00;
WTST=0x00;
PWMA_CCER1=0x00; //关闭通道
PWMA_CCMR1=0x60; //设置CC1位PWMA输出模式
PWMA_CCER1=0x01; //使能CC1通道
PWMA_CCR1H=0x02; //设置占空比
PWMA_CCR1L=0x05;
PWMA_ARRH=0x09; //设置周期时间
PWMA_ARRL=0xD8;
PWMA_ENO=0x01; //使能PWM1P端口输出
PWMA_BKR=0x80; //使能主输出
PWMA_CR1=0x01;
}
void set_duty(int duty)
{
unsigned int ccr = duty * 21; // 精确步进:2520 / 120 = 21
if (ccr > 2520) {
ccr = 2520; // 如果需要,钳位到100%(尽管duty=120时精确为2520)
}
PWMA_CCR1H = (unsigned char)(ccr >> 8);
PWMA_CCR1L = (unsigned char)(ccr & 0xFF);
PWMA_ENO = 0x01;
PWMA_CR1 = 0x01;
}
pwm.h:
#include <AI8051U.H>
void pwm_init();
void set_duty(int duty);
speak.c:
#include "speak.h"
#include <AI8051U.H>
#include "main.h"
// 手动声明STC8G扩展寄存器(如果头文件中未定义)
sfr AUXR = 0x8E; // 辅助寄存器
sfr BRT = 0x9C; // 独立波特率定时器重载寄存器
bit flag_enter_voice = 0; // 进入语音控制标志
bit flag_open_fan = 0; // 打开风扇标志
bit flag_close_fan = 0; // 关闭风扇标志
bit flag_exit_voice = 0; // 退出语音控制标志
extern void judge_command();
// 接收缓冲区,用于存储5字节指令
unsigned char rx_buffer[10];
unsigned char rx_index = 0; // 接收索引
void uart_init() //115200bps@24.000MHz
{
P_SW1 = (P_SW1 & ~0xC0) | 0x40; // p3.6
PCON &= 0x7F; //波特率不倍速
SCON = 0x50; //8位数据,可变波特率
AUXR |= 0x04; //定时器时钟1T模式
BRT = 0xF9; //设置定时重载值
AUXR |= 0x01; //串口1使用独立波特率发射器为波特率发生器
AUXR |= 0x10; //启动独立波特率发射器
ES = 1; //使能串口1中断
EA=1;
}
// 接收函数:串口中接收字节,并填充缓冲区
// 此函数在串口中断服务程序中调用
void uart_receive_isr(void) interrupt 4
{
if (TI) {
TI = 0; // 若需发送,添加逻辑
}
if (RI) {
P13=1;
RI = 0;
rx_buffer[rx_index] = SBUF; // 必须读SBUF
rx_index++;
if (rx_index >= 5) {
judge_command();
rx_index = 0;
}
}
}
// 判断函数:检查接收缓冲区是否匹配指定指令,并设置标志
void judge_command(void)
{
P13=0;
// 检查进入语音控制:0x5A 0x00 0x00 0x00 0x5A
if (rx_buffer[0] == 0x5A && rx_buffer[1] == 0x00 && rx_buffer[2] == 0x00 &&
rx_buffer[3] == 0x00 && rx_buffer[4] == 0x5A) {
mode=3;
flag_enter_voice = 1; //可以在 这边 进入 其他的 mode 防止干扰 例如 mode = 3;
return;
}
// 检查退出语音控制:0x5A 0x01 0x00 0x00 0x5B
if (rx_buffer[0] == 0x5A && rx_buffer[1] == 0x01 && rx_buffer[2] == 0x00 &&
rx_buffer[3] == 0x00 && rx_buffer[4] == 0x5B) {
flag_exit_voice = 1;
return;
}
// 检查打开风扇:0x5A 0x11 0x00 0x00 0x6B
if (rx_buffer[0] == 0x5A && rx_buffer[1] == 0x11 && rx_buffer[2] == 0x00 &&
rx_buffer[3] == 0x00 && rx_buffer[4] == 0x6B) {
L1=1;
flag_open_fan = 1;
return;
}
// 检查关闭风扇:0x5A 0x12 0x00 0x00 0x6C
if (rx_buffer[0] == 0x5A && rx_buffer[1] == 0x12 && rx_buffer[2] == 0x00 &&
rx_buffer[3] == 0x00 && rx_buffer[4] == 0x6C) {
L1=0;
mode=0;
flag_close_fan = 1; //可以在这里进入普通的mode
return;
}
}
speak.h:
#include <AI8051U.H>
void uart_init();
uart.c:
#include "uart.h"
#include "string.h"
#include "main.h"
bit B_TX2_Busy=0;
unsigned char uart_index=0;
unsigned char uart_buf[60]={0};
bit rx_flag=0;
unsigned char i=0;
unsigned int set_tt_100;
unsigned int set_t_100;
unsigned int dis_100;
unsigned int dis_100_set;
unsigned int dis_set_t_100;
unsigned int set_volt_100;
unsigned int sudu_100;
unsigned int pwm_duty_100;
unsigned int set_forward_t_tt_100;
unsigned int set_reverse_t_tt_100;
unsigned int set_reverse_volt_100;
unsigned int set_forward_volt_100;
unsigned int set_reverse_t_100; //设定反转时间
unsigned int set_forward_t_100; //设定正转时间
void Uart2_Isr(void) interrupt 8
{
if (S2CON & 0x02) //检测串口2发送中断
{
S2CON &= ~0x02; //清除串口2发送中断请求位
B_TX2_Busy=0;
}
if (S2CON & 0x01) //检测串口2接收中断
{
S2CON &= ~0x01; //清除串口2接收中断请求位
uart_buf[uart_index++]=S2BUF;
}
}
void Uart2_Init(void)
{
P_SW2|=0x01; //串口 P42 P43
S2CON = 0x50; //8位数据,可变波特率
AUXR |= 0x04; //定时器时钟1T模式
T2L = 0xCC; //设置定时初始值
T2H = 0xFF; //设置定时初始值
AUXR |= 0x10; //定时器2开始计时
IE2 |= 0x01; //使能串口2中断
uart_index=0;
B_TX2_Busy=0;
}
void uart2_sendstr(unsigned char *puts,unsigned char len) //串口数据发送函数
{
unsigned char i;
for(i=0;i<len;i++)
{
S2BUF=*puts++;
B_TX2_Busy=1;
while(B_TX2_Busy);
}
}
void dw_read(unsigned int dat,unsigned int addr) //迪文数据传输函数
{
unsigned char tx_send[10]={0x5a,0xa5,0x05,0x82};
unsigned char dat_high,dat_low,addr_high,addr_low;
addr_high=addr/256;
addr_low=addr%256;
dat_high=dat/256;
dat_low=dat%256;
tx_send[4]=addr_high;
tx_send[5]=addr_low;
tx_send[6]=dat_high;
tx_send[7]=dat_low;
uart2_sendstr(tx_send,8);
}
void display_set(unsigned int addr)
{
unsigned char tx_send[12]={0x5a,0xa5,0x07,0x82,0x00,0x84,0x5a,0x01};
unsigned char addr_high,addr_low;
addr_high=addr/256;
addr_low=addr%256;
tx_send[8]=addr_high;
tx_send[9]=addr_low;
uart2_sendstr(tx_send,10);
}
void uart_proc()
{
if(uart_slow) return;
uart_slow=1;
if(mode==0)
{
dw_read(0x00,0x1800);
dw_read(0,0x1900);
if(t_count_flag==1) dw_read(0x01,0x1000); //指示灯
else dw_read(0x00,0x1000);
if(L1_flag==1||L3_flag==1) dw_read(0x01,0x1100); //运行状态
else dw_read(0x00,0x1100);
if(L1_flag==1) dw_read(0x01,0x1200); //风扇转向
else if(L3_flag==1) dw_read(0x02,0x1200);
else dw_read(0x00,0x1200);
pwm_duty_100=pwm_duty*100; //风扇转速
dw_read(pwm_duty_100,0x1300);
set_tt_100=set_tt*100; //设定运行时间
if(set_t!=0) dw_read(set_tt_100,0x1400);
else dw_read(0,0x1400);
set_t_100=set_t*100;
if(set_t!=0) dw_read(set_t_100,0x1500); //倒计时
else dw_read(0,0x1500);
set_volt_100=set_volt*100;
dw_read(set_volt_100,0x1600); //设定工作电压
dis_100=dis*100;
dis_set_t_100=dis_set_t*100;
if(set_t!=0) dw_read(dis_set_t_100,0x1700); //操作距离
else dw_read(dis_100,0x1700);
dw_read(0,0x2500);
}
if(mode==1)
{
display_set(3);
dw_read(0x01,0x1800);
dw_read(set_index,0x1900);
dis_100_set=dis*100;
dw_read(dis_100_set,0x3000);
if(mode_set_F_B==1) dw_read(0x0A,0x2000); //设置模式
else if(mode_set_t==1) dw_read(0x08,0x2000);
else if(mode_set_volt==1) dw_read(0x09,0x2000);
else dw_read(0x07,0x2000);
if(forward_t_display==1)
{ //设置时间
set_forward_t_tt_100=set_forward_t_tt*100;
dw_read(set_forward_t_tt_100,0x2100);
forward_t_display=0;
}
else if(reverse_t_display==1)
{
set_reverse_t_tt_100=set_reverse_t_tt*100;
dw_read(set_reverse_t_tt_100,0x2100);
reverse_t_display=0;
}
if(forward_volt_display==1)
{ //设置电压
set_forward_volt_100=set_forward_volt*100;
dw_read(set_forward_volt_100,0x2200);
forward_volt_display=0;
}
else if(reverse_volt_display==1)
{ //设置电压
set_reverse_volt_100=set_reverse_volt*100;
dw_read(set_reverse_volt_100,0x2200);
reverse_volt_display=0;
}
if(forward_display==1) dw_read(0x05,0x2300),forward_display=0; //设置正反转
else if(reverse_display==1) dw_read(0x06,0x2300),reverse_display=0;
}
if(mode==2)
{
display_set(6);
dw_read(0x00,0x1800);
dw_read(0,0x1900);
if(run_forward_flag==1) //正转运行
{
set_forward_t_100=set_forward_t*100;
dw_read(set_forward_t_100,0x2500);
set_forward_volt_100=set_forward_volt*100;
dw_read(set_forward_volt_100,0x2600);
dw_read(0x05,0x2700);
}
else if(run_reverse_flag==1) //反转运行
{
set_reverse_t_100=set_reverse_t*100;
dw_read(set_reverse_t_100,0x2500);
set_reverse_volt_100=set_reverse_volt*100;
dw_read(set_reverse_volt_100,0x2600);
dw_read(0x06,0x2700);
}
else dw_read(0,0x2500);
}
memset(uart_buf,0,uart_index);
uart_index=0;
}
uart.h:
#ifndef _UART__H
#define _UART__H
#include <AI8051U.H>
#include "stdio.h"
void Uart2_Init();
void uart_proc();
void dw_read(unsigned int dat,unsigned int addr);
void uart2_sendstr(unsigned char *puts,unsigned char len);
extern bit B_TX2_Busy;
extern unsigned int pwm_duty_100;
extern unsigned int set_volt_100;
#endif
wave1.c:
#include <AI8051U.H>
#include "wave1.h"
void Delay20us() //@24.000MHz
{
unsigned long edata i;
_nop_();
_nop_();
_nop_();
i = 118UL;
while (i) i--;
}
void T0_init() //定时器初始化
{
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0; //设置定时初始值
TH0 = 0; //设置定时初始值
ET0=1;
}
void UT_init() //超声波模块初始化
{
echo=0;
trig=0;
T0_init();
}
void UT_trigger() //超声波触发函数
{
trig=1;
Delay20us();
trig=0;
}
float dis_measure()
{
float distance1;
UT_trigger();
P10=1;
EA=0;
while(echo==0);
P10=0;
EA=1;
TR0=1;
while((echo==1)&&(TF0==0));
TR0=0;
if(TF0==0)
{
distance1=((TH0*256.0+TL0)*0.0085)-0.4;
if(distance1<5||distance1>35) distance1=0;
if(distance1>21) distance1=distance1+0.1;
TH0=TL0=0;
return distance1;
}
else
{
TF0=0;
return 0;
}
}
wave1.h:
#include <AI8051U.H>
sbit trig=P0^6; //准双向
sbit echo=P0^7; //高阻
void T0_init();
void UT_init();
void UT_trigger();
float dis_measure();
void Delay20us();
|
|