kirbyklein 发表于 2017-12-11 18:12:16

用ATtiny85做了一个倒计时器

本帖最后由 kirbyklein 于 2017-12-11 18:19 编辑

很久前,买了一块digispark的ATtiny85小板子,由于一直不知道怎么用就一直搁那里吃灰。 最近正好看到一篇关于这块板子的文章,所以就准备试着玩玩。

首先, 要用这块板子,就先要下载Attiny85这块板子的core files。在arduino IDE的“文件”->“首选项” 里就可以加入开发板管理网址

然后在“工具”->“开发板”->“开发板管理器” 里就有了, 下载就行了。


下载完后, 在开发板里就会多这么多板子


选好板子, 就可以写代码了。当然写代码前要先知道tiny85的引脚, 我是直接下载了atmel avr的官方文档


tiny85总共有8个脚,8kb flash, 去掉VCC 和 GND, 就剩6个可用io了, 然而PB5和RESET是同一个脚, 用了reset功能就又少了一个可用引脚。我的定时器要用到I2C的OLED(因为用数码管需要更多的引脚),于是SCL和SDA要被用掉。 用tiny85驱动128x64的oled在板子的example里就有,所以直接拿来用,它比其它ssd1306驱动要小的多,对于tiny85这么小的flash压力不大


然后调时间设置用编码器又要用掉2个引脚,(因为外部中断INT0在PB2上,而PB2被I2C的SCL占用了,编码器怎么响应中断就是个问题,后来想到以前玩的328p都是有pin change interrput的,所以看了datasheet, 发现也有,于是就按照文档上的说明来, 确实器作用了)。下面是关于pin change interrput的说明, 其实很简单,将GIMSK寄存器的PCIE置位,然后再将PCMSK的PCINT3置位,这样就启动了PB3脚的外部中断了。
GIMSK |= 1 << PCIE;                // 置位PCIE
PCMSK |= 1 << PCINT3;        // 置位PCINT3 (如果要启用其它引脚中断 把PCINT3换成其它引脚就行了)



最后就剩区区一个,所以我就只能把按键和蜂鸣器合用一个引脚(当要读取引脚电平时是INPUT, 用作蜂鸣器时是OUTPUT,最终还是可行的)。

最后编译上传发现串口不认,然后根据网上文章来安装驱动,发现还是不行。最后放弃了USB上传, 改用USBasp来直接写入flash。一次就成功了,如果有哪位大神知道怎么用USB通过BOOTLOADER上传也请指教。但最终还是成功了~~~lol...

贴上最终效果和代码。


#include <font8x16.h>
#include <font6x8.h>
#include <DigisparkOLED.h>
#include <Wire.h>
// ===========================================================================

const byte encoder_SCK = PB3;
const byte encoder_SDA = PB4;
const byte encoder_SW= PB1;
volatile bool encoder_SCK_Last = HIGH;

volatile int seconds = 90;
char time;

void setup() {
        pinMode(encoder_SCK, INPUT_PULLUP);
        pinMode(encoder_SDA, INPUT_PULLUP);
        pinMode(encoder_SW, INPUT_PULLUP);
        // enable pin change interrupt on P3
        GIMSK |= 1 << PCIE;
        PCMSK |= 1 << PCINT3;
        // put your setup code here, to run once
        oled.begin();
        second_to_char(seconds);
        display();
}

// PCINT0 isr 引脚中断函数
ISR(PCINT0_vect) {
        bool encoder_sck_sta = digitalRead(encoder_SCK);
        if ((encoder_SCK_Last == HIGH) && (encoder_sck_sta == LOW)) {// rotation detected
                if (digitalRead(encoder_SDA) == LOW) {
                        if(seconds < 3600) seconds++;
                }
                else {
                        if (seconds > 0) seconds--;
                }
        }
        encoder_SCK_Last = encoder_sck_sta;
        second_to_char(seconds);
        display();
}

