|
先上电路图:
(原文件名:SD.png)
程序如下:
/*****************
接线说明: PB0: PWM输出, 控制模式
PB1: (档位切换)按键输入检测, 平时为高电平, 有按键时变为低电平
熔丝位设置 :
1: SPIEN = 0 SPI下载使能
2: EESAVE = 1 芯片擦除时EEPROM擦除
3: WDTON = 1 开门狗禁用
4: CKDIV8 = 0 时钟不8分频
5: SUT1:0 = 00 快速上电
6: CKSEL1:0 = 10 使用内部9.6MHZ频率
7: SELFPRGEN = 0
8: DWEN = 0
9: BODLEVEL1:0= 10 BOD触发电平1.8V
10: RSTDISBL = 0; 外部复位禁用
*****************/
#include <inavr.h>
#include <iotiny13.h>
volatile unsigned int flash_sign = 0x00;
volatile unsigned int key_pattern = 0x00;
volatile unsigned int sos_count1 = 0x00;
volatile unsigned int sos_count2 = 0x00;
/****************
功能与切换状态的设置
****************/
#define Dis_Min 1 //低亮10%
#define Dis_Mid 2 //中亮30%
#define Dis_Max 3 //高亮100%
#define Dis_Flash 4 //暴闪
#define Dis_Sos 5
//SOS求救信号(3短3长3短)
//长的时间是三个短的时间
//短和短,长和长之间的间隔为一个短的时间
//短和长之间的间隔是三个短的时间
//两次发送间隔是7个短的时间
#define Dis_top 5 //支持模式最大值
/****************
占空比设置
****************/
#define Stack_min 0xe0
#define Stack_mid 0xa0
#define Stack_max 0x01
#define Stack_flash 0xd0
#define Stack_sos 0xb0
/***************
Use_eeprom=1 亮度记忆功能
Use_eeprom=0 没有亮度记忆功能
***************/
#define Use_eeprom 0
/****************
PB0为PWM模式输出;
PB1为按键信号检测,控制模式切换
****************/
void IO_init(void)
{
DDRB = 0x1d; //0001 1101
PORTB = 0x02;//0000 0010
}
void Inter_pwm(void)
{
TCCR0B = 0x00; //关T/C0
PORTB &= 0xfe;
TCNT0 = 0x00; //设置TC0计数寄存器初值
TCCR0A = 0xc3; //比较匹配时set OC0A;TOP时clr OC0A
TIMSK0 &= 0xf1; //屏蔽OCIE0A与TOIE0中断
TCCR0B = 0x01; //开T/C0;开T/C0;不预分频
}
void Inter_ctc(void)
{
TCCR0B = 0x00; //关T/C0
PORTB &= 0xfe;
TCNT0 = 0x00; //设置TC0计数寄存器初值
TCCR0A = 0x02; //CTC模式
TIMSK0 |= 0x0f; //输出比较匹配OCIE0A 中断使能
SREG |= 0x80; //开启全局中断I
TCCR0B = 0x05; //开T/C0;1024分频
}
void Display_status(unsigned int Dis_st)
{
if(Dis_st == Dis_Flash)
flash_sign = 0x01;
else
flash_sign = 0x00;
switch(Dis_st)
{
case Dis_Min: OCR0A = Stack_min;
Inter_pwm();
break;
case Dis_Mid: OCR0A = Stack_mid;
Inter_pwm();
break;
case Dis_Max: OCR0A = Stack_max;
Inter_pwm();
break;
case Dis_Flash: OCR0A = Stack_flash;
Inter_ctc();
break;
case Dis_Sos: OCR0A = Stack_sos;
sos_count1 = 0x00;
sos_count2 = 0x00;
Inter_ctc();
break;
}
}
#if Use_eeprom
#define ER_address 0x00 //设置数据在EEPROM中存储地址
void EEPROM_write(unsigned char Address, unsigned char Data)
{
SREG &= 0x7f; //关全局中断;防止写操作有中断产生
while(EECR & 0x02); //等待上一次写操作结束
EECR &= 0x0f; //设置编程模式
EEAR = Address;
EEDR = Data; //设置地址与数据寄存器
EECR |= 0x04;
EECR |= 0x02; //启动写操作
SREG |= 0x80; //开全局中断
}
void EEPROM_read(unsigned char Address)
{
while(EECR & 0x02); //等待上一次写操作结束
EEAR = Address;
EECR |= 0x01; //启动读操作
key_pattern = EECR;
Display_status(key_pattern);
}
#endif
void Key_check(void)
{
static unsigned int key_sign = 0x00;
static unsigned int i = 0x00;
#if Use_eeprom
static unsigned int j = 0x00;
if(key_sign==0x01)
{
if(++j>100)
{
EEPROM_write(ER_address, key_pattern);
j = 0x00;
}
}
#endif
if((PINB&0x02)==0x00)
{
i++;
if(i>200)
key_sign = 0x01;
}
if(key_sign == 0x01)
{
i = 0x00;
if((PINB&0x02)==0x02)
{
PORTB ^= 0x04; //test
if((++key_pattern)>Dis_top)
key_pattern= 0x01;
Display_status(key_pattern);
key_sign = 0x00;
}
}
}
#pragma vector = TIM0_COMPA_vect
__interrupt void CTC_COMPA(void)
{
TIFR0 &= 0xfa; //清除 OCF0A输出比较标志位
if((TCCR0A & 0x02) == 0x02)
{
if(flash_sign == 0x01)
PORTB ^= 0x01;
else
{
if(sos_count1 > 0)
sos_count1--;
else
{
PORTB ^= 0x01;
switch(++sos_count2)
{
case 0x06: sos_count1 = 0x02;
break;
case 0x07: sos_count1 = 0x02;
break;
case 0x09: sos_count1 = 0x02;
break;
case 0x0b: sos_count1 = 0x02;
break;
case 0x0c: sos_count1 = 0x02;
break;
case 0x12: sos_count1 = 0x06;
sos_count2 = 0x00;
return;
}
}
}
}
}
void main(void)
{
IO_init();
#if Use_eeprom
EEPROM_read(ER_address);
#else
key_pattern = Dis_Sos;
Display_status(key_pattern);
#endif
while(1)
{
Key_check();
}
}
这个程序用POTUES仿真可以,但是我用实物仿真的时候开关电后档位不会发生变化;即使我把PB1口设置为按键输入直接拉低 档位也不会变化。。。。小弟第一次学写程序 希望各位前辈指点指点 。。。。先在此谢谢过。。。 |
阿莫论坛20周年了!感谢大家的支持与爱护!!
月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!
|