📄 display.c
字号:
#include <avr/pgmspace.h>
#include <avr/sfr_defs.h>
#include "display.h"
// LED 数码块段代码: 0, 1,2,3,4,5,6,7,8,9,A,b,c,d,e,f,
const prog_uchar led_seg[16] = {0xfc, 0x60, 0xda, 0xf2, 0x66, 0xb6, 0xbe,0xe0, 0xfe, 0xf6, 0xee, 0x3e, 0x9c, 0x7a, 0x9e, 0x8e};
// LED 数码块位选:
// 位置译码:0->6选LED0->6,7->12选LED7->12
const prog_uchar led_select[14] = {0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x01, 0x20, 0x10, 0x08, 0x04, 0x02};
// 13个LED数码块显示缓冲区,值为BCD码
// (bit0-3) 0x0~0x9 显示数
// (bit4-7) 任意一位不为0,表示该单元显示小数点
u8_t bcd_buf[13];
void init_display(void) {
u8_t tmp;
// I/O SPI: SD/SCLK/SS is 0 for idle!
DDRB |= (_BV(SD)|_BV(SCLK)|_BV(SS));
PORTB &= ~(_BV(SD)|_BV(SCLK));
PORTB |= _BV(SS);
// SPI mode:
SPCR = (_BV(SPE)|_BV(MSTR));
// I/O 74HC595: latch is 0 for lock, oe is 0 for open display
DDRC |= (_BV(LATCH1)|_BV(LATCH2)|_BV(LATCH3)|_BV(OE));
PORTC &= ~(_BV(LATCH1)|_BV(LATCH2)|_BV(LATCH3)|_BV(OE));
// I/O LED14/15/16: dark is 1
DDRC |= (_BV(LED14)|_BV(LED15));
PORTC |= (_BV(LED14)|_BV(LED15));
DDRD |= _BV(LED16);
PORTD |= _BV(LED16);
// 清显示缓冲区
for (tmp=0; tmp<13; tmp++) {
bcd_buf[tmp] = 0;
}
return;
}
// 用于立即关闭所有显示
// 通常在掉电时节能,以便完成剩余的紧急事件。比如:写EEPROM
void display_off(void) {
// 74HC595 ouput Z, display off
PORTC |= _BV(OE);
// 指示灯关闭
LED14_OFF;
LED15_OFF;
LED16_OFF;
return;
}
// sdata: 显示的BCD码0xo~0x9
// spos: 显示位置
// spt: 0x01显示小数点,00x00不显示小数点
// 该过程主要由T0中断自动调用,也可以外部使用
void led_putchar(u8_t sdata, u8_t spos, u8_t spt) {
// 以下参看硬件原理图:操作LED14/15/16
// 74HC595 ouput Z, display off
PORTC |= _BV(OE);
// SPI send out LED segment code,如果该位显示小数点:led_data[i] |= 0x01;
SPDR = (pgm_read_byte(&led_seg[sdata]) | spt);
while (!(SPSR & _BV(SPIF)));
PORTC |= _BV(LATCH1);
PORTC &= ~_BV(LATCH1);
// select need of LED0-4
SPDR = (spos > 6) ? 0x00 : pgm_read_byte(&led_select[spos]);
while (!(SPSR & _BV(SPIF)));
PORTC |= _BV(LATCH2);
PORTC &= ~_BV(LATCH2);
// select need of LED5-12
SPDR = (spos > 6) ? pgm_read_byte(&led_select[spos]) : 0x00;
while (!(SPSR & _BV(SPIF)));
PORTC |= _BV(LATCH3);
PORTC &= ~_BV(LATCH3);
// 74HC595 ouput enable, display on
PORTC &= ~_BV(OE);
return ;
}
// buff: BCD的数据指针,指向8单元的数组
// pdata: 数据最大99999999
// 转换正确返回: 1
u8_t htobcd8(u8_t *buff, u32_t pdata) {
if (pdata > 99999999) {
return 0;
}
else {
buff[0]= pdata/10000000; // BCD码第8位
pdata %= 10000000;
buff[1] = pdata/1000000; // BCD码第7位
pdata %= 1000000;
buff[2] = pdata/100000; // BCD码第6位
pdata %= 100000;
buff[3] = pdata/10000; // BCD码第5位
pdata %= 10000;
buff[4] = pdata/1000; // BCD码第4位
pdata %= 1000;
buff[5] = pdata/100; // BCD码第3位
pdata %= 100;
buff[6] = pdata/10; // BCD码第2位
pdata %= 10;
buff[7] = pdata; // BCD码第1位
}
return 1;
}
// buff: BCD的数据指针,指向8单元的数组
// pdata: 数据最大99999
// 转换正确返回: 1
u8_t htobcd5(u8_t *buff, u32_t pdata) {
if (pdata > 99999) {
return 0;
}
else {
buff[0] = pdata/10000; // BCD码第5位
pdata %= 10000;
buff[1] = pdata/1000; // BCD码第4位
pdata %= 1000;
buff[2] = pdata/100; // BCD码第3位
pdata %= 100;
buff[3] = pdata/10; // BCD码第2位
pdata %= 10;
buff[4] = pdata; // BCD码第1位
}
return 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -