搜索
bottom↓
回复: 6

attiny13做的手电仿真可以实现,焊接实物后按键换挡没有作用。

[复制链接]

出0入0汤圆

发表于 2010-12-28 11:29:33 | 显示全部楼层 |阅读模式
先上电路图:

(原文件名: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来反美的!

出0入0汤圆

发表于 2010-12-30 20:53:05 | 显示全部楼层
听我的建议,对于初学者,不要使用什么“仿真”,从简单的DD开始,实物练习。

等你具备了一定的水平和能力后,才知道如何真正使用仿真。

一根接线接错了,二极管装反了,溶丝位设置不对,这个你能“仿真”出来吗?这种查错的能力不是仿出来的,只能在实际的做中得到锻炼和经验。

出0入0汤圆

发表于 2010-12-31 09:24:09 | 显示全部楼层
1楼说的很对啊!

看了楼主(代表了当前大部分的“好学生”,因为“坏学生”们都去“不务正业”了)的描述,我也很感慨的:
这也是我们教育的问题,很严重的问题:理论和实践的严重脱节!

我想对楼主说,你到大学学习,更重要的是要学会分析问题和解决问题的能力,可很遗憾,在你的言论中我看得出,你还不具备。

例如,上述的电路,其实可以分成两个相互独立的单元,分别进行调试的。一块是LED驱动,一块是PWM。可是你却只是抛出一整个大问题,全部的电路,加上全部的程序,丢给大家来解决,这怎么行呢?

然后,就是仿真。仿真只是验证你设计阶段的想法的一个手段。特别是在试制成本非常高的时候(比如IC设计),这是有用的手段。但是,并非仿真就一定等于实际。有时候仿真过了,实际的通不过;甚至会发生仿真通不过而实际可用的情况。

最后我要感慨一下不少人对“科学”二字的认识。比如前段时间的中_医(伪)科学之争。我看倒一个能左右大众思想言论的学者,竟然抛出这样的话语,很是伤心!
什么是科学?能验证的是科学吗?“中”医是不能用现阶段的科学理论来验证的,那它就是不科学的,就该废除吗?
恰恰相反,科学是探索,是发现,是否定,是证伪。

出0入0汤圆

 楼主| 发表于 2010-12-31 17:52:50 | 显示全部楼层
十分感谢 machao 和 Cliff 的建议和指点。。。程序中问题已经解决, 同时验证了仿真有时候不一定可靠。

出0入0汤圆

发表于 2010-12-31 20:59:00 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-4-15 16:15:05 | 显示全部楼层
我也在学习






请问最后问题在那!谢谢!

出0入0汤圆

发表于 2011-4-15 16:35:34 | 显示全部楼层
LZ不就问个小问题。。。。真能扯。。。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-25 06:14

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表