📄 main.c
字号:
//*************头文件***************************
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include <avr/delay.h>
//*************宏定义************************
#define clr 0
#define en_ 1
#define refresh_ 2
#define c_595 PORTB
#define c_154 PORTA
#define Pi_ 3.1415926535
#define Deg_Pi 3.1415926535/180
#define r_hour 9
#define r_min 11
#define r_sec 14
//*************全局变量声明******************
unsigned int sec_flag;
unsigned char cour_=0,op_=1;
//-------------------------------------------
// 数组初始化,直接复制过来,【行】, 【列】
//-------------------------------------------
unsigned char dis_mem[2][32][4]=
{
/*-- 调入了一幅图像:D:\Download\1.bmp --*/
/*-- 宽度x高度=32x32 --*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};
const unsigned char round_[32][4]=
{
/*-- 调入了一幅图像:D:\LiangLei\MyProtuesProject\RoundClock\1.bmp --*/
/*-- 宽度x高度=32x32 --*/
0x00,0x07,0xE0,0x00,0x00,0x39,0x9C,0x00,0x00,0xC1,0x83,0x00,0x01,0x00,0x02,0x80,
0x07,0x00,0x04,0x60,0x08,0x80,0x00,0x10,0x08,0x00,0x00,0x08,0x10,0x00,0x00,0x18,
0x20,0x00,0x00,0x24,0x30,0x00,0x00,0x04,0x48,0x00,0x00,0x02,0x40,0x00,0x00,0x02,
0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x01,0x80,0x00,0x00,0x01,0xE0,0x01,0x80,0x07,
0xE0,0x01,0x80,0x07,0x80,0x00,0x00,0x01,0x80,0x00,0x00,0x01,0x00,0x00,0x00,0x00,
0x40,0x00,0x00,0x02,0x40,0x00,0x00,0x02,0x20,0x00,0x00,0x14,0x24,0x00,0x00,0x0C,
0x18,0x00,0x00,0x08,0x10,0x00,0x00,0x10,0x08,0x00,0x00,0x10,0x06,0x40,0x02,0x20,
0x00,0x80,0x01,0x40,0x01,0x81,0x81,0x80,0x00,0x61,0x86,0x00,0x00,0x17,0xE8,0x00,
};
//*************函数声明**********************
void Delay(unsigned int x);
void init(void);
void Byte_out(unsigned char);
void Dis_Point(unsigned char x, unsigned char y);
void Dis_Deg(float alfa,unsigned char r);
void Dis_D_A(unsigned char hour, unsigned char min, unsigned char sec );
//*************主程序************************
void main (void)
{
/////////////////
/*初始化时间*/
unsigned char hour=2,min=48,sec=45,i,j;
init();
Delay(50);
/////////////////
while(1)
{
if (sec_flag == 1)
{
if(sec==59 && min==59 && hour==23) {hour=0x00;min=0x00;sec=0x00;}
else if (min==59 && sec == 59) {hour++;min=0x00;sec=0x00;}
else if (sec==59) {min++;sec=0x00;}
else {sec++;}
/* 确定当前显示哪个数组*/
if (cour_ == 0) {cour_ = 1;op_ = 0;}
else {cour_ = 0;op_ = 1;}
/* 处理不显示的那个,*/
for (i=0; i<32; i++)
{
for (j=0; j<4; j++)
{
dis_mem[op_][i][j]=round_[i][j];
}
}
Dis_D_A(hour,min,sec);
sec_flag = 0;
}
}
}
/******************************************************************/
/* 函数名:dis_point(unsigned char x, unsgined char y)
/* 参 数:无
/* 功 能:用于在确定的点显示
/******************************************************************/
void Dis_Point(unsigned char x, unsigned char y)
{
dis_mem[op_][y][x/8] = dis_mem[op_][y][x/8] | 1<<(7-x%8);
}
/******************************************************************/
/* 函数名:显示极坐标的点
/* 参 数:无
/* 功 能:用于显示直线从r1 到 r2
/******************************************************************/
void Dis_Deg(float alfa,unsigned char r)
{
unsigned char x,y;
alfa = alfa * Deg_Pi;
x = r*sin(alfa) +15.5;
y = 15.5 - r*cos(alfa);
Dis_Point(x,y);
}
/******************************************************************/
/* 函数名:由数字时间显示图形
/* 参 数:无
/* 功 能:
/******************************************************************/
void Dis_D_A(unsigned char hour, unsigned char min, unsigned char sec )
{
float alfa_sec,alfa_min,alfa_hour,i;
alfa_sec = 6*sec;
alfa_min = 6*min + sec/10;
alfa_hour = 30*hour + min/2;
/*绘制定点*/
/*
Dis_Deg(alfa_sec,r_sec);
Dis_Deg(alfa_min,r_min);
Dis_Deg(alfa_hour,r_hour);
*/
/*极坐标方式绘制指针*/
//秒
for (i=0; i<=r_sec; i=i+0.2)
{
Dis_Deg(alfa_sec,i);
Dis_Deg(alfa_sec+r_sec-i,i);
}
//分
for (i=0; i<=r_min; i=i+0.2)
{
Dis_Deg(alfa_min,i);
Dis_Deg(alfa_min+r_min-i,i);
}
//时
for (i=0; i<=r_hour; i=i+0.2)
{
Dis_Deg(alfa_hour,i);
Dis_Deg(alfa_hour+r_hour-i,i);
}
}
//***初始化*****************************
void init(void)
{
//***关中断***
cli();
DDRA = 0xff; PORTA = 0xff;//A口输出
DDRB = 0xff; PORTB = 0xff;//B口输出
DDRC = 0xff; PORTC = 0xff;
DDRD = 0xff; PORTD = 0xff;
TCNT1H = 0xfa; TCNT1L = 0x24; //8Mhz,1.5ms
//***控制寄存器***
TCCR1A = 0x00;
TCCR1B = 0x02;//8分频
//T1溢出中断使能
TIMSK |= _BV(TOIE1);
//***禁止JTAG***
MCUCSR |= _BV(JTD);
MCUCSR |= _BV(JTD);
MCUCSR |= _BV(JTD);
MCUCSR |= _BV(JTD);
/*初始化SPI*/
/*配置输入输出*/
SPCR = (1<<SPE)|(1<<DORD)|(1<<MSTR);/*使能,主机,分频4*/
SPSR = (1<<SPI2X);//倍频 8Mhz
//***开中断***
sei();
c_595 &=~ _BV(en_);//使能,一直有效
}
/******************************************************************/
/* 函数名:定时器中断
/* 参 数:无
/* 功 能:用于时间的刷新,日期的维护
/******************************************************************/
SIGNAL (SIG_OVERFLOW1 )
{
static unsigned int time_add;
static unsigned char i=0;
unsigned char k;
unsigned char dis_[4];//动态扫描中用到的缓存
TCNT1H = 0xfa; TCNT1L = 0x24; //8Mhz,1.5ms
time_add++;
//-------------------------------------------------------------
// 显示缓存的概念:
//
// 在每次输出前,维护显存,就可以实现字符的移动。
//-------------------------------------------------------------
//i 表示当前被点亮的行
i++; //位置很重要
if(i>=32){i=0;}
dis_[0]=dis_mem[cour_][i][0];//先发1,[0]
dis_[1]=dis_mem[cour_][i][1];
dis_[2]=dis_mem[cour_][i][2];
dis_[3]=dis_mem[cour_][i][3];
if (time_add == 500)//秒
{
time_add = 0;
//显示
sec_flag = 1;
}
c_595 &=~ _BV(clr);//寄存器清零
c_595 |= _BV(clr);
for(k=0; k<4; k++)
{
Byte_out(dis_[k]);
}
c_154= i;//一定要在刷新之前
c_595 &=~ _BV(refresh_);//数据更新
c_595 |= _BV(refresh_);
}
//-------------------------------------------------------------------------------------------------------
// 函数名称:Byte_out()
// 输入参数:byte,需要从74LS164并行口输出的数据
// 输出参数:无
// 功能说明:发送八位串行数据至并口
//--------------------------------------------------------------------------------------------------------
void Byte_out(unsigned char byte)
{
unsigned char i;
SPDR=byte;
while(!(SPSR & (1<<SPIF)));// 等待SPIF置位,即等待数据发送完毕
}
/******************************************************************/
/* 函数名:Delay(unsigned int x)
/* 参 数:int型延时参数
/* 功 能:延时
/******************************************************************/
void Delay(unsigned int x)
{
unsigned int j;
while(x--)
{
for (j=0;j<200;j++){;}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -