极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 35011|回复: 12

用ATtiny85做了一个倒计时器

[复制链接]
发表于 2017-12-11 18:12:16 | 显示全部楼层 |阅读模式
本帖最后由 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...

贴上最终效果和代码。


  1. #include <font8x16.h>
  2. #include <font6x8.h>
  3. #include <DigisparkOLED.h>
  4. #include <Wire.h>
  5. // ===========================================================================

  6. const byte encoder_SCK = PB3;
  7. const byte encoder_SDA = PB4;
  8. const byte encoder_SW  = PB1;
  9. volatile bool encoder_SCK_Last = HIGH;

  10. volatile int seconds = 90;
  11. char time[6];

  12. void setup() {
  13.         pinMode(encoder_SCK, INPUT_PULLUP);
  14.         pinMode(encoder_SDA, INPUT_PULLUP);
  15.         pinMode(encoder_SW, INPUT_PULLUP);
  16.         // enable pin change interrupt on P3
  17.         GIMSK |= 1 << PCIE;
  18.         PCMSK |= 1 << PCINT3;
  19.         // put your setup code here, to run once
  20.         oled.begin();
  21.         second_to_char(seconds);
  22.         display();
  23. }

  24. // PCINT0 isr 引脚中断函数
  25. ISR(PCINT0_vect) {
  26.         bool encoder_sck_sta = digitalRead(encoder_SCK);
  27.         if ((encoder_SCK_Last == HIGH) && (encoder_sck_sta == LOW)) {  // rotation detected
  28.                 if (digitalRead(encoder_SDA) == LOW) {
  29.                         if(seconds < 3600) seconds++;
  30.                 }
  31.                 else {
  32.                         if (seconds > 0) seconds--;
  33.                 }
  34.         }
  35.         encoder_SCK_Last = encoder_sck_sta;
  36.         second_to_char(seconds);
  37.         display();
  38. }

  39. void loop() {
  40.         if (digitalRead(encoder_SW) == 1) {
  41.                 delay(50);
  42.                 if(digitalRead(encoder_SW) == 1)
  43.                         // 禁止引脚中断
  44.                         GIMSK = 0;
  45.                         PCMSK = 0;
  46.                         countDown();
  47.         }
  48. }

  49. void countDown() {
  50.         int countSec = seconds;
  51.         while (countSec > 0) {
  52.                 delay(1000);
  53.                 countSec--;
  54.                 second_to_char(countSec);
  55.                 display();
  56.         }
  57.         beep();
  58.         second_to_char(seconds);
  59.         display();
  60.         // 重新启用引脚中断
  61.         GIMSK |= 1 << PCIE;
  62.         PCMSK |= 1 << PCINT3;
  63. }

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

  71. void beep() {
  72.         pinMode(encoder_SW, OUTPUT);
  73.         delay(10);
  74.         for (byte i = 0; i < 3; i++) {
  75.                 digitalWrite(encoder_SW, HIGH);
  76.                 delay(100);
  77.                 digitalWrite(encoder_SW, LOW);
  78.                 delay(100);
  79.         }
  80.         pinMode(encoder_SW, INPUT_PULLUP);
  81.         delay(10);
  82. }

  83. // 用了string类 flash就爆了 只能用最原始方法
  84. void second_to_char(int sec) {
  85.         time[0] = char(int(sec / 60) / 10) + 48;  // numeric + 48 = numeric's ascii
  86.         time[1] = char(int(sec / 60) % 10) + 48;
  87.         time[2] = 58;        // ":" ascii
  88.         time[3] = char(int(sec % 60) / 10) + 48;
  89.         time[4] = char(int(sec % 60) % 10) + 48;
  90. }
复制代码


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复

使用道具 举报

发表于 2017-12-12 09:28:56 | 显示全部楼层
学习了。
楼主是个有想法有执行力的人。。。。

attiny85我买了好几个,都是折腾一下就吃灰了。
回复 支持 反对

使用道具 举报

发表于 2017-12-12 10:07:08 | 显示全部楼层
最近也在玩85,不错。至于现在淘宝上的板子,电脑不认,我都是自己刷上1.06版的HEX,就可以了
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-12-12 11:06:02 | 显示全部楼层
电脑不认,我都是自己刷上1.06版的HEX,就可以了

你刷的是bootloader吗?我刷了这个上的电脑还是不认
https://github.com/micronucleus/micronucleus
回复 支持 反对

使用道具 举报

发表于 2017-12-14 21:04:12 | 显示全部楼层
最近也買了一片 ATTINY85 的開發板要來試試,
首先就是研究如何將程式上傳,折騰了一陣子,
最後成功了

這是我找到的教學影片:
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
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-12-15 11:15:40 | 显示全部楼层
本帖最后由 kirbyklein 于 2017-12-15 11:48 编辑

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

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

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

发表于 2017-12-15 20:26:35 | 显示全部楼层
TINY85 就是8个脚,体积小,价格真的挺高的
回复 支持 反对

使用道具 举报

发表于 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)
的程式還沒失敗過(單純改變閃爍頻率來測試是否有上傳成功),
但大程式就沒試過了,您可以先上傳小程式試試
回复 支持 反对

使用道具 举报

发表于 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 來做紅外線遙控使用

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

使用道具 举报

 楼主| 发表于 2017-12-18 15:46:13 | 显示全部楼层
這樣應該就沒什麼問題才對,我試過 IDE 選用其他的開發板配置
都沒成功(上傳會停住不動),只有 Default 16.5mhz 這項沒問題,

我也是用的这个,但就是上传到65%时发生错误。估计会不会是bootloader的问题。
你是烧的哪个bootloader啊?
回复 支持 反对

使用道具 举报

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

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

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

btw,您有先試試小程式能不能用嗎? 比方說 BLANK 這種
範例程式
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-12-19 12:29:50 | 显示全部楼层
btw,您有先試試小程式能不能用嗎? 比方說 BLANK 這種
範例程式


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

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-4-20 06:31 , Processed in 0.041811 second(s), 23 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

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