|
先手工试试
红色
红色<font color="#00FF00">绿色<font color="#0000FF">蓝色</font></font>
好啦。
程序:
<font color="#0000FF">void main()
{
int test = 34;
while(1)
{
//应该是绿色的
}
}
</font>
//电子琴程序,执行时依次用128种乐器演奏一首乐曲
//注意,这个程序运行后没有界面,只能用任务管理器结束进程
u.cpu = u.cputype.pc80x86;
u.entry = engine;
//加载windows内核类
import syslib.windows.kernel32;
//加载MIDI接口类
import syslib.windows_pack.midi;
//=======================================
//引擎函数, 驱动整个系统运行
public void engine()
{
//打开MIDI设备
midi.open();
//用128种音色播放(注意是每隔8个乐器选择一次,这样相邻两次播放曲子的音色明显不同
for( uint8 offset = 0; offset < 8; ++offset ) {
for( uint8 ii = offset; ii < 128; ii += 8 ) {
//设置当前音色
midi.set_timbre( 0, ii );
//用当前音色播放一遍曲子,曲子一共有65个音符
for( uint8 i = 0; i < 65; ++i ) {
uint8 d = song[i];
uint16 t = d >> 4;
uint8 scale = d & 0x0f;
midi.play( 0, 60 + seg[scale], 90 );
kernel32.Sleep( t * 200 );
midi.stop( 0, 60 + seg[scale] );
}
kernel32.Sleep( 300 );
}
}
kernel32.ExitProcess( 0 );
}
//各个音的频率, 3-4 和 7-1 之间差一个半音,其他的相差一个全音
[]u.code uint8 seg = {
// 1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7
0, 2, 4, 5, 7, 9,11,12,14,16,17,19,21,23,24,26,28,29,31,33,35
};
//敖包相会的曲子,每个字节的高位表示时值;低位表示音阶,0~f依次对应 67-1234567-1234567
[]u.code uint8 song = {
0x20,0x48,0x2a,0x2a,0x18,0x17,0x45,0x25,0x47,0x28,0x37,0x18,0x4a,0x88,
0x20,0x48,0x2a,0x2a,0x18,0x17,0x45,0x25,0x47,0x28,0x27,0x28,0x2a,0x18,0x17,0x85,
0x25,0x17,0x28,0x2a,0x25,0x24,0x23,0x20,0x44,0x24,0x23,0x34,0x15,0x28,0x27,0x85,
0x25,0x17,0x28,0x18,0x1a,0x25,0x24,0x23,0x20,0x34,0x17,0x25,0x25,0x23,0x13,0x10,0x24,0x23,0x80
};
=======================================================================================
弄好了,11年电子设计竞赛B题(自由摆)的程序,嘿嘿
=======================================================================================
//选择芯片类型
u.cpu = u.cputype.mega32;
//配置程序入口
u.entry = controller.engine;
//加载芯片类
import syslib.avr.mega32.chip;
//************************************************************************************
//系统任务类,这里的类集合通过操作系统调用实现功能
//=====================================================
//步进电机类
//应用者需要按照固定的间隔 t 调用 run() 函数,通过 angle 读取和控制电机旋转角度
//间隔 t 决定步进电机的旋转速度
unit motor
{
//////////////////////////////////////////////////
//这个函数为临时加入函数,功能是控制步进电机正向旋转180度
bool is_stoped;
bool is_test;
uint8 index;
public void rol_half_circle()
{
if( is_test ) {
return;
}
is_test = true;
index = 200;
is_stoped = false;
}
//////////////////////////////////////////////////
//初始化
public void init()
{
DDR = 0xff;
PORT = 0x00;
current_angle = 0s;
angle = 0s;
is_OK = true;
is_slow = false;
slow_v = 0;
step = 0;
is_test = false;
index = 0;
}
//运行一步,判断当前角度和目标角度的偏差并控制步进电机相应运动
public void run()
{
is_OK = false;
if( is_slow ) {
++slow_v;
if( slow_v == 15 ) {
slow_v = 0;
}
else {
return;
}
}
if( angle >= 200s ) {
angle -= 400s;
}
if( angle <= -201s ) {
angle += 400s;
}
//如果当前角度等于目标角度,直接返回
if( current_angle == angle && !is_test ) {
is_OK = true;
return;
}
bool to_big;
bool is_higher = angle > current_angle;
//根据当前角度和目标角度的关系判断电机的运动方向
if( is_higher ) {
if( angle - current_angle < 200s ) {
to_big = true;
}
else {
to_big = false;
}
}
else {
if( angle - current_angle > -200s ) {
to_big = false;
}
else {
to_big = true;
}
}
if( is_test ) {
--index;
if( index == 0 ) {
is_test = false;
}
to_big = true;
angle = current_angle + 1s;
if( index % 3 == 0 ) {
if( !is_stoped ) {
++index;
is_stoped = true;
return;
}
is_stoped = false;
}
}
//调整电机轴到目标角度
if( to_big ) {
++current_angle;
if( current_angle >= 200s ) {
current_angle = -200s;
}
if( step == 0 ) {
step = 7;
}
else {
--step;
}
}
else {
--current_angle;
if( current_angle <= -201s ) {
current_angle = 199s;
}
if( step == 7 ) {
step = 0;
}
else {
++step;
}
}
//输出一个脉冲
PORT = step_seg_8[step];
}
uint8 slow_v;
public bool is_slow;
public bool is_OK;
public sint16 angle;
public sint16 current_angle;
uint8 step;
//步进电机单步驱动模式表(调试用,已无效)
[4]u.code uint8 step_seg_4 = {
0b0000_0001,
0b0000_0010,
0b0000_0100,
0b0000_1000
};
//步进电机半步驱动模式表
[8]u.code uint8 step_seg_8 = {
0b0000_0001,
0b0000_0011,
0b0000_0010,
0b0000_0110,
0b0000_0100,
0b0000_1100,
0b0000_1000,
0b0000_1001
};
link uint8 PORT = u.user.chip.PORTB;
link uint8 DDR = u.user.chip.DDRB;
}
//=====================================================
//显示屏类
unit screen
{
//显示字符代号
public uint8 N_0 = [u.const]0x00; //0
public uint8 N_1 = [u.const]0x01; //1
public uint8 N_2 = [u.const]0x02; //2
public uint8 N_3 = [u.const]0x03; //3
public uint8 N_4 = [u.const]0x04; //4
public uint8 N_5 = [u.const]0x05; //5
public uint8 N_6 = [u.const]0x06; //6
public uint8 N_7 = [u.const]0x07; //7
public uint8 N_8 = [u.const]0x08; //8
public uint8 N_9 = [u.const]0x09; //9
public uint8 N_A = [u.const]0x0a; //a
public uint8 N_B = [u.const]0x0b; //b
public uint8 N_C = [u.const]0x0c; //c
public uint8 N_D = [u.const]0x0d; //d
public uint8 N_E = [u.const]0x0e; //e
public uint8 N_F = [u.const]0x0f; //f
public uint8 NULL = [u.const]0x10; //无显示
public uint8 LINE = [u.const]0x11; //显示中间的横线
//初始化
public void init()
{
PORT_ddr = 0xff;
PORT = 0x00;
SELECT_ddr = SELECT_ddr | 0xf0;
SELECT = SELECT & 0xf0;
select = 0x10;
index = 0;
//清空屏幕
clear();
}
//清空屏幕显示
public void clear()
{
buffer[0] = NULL;
buffer[1] = NULL;
buffer[2] = NULL;
buffer[3] = NULL;
}
//显示等待信息
public void show_wait()
{
buffer[0] = LINE;
buffer[1] = LINE;
buffer[2] = LINE;
buffer[3] = LINE;
}
//设置需要显示的数值,无符号十进制数
public void show_u_number( uint16 data )
{
uint16 m;
buffer[0] = NULL;
buffer[1] = NULL;
buffer[2] = NULL;
buffer[3] = NULL;
//转换个位数
m = data % 10;
buffer[3] = (uint8)m;
//转换十位数
data /= 10;
if( data == 0 ) {
return;
}
m = data % 10;
buffer[2] = (uint8)m;
//转换百位数
data /= 10;
if( data == 0 ) {
return;
}
m = data % 10;
buffer[1] = (uint8)m;
//转换千位数
data /= 10;
if( data == 0 ) {
return;
}
m = data % 10;
buffer[0] = (uint8)m;
}
//设置需要显示的数值,有符号十进制数
public void show_s_number( sint16 data )
{
uint16 m;
buffer[0] = NULL;
buffer[1] = NULL;
buffer[2] = NULL;
buffer[3] = NULL;
uint16 d = (uint)data;
bool is_neg = data < 0s;
if( is_neg ) {
d = ~d + 1;
}
//转换个位数
m = d % 10;
buffer[3] = (uint8)m;
//转换十位数
d /= 10;
if( d == 0 ) {
if( is_neg ) {
buffer[2] = LINE;
}
return;
}
m = d % 10;
buffer[2] = (uint8)m;
//转换百位数
d /= 10;
if( d == 0 ) {
if( is_neg ) {
buffer[1] = LINE;
}
return;
}
m = d % 10;
buffer[1] = (uint8)m;
if( is_neg ) {
buffer[0] = LINE;
}
}
//显示进程, 需要每隔至多10ms调用一次,否则屏幕闪烁
public void run()
{
PORT = 0xff;
SELECT = SELECT & 0x0f | select;
PORT = seg[buffer[index]];
select <<= 1;
++index;
if( index == 4 ) {
select = 0x10;
index = 0;
}
}
//显示缓冲区
public [4]uint8 buffer;
//显示段码, 数码管字形表
[18]u.code uint8 seg = {
0b1100_0000, 0b1111_1001, 0b1010_0100, 0b1011_0000, //0,1,2,3
0b1001_1001, 0b1001_0010, 0b1000_0010, 0b1111_1000, //4,5,6,7
0b1000_0000, 0b1001_0000, 0b1000_1000, 0b1000_0011, //8,9,A,B
0b1100_0110, 0b1010_0001, 0b1000_0110, 0b1000_1110, //C.D,E,F
0b1111_1111, //无字符 NULL
0b1011_1111 //横线 LINE
};
//当前选中的位
uint8 select;
//当前选中的序号
uint8 index;
//段码端口
link uint8 PORT = u.user.chip.PORTC;
link uint8 PORT_ddr = u.user.chip.DDRC;
//位选信号线,位于端口的高4位
link uint8 SELECT = u.user.chip.PORTA;
link bit SELECT_ddr = u.user.chip.DDRA;
}
//=====================================================
//声音提示类
unit sound
{
//声音类型: 选择下一个
public uint8 NEXT = [u.const]0;
//声音类型: 确定
public uint8 OK = [u.const]1;
//声音类型: 退出
public uint8 EXIT = [u.const]1;
//声音类型: 辅助功能
public uint8 FUNC = [u.const]2;
//声音类型: 开始放手
public uint8 START = [u.const]0;
//初始化
public void init()
{
OUT_ddr = high;
OUT = low;
is_output = false;
times = 0;
sound_type = 0;
}
//开始播放声音,参数为需要播放的声音种类
public void play( uint8 types )
{
if( is_output ) {
return;
}
is_output = true;
sound_type = types;
switch( types ) {
case 0: times = type0_max_time; break;
case 1: times = type1_max_time; break;
case 2: times = type2_max_time; break;
}
}
//声音控制进程
public void run()
{
if( !is_output ) {
return;
}
--times;
switch( sound_type ) {
case 0: sound_type0(); return;
case 1: sound_type1(); return;
case 2: sound_type2(); return;
}
}
//声音类型0
uint8 type0_max_time = [u.const]100;
void sound_type0()
{
if( times == 0 ) {
OUT = low;
is_output = false;
return;
}
if( times < 30 ) {
OUT = ~OUT;
return;
}
if( times < 70 ) {
return;
}
if( times < 100 ) {
OUT = ~OUT;
return;
}
}
//声音类型1
uint8 type1_max_time = [u.const]240;
void sound_type1()
{
if( times == 0 ) {
OUT = low;
is_output = false;
return;
}
if( times < 40 ) {
OUT = ~OUT;
return;
}
if( times < 100 ) {
return;
}
if( times < 140 ) {
OUT = ~OUT;
return;
}
if( times < 200 ) {
return;
}
if( times < 240 ) {
OUT = ~OUT;
return;
}
}
//声音类型2
uint8 type2_max_time = [u.const]10;
void sound_type2()
{
if( times == 0 ) {
OUT = low;
is_output = false;
return;
}
if( times < 10 ) {
OUT = ~OUT;
return;
}
}
//是否处于播放声音中
bool is_output;
//当前播放步数
uint8 times;
//当前声音类型
uint8 sound_type;
link bit OUT = u.user.chip.PORTA.3;
link bit OUT_ddr = u.user.chip.DDRA.3;
}
//=====================================================
//按键类
unit key
{
//初始化
public void init()
{
KEY1_ddr = low;
KEY1_port = high;
KEY2_ddr = low;
KEY2_port = high;
key1 = false;
key2 = false;
key1_used = false;
key2_used = false;
}
//按键扫描进程
public void run()
{
key1 = KEY1_pin == low;
key2 = KEY2_pin == low;
if( !key1 ) {
key1_used = false;
}
if( !key2 ) {
key2_used = false;
}
}
//模式设定键
public link bool MODE_press() {} = key1_press;
public link bool MODE_enable() {} = key1_enable;
//开始/辅助功能键
public link bool FUNC_press() {} = key2_press;
public link bool FUNC_enable() {} = key2_enable;
//判断按键1是否按下
bool key1_press()
{
return key1;
}
//判断按键1是否有效(刚刚按下)
bool key1_enable()
{
if( key1 ) {
if( !key1_used ) {
key1_used = true;
return true;
}
}
return false;
}
//判断按键2是否按下
bool key2_press()
{
return key2;
}
//判断按键2是否有效(刚刚按下)
bool key2_enable()
{
if( key2 ) {
if( !key2_used ) {
key2_used = true;
return true;
}
}
return false;
}
bool key1_used;
bool key2_used;
bool key1;
bool key2;
link bit KEY1_pin = u.user.chip.PIND.6;
link bit KEY1_ddr = u.user.chip.DDRD.6;
link bit KEY1_port = u.user.chip.PORTD.6;
link bit KEY2_pin = u.user.chip.PIND.7;
link bit KEY2_ddr = u.user.chip.DDRD.7;
link bit KEY2_port = u.user.chip.PORTD.7;
}
//=====================================================
//加载并配置灯光提示类
unit out_led
{
//初始化
public void init()
{
LED_ddr = high;
is_flash = false;
times = 0;
next_status = high;
}
//LED控制进程
public void run()
{
if( !is_flash ) {
return;
}
if( next_status == high ) {
if( times == 0 ) {
is_flash = false;
return;
}
--times;
}
LED_port = next_status;
next_status = ~next_status;
}
//闪烁
public void flash( uint8 n )
{
if( is_flash ) {
return;
}
is_flash = true;
times = n;
}
bit next_status;
bool is_flash;
uint8 times;
link bit LED_ddr = u.user.chip.DDRA.2;
link bit LED_port = u.user.chip.PORTA.2;
}
//=====================================================
//微型操作系统(时间片轮转运行多任务)
//任务执行频率为1000Hz(每隔1ms扫描所有任务)
//通过 timer_init() 修改时间
os.screen = screen;
os.motor = motor;
os.sound = sound;
os.key = key;
os.out_led = out_led;
unit os
{
public link unit screen {}
public link unit motor {}
public link unit sound {}
public link unit key {}
public link unit out_led {}
//操作系统初始化
public void init()
{
//OS初始化(与任务无关项)
timer_init();
//任务初始化
task_init();
}
//开始操作系统运行(定时器后台运行)
public void start()
{
//打开中断,进入系统工作状态
#asm "sei"
}
//定时器初始化
//晶振 12MHz, 分频比为64, 计数脉冲频率为 187500Hz
//计数值为 0 * 256 + 188 = 188
//中断频率为 187500 / 188 = 1000Hz
void timer_init()
{
//工作模式设置
chip.TCCR1A = 0;
chip.TCCR1B = 0b0000_1011;
//定时间隔设置
chip.OCR1AH = 0;
chip.OCR1AL = 188;
//清中断
chip.TIMSK |= 0b0001_0000;
}
//任务初始化
void task_init()
{
screen_tick = 0;
motor_tick = 0;
sound_tick = 0;
key_tick = 0;
out_led_tick = 0;
}
//中断服务函数
interrupt [chip.interrupt_m.timer1_compA] void timer1_compA()
{
#asm "cli"
//运行屏幕显示进程
++screen_tick;
if( screen_tick == max_screen_tick ) {
screen_tick = 0;
screen.run();
}
//运行电机控制进程
++motor_tick;
if( motor_tick == max_motor_tick ) {
motor_tick = 0;
motor.run();
}
//运行声音控制进程
++sound_tick;
if( sound_tick == max_sound_tick ) {
sound_tick = 0;
sound.run();
}
//运行按键扫描进程
++key_tick;
if( key_tick == max_key_tick ) {
key_tick = 0;
key.run();
}
//运行指示灯控制进程
++out_led_tick;
if( out_led_tick == max_out_led_tick ) {
out_led_tick = 0;
out_led.run();
}
}
//屏幕显示进程参数
uint8 screen_tick;
uint8 max_screen_tick = [u.const]5;
//电机控制进程参数
uint8 motor_tick;
uint8 max_motor_tick = [u.const]3;
//声音控制进程参数
uint8 sound_tick;
uint8 max_sound_tick = [u.const]1;
//按键扫描进程参数
uint8 key_tick;
uint8 max_key_tick = [u.const]50;
//指示灯控制进程参数
uint8 out_led_tick;
uint8 max_out_led_tick = [u.const]120;
link unit chip {} = u.user.chip;
}
//************************************************************************************
//以下为非进程函数,直接进行调用,有些函数的执行时间可能很长
//加载软件定时器类
import syslib.software.time.avr_12mhz.time;
//=====================================================
//加载并配置指示灯类
unit led_pack
{
public link unit user {} = led;
unit config
{
public link bit LED_ddr = u.user.chip.DDRA.1;
public link bit LED_port = u.user.chip.PORTA.1;
}
led.config = config;
led.time = u.user.time;
import syslib.hardware.led.avr_single.led;
}
//=====================================================
//激光器类
unit laser
{
//初始化
public void init()
{
OUT_ddr = high;
OUT = low;
}
//打开激光器
public void open()
{
OUT = high;
}
//关闭激光器
public void close()
{
OUT = low;
}
link bit OUT = u.user.chip.PORTD.0;
link bit OUT_ddr = u.user.chip.DDRD.0;
}
//=====================================================
//自由摆 角度转换类
unit pendulum
{
//初始化
public link void init() {} = AD.init;
//获取单摆角度
public sint16 read_angle()
{
uint16 data = AD.convert( 0 );
return (sint)( data - 512 ) * 40s / 135s;
//忽略下列运算
data >>= 2;
return (sint)standard_angle[data.0[uint8]];
}
///////////////////////////////////////////////
//注意:以下表格仅用于调试,已无效
//电位器角度范围: 277°
[256]u.code uint8 standard_angle = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 128, 129, 130, 131, 133, 134, 135, 136, 137, 139, 140,
141, 142, 143, 145, 146, 147, 148, 149, 151, 152, 153, 154, 156, 157, 158, 159,
160, 162, 163, 164, 165, 166, 168, 169, 170, 171, 172, 174, 175, 176, 177, 178,
180, 181, 182, 183, 184, 186, 187, 188, 189, 190, 192, 193, 194, 195, 196, 198,
199, 200, 201, 202, 204, 205, 206, 207, 208, 210, 211, 212, 213, 214, 216, 217,
218, 219, 220, 222, 223, 224, 225, 226, 228, 229, 230, 231, 232, 234, 235, 236,
237, 238, 240, 241, 242, 243, 244, 246, 247, 248, 249, 250, 252, 253, 254, 255,
0, 1, 2, 3, 4, 6, 7, 8, 9, 10, 12, 13, 14, 15, 16, 18,
19, 20, 21, 22, 24, 25, 26, 27, 28, 30, 31, 32, 33, 34, 36, 37,
38, 39, 40, 42, 43, 44, 45, 46, 48, 49, 50, 51, 52, 54, 55, 56,
57, 58, 60, 61, 62, 63, 64, 66, 67, 68, 69, 70, 72, 73, 74, 75,
76, 78, 79, 80, 81, 82, 84, 85, 86, 87, 88, 90, 91, 92, 93, 94,
96, 97, 98, 99, 100, 102, 103, 104, 105, 107, 108, 109, 110, 111, 113, 114,
115, 116, 117, 119, 120, 121, 122, 123, 125, 126, 127, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
//==============================================
//AD转换元件
unit AD
{
//初始化
public void init()
{
chip.DDRA.0 = low;
chip.PORTA.0 = low;
chip.ADCSRA = 0b1000_0111; //128分频
}
//读取某个通道的AD数值
public uint16 convert( uint8 channel )
{
chip.ADMUX = 0b0100_0000 + channel;
chip.ADCSRA.6 = high;
while( chip.ADCSRA.4 == low ) {}
chip.ADCSRA.4 = low;
uint16 data;
data.0[uint8] = chip.ADCL;
data.8[uint8] = chip.ADCH;
return data;
}
link unit chip {} = u.user.chip;
}
}
//************************************************************************************
//主控制类集合,在此对所有设备进行控制
//=====================================================
//主控制元件
controller.led = led_pack.user;
controller.time = time;
controller.motor = motor;
controller.key = key;
controller.screen = screen;
controller.sound = sound;
controller.out_led = out_led;
controller.pendulum = pendulum;
controller.laser = laser;
controller.os = os;
controller.function_list = function_list;
unit controller
{
public link unit led {}
public link unit time {}
public link unit motor {}
public link unit key {}
public link unit screen {}
public link unit sound {}
public link unit out_led {}
public link unit pendulum {}
public link unit laser {}
public link unit function_list {}
public link unit os {}
//引擎函数
public void engine()
{
//----------------------------------------
//底层驱动类
//指示灯初始化
led.init();
led.flash( 3 );
time.delay_10ms( 50 );
//单摆角度转换器初始化
pendulum.init();
//激光器初始化
laser.init();
//----------------------------------------
//系统进程类
//灯光提示初始化
out_led.init();
//声音提示初始化
sound.init();
//按键初始化
key.init();
//显示屏初始化
screen.init();
//步进电机初始化
motor.init();
//操作系统初始化
os.init();
//开始运行操作系统(在后台运行)
os.start();
//----------------------------------------
//运行用户界面
UI();
}
//用户界面初始化
void UI_init()
{
out_led.flash( 5 );
sound.play( sound.OK );
current_item_index = 0;
UI_refresh();
}
//刷新用户界面显示
void UI_refresh()
{
uint8 i = 0;
loop( 4 ) {
screen.buffer[i] = item_name_list[current_item_index][i];
++i;
}
}
//用户界面
void UI()
{
//用户界面初始化
UI_init();
//无限循环,运行用户界面
forever {
//如果按下模式选择键,选择下一个模式
if( key.MODE_enable() ) {
sound.play( sound.NEXT );
out_led.flash( 1 );
++current_item_index;
if( current_item_index == item_number ) {
current_item_index = 0;
}
}
//如果按下功能键,进入当前模式
if( key.FUNC_enable() ) {
sound.play( sound.OK );
out_led.flash( 3 );
//根据当前选中菜单项执行相应功能
switch( current_item_index ) {
case 0: function_list.base_function1();
break;
case 1: function_list.base_function2();
break;
case 2: function_list.base_function3();
break;
case 3: function_list.extend_function1();
break;
case 4: function_list.extend_function2();
break;
case 5: function_list.my_function1();
break;
default: //流程不会执行到这里
break;
}
current_item_index = 0;
}
//刷新用户界面
UI_refresh();
}
}
//当前选中菜单项
uint8 current_item_index;
//菜单项数目
uint8 item_number = [u.const]6;
//用户界面菜单项元素显示
[item_number][4]u.code uint8 item_name_list = {
1, 0x11, 0x0b, 1,
2, 0x11, 0x0b, 2,
3, 0x11, 0x0b, 3,
4, 0x11, 0x0e, 1,
5, 0x11, 0x0e, 2,
6, 0x11, 0x0a, 1
};
}
//=====================================================
//用户功能类
function_list.motor = motor;
function_list.key = key;
function_list.screen = screen;
function_list.sound = sound;
function_list.out_led = out_led;
function_list.pendulum = pendulum;
function_list.laser = laser;
function_list.time = time;
unit function_list
{
public link unit motor {}
public link unit key {}
public link unit screen {}
public link unit sound {}
public link unit out_led {}
public link unit pendulum {}
public link unit laser {}
public link unit time {}
//以下设计了很多功能程序,按照电子大赛B题的题目要求只需展示其中的5个功能
//通过虚拟函数链接到对应的功能函数
public link void base_function1() {} = 摆动一个周期平板自动旋转一周;
public link void base_function2() {} = 托住一枚硬币;
public link void base_function3() {} = 托住八枚硬币;
public link void extend_function1() {} = 激光笔静止定位;
public link void extend_function2() {} = 激光笔自动跟踪;
public link void my_function1() {} = 自动保持平板水平;
//空函数
public void NULL_function() {}
public void 摆动一个周期平板自动旋转一周()
{
sint16 buffer0 = 0s;
sint16 buffer1 = 0s;
sint16 buffer2 = 0s;
sint16 current_angle = 0s;
uint8 screen_tick = 0;
forever {
//按下模式键则退出当前功能, 返回模式选择用户界面
if( key.MODE_enable() ) {
sound.play( sound.EXIT );
return;
}
//读取角度并计算平均数
buffer0 = buffer1;
buffer1 = buffer2;
buffer2 = current_angle;
current_angle = pendulum.read_angle();
current_angle += buffer2 + buffer1 + buffer0;
current_angle /= 4s;
if( current_angle == 0s ) {
motor.rol_half_circle();
}
//显示进程
++screen_tick;
if( screen_tick == 10 ) {
screen_tick = 0;
screen.show_s_number( current_angle );
}
}
}
public void 托住一枚硬币()
{
sint16 buffer0 = 0s;
sint16 buffer1 = 0s;
sint16 buffer2 = 0s;
sint16 current_angle = 0s;
uint8 screen_tick = 0;
//等待开始
while( !key.FUNC_enable() ) {
//读取当前角度并进行滤波
buffer0 = buffer1;
buffer1 = buffer2;
buffer2 = current_angle;
current_angle = pendulum.read_angle();
current_angle += buffer2 + buffer1 + buffer0;
current_angle /= 4s;
//保持平板水平
motor.angle = -current_angle;
//显示进程
++screen_tick;
if( screen_tick == 10 ) {
screen_tick = 0;
screen.show_s_number( current_angle );
}
}
sound.play( sound.START );
//显示等待
screen.show_wait();
//用户等待
time.delay_10ms( 250 );
//指示操作者开始放手
out_led.flash( 3 );
sound.play( sound.START );
//等待操作者的反应时间
time.delay_10ms( 30 );
bool is_ok = false;
forever {
//按下模式键则退出当前功能, 返回模式选择用户界面
if( key.MODE_enable() ) {
sound.play( sound.EXIT );
return;
}
//读取角度
buffer0 = buffer1;
buffer1 = buffer2;
buffer2 = current_angle;
current_angle = pendulum.read_angle();
current_angle += buffer2 + buffer1 + buffer0;
current_angle /= 4s;
if( !is_ok ) {
motor.angle = -current_angle / 3s;
if( current_angle > 0s ) {
motor.angle = 0s;
is_ok = true;
}
}
//显示进程
++screen_tick;
if( screen_tick == 10 ) {
screen_tick = 0;
screen.show_s_number( current_angle );
}
}
}
public void 托住八枚硬币()
{
//哎 没实现...
//用前一个函数实现这个功能,效果不太好.
//没时间了,就这样吧
托住一枚硬币();
}
public void 激光笔静止定位()
{
sint16 buffer0 = 0s;
sint16 buffer1 = 0s;
sint16 buffer2 = 0s;
sint16 current_angle = 0s;
uint8 screen_tick = 0;
bool is_auto = false;
motor.is_slow = true;
//打开激光器
laser.init();
forever {
//按下模式键则退出当前功能, 返回模式选择用户界面
if( key.MODE_enable() ) {
motor.is_slow = false;
sound.play( sound.EXIT );
//关闭激光器
laser.init();
return;
}
//读取角度
buffer0 = buffer1;
buffer1 = buffer2;
buffer2 = current_angle;
current_angle = pendulum.read_angle();
current_angle += buffer2 + buffer1 + buffer0;
current_angle /= 4s;
//按下开始键则控制电机转到目标角度
if( key.FUNC_enable() ) {
is_auto = true;
motor.is_OK = false;
sound.play( sound.START );
}
//判断是否自动跟踪
if( is_auto ) {
motor.angle = (sint)seg[(uint)( current_angle + 100s )];
if( motor.is_OK ) {
out_led.flash( 3 );
sound.play( sound.OK );
is_auto = false;
}
}
//显示进程
++screen_tick;
if( screen_tick == 10 ) {
screen_tick = 0;
screen.show_s_number( motor.current_angle );
}
}
}
public void 激光笔自动跟踪()
{
sint16 buffer0 = 0s;
sint16 buffer1 = 0s;
sint16 buffer2 = 0s;
sint16 current_angle = 0s;
uint8 screen_tick = 0;
//打开激光器
laser.init();
forever {
//按下模式键则退出当前功能, 返回模式选择用户界面
if( key.MODE_enable() ) {
sound.play( sound.EXIT );
//关闭激光器
laser.close();
return;
}
//读取角度
buffer0 = buffer1;
buffer1 = buffer2;
buffer2 = current_angle;
current_angle = pendulum.read_angle();
current_angle += buffer2 + buffer1 + buffer0;
current_angle /= 4s;
motor.angle = (sint)seg[(uint)( current_angle + 100s )];
//显示进程
++screen_tick;
if( screen_tick == 10 ) {
screen_tick = 0;
screen.show_s_number( current_angle );
}
}
}
//激光笔跟踪曲线,根据一个事先推导的数学公式产生此表格
[200]u.code uint16 seg = {
181, 180, 178, 176, 175, 173, 172, 170, 168, 168,
166, 164, 162, 160, 158, 157, 155, 153, 151, 150,
148, 146, 143, 141, 139, 137, 135, 133, 130, 129,
127, 125, 122, 120, 118, 115, 113, 110, 108, 107,
104, 102, 100, 97, 95, 93, 91, 88, 86, 85,
83, 80, 78, 76, 74, 72, 70, 68, 66, 65,
63, 61, 59, 57, 56, 54, 52, 50, 49, 48,
46, 45, 43, 42, 40, 39, 37, 36, 34, 34,
32, 31, 30, 28, 27, 26, 24, 23, 22, 21,
20, 19, 18, 17, 15, 14, 13, 12, 11, 11,
10, 9, 8, 7, 6, 5, 4, 3, 2, 2,
1, 0,65535,65534,65533,65532,65531,65530,65529,65529,
65528,65527,65526,65525,65524,65523,65522,65521,65521,65521,
65520,65519,65518,65517,65516,65515,65514,65513,65513,65513,
65512,65511,65510,65509,65508,65508,65507,65506,65505,65505,
65504,65504,65503,65502,65501,65500,65499,65499,65498,65498,
65497,65496,65495,65495,65494,65493,65492,65491,65491,65491,
65490,65489,65488,65488,65487,65486,65485,65484,65484,65484,
65483,65482,65482,65481,65480,65479,65478,65478,65477,65477,
65476,65476,65475,65474,65473,65472,65472,65471,65470,65470
};
public void 自动保持平板水平()
{
uint8 screen_tick = 0;
forever {
//按下模式键则退出当前功能, 返回模式选择用户界面
if( key.MODE_enable() ) {
sound.play( sound.EXIT );
return;
}
sint16 a = pendulum.read_angle();
motor.angle = -a;
++screen_tick;
if( screen_tick == 10 ) {
screen.show_s_number( a );
}
}
}
} |
阿莫论坛20周年了!感谢大家的支持与爱护!!
知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)
|