void loop() {
        if (digitalRead(encoder_SW) == 1) {
                delay(50);
                if(digitalRead(encoder_SW) == 1)
                        // 禁止引脚中断
                        GIMSK = 0;
                        PCMSK = 0;
                        countDown();
        }
}

void countDown() {
        int countSec = seconds;
        while (countSec > 0) {
                delay(1000);
                countSec--;
                second_to_char(countSec);
                display();
        }
        beep();
        second_to_char(seconds);
        display();
        // 重新启用引脚中断
        GIMSK |= 1 << PCIE;
        PCMSK |= 1 << PCINT3;
}

void display() {
        oled.setCursor(50, 3); //top left
        oled.setFont(FONT8X16);
        for (byte i = 0; i < 5; i++) {
                oled.write(time); //wrap strings in F() to save RAM!
        }
}

void beep() {
        pinMode(encoder_SW, OUTPUT);
        delay(10);
        for (byte i = 0; i < 3; i++) {
                digitalWrite(encoder_SW, HIGH);
                delay(100);
                digitalWrite(encoder_SW, LOW);
                delay(100);
        }
        pinMode(encoder_SW, INPUT_PULLUP);
        delay(10);
}

// 用了string类 flash就爆了 只能用最原始方法
void second_to_char(int sec) {
        time = char(int(sec / 60) / 10) + 48;// numeric + 48 = numeric's ascii
        time = char(int(sec / 60) % 10) + 48;
        time = 58;        // ":" ascii
        time = char(int(sec % 60) / 10) + 48;
        time = char(int(sec % 60) % 10) + 48;
}


maxims 发表于 2017-12-12 09:28:56

学习了。
楼主是个有想法有执行力的人。。。。

attiny85我买了好几个,都是折腾一下就吃灰了。

guansir518 发表于 2017-12-12 10:07:08

最近也在玩85,不错。至于现在淘宝上的板子,电脑不认,我都是自己刷上1.06版的HEX,就可以了

kirbyklein 发表于 2017-12-12 11:06:02

电脑不认,我都是自己刷上1.06版的HEX,就可以了
你刷的是bootloader吗?我刷了这个上的电脑还是不认
https://github.com/micronucleus/micronucleus

shouzama 发表于 2017-12-14 21:04:12

最近也買了一片 ATTINY85 的開發板要來試試,
首先就是研究如何將程式上傳,折騰了一陣子,
最後成功了 :victory:

這是我找到的教學影片:
https://www.youtube.com/watch?v=MmDBvgrYGZs

基本上要安裝 2 個東西,一個是開發板管理員,讓 ARDUINO IDE
能選擇 ATTINY85 的開發板

第二個是 WINDOWS DRIVER ,讓 WINDOWS 能辨識 ATTINY85
開發板,但這個辨識只有幾秒鐘有效,剛插上板子後有出現 USB 週邊,
然後過幾秒就消失,這是正常的,昨天以為沒裝好,弄了好久才發現
不是沒裝好,是本來的特性就是這樣

然後先把 ATTINY85 拔離開 USB,開發板管理員選這個:
Digispark (Default 16.5 mhz)

寫好程式後上傳,編輯器會通知你在 60秒內插上 ATTINY85 的
開發板到 USB ,在時間內插上的話,程式就可以順利上傳了

剛剛有找到一篇教學文,基本上相同,但我弄的比較接近前面影片中的結果

https://sites.google.com/site/3dpttaiwan/00_arduino-shi-yan-shi/00-01

kirbyklein 发表于 2017-12-15 11:15:40

本帖最后由 kirbyklein 于 2017-12-15 11:48 编辑

@shouzama 感谢你的意见,不过youtube在这边是被墙的,要有代理才能翻墙。

几分钟前按照你的方法试了下, 系统已经认了开发板,但上传时有错误,不知你是否遇到过。

迷你强 发表于 2017-12-15 20:26:35

TINY85 就是8个脚,体积小,价格真的挺高的

shouzama 发表于 2017-12-15 21:17:15

kirbyklein 发表于 2017-12-15 11:15
@shouzama 感谢你的意见,不过youtube在这边是被墙的,要有代理才能翻墙。

