写一个针对于CC2530的程序用定时器1,一共有四个灯和一个开关,要求如下:1、模块上电后D3、D4、D5、D6都不亮 2、按下第一次按键后,D3亮一秒灭一秒,循环 3、按下第二次按键后,D4亮两秒灭一秒,循环 4、按下第三次按键后,D5亮一秒灭两秒,循环 5、按下第四次按键后,D6亮半秒灭半秒,循环 6、按下第五次按键后,所有灯全灭 7、可循环以上效果
时间: 2023-07-10 19:08:23 浏览: 60
以下是针对CC2530的程序,实现上述要求:
```c
#include "ioCC2530.h"
#define LED_3 P0_0 // D3
#define LED_4 P0_1 // D4
#define LED_5 P0_2 // D5
#define LED_6 P0_3 // D6
#define BTN P0_4 // 开关
#define TIMER_PRESCALER 128
#define TIMER_PERIOD_MS 10
#define BTN_RELEASED 1
#define BTN_PRESSED 0
enum {
LED_OFF,
LED_ON,
LED_BLINK_1S,
LED_BLINK_2S,
LED_BLINK_1S_2S,
LED_BLINK_HALF_S,
};
unsigned char led_state[4] = {LED_OFF, LED_OFF, LED_OFF, LED_OFF};
unsigned char current_led = 0;
unsigned char btn_state = BTN_RELEASED;
unsigned int timer_count = 0;
unsigned int blink_count = 0;
void init_timer1() {
T1CTL |= 0x0C; // 开启定时器1,使用ACLK,不分频
T1CCTL0 |= 0x44; // 模式为比较模式,输出模式为设置输出
T1CC0L = (65535 - (32768 / TIMER_PRESCALER * TIMER_PERIOD_MS / 1000)) & 0xFF; // 计算比较值
T1CC0H = (65535 - (32768 / TIMER_PRESCALER * TIMER_PERIOD_MS / 1000)) >> 8;
IEN1 |= 0x04; // 开启定时器1比较中断
}
void init_gpio() {
P0SEL &= ~0x1F; // 把P0的0~4这5个引脚设为普通IO口
P0DIR |= 0x0F; // 把P0的0~3这4个引脚设为输出
P0DIR &= ~0x10; // 把P0的4这个引脚设为输入
P0 |= 0x10; // 把P0的4这个引脚上拉
}
void switch_led() {
led_state[current_led] = LED_OFF;
current_led = (current_led + 1) % 4;
led_state[current_led] = LED_BLINK_1S;
}
void toggle_btn_state() {
if (btn_state == BTN_RELEASED) {
btn_state = BTN_PRESSED;
} else {
btn_state = BTN_RELEASED;
}
}
void toggle_led(unsigned char led) {
switch (led_state[led]) {
case LED_OFF:
P0 &= ~(1 << led);
break;
case LED_ON:
P0 |= (1 << led);
break;
case LED_BLINK_1S:
if (blink_count % 2 == 0) {
P0 |= (1 << led);
} else {
P0 &= ~(1 << led);
}
break;
case LED_BLINK_2S:
if (blink_count % 3 == 0) {
P0 |= (1 << led);
} else {
P0 &= ~(1 << led);
}
break;
case LED_BLINK_1S_2S:
if (blink_count % 3 != 2) {
P0 |= (1 << led);
} else {
P0 &= ~(1 << led);
}
break;
case LED_BLINK_HALF_S:
if (blink_count % 2 == 0) {
P0 |= (1 << led);
} else {
P0 &= ~(1 << led);
}
break;
}
}
#pragma vector=T1_VECTOR
__interrupt void timer1_isr() {
T1STAT &= ~0x01; // 清除中断标志
timer_count++;
if (timer_count % 100 == 0) {
blink_count++;
}
if (timer_count % 200 == 0) {
switch_led();
}
toggle_led(0);
toggle_led(1);
toggle_led(2);
toggle_led(3);
}
int main() {
init_gpio();
init_timer1();
while (1) {
if (btn_state == BTN_PRESSED) {
if (btn_state != BTN_PRESSED) {
switch_led();
blink_count = 0;
} else if (led_state[current_led] != LED_OFF) {
switch (current_led) {
case 0:
led_state[current_led] = LED_BLINK_1S;
break;
case 1:
led_state[current_led] = LED_BLINK_2S;
break;
case 2:
led_state[current_led] = LED_BLINK_1S_2S;
break;
case 3:
led_state[current_led] = LED_BLINK_HALF_S;
break;
}
blink_count = 0;
} else {
led_state[0] = LED_OFF;
led_state[1] = LED_OFF;
led_state[2] = LED_OFF;
led_state[3] = LED_OFF;
P0 &= ~0x0F;
}
}
}
}
```
这个程序使用定时器1和GPIO控制四个LED灯和一个开关,实现上述要求。程序中使用了一个状态数组 `led_state`,保存每个LED的状态,使用一个计数器 `current_led` 记录当前亮的LED的编号,使用一个计数器 `timer_count` 记录定时器中断的次数,以及一个计数器 `blink_count` 记录闪烁的次数。在定时器中断中,根据当前的状态控制LED的亮灭,并更新计数器。在主循环中,根据按键状态和LED状态进行操作。