⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 display.c

📁 AVR红外遥控
💻 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 + -