代码:
7-seg.c
/*《AVR专题精选》随书例程3.通信接口使用技巧项目:改进的延时法实现半双工软件串口文件:7seg.c说明:SPI控制数码管驱动文件作者:邵子扬时间:2012年12月15日*/#include <avr/io.h>extern unsigned char SPI_RW(unsigned char dat);// LED 数码管数量
#define SEG_CNT 2// 7 SEG LED, 共阳极字模(共阴极类似)
//
// 0
// ---
// 5| 6 |1
// ---
// 4| |2
// --- .7
// 3
//
const unsigned char LEDMASK[] =
{ //7654 3210 No0xC0, // 0 1100 0000 00xF9, // 1 1111 1001 10xA4, // 2 1001 0100 20xB0, // 3 1011 0000 30x99, // 4 1001 1001 40x92, // 5 1001 0010 50x82, // 6 1000 0010 60xF8, // 7 1111 1000 70x80, // 8 1000 0000 80x90, // 9 1001 0000 90x88, // A 1000 1000 100x83, // b 1000 0011 110xC6, // C 1100 0110 120xA1, // d 1010 0001 130x86, // E 1000 0110 140x8E, // F 1000 1110 150xC2, // G 1100 0010 160x89, // H 1000 1001 170x7F, // . 0111 1111 180xF1, // J 1111 0001 190xFF, // blank 1111 1111 200xC7, // L 1100 0111 210xBF, // - 1011 1111 220xF7, // _ 1111 0111 230xA3, // o 1010 0011 240xA7, // [ 1010 0111 250xE3, // u 1110 0011 260xB3, // ] 1011 0011 270xAB, // n 1010 1011 280xFF,0xFF,0xFF
};// 显示驱动文件
void DISP7SEG(unsigned char *ledbuf)
{unsigned char i, t;// Enable updatePORTB |= (1 << PB2);for(i = 0; i < SEG_CNT; i++){t = LEDMASK[ledbuf[i] % 32];// 缓存最高位控制数据闪烁if(ledbuf[i] & 0x80)t &= 0x7F;SPI_RW(t);}// Disable updatePORTB &= ~(1 << PB2);
}
main.c
/*《AVR专题精选》随书例程3.通信接口使用技巧项目:SPI驱动数码管文件:main.c说明:主程序作者:邵子扬时间:2012年12月15日*/#include <avr/io.h>// 系统时钟频率
#define F_CPU 1000000UL#include <util/delay.h>#include "macromcu.h"// 定义SPI端口
#define CS B, 2
#define SCK B, 5
#define MOSI B, 3/*函数说明: SPI初始化输入参数:mode: b7: 1 slave, 0 masterb65432: not useb10: mode CPOL CPHA3 1 12 1 01 0 10 0 0speed: b76543: not useb210: speed KHz0 500 F/21 500 F/22 250 F/43 125 F/84 62.5 F/165 31.25 F/326 15.63 F/647 7.81 F/128*/
void SPI_init(char mode, char speed)
{unsigned char bSPR, bSPI2X, bMODE;PINDIR(CS, PIN_OUTPUT);PINDIR(SCK, PIN_OUTPUT);PINDIR(MOSI,PIN_OUTPUT);// SPI modeswitch(mode%4){case 1:// mode 1bMODE = (0 << CPOL)|(1 << CPHA);break;case 2:// mode 2bMODE = (1 << CPOL)|(0 << CPHA);break;case 3:// mode 3bMODE = (1 << CPOL)|(1 << CPHA);break;default:// mode 0bMODE = (0 << CPOL)|(0 << CPHA);break;}// Master or Slaveif((mode & 0x80) == 0)bMODE |= (1 << MSTR);// SPI speedbSPI2X = 0;switch(speed){case 7:// F/128 = 7.8125KbSPR = (1 << SPR1)|(1 << SPR0);break;case 6:// F/64 = 15.625KbSPR = (1 << SPR1)|(0 << SPR0);break;case 5:// F/32 = 31.25KbSPR = (1 << SPR1)|(0 << SPR0);bSPI2X = 1;break;case 4:// F/16 = 62.5KbSPR = (0 << SPR1)|(1 << SPR0);break;case 3:// F/8 = 125KbSPR = (0 << SPR1)|(1 << SPR0);bSPI2X = 1;break;case 2:// F/4 = 250KbSPR = (0 << SPR1)|(0 << SPR0);break;default:// F/2 = 500KbSPR = (0 << SPR1)|(0 << SPR0);bSPI2X = 1;break;}SPCR = (1 << SPE)|bMODE|bSPR;SPSR = (bSPI2X << SPI2X);
}// SPI读写
unsigned char SPI_RW(unsigned char dat)
{SPSR &= ~(1 << SPIF);SPDR = dat;while((SPSR & (1 << SPIF)) == 0);return SPDR;
}// 系统初始化
void init()
{SPI_init(0, 0);
}extern void DISP7SEG(unsigned char *ledbuf);// LED显示缓存
unsigned char LEDBUF[2];
unsigned char cnt;int main()
{init(); // 初始化for(;;){_delay_ms(500); // 延时500mscnt++; // 计数器递增LEDBUF[0] = cnt / 16; // 修改缓存内容LEDBUF[1] = (cnt % 16)|0x80;DISP7SEG(LEDBUF); // 更新显示}return 0;
}
仿真