几分钟前按照你的方法试了下 ...

原來如此,那我概略敘述一下我的安裝方式,首先,
ARDUINO IDE 偏好設定裏面有一個"額外的開發板管理員網址",
請打:
http://digistump.com/package_digistump_index.json

之後進到 IDE 的開發板管理員,就可以找到一個:
Digistump AVR Boards by Digistump 版本 1.6.7

安裝它,裝完後,在開發板功能表中往下找到這項:
Digispark (Default - 16.5mhz)

至於 WINDOWS 的 DRIVER,因為我是用 WIN7 64位元版,
DRIVER 下載網址在: (Digistump Arduino Release 1.6.7)
https://github.com/digistump/DigistumpArduino/releases

裏面有個 Digistump.Drivers.zip ,請下載它並解壓縮,32位元
系統執行 DPinst.exe (64位元則執行 DPinst64.exe)進行安裝,
安裝後,每次插上 ATTINY85的開發板,裝置管理員就會短暫秀出
一個 USB 的週邊(過幾秒鐘後消失),就像您貼的照片那樣

這樣應該就沒什麼問題才對,我試過 IDE 選用其他的開發板配置
都沒成功(上傳會停住不動),只有 Default 16.5mhz 這項沒問題,
目前試傳了幾次驅動 ATTINY85 板上內建 LED (I/O PORT 1)
的程式還沒失敗過(單純改變閃爍頻率來測試是否有上傳成功),
但大程式就沒試過了,您可以先上傳小程式試試 :loveliness:

shouzama 发表于 2017-12-15 21:33:49

迷你强 发表于 2017-12-15 20:26
TINY85 就是8个脚,体积小,价格真的挺高的

就是說啊,TINY85 > NANO > PRO MINI,PRO
MINI 還得加條 CP-2102 USB-TTL 來上傳程式,
感覺上還是 NANO 性價比高一些, CP-2102
我也是有買(為了用 PRO MINI 必要的投資)

目前用 PRO MINI 在做 4X4X4 光立方,也是
踩到 A6 A7 的"陷阱"後才不得已改用 0、1,
又不甘心放著 A6 A7 沒作用,最後爬了一些
紅外線解碼相關的分享文,自已改寫程式、
解遙控器的編碼,拿 A6 來做紅外線遙控使用 :lol

會買 ATTINY85 主要是想試試自己能不能順利
上傳程式使用它,改天我要做個紅外線遙控器
來取代我的 PHILIPS 音響遙控器(快掛點了,買不到),
TINY85 的體積、功能、內存大小就蠻適合的

kirbyklein 发表于 2017-12-18 15:46:13

這樣應該就沒什麼問題才對,我試過 IDE 選用其他的開發板配置
都沒成功(上傳會停住不動),只有 Default 16.5mhz 這項沒問題,
我也是用的这个,但就是上传到65%时发生错误。估计会不会是bootloader的问题。
你是烧的哪个bootloader啊?

shouzama 发表于 2017-12-18 21:39:59

kirbyklein 发表于 2017-12-18 15:46
我也是用的这个,但就是上传到65%时发生错误。估计会不会是bootloader的问题。
你是烧的哪个bootloader ...

bootloader 我沒有弄耶,買來直接用它原本就燒好的,
只有裝開發板管理員、windows驅動程式,就上傳成功了

我目前還沒有自己燒 bootloader 的經驗,因為不是
很需要自己來(連 28支腳的 328p 也是買賣方燒好
bootloader 的 ic 來用 :P)

btw,您有先試試小程式能不能用嗎? 比方說 BLANK 這種
範例程式

kirbyklein 发表于 2017-12-19 12:29:50

btw,您有先試試小程式能不能用嗎? 比方說 BLANK 這種
範例程式

blink上传成功了,然后再传我目前这个又失败,所以我估计是程序过大的问题。

xuqin3 发表于 2018-1-15 11:11:23

不错,测试。
页: [1]
查看完整版本: 用ATtiny85做了一个倒计